diff --git a/docs/src/ptf-catalog/sources/index.md b/docs/src/ptf-catalog/sources/index.md index f25285f..2f9117c 100644 --- a/docs/src/ptf-catalog/sources/index.md +++ b/docs/src/ptf-catalog/sources/index.md @@ -33,3 +33,4 @@ Each page describes the source, scope, inputs, outputs, status, and limitations | [Vereecken et al. soil-moisture retention regressions for Belgian soils.](./vereecken1989.md) | Belgian territory north of the river axis Samber and Meuse | 2 | | [Wang et al. (2012), surface loess across China's Loess Plateau.](./wang2012.md) | Surface soils across the entire Loess Plateau, China | 1 | | [Weber et al. (2020), compiled international soil hydraulic data.](./weber2020.md) | Portuguese, German, UNSODA, and Vereecken soil data collections | 1 | +| [Saturated hydraulic conductivity PTFs for the Loess Plateau of China.](./zhao2016.md) | Typical Loess Plateau of China, covering approximately 430,000 square kilometers. | 6 | diff --git a/docs/src/ptf-catalog/sources/zhao2016.md b/docs/src/ptf-catalog/sources/zhao2016.md new file mode 100644 index 0000000..2642348 --- /dev/null +++ b/docs/src/ptf-catalog/sources/zhao2016.md @@ -0,0 +1,250 @@ +--- +# @generated by ptfkit-codegen; DO NOT EDIT. + +title: PTF source zhao2016 +nav-title: zhao2016 +--- + +# Saturated hydraulic conductivity PTFs for the Loess Plateau of China. + +## Source + +Zhao, C., Shao, M., Jia, X., Nasir, M., & Zhang, C. (2016). Using pedotransfer functions to estimate soil hydraulic conductivity in the Loess Plateau of China. CATENA, 143, 1-6. https://doi.org/10.1016/j.catena.2016.03.037 + +[DOI: 10.1016/j.catena.2016.03.037](https://doi.org/10.1016/j.catena.2016.03.037) + +## Scope + +**Territory:** Typical Loess Plateau of China, covering approximately 430,000 square kilometers. + +**Dataset:** 729 samples from 243 sites, sampled in 2012 at depths of 0-10, 10-20, and 20-40 cm. Each of 400 random calibration-validation splits used 583 development records and 146 validation records (Section 2.3.1). + +## Functions + +### `calc_ptf_zhao2016_m2_1` + +Estimate saturated hydraulic conductivity using reconstructed M2-1. + +**Status:** `implemented` + +**Prediction target:** Saturated hydraulic conductivity + +#### Inputs + +| Name | Type | Unit | Domain | Description | +| --- | --- | --- | --- | --- | +| `bulk_density` | `number` | g/cm^3 | Observed range in Table 1: 0.97 to 1.79 g/cm^3. | Soil bulk density measured on undisturbed cores. | +| `silt` | `number` | % | Observed range in Table 1: 2.04 to 76.01 percent. | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). | +| `clay` | `number` | % | Observed range in Table 1: 0.010 to 32.67 percent. | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). | + +#### Outputs + +| Name | Unit | Domain | Description | +| --- | --- | --- | --- | +| `ks` | mm/min | Observed range in Table 1: 0.01 to 0.99 mm/min; not an output clamp. | Saturated hydraulic conductivity, measured by the constant-head method. | + +!!! note + + Highest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_2` + +Estimate saturated hydraulic conductivity using reconstructed M2-2. + +**Status:** `implemented` + +**Prediction target:** Saturated hydraulic conductivity + +#### Inputs + +| Name | Type | Unit | Domain | Description | +| --- | --- | --- | --- | --- | +| `bulk_density` | `number` | g/cm^3 | Observed range in Table 1: 0.97 to 1.79 g/cm^3. | Soil bulk density measured on undisturbed cores. | +| `silt` | `number` | % | Observed range in Table 1: 2.04 to 76.01 percent. | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). | +| `clay` | `number` | % | Observed range in Table 1: 0.010 to 32.67 percent. | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). | + +#### Outputs + +| Name | Unit | Domain | Description | +| --- | --- | --- | --- | +| `ks` | mm/min | Observed range in Table 1: 0.01 to 0.99 mm/min; not an output clamp. | Saturated hydraulic conductivity, measured by the constant-head method. | + +!!! note + + Mean coefficients of the top 25 percent, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_3` + +Estimate saturated hydraulic conductivity using reconstructed M2-3. + +**Status:** `implemented` + +**Prediction target:** Saturated hydraulic conductivity + +#### Inputs + +| Name | Type | Unit | Domain | Description | +| --- | --- | --- | --- | --- | +| `bulk_density` | `number` | g/cm^3 | Observed range in Table 1: 0.97 to 1.79 g/cm^3. | Soil bulk density measured on undisturbed cores. | +| `silt` | `number` | % | Observed range in Table 1: 2.04 to 76.01 percent. | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). | +| `clay` | `number` | % | Observed range in Table 1: 0.010 to 32.67 percent. | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). | + +#### Outputs + +| Name | Unit | Domain | Description | +| --- | --- | --- | --- | +| `ks` | mm/min | Observed range in Table 1: 0.01 to 0.99 mm/min; not an output clamp. | Saturated hydraulic conductivity, measured by the constant-head method. | + +!!! note + + Mean coefficients of the top 50 percent, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_4` + +Estimate saturated hydraulic conductivity using reconstructed M2-4. + +**Status:** `implemented` + +**Prediction target:** Saturated hydraulic conductivity + +#### Inputs + +| Name | Type | Unit | Domain | Description | +| --- | --- | --- | --- | --- | +| `bulk_density` | `number` | g/cm^3 | Observed range in Table 1: 0.97 to 1.79 g/cm^3. | Soil bulk density measured on undisturbed cores. | +| `silt` | `number` | % | Observed range in Table 1: 2.04 to 76.01 percent. | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). | +| `clay` | `number` | % | Observed range in Table 1: 0.010 to 32.67 percent. | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). | + +#### Outputs + +| Name | Unit | Domain | Description | +| --- | --- | --- | --- | +| `ks` | mm/min | Observed range in Table 1: 0.01 to 0.99 mm/min; not an output clamp. | Saturated hydraulic conductivity, measured by the constant-head method. | + +!!! note + + Mean coefficients of the top 75 percent, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_5` + +Estimate saturated hydraulic conductivity using reconstructed M2-5. + +**Status:** `implemented` + +**Prediction target:** Saturated hydraulic conductivity + +#### Inputs + +| Name | Type | Unit | Domain | Description | +| --- | --- | --- | --- | --- | +| `bulk_density` | `number` | g/cm^3 | Observed range in Table 1: 0.97 to 1.79 g/cm^3. | Soil bulk density measured on undisturbed cores. | +| `silt` | `number` | % | Observed range in Table 1: 2.04 to 76.01 percent. | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). | +| `clay` | `number` | % | Observed range in Table 1: 0.010 to 32.67 percent. | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). | + +#### Outputs + +| Name | Unit | Domain | Description | +| --- | --- | --- | --- | +| `ks` | mm/min | Observed range in Table 1: 0.01 to 0.99 mm/min; not an output clamp. | Saturated hydraulic conductivity, measured by the constant-head method. | + +!!! note + + Mean coefficients of all 400 PTFs, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_6` + +Estimate saturated hydraulic conductivity using reconstructed M2-6. + +**Status:** `implemented` + +**Prediction target:** Saturated hydraulic conductivity + +#### Inputs + +| Name | Type | Unit | Domain | Description | +| --- | --- | --- | --- | --- | +| `bulk_density` | `number` | g/cm^3 | Observed range in Table 1: 0.97 to 1.79 g/cm^3. | Soil bulk density measured on undisturbed cores. | +| `silt` | `number` | % | Observed range in Table 1: 2.04 to 76.01 percent. | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). | +| `clay` | `number` | % | Observed range in Table 1: 0.010 to 32.67 percent. | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). | + +#### Outputs + +| Name | Unit | Domain | Description | +| --- | --- | --- | --- | +| `ks` | mm/min | Observed range in Table 1: 0.01 to 0.99 mm/min; not an output clamp. | Saturated hydraulic conductivity, measured by the constant-head method. | + +!!! note + + Lowest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. diff --git a/docs/src/reference/c/functions.md b/docs/src/reference/c/functions.md index 3382419..786e3f7 100644 --- a/docs/src/reference/c/functions.md +++ b/docs/src/reference/c/functions.md @@ -133,3 +133,9 @@ title: C function index | [`calc_ptf_vereecken1989_detailed`](headers/vereecken1989.md#function-calc_ptf_vereecken1989_detailed) | Estimate van Genuchten parameters from nine particle-size fractions and particle-size distribution descriptors. | [``](headers/vereecken1989.md) | | [`calc_ptf_wang2012`](headers/wang2012.md#function-calc_ptf_wang2012) | Estimate saturated water content, field capacity, and saturated conductivity. | [``](headers/wang2012.md) | | [`calc_ptf_weber2020`](headers/weber2020.md#function-calc_ptf_weber2020) | Convert VGM parameters to Brunswick-VGM parameters. | [``](headers/weber2020.md) | +| [`calc_ptf_zhao2016_m2_1`](headers/zhao2016.md#function-calc_ptf_zhao2016_m2_1) | Estimate saturated hydraulic conductivity using reconstructed M2-1. | [``](headers/zhao2016.md) | +| [`calc_ptf_zhao2016_m2_2`](headers/zhao2016.md#function-calc_ptf_zhao2016_m2_2) | Estimate saturated hydraulic conductivity using reconstructed M2-2. | [``](headers/zhao2016.md) | +| [`calc_ptf_zhao2016_m2_3`](headers/zhao2016.md#function-calc_ptf_zhao2016_m2_3) | Estimate saturated hydraulic conductivity using reconstructed M2-3. | [``](headers/zhao2016.md) | +| [`calc_ptf_zhao2016_m2_4`](headers/zhao2016.md#function-calc_ptf_zhao2016_m2_4) | Estimate saturated hydraulic conductivity using reconstructed M2-4. | [``](headers/zhao2016.md) | +| [`calc_ptf_zhao2016_m2_5`](headers/zhao2016.md#function-calc_ptf_zhao2016_m2_5) | Estimate saturated hydraulic conductivity using reconstructed M2-5. | [``](headers/zhao2016.md) | +| [`calc_ptf_zhao2016_m2_6`](headers/zhao2016.md#function-calc_ptf_zhao2016_m2_6) | Estimate saturated hydraulic conductivity using reconstructed M2-6. | [``](headers/zhao2016.md) | diff --git a/docs/src/reference/c/headers/ptfkit.md b/docs/src/reference/c/headers/ptfkit.md index f8d435c..4f4add9 100644 --- a/docs/src/reference/c/headers/ptfkit.md +++ b/docs/src/reference/c/headers/ptfkit.md @@ -37,3 +37,4 @@ This umbrella header aggregates every public ptfkit source header. Include an in - [``](vereecken1989.md) — Vereecken et al. soil-moisture retention regressions for Belgian soils. - [``](wang2012.md) — Wang et al. (2012), surface loess across China's Loess Plateau. - [``](weber2020.md) — Weber et al. (2020), compiled international soil hydraulic data. +- [``](zhao2016.md) — Saturated hydraulic conductivity PTFs for the Loess Plateau of China. diff --git a/docs/src/reference/c/headers/zhao2016.md b/docs/src/reference/c/headers/zhao2016.md new file mode 100644 index 0000000..53dce93 --- /dev/null +++ b/docs/src/reference/c/headers/zhao2016.md @@ -0,0 +1,245 @@ +--- +title: "zhao2016.h" +--- + + + +# `` + +```c +#include +``` + +Saturated hydraulic conductivity PTFs for the Loess Plateau of China. + +## Source + +Zhao, C., Shao, M., Jia, X., Nasir, M., & Zhang, C. (2016). Using pedotransfer functions to estimate soil hydraulic conductivity in the Loess Plateau of China. CATENA, 143, 1-6. https://doi.org/10.1016/j.catena.2016.03.037 + +[DOI: 10.1016/j.catena.2016.03.037](https://doi.org/10.1016/j.catena.2016.03.037) + +## Scope + +**Territory:** Typical Loess Plateau of China, covering approximately 430,000 square kilometers. + +**Dataset:** 729 samples from 243 sites, sampled in 2012 at depths of 0-10, 10-20, and 20-40 cm. Each of 400 random calibration-validation splits used 583 development records and 146 validation records (Section 2.3.1). + +[PTF catalog page](../../../ptf-catalog/sources/zhao2016.md) + +## Functions + +### `calc_ptf_zhao2016_m2_1` {#function-calc_ptf_zhao2016_m2_1} + +Estimate saturated hydraulic conductivity using reconstructed M2-1. + +```c +static inline double calc_ptf_zhao2016_m2_1(double bulk_density, double silt, double clay); +``` + +#### Parameters + +| Name | Direction | Description | +| --- | --- | --- | +| `bulk_density` | in | Soil bulk density measured on undisturbed cores. (g/cm^3) | +| `silt` | in | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | +| `clay` | in | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | + +#### Returns + +Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +!!! note + + Highest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_2` {#function-calc_ptf_zhao2016_m2_2} + +Estimate saturated hydraulic conductivity using reconstructed M2-2. + +```c +static inline double calc_ptf_zhao2016_m2_2(double bulk_density, double silt, double clay); +``` + +#### Parameters + +| Name | Direction | Description | +| --- | --- | --- | +| `bulk_density` | in | Soil bulk density measured on undisturbed cores. (g/cm^3) | +| `silt` | in | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | +| `clay` | in | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | + +#### Returns + +Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +!!! note + + Mean coefficients of the top 25 percent, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_3` {#function-calc_ptf_zhao2016_m2_3} + +Estimate saturated hydraulic conductivity using reconstructed M2-3. + +```c +static inline double calc_ptf_zhao2016_m2_3(double bulk_density, double silt, double clay); +``` + +#### Parameters + +| Name | Direction | Description | +| --- | --- | --- | +| `bulk_density` | in | Soil bulk density measured on undisturbed cores. (g/cm^3) | +| `silt` | in | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | +| `clay` | in | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | + +#### Returns + +Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +!!! note + + Mean coefficients of the top 50 percent, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_4` {#function-calc_ptf_zhao2016_m2_4} + +Estimate saturated hydraulic conductivity using reconstructed M2-4. + +```c +static inline double calc_ptf_zhao2016_m2_4(double bulk_density, double silt, double clay); +``` + +#### Parameters + +| Name | Direction | Description | +| --- | --- | --- | +| `bulk_density` | in | Soil bulk density measured on undisturbed cores. (g/cm^3) | +| `silt` | in | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | +| `clay` | in | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | + +#### Returns + +Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +!!! note + + Mean coefficients of the top 75 percent, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_5` {#function-calc_ptf_zhao2016_m2_5} + +Estimate saturated hydraulic conductivity using reconstructed M2-5. + +```c +static inline double calc_ptf_zhao2016_m2_5(double bulk_density, double silt, double clay); +``` + +#### Parameters + +| Name | Direction | Description | +| --- | --- | --- | +| `bulk_density` | in | Soil bulk density measured on undisturbed cores. (g/cm^3) | +| `silt` | in | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | +| `clay` | in | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | + +#### Returns + +Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +!!! note + + Mean coefficients of all 400 PTFs, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_6` {#function-calc_ptf_zhao2016_m2_6} + +Estimate saturated hydraulic conductivity using reconstructed M2-6. + +```c +static inline double calc_ptf_zhao2016_m2_6(double bulk_density, double silt, double clay); +``` + +#### Parameters + +| Name | Direction | Description | +| --- | --- | --- | +| `bulk_density` | in | Soil bulk density measured on undisturbed cores. (g/cm^3) | +| `silt` | in | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | +| `clay` | in | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | + +#### Returns + +Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +!!! note + + Lowest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. diff --git a/docs/src/reference/c/index.md b/docs/src/reference/c/index.md index ee89e4c..4fa6792 100644 --- a/docs/src/reference/c/index.md +++ b/docs/src/reference/c/index.md @@ -34,5 +34,6 @@ ptfkit's C API is organized around installed headers. - [``](headers/vereecken1989.md) — Vereecken et al. soil-moisture retention regressions for Belgian soils. - [``](headers/wang2012.md) — Wang et al. (2012), surface loess across China's Loess Plateau. - [``](headers/weber2020.md) — Weber et al. (2020), compiled international soil hydraulic data. +- [``](headers/zhao2016.md) — Saturated hydraulic conductivity PTFs for the Loess Plateau of China. See the [function index](functions.md) for all public C functions. diff --git a/docs/src/reference/cpp/functions.md b/docs/src/reference/cpp/functions.md index 89af0ba..dbdc0bb 100644 --- a/docs/src/reference/cpp/functions.md +++ b/docs/src/reference/cpp/functions.md @@ -133,3 +133,9 @@ title: C++ function index | [`ptfkit::vereecken1989::calc_ptf_vereecken1989_detailed`](modules/vereecken1989.md#function-calc_ptf_vereecken1989_detailed) | Estimate van Genuchten parameters from nine particle-size fractions and particle-size distribution descriptors. | [`ptfkit.vereecken1989`](modules/vereecken1989.md) | | [`ptfkit::wang2012::calc_ptf_wang2012`](modules/wang2012.md#function-calc_ptf_wang2012) | Estimate saturated water content, field capacity, and saturated conductivity. | [`ptfkit.wang2012`](modules/wang2012.md) | | [`ptfkit::weber2020::calc_ptf_weber2020`](modules/weber2020.md#function-calc_ptf_weber2020) | Convert VGM parameters to Brunswick-VGM parameters. | [`ptfkit.weber2020`](modules/weber2020.md) | +| [`ptfkit::zhao2016::calc_ptf_zhao2016_m2_1`](modules/zhao2016.md#function-calc_ptf_zhao2016_m2_1) | Estimate saturated hydraulic conductivity using reconstructed M2-1. | [`ptfkit.zhao2016`](modules/zhao2016.md) | +| [`ptfkit::zhao2016::calc_ptf_zhao2016_m2_2`](modules/zhao2016.md#function-calc_ptf_zhao2016_m2_2) | Estimate saturated hydraulic conductivity using reconstructed M2-2. | [`ptfkit.zhao2016`](modules/zhao2016.md) | +| [`ptfkit::zhao2016::calc_ptf_zhao2016_m2_3`](modules/zhao2016.md#function-calc_ptf_zhao2016_m2_3) | Estimate saturated hydraulic conductivity using reconstructed M2-3. | [`ptfkit.zhao2016`](modules/zhao2016.md) | +| [`ptfkit::zhao2016::calc_ptf_zhao2016_m2_4`](modules/zhao2016.md#function-calc_ptf_zhao2016_m2_4) | Estimate saturated hydraulic conductivity using reconstructed M2-4. | [`ptfkit.zhao2016`](modules/zhao2016.md) | +| [`ptfkit::zhao2016::calc_ptf_zhao2016_m2_5`](modules/zhao2016.md#function-calc_ptf_zhao2016_m2_5) | Estimate saturated hydraulic conductivity using reconstructed M2-5. | [`ptfkit.zhao2016`](modules/zhao2016.md) | +| [`ptfkit::zhao2016::calc_ptf_zhao2016_m2_6`](modules/zhao2016.md#function-calc_ptf_zhao2016_m2_6) | Estimate saturated hydraulic conductivity using reconstructed M2-6. | [`ptfkit.zhao2016`](modules/zhao2016.md) | diff --git a/docs/src/reference/cpp/index.md b/docs/src/reference/cpp/index.md index fe0d78e..6e4651c 100644 --- a/docs/src/reference/cpp/index.md +++ b/docs/src/reference/cpp/index.md @@ -34,5 +34,6 @@ ptfkit's C++ API is organized around C++23 modules. - [`ptfkit.vereecken1989`](modules/vereecken1989.md) — Vereecken et al. soil-moisture retention regressions for Belgian soils. - [`ptfkit.wang2012`](modules/wang2012.md) — Wang et al. (2012), surface loess across China's Loess Plateau. - [`ptfkit.weber2020`](modules/weber2020.md) — Weber et al. (2020), compiled international soil hydraulic data. +- [`ptfkit.zhao2016`](modules/zhao2016.md) — Saturated hydraulic conductivity PTFs for the Loess Plateau of China. See the [function index](functions.md) for all public C++ functions. diff --git a/docs/src/reference/cpp/modules/ptfkit.md b/docs/src/reference/cpp/modules/ptfkit.md index 44a5276..2827c69 100644 --- a/docs/src/reference/cpp/modules/ptfkit.md +++ b/docs/src/reference/cpp/modules/ptfkit.md @@ -38,3 +38,4 @@ This umbrella module re-exports every public ptfkit source module. Import an ind - [`ptfkit.vereecken1989`](vereecken1989.md) — Vereecken et al. soil-moisture retention regressions for Belgian soils. - [`ptfkit.wang2012`](wang2012.md) — Wang et al. (2012), surface loess across China's Loess Plateau. - [`ptfkit.weber2020`](weber2020.md) — Weber et al. (2020), compiled international soil hydraulic data. +- [`ptfkit.zhao2016`](zhao2016.md) — Saturated hydraulic conductivity PTFs for the Loess Plateau of China. diff --git a/docs/src/reference/cpp/modules/zhao2016.md b/docs/src/reference/cpp/modules/zhao2016.md new file mode 100644 index 0000000..e3860f0 --- /dev/null +++ b/docs/src/reference/cpp/modules/zhao2016.md @@ -0,0 +1,254 @@ +--- +# @generated by ptfkit-codegen; DO NOT EDIT. + +title: C++ module ptfkit.zhao2016 +nav-title: ptfkit.zhao2016 +--- + +# `ptfkit.zhao2016` + +```cpp +import ptfkit.zhao2016; +``` + +**Exported namespace:** `ptfkit::zhao2016` + +Saturated hydraulic conductivity PTFs for the Loess Plateau of China. + +## Source + +Zhao, C., Shao, M., Jia, X., Nasir, M., & Zhang, C. (2016). Using pedotransfer functions to estimate soil hydraulic conductivity in the Loess Plateau of China. CATENA, 143, 1-6. https://doi.org/10.1016/j.catena.2016.03.037 + +[DOI: 10.1016/j.catena.2016.03.037](https://doi.org/10.1016/j.catena.2016.03.037) + +## Scope + +**Territory:** Typical Loess Plateau of China, covering approximately 430,000 square kilometers. + +**Dataset:** 729 samples from 243 sites, sampled in 2012 at depths of 0-10, 10-20, and 20-40 cm. Each of 400 random calibration-validation splits used 583 development records and 146 validation records (Section 2.3.1). + +[PTF catalog page](../../../ptf-catalog/sources/zhao2016.md) + +## Functions + +### `calc_ptf_zhao2016_m2_1` {#function-calc_ptf_zhao2016_m2_1} + +Estimate saturated hydraulic conductivity using reconstructed M2-1. + +```cpp +[[nodiscard]] +inline double calc_ptf_zhao2016_m2_1(double bulk_density, double silt, double clay) +``` + +#### Parameters + +| Name | Description | +| --- | --- | +| `bulk_density` | Soil bulk density measured on undisturbed cores. (g/cm^3) | +| `silt` | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | +| `clay` | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | + +#### Returns + +Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +!!! note + + Highest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_2` {#function-calc_ptf_zhao2016_m2_2} + +Estimate saturated hydraulic conductivity using reconstructed M2-2. + +```cpp +[[nodiscard]] +inline double calc_ptf_zhao2016_m2_2(double bulk_density, double silt, double clay) +``` + +#### Parameters + +| Name | Description | +| --- | --- | +| `bulk_density` | Soil bulk density measured on undisturbed cores. (g/cm^3) | +| `silt` | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | +| `clay` | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | + +#### Returns + +Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +!!! note + + Mean coefficients of the top 25 percent, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_3` {#function-calc_ptf_zhao2016_m2_3} + +Estimate saturated hydraulic conductivity using reconstructed M2-3. + +```cpp +[[nodiscard]] +inline double calc_ptf_zhao2016_m2_3(double bulk_density, double silt, double clay) +``` + +#### Parameters + +| Name | Description | +| --- | --- | +| `bulk_density` | Soil bulk density measured on undisturbed cores. (g/cm^3) | +| `silt` | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | +| `clay` | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | + +#### Returns + +Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +!!! note + + Mean coefficients of the top 50 percent, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_4` {#function-calc_ptf_zhao2016_m2_4} + +Estimate saturated hydraulic conductivity using reconstructed M2-4. + +```cpp +[[nodiscard]] +inline double calc_ptf_zhao2016_m2_4(double bulk_density, double silt, double clay) +``` + +#### Parameters + +| Name | Description | +| --- | --- | +| `bulk_density` | Soil bulk density measured on undisturbed cores. (g/cm^3) | +| `silt` | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | +| `clay` | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | + +#### Returns + +Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +!!! note + + Mean coefficients of the top 75 percent, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_5` {#function-calc_ptf_zhao2016_m2_5} + +Estimate saturated hydraulic conductivity using reconstructed M2-5. + +```cpp +[[nodiscard]] +inline double calc_ptf_zhao2016_m2_5(double bulk_density, double silt, double clay) +``` + +#### Parameters + +| Name | Description | +| --- | --- | +| `bulk_density` | Soil bulk density measured on undisturbed cores. (g/cm^3) | +| `silt` | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | +| `clay` | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | + +#### Returns + +Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +!!! note + + Mean coefficients of all 400 PTFs, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. + +### `calc_ptf_zhao2016_m2_6` {#function-calc_ptf_zhao2016_m2_6} + +Estimate saturated hydraulic conductivity using reconstructed M2-6. + +```cpp +[[nodiscard]] +inline double calc_ptf_zhao2016_m2_6(double bulk_density, double silt, double clay) +``` + +#### Parameters + +| Name | Description | +| --- | --- | +| `bulk_density` | Soil bulk density measured on undisturbed cores. (g/cm^3) | +| `silt` | Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | +| `clay` | Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) | + +#### Returns + +Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +!!! note + + Lowest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). + +!!! note + + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors and response, as a reviewed reconstruction. + +!!! warning + + The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants or the application of response scaling. This reconstruction has not been verified against author software. + +!!! warning + + Observed ranges describe the sampled soils; predictions are not clamped. diff --git a/docs/src/reference/python/index.md b/docs/src/reference/python/index.md index 18d4e5b..e5fb401 100644 --- a/docs/src/reference/python/index.md +++ b/docs/src/reference/python/index.md @@ -33,3 +33,4 @@ ptfkit's Python API is organized around public source modules. - [`ptfkit.vereecken1989`](vereecken1989.md) — Vereecken et al. soil-moisture retention regressions for Belgian soils. - [`ptfkit.wang2012`](wang2012.md) — Wang et al. (2012), surface loess across China's Loess Plateau. - [`ptfkit.weber2020`](weber2020.md) — Weber et al. (2020), compiled international soil hydraulic data. +- [`ptfkit.zhao2016`](zhao2016.md) — Saturated hydraulic conductivity PTFs for the Loess Plateau of China. diff --git a/docs/src/reference/python/zhao2016.md b/docs/src/reference/python/zhao2016.md new file mode 100644 index 0000000..33205c8 --- /dev/null +++ b/docs/src/reference/python/zhao2016.md @@ -0,0 +1,8 @@ +--- +# @generated by ptfkit-codegen; DO NOT EDIT. + +title: Python module ptfkit.zhao2016 +nav-title: ptfkit.zhao2016 +--- + +::: ptfkit.zhao2016 diff --git a/specs/functions/zhao2016.yaml b/specs/functions/zhao2016.yaml new file mode 100644 index 0000000..e85d0fc --- /dev/null +++ b/specs/functions/zhao2016.yaml @@ -0,0 +1,544 @@ +source: + summary: Saturated hydraulic conductivity PTFs for the Loess Plateau of China. + citation_apa: >- + Zhao, C., Shao, M., Jia, X., Nasir, M., & Zhang, C. (2016). + Using pedotransfer functions to estimate soil hydraulic conductivity in + the Loess Plateau of China. CATENA, 143, 1-6. + https://doi.org/10.1016/j.catena.2016.03.037 + doi: + identifier: 10.1016/j.catena.2016.03.037 + url: https://doi.org/10.1016/j.catena.2016.03.037 +scope: + territory: Typical Loess Plateau of China, covering approximately 430,000 square kilometers. + dataset: >- + 729 samples from 243 sites, sampled in 2012 at depths of 0-10, 10-20, + and 20-40 cm. Each of 400 random calibration-validation splits used + 583 development records and 146 validation records (Section 2.3.1). +$defs: + bulk_density: + name: bulk_density + symbol: BD + unit: g/cm^3 + domain: 'Observed range in Table 1: 0.97 to 1.79 g/cm^3.' + description: >- + Soil bulk density measured on undisturbed cores. + silt: + name: silt + symbol: Silt + unit: '%' + domain: 'Observed range in Table 1: 2.04 to 76.01 percent.' + description: >- + Silt content measured by laser diffraction using USDA taxonomy + (Section 2.2.2). + clay: + name: clay + symbol: Clay + unit: '%' + domain: 'Observed range in Table 1: 0.010 to 32.67 percent.' + description: >- + Clay content measured by laser diffraction using USDA taxonomy + (Section 2.2.2). + conductivity: + type: scalar + name: ks + quantity: saturated_hydraulic_conductivity + symbol: Ks + unit: millimeter_per_minute + reported_unit: mm/min + domain: 'Observed range in Table 1: 0.01 to 0.99 mm/min; not an output clamp.' + description: >- + Saturated hydraulic conductivity, measured by the constant-head method. +functions: + - name: calc_ptf_zhao2016_m2_1 + status: implemented + public_api: + name: calc_ptf_zhao2016_m2_1 + result_class: null + summary: Estimate saturated hydraulic conductivity using reconstructed M2-1. + scope: + prediction_target: Saturated hydraulic conductivity + models: + h_theta: null + k_h: null + inputs: + - $ref: '#/$defs/bulk_density' + - $ref: '#/$defs/silt' + - $ref: '#/$defs/clay' + outputs: + $ref: '#/$defs/conductivity' + verification_cases: + - id: published_predictor_means + kind: calculated + inputs: + bulk_density: 1.32 + silt: 63.33 + clay: 17.41 + expected: + ks: 0.3780 + rationale: >- + Uses Table 1 predictor means, within the observed marginal ranges. + Silt and clay leave 19.26 percent sand. All standardized predictors + equal 0.5. Expected conductivity was calculated with decimal arithmetic + from Table 4 and the reviewed scaling reconstruction. + - id: interior_soil + kind: calculated + inputs: + bulk_density: 1.2 + silt: 60 + clay: 20 + expected: + ks: 0.5615765333953871 + rationale: >- + Interior soil with 60 percent silt, 20 percent clay and a residual + 20 percent sand, at bulk density 1.2 g/cm^3. All inputs are within + Table 1 ranges and differ from the scaling means. Expected output + was fixed from decimal reference calculations of Jia Equation 3, + Table 4 and the reviewed inverse response transformation. + edge_cases: [] + documentation: + notes: + - 'Highest-ranked fitted PTF, ranked by descending R-squared (Section 3.3).' + - >- + Uses Table 1 means and standard deviations for Jia et al. (2012) + Equation 3 on both predictors and response, as a reviewed reconstruction. + warnings: + - >- + The publication does not explicitly confirm Table 1 statistics as + the fitted scaling constants or the application of response scaling. + This reconstruction has not been verified against author software. + - Observed ranges describe the sampled soils; predictions are not clamped. + implementation: + variables: + - name: bd_scaled + expr: '(bulk_density - (1.32 - 2 * 0.14)) / (4 * 0.14)' + - name: silt_scaled + expr: '(silt - (63.33 - 2 * 9.85)) / (4 * 9.85)' + - name: clay_scaled + expr: '(clay - (17.41 - 2 * 4.69)) / (4 * 4.69)' + - name: response_scaled + expr: '0.873 - 0.555 * bd_scaled - 0.399 * silt_scaled + 0.224 * clay_scaled' + - name: ks + expr: '4 * 0.25 * response_scaled + 0.37 - 2 * 0.25' + - name: calc_ptf_zhao2016_m2_2 + status: implemented + public_api: + name: calc_ptf_zhao2016_m2_2 + result_class: null + summary: Estimate saturated hydraulic conductivity using reconstructed M2-2. + scope: + prediction_target: Saturated hydraulic conductivity + models: + h_theta: null + k_h: null + inputs: + - $ref: '#/$defs/bulk_density' + - $ref: '#/$defs/silt' + - $ref: '#/$defs/clay' + outputs: + $ref: '#/$defs/conductivity' + verification_cases: + - id: published_predictor_means + kind: calculated + inputs: + bulk_density: 1.32 + silt: 63.33 + clay: 17.41 + expected: + ks: 0.3710 + rationale: >- + Uses Table 1 predictor means, within the observed marginal ranges. + Silt and clay leave 19.26 percent sand. All standardized predictors + equal 0.5. Expected conductivity was calculated with decimal arithmetic + from Table 4 and the reviewed scaling reconstruction. + - id: interior_soil + kind: calculated + inputs: + bulk_density: 1.2 + silt: 60 + clay: 20 + expected: + ks: 0.5567321826328834 + rationale: >- + Interior soil with 60 percent silt, 20 percent clay and a residual + 20 percent sand, at bulk density 1.2 g/cm^3. All inputs are within + Table 1 ranges and differ from the scaling means. Expected output + was fixed from decimal reference calculations of Jia Equation 3, + Table 4 and the reviewed inverse response transformation. + edge_cases: [] + documentation: + notes: + - 'Mean coefficients of the top 25 percent, ranked by descending R-squared (Section 3.3).' + - >- + Uses Table 1 means and standard deviations for Jia et al. (2012) + Equation 3 on both predictors and response, as a reviewed reconstruction. + warnings: + - >- + The publication does not explicitly confirm Table 1 statistics as + the fitted scaling constants or the application of response scaling. + This reconstruction has not been verified against author software. + - Observed ranges describe the sampled soils; predictions are not clamped. + implementation: + variables: + - name: bd_scaled + expr: '(bulk_density - (1.32 - 2 * 0.14)) / (4 * 0.14)' + - name: silt_scaled + expr: '(silt - (63.33 - 2 * 9.85)) / (4 * 9.85)' + - name: clay_scaled + expr: '(clay - (17.41 - 2 * 4.69)) / (4 * 4.69)' + - name: response_scaled + expr: '0.868 - 0.557 * bd_scaled - 0.408 * silt_scaled + 0.231 * clay_scaled' + - name: ks + expr: '4 * 0.25 * response_scaled + 0.37 - 2 * 0.25' + - name: calc_ptf_zhao2016_m2_3 + status: implemented + public_api: + name: calc_ptf_zhao2016_m2_3 + result_class: null + summary: Estimate saturated hydraulic conductivity using reconstructed M2-3. + scope: + prediction_target: Saturated hydraulic conductivity + models: + h_theta: null + k_h: null + inputs: + - $ref: '#/$defs/bulk_density' + - $ref: '#/$defs/silt' + - $ref: '#/$defs/clay' + outputs: + $ref: '#/$defs/conductivity' + verification_cases: + - id: published_predictor_means + kind: calculated + inputs: + bulk_density: 1.32 + silt: 63.33 + clay: 17.41 + expected: + ks: 0.3710 + rationale: >- + Uses Table 1 predictor means, within the observed marginal ranges. + Silt and clay leave 19.26 percent sand. All standardized predictors + equal 0.5. Expected conductivity was calculated with decimal arithmetic + from Table 4 and the reviewed scaling reconstruction. + - id: interior_soil + kind: calculated + inputs: + bulk_density: 1.2 + silt: 60 + clay: 20 + expected: + ks: 0.5595593556871192 + rationale: >- + Interior soil with 60 percent silt, 20 percent clay and a residual + 20 percent sand, at bulk density 1.2 g/cm^3. All inputs are within + Table 1 ranges and differ from the scaling means. Expected output + was fixed from decimal reference calculations of Jia Equation 3, + Table 4 and the reviewed inverse response transformation. + edge_cases: [] + documentation: + notes: + - 'Mean coefficients of the top 50 percent, ranked by descending R-squared (Section 3.3).' + - >- + Uses Table 1 means and standard deviations for Jia et al. (2012) + Equation 3 on both predictors and response, as a reviewed reconstruction. + warnings: + - >- + The publication does not explicitly confirm Table 1 statistics as + the fitted scaling constants or the application of response scaling. + This reconstruction has not been verified against author software. + - Observed ranges describe the sampled soils; predictions are not clamped. + implementation: + variables: + - name: bd_scaled + expr: '(bulk_density - (1.32 - 2 * 0.14)) / (4 * 0.14)' + - name: silt_scaled + expr: '(silt - (63.33 - 2 * 9.85)) / (4 * 9.85)' + - name: clay_scaled + expr: '(clay - (17.41 - 2 * 4.69)) / (4 * 4.69)' + - name: response_scaled + expr: '0.872 - 0.565 * bd_scaled - 0.413 * silt_scaled + 0.236 * clay_scaled' + - name: ks + expr: '4 * 0.25 * response_scaled + 0.37 - 2 * 0.25' + - name: calc_ptf_zhao2016_m2_4 + status: implemented + public_api: + name: calc_ptf_zhao2016_m2_4 + result_class: null + summary: Estimate saturated hydraulic conductivity using reconstructed M2-4. + scope: + prediction_target: Saturated hydraulic conductivity + models: + h_theta: null + k_h: null + inputs: + - $ref: '#/$defs/bulk_density' + - $ref: '#/$defs/silt' + - $ref: '#/$defs/clay' + outputs: + $ref: '#/$defs/conductivity' + verification_cases: + - id: published_predictor_means + kind: calculated + inputs: + bulk_density: 1.32 + silt: 63.33 + clay: 17.41 + expected: + ks: 0.3710 + rationale: >- + Uses Table 1 predictor means, within the observed marginal ranges. + Silt and clay leave 19.26 percent sand. All standardized predictors + equal 0.5. Expected conductivity was calculated with decimal arithmetic + from Table 4 and the reviewed scaling reconstruction. + - id: interior_soil + kind: calculated + inputs: + bulk_density: 1.2 + silt: 60 + clay: 20 + expected: + ks: 0.5615354864546015 + rationale: >- + Interior soil with 60 percent silt, 20 percent clay and a residual + 20 percent sand, at bulk density 1.2 g/cm^3. All inputs are within + Table 1 ranges and differ from the scaling means. Expected output + was fixed from decimal reference calculations of Jia Equation 3, + Table 4 and the reviewed inverse response transformation. + edge_cases: [] + documentation: + notes: + - 'Mean coefficients of the top 75 percent, ranked by descending R-squared (Section 3.3).' + - >- + Uses Table 1 means and standard deviations for Jia et al. (2012) + Equation 3 on both predictors and response, as a reviewed reconstruction. + warnings: + - >- + The publication does not explicitly confirm Table 1 statistics as + the fitted scaling constants or the application of response scaling. + This reconstruction has not been verified against author software. + - Observed ranges describe the sampled soils; predictions are not clamped. + implementation: + variables: + - name: bd_scaled + expr: '(bulk_density - (1.32 - 2 * 0.14)) / (4 * 0.14)' + - name: silt_scaled + expr: '(silt - (63.33 - 2 * 9.85)) / (4 * 9.85)' + - name: clay_scaled + expr: '(clay - (17.41 - 2 * 4.69)) / (4 * 4.69)' + - name: response_scaled + expr: '0.877 - 0.572 * bd_scaled - 0.417 * silt_scaled + 0.237 * clay_scaled' + - name: ks + expr: '4 * 0.25 * response_scaled + 0.37 - 2 * 0.25' + - name: calc_ptf_zhao2016_m2_5 + status: implemented + public_api: + name: calc_ptf_zhao2016_m2_5 + result_class: null + summary: Estimate saturated hydraulic conductivity using reconstructed M2-5. + scope: + prediction_target: Saturated hydraulic conductivity + models: + h_theta: null + k_h: null + inputs: + - $ref: '#/$defs/bulk_density' + - $ref: '#/$defs/silt' + - $ref: '#/$defs/clay' + outputs: + $ref: '#/$defs/conductivity' + verification_cases: + - id: published_predictor_means + kind: calculated + inputs: + bulk_density: 1.32 + silt: 63.33 + clay: 17.41 + expected: + ks: 0.3705 + rationale: >- + Uses Table 1 predictor means, within the observed marginal ranges. + Silt and clay leave 19.26 percent sand. All standardized predictors + equal 0.5. Expected conductivity was calculated with decimal arithmetic + from Table 4 and the reviewed scaling reconstruction. + - id: interior_soil + kind: calculated + inputs: + bulk_density: 1.2 + silt: 60 + clay: 20 + expected: + ks: 0.5638008258201379 + rationale: >- + Interior soil with 60 percent silt, 20 percent clay and a residual + 20 percent sand, at bulk density 1.2 g/cm^3. All inputs are within + Table 1 ranges and differ from the scaling means. Expected output + was fixed from decimal reference calculations of Jia Equation 3, + Table 4 and the reviewed inverse response transformation. + edge_cases: [] + documentation: + notes: + - 'Mean coefficients of all 400 PTFs, ranked by descending R-squared (Section 3.3).' + - >- + Uses Table 1 means and standard deviations for Jia et al. (2012) + Equation 3 on both predictors and response, as a reviewed reconstruction. + warnings: + - >- + The publication does not explicitly confirm Table 1 statistics as + the fitted scaling constants or the application of response scaling. + This reconstruction has not been verified against author software. + - Observed ranges describe the sampled soils; predictions are not clamped. + implementation: + variables: + - name: bd_scaled + expr: '(bulk_density - (1.32 - 2 * 0.14)) / (4 * 0.14)' + - name: silt_scaled + expr: '(silt - (63.33 - 2 * 9.85)) / (4 * 9.85)' + - name: clay_scaled + expr: '(clay - (17.41 - 2 * 4.69)) / (4 * 4.69)' + - name: response_scaled + expr: '0.882 - 0.581 * bd_scaled - 0.422 * silt_scaled + 0.240 * clay_scaled' + - name: ks + expr: '4 * 0.25 * response_scaled + 0.37 - 2 * 0.25' + - name: calc_ptf_zhao2016_m2_6 + status: implemented + public_api: + name: calc_ptf_zhao2016_m2_6 + result_class: null + summary: Estimate saturated hydraulic conductivity using reconstructed M2-6. + scope: + prediction_target: Saturated hydraulic conductivity + models: + h_theta: null + k_h: null + inputs: + - $ref: '#/$defs/bulk_density' + - $ref: '#/$defs/silt' + - $ref: '#/$defs/clay' + outputs: + $ref: '#/$defs/conductivity' + verification_cases: + - id: published_predictor_means + kind: calculated + inputs: + bulk_density: 1.32 + silt: 63.33 + clay: 17.41 + expected: + ks: 0.3655 + rationale: >- + Uses Table 1 predictor means, within the observed marginal ranges. + Silt and clay leave 19.26 percent sand. All standardized predictors + equal 0.5. Expected conductivity was calculated with decimal arithmetic + from Table 4 and the reviewed scaling reconstruction. + - id: interior_soil + kind: calculated + inputs: + bulk_density: 1.2 + silt: 60 + clay: 20 + expected: + ks: 0.5853502159254489 + rationale: >- + Interior soil with 60 percent silt, 20 percent clay and a residual + 20 percent sand, at bulk density 1.2 g/cm^3. All inputs are within + Table 1 ranges and differ from the scaling means. Expected output + was fixed from decimal reference calculations of Jia Equation 3, + Table 4 and the reviewed inverse response transformation. + edge_cases: [] + documentation: + notes: + - 'Lowest-ranked fitted PTF, ranked by descending R-squared (Section 3.3).' + - >- + Uses Table 1 means and standard deviations for Jia et al. (2012) + Equation 3 on both predictors and response, as a reviewed reconstruction. + warnings: + - >- + The publication does not explicitly confirm Table 1 statistics as + the fitted scaling constants or the application of response scaling. + This reconstruction has not been verified against author software. + - Observed ranges describe the sampled soils; predictions are not clamped. + implementation: + variables: + - name: bd_scaled + expr: '(bulk_density - (1.32 - 2 * 0.14)) / (4 * 0.14)' + - name: silt_scaled + expr: '(silt - (63.33 - 2 * 9.85)) / (4 * 9.85)' + - name: clay_scaled + expr: '(clay - (17.41 - 2 * 4.69)) / (4 * 4.69)' + - name: response_scaled + expr: '0.891 - 0.637 * bd_scaled - 0.470 * silt_scaled + 0.316 * clay_scaled' + - name: ks + expr: '4 * 0.25 * response_scaled + 0.37 - 2 * 0.25' +scientific_notes: | + ## Supported models + + Section 3.3 and Table 4 publish six coefficient sets for M2, predicting + saturated hydraulic conductivity from bulk density, silt and clay. M2 was + selected for stability, ease of measuring its predictors and accuracy + comparable to M1. The six functions retain the published row order: + highest-ranked fit, averages of the top 25%, 50%, 75% and 100% of 400 fits, + and lowest-ranked fit, ranked by descending R-squared. + + ## Accepted review interpretation + + On 2026-09-07 the user requested generation in response to the concrete + reconstruction proposal. This was treated as acceptance of using Zhao + Table 1 statistics with Jia Equation 3 for both predictors and response. + This is an explicitly reviewed reconstruction, not a newly discovered + author-confirmed preprocessing contract. + + Zhao Section 2.3.1 cites Jia, X., Shao, M., & Wei, X. (2012). + State-space prediction of soil respiration time series in temperate, + semi-arid grassland in northern China. Soil Research, 50(4), 293-303. + https://doi.org/10.1071/SR12068 + The user-supplied sr12068.pdf, page 295 (PDF page 3), Theory, Equation 3, + defines z = [Z - (mu - 2*sigma)] / (4*sigma). Here mu and sigma are the + measured variable's mean and standard deviation. Algebraically, + Z = 4*sigma*z + mu - 2*sigma. This derivation justifies the inverse used + under the accepted interpretation; it does not establish author-code parity. + + Table 1 supplies means and SDs of BD (1.32, 0.14), Silt (63.33, 9.85), + Clay (17.41, 4.69), and Ks (0.37, 0.25), in the documented physical units. + These published values define this implementation at their stated precision. + Section 2.3.1 discusses standardization before random calibration-validation + splitting, supporting the accepted whole-dataset interpretation. It does + not explicitly identify those statistics as the fitted scaling constants + or unambiguously specify whether the response was standardized. + + A consistency check supports, but does not prove, response scaling: + at the predictor means all scaled predictors are 0.5, and M2-5 (the average + over all 400 fits) gives a fitted response of 0.5005. Inverse scaling gives + 0.3705 mm/min, close to Table 1's mean Ks of 0.37 mm/min. Without inverse + scaling the same fitted response would be 0.5005 mm/min. This comparison + is a diagnostic inference; differing training subsets are unavailable. + + ## Verification decision + + No complete published input-output pair is present in the supplied source. + Each model has calculated cases at published predictor means and at an + interior soil with nonzero deviations from those means. Fixed expected + outputs were evaluated using Python decimal arithmetic directly from + the reviewed transformation and published coefficients, without codegen. + These cases check the computational reconstruction, not predictive accuracy + or agreement with unpublished author artifacts. Model RMSE is not an + implementation tolerance. Source-bundle instructions requiring published + golden cases are superseded by the current verification policy. + + ## Documented limitations and excluded models + + Published marginal ranges describe the dataset, not joint extreme soils + or guarantees outside the sampled region. The regressions are not clamped. + M1 and M3-M6 in Table 3 lack fitted coefficients. ANN models A1-A6 lack + trained weights, biases and a complete preprocessing contract. These + alternative models are excluded and do not block the reviewed M2 functions. + + ## Evidence provenance + + Zhao's supplied local Markdown contains the article text, Tables 1 and 4, + and prior research notes. Automated image descriptions are not numerical + evidence. The publisher confirms CATENA volume 143, pages 1-6: + https://www.sciencedirect.com/science/article/pii/S0341816216301242 + Title, DOI, institutional-repository and coefficient searches on 2026-09-07 + did not locate an accessible author preprocessing or trained-model artifact. + The subsequent local Jia PDF resolved the referenced normalization equation. + It concerns a separate respiration dataset; its own statistics are not used. diff --git a/specs/quantities.yaml b/specs/quantities.yaml index 3a40885..6361efe 100644 --- a/specs/quantities.yaml +++ b/specs/quantities.yaml @@ -44,6 +44,10 @@ saturated_hydraulic_conductivity: absolute: 1.0e-5 relative: 0.01 rationale: Conductivity spans orders of magnitude; use one percent with a lower resolution. + millimeter_per_minute: + absolute: 1.0e-4 + relative: 0.01 + rationale: Equivalent to the reviewed centimeter-per-minute resolution, with one percent relative tolerance. centimeter_per_day: absolute: 1.0e-4 relative: 0.01 diff --git a/specs/units.yaml b/specs/units.yaml index e71cfc8..5deb485 100644 --- a/specs/units.yaml +++ b/specs/units.yaml @@ -34,6 +34,10 @@ centimeter_per_minute: preferred_notation: "cm/min" aliases: [] +millimeter_per_minute: + preferred_notation: "mm/min" + aliases: [] + centimeter_per_day: preferred_notation: "cm d^-1" aliases: ["cm/day"] diff --git a/targets/ptfkit-native/cpp/ptfkit.cppm b/targets/ptfkit-native/cpp/ptfkit.cppm index c54753f..5cefe0c 100644 --- a/targets/ptfkit-native/cpp/ptfkit.cppm +++ b/targets/ptfkit-native/cpp/ptfkit.cppm @@ -25,3 +25,4 @@ export import ptfkit.varallyai1982; export import ptfkit.vereecken1989; export import ptfkit.wang2012; export import ptfkit.weber2020; +export import ptfkit.zhao2016; diff --git a/targets/ptfkit-native/cpp/zhao2016.cppm b/targets/ptfkit-native/cpp/zhao2016.cppm new file mode 100644 index 0000000..1c03c88 --- /dev/null +++ b/targets/ptfkit-native/cpp/zhao2016.cppm @@ -0,0 +1,199 @@ +/* @generated by ptfkit-codegen; DO NOT EDIT. */ + +export module ptfkit.zhao2016; + +/** + * @brief Saturated hydraulic conductivity PTFs for the Loess Plateau of China. + * + * @details Source publication: + * Zhao, C., Shao, M., Jia, X., Nasir, M., & Zhang, C. (2016). Using pedotransfer functions to + * estimate soil hydraulic conductivity in the Loess Plateau of China. CATENA, 143, 1-6. + * https://doi.org/10.1016/j.catena.2016.03.037 + * @see https://doi.org/10.1016/j.catena.2016.03.037 DOI: 10.1016/j.catena.2016.03.037 + * + * @remark Geographic scope: + * Typical Loess Plateau of China, covering approximately 430,000 square kilometers. + * + * @remark Calibration dataset: + * 729 samples from 243 sites, sampled in 2012 at depths of 0-10, 10-20, and 20-40 cm. Each of + * 400 random calibration-validation splits used 583 development records and 146 validation + * records (Section 2.3.1). + */ + +export namespace ptfkit::zhao2016 { + +/** + * @brief Estimate saturated hydraulic conductivity using reconstructed M2-1. + * @param bulk_density Soil bulk density measured on undisturbed cores. (g/cm^3) + * @param silt Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @param clay Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @return Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + * + * @details Prediction target: + * Saturated hydraulic conductivity + * @note Highest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). + * @note Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + * predictors and response, as a reviewed reconstruction. + * @warning The publication does not explicitly confirm Table 1 statistics as the fitted + * scaling constants or the application of response scaling. This reconstruction has not been + * verified against author software. + * @warning Observed ranges describe the sampled soils; predictions are not clamped. + */ +[[nodiscard]] +inline double calc_ptf_zhao2016_m2_1(double bulk_density, double silt, double clay) { + const double bd_scaled = (bulk_density - (1.32 - 2.0 * 0.14)) / (4.0 * 0.14); + const double silt_scaled = (silt - (63.33 - 2.0 * 9.85)) / (4.0 * 9.85); + const double clay_scaled = (clay - (17.41 - 2.0 * 4.69)) / (4.0 * 4.69); + const double response_scaled = + 0.873 - 0.555 * bd_scaled - 0.399 * silt_scaled + 0.224 * clay_scaled; + return 4.0 * 0.25 * response_scaled + 0.37 - 2.0 * 0.25; +} + +/** + * @brief Estimate saturated hydraulic conductivity using reconstructed M2-2. + * @param bulk_density Soil bulk density measured on undisturbed cores. (g/cm^3) + * @param silt Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @param clay Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @return Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + * + * @details Prediction target: + * Saturated hydraulic conductivity + * @note Mean coefficients of the top 25 percent, ranked by descending R-squared (Section 3.3). + * @note Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + * predictors and response, as a reviewed reconstruction. + * @warning The publication does not explicitly confirm Table 1 statistics as the fitted + * scaling constants or the application of response scaling. This reconstruction has not been + * verified against author software. + * @warning Observed ranges describe the sampled soils; predictions are not clamped. + */ +[[nodiscard]] +inline double calc_ptf_zhao2016_m2_2(double bulk_density, double silt, double clay) { + const double bd_scaled = (bulk_density - (1.32 - 2.0 * 0.14)) / (4.0 * 0.14); + const double silt_scaled = (silt - (63.33 - 2.0 * 9.85)) / (4.0 * 9.85); + const double clay_scaled = (clay - (17.41 - 2.0 * 4.69)) / (4.0 * 4.69); + const double response_scaled = + 0.868 - 0.557 * bd_scaled - 0.408 * silt_scaled + 0.231 * clay_scaled; + return 4.0 * 0.25 * response_scaled + 0.37 - 2.0 * 0.25; +} + +/** + * @brief Estimate saturated hydraulic conductivity using reconstructed M2-3. + * @param bulk_density Soil bulk density measured on undisturbed cores. (g/cm^3) + * @param silt Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @param clay Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @return Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + * + * @details Prediction target: + * Saturated hydraulic conductivity + * @note Mean coefficients of the top 50 percent, ranked by descending R-squared (Section 3.3). + * @note Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + * predictors and response, as a reviewed reconstruction. + * @warning The publication does not explicitly confirm Table 1 statistics as the fitted + * scaling constants or the application of response scaling. This reconstruction has not been + * verified against author software. + * @warning Observed ranges describe the sampled soils; predictions are not clamped. + */ +[[nodiscard]] +inline double calc_ptf_zhao2016_m2_3(double bulk_density, double silt, double clay) { + const double bd_scaled = (bulk_density - (1.32 - 2.0 * 0.14)) / (4.0 * 0.14); + const double silt_scaled = (silt - (63.33 - 2.0 * 9.85)) / (4.0 * 9.85); + const double clay_scaled = (clay - (17.41 - 2.0 * 4.69)) / (4.0 * 4.69); + const double response_scaled = + 0.872 - 0.565 * bd_scaled - 0.413 * silt_scaled + 0.236 * clay_scaled; + return 4.0 * 0.25 * response_scaled + 0.37 - 2.0 * 0.25; +} + +/** + * @brief Estimate saturated hydraulic conductivity using reconstructed M2-4. + * @param bulk_density Soil bulk density measured on undisturbed cores. (g/cm^3) + * @param silt Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @param clay Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @return Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + * + * @details Prediction target: + * Saturated hydraulic conductivity + * @note Mean coefficients of the top 75 percent, ranked by descending R-squared (Section 3.3). + * @note Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + * predictors and response, as a reviewed reconstruction. + * @warning The publication does not explicitly confirm Table 1 statistics as the fitted + * scaling constants or the application of response scaling. This reconstruction has not been + * verified against author software. + * @warning Observed ranges describe the sampled soils; predictions are not clamped. + */ +[[nodiscard]] +inline double calc_ptf_zhao2016_m2_4(double bulk_density, double silt, double clay) { + const double bd_scaled = (bulk_density - (1.32 - 2.0 * 0.14)) / (4.0 * 0.14); + const double silt_scaled = (silt - (63.33 - 2.0 * 9.85)) / (4.0 * 9.85); + const double clay_scaled = (clay - (17.41 - 2.0 * 4.69)) / (4.0 * 4.69); + const double response_scaled = + 0.877 - 0.572 * bd_scaled - 0.417 * silt_scaled + 0.237 * clay_scaled; + return 4.0 * 0.25 * response_scaled + 0.37 - 2.0 * 0.25; +} + +/** + * @brief Estimate saturated hydraulic conductivity using reconstructed M2-5. + * @param bulk_density Soil bulk density measured on undisturbed cores. (g/cm^3) + * @param silt Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @param clay Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @return Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + * + * @details Prediction target: + * Saturated hydraulic conductivity + * @note Mean coefficients of all 400 PTFs, ranked by descending R-squared (Section 3.3). + * @note Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + * predictors and response, as a reviewed reconstruction. + * @warning The publication does not explicitly confirm Table 1 statistics as the fitted + * scaling constants or the application of response scaling. This reconstruction has not been + * verified against author software. + * @warning Observed ranges describe the sampled soils; predictions are not clamped. + */ +[[nodiscard]] +inline double calc_ptf_zhao2016_m2_5(double bulk_density, double silt, double clay) { + const double bd_scaled = (bulk_density - (1.32 - 2.0 * 0.14)) / (4.0 * 0.14); + const double silt_scaled = (silt - (63.33 - 2.0 * 9.85)) / (4.0 * 9.85); + const double clay_scaled = (clay - (17.41 - 2.0 * 4.69)) / (4.0 * 4.69); + const double response_scaled = + 0.882 - 0.581 * bd_scaled - 0.422 * silt_scaled + 0.240 * clay_scaled; + return 4.0 * 0.25 * response_scaled + 0.37 - 2.0 * 0.25; +} + +/** + * @brief Estimate saturated hydraulic conductivity using reconstructed M2-6. + * @param bulk_density Soil bulk density measured on undisturbed cores. (g/cm^3) + * @param silt Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @param clay Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @return Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + * + * @details Prediction target: + * Saturated hydraulic conductivity + * @note Lowest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). + * @note Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + * predictors and response, as a reviewed reconstruction. + * @warning The publication does not explicitly confirm Table 1 statistics as the fitted + * scaling constants or the application of response scaling. This reconstruction has not been + * verified against author software. + * @warning Observed ranges describe the sampled soils; predictions are not clamped. + */ +[[nodiscard]] +inline double calc_ptf_zhao2016_m2_6(double bulk_density, double silt, double clay) { + const double bd_scaled = (bulk_density - (1.32 - 2.0 * 0.14)) / (4.0 * 0.14); + const double silt_scaled = (silt - (63.33 - 2.0 * 9.85)) / (4.0 * 9.85); + const double clay_scaled = (clay - (17.41 - 2.0 * 4.69)) / (4.0 * 4.69); + const double response_scaled = + 0.891 - 0.637 * bd_scaled - 0.470 * silt_scaled + 0.316 * clay_scaled; + return 4.0 * 0.25 * response_scaled + 0.37 - 2.0 * 0.25; +} + +} // namespace ptfkit::zhao2016 diff --git a/targets/ptfkit-native/include/ptfkit/ptfkit.h b/targets/ptfkit-native/include/ptfkit/ptfkit.h index 1b931ab..d3088f0 100644 --- a/targets/ptfkit-native/include/ptfkit/ptfkit.h +++ b/targets/ptfkit-native/include/ptfkit/ptfkit.h @@ -26,5 +26,6 @@ #include #include #include +#include #endif diff --git a/targets/ptfkit-native/include/ptfkit/zhao2016.h b/targets/ptfkit-native/include/ptfkit/zhao2016.h new file mode 100644 index 0000000..be92a55 --- /dev/null +++ b/targets/ptfkit-native/include/ptfkit/zhao2016.h @@ -0,0 +1,192 @@ +/* @generated by ptfkit-codegen; DO NOT EDIT. */ + +#ifndef PTFKIT_ZHAO2016_H +#define PTFKIT_ZHAO2016_H + +/** + * @brief Saturated hydraulic conductivity PTFs for the Loess Plateau of China. + * + * @details Source publication: + * Zhao, C., Shao, M., Jia, X., Nasir, M., & Zhang, C. (2016). Using pedotransfer functions to + * estimate soil hydraulic conductivity in the Loess Plateau of China. CATENA, 143, 1-6. + * https://doi.org/10.1016/j.catena.2016.03.037 + * @see https://doi.org/10.1016/j.catena.2016.03.037 DOI: 10.1016/j.catena.2016.03.037 + * + * @remark Geographic scope: + * Typical Loess Plateau of China, covering approximately 430,000 square kilometers. + * + * @remark Calibration dataset: + * 729 samples from 243 sites, sampled in 2012 at depths of 0-10, 10-20, and 20-40 cm. Each of + * 400 random calibration-validation splits used 583 development records and 146 validation + * records (Section 2.3.1). + */ + +/** + * @brief Estimate saturated hydraulic conductivity using reconstructed M2-1. + * @param bulk_density Soil bulk density measured on undisturbed cores. (g/cm^3) + * @param silt Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @param clay Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @return Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + * + * @details Prediction target: + * Saturated hydraulic conductivity + * @note Highest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). + * @note Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + * predictors and response, as a reviewed reconstruction. + * @warning The publication does not explicitly confirm Table 1 statistics as the fitted + * scaling constants or the application of response scaling. This reconstruction has not been + * verified against author software. + * @warning Observed ranges describe the sampled soils; predictions are not clamped. + */ +static inline double calc_ptf_zhao2016_m2_1(double bulk_density, double silt, double clay) { + const double bd_scaled = (bulk_density - (1.32 - 2.0 * 0.14)) / (4.0 * 0.14); + const double silt_scaled = (silt - (63.33 - 2.0 * 9.85)) / (4.0 * 9.85); + const double clay_scaled = (clay - (17.41 - 2.0 * 4.69)) / (4.0 * 4.69); + const double response_scaled = + 0.873 - 0.555 * bd_scaled - 0.399 * silt_scaled + 0.224 * clay_scaled; + return 4.0 * 0.25 * response_scaled + 0.37 - 2.0 * 0.25; +} + +/** + * @brief Estimate saturated hydraulic conductivity using reconstructed M2-2. + * @param bulk_density Soil bulk density measured on undisturbed cores. (g/cm^3) + * @param silt Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @param clay Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @return Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + * + * @details Prediction target: + * Saturated hydraulic conductivity + * @note Mean coefficients of the top 25 percent, ranked by descending R-squared (Section 3.3). + * @note Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + * predictors and response, as a reviewed reconstruction. + * @warning The publication does not explicitly confirm Table 1 statistics as the fitted + * scaling constants or the application of response scaling. This reconstruction has not been + * verified against author software. + * @warning Observed ranges describe the sampled soils; predictions are not clamped. + */ +static inline double calc_ptf_zhao2016_m2_2(double bulk_density, double silt, double clay) { + const double bd_scaled = (bulk_density - (1.32 - 2.0 * 0.14)) / (4.0 * 0.14); + const double silt_scaled = (silt - (63.33 - 2.0 * 9.85)) / (4.0 * 9.85); + const double clay_scaled = (clay - (17.41 - 2.0 * 4.69)) / (4.0 * 4.69); + const double response_scaled = + 0.868 - 0.557 * bd_scaled - 0.408 * silt_scaled + 0.231 * clay_scaled; + return 4.0 * 0.25 * response_scaled + 0.37 - 2.0 * 0.25; +} + +/** + * @brief Estimate saturated hydraulic conductivity using reconstructed M2-3. + * @param bulk_density Soil bulk density measured on undisturbed cores. (g/cm^3) + * @param silt Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @param clay Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @return Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + * + * @details Prediction target: + * Saturated hydraulic conductivity + * @note Mean coefficients of the top 50 percent, ranked by descending R-squared (Section 3.3). + * @note Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + * predictors and response, as a reviewed reconstruction. + * @warning The publication does not explicitly confirm Table 1 statistics as the fitted + * scaling constants or the application of response scaling. This reconstruction has not been + * verified against author software. + * @warning Observed ranges describe the sampled soils; predictions are not clamped. + */ +static inline double calc_ptf_zhao2016_m2_3(double bulk_density, double silt, double clay) { + const double bd_scaled = (bulk_density - (1.32 - 2.0 * 0.14)) / (4.0 * 0.14); + const double silt_scaled = (silt - (63.33 - 2.0 * 9.85)) / (4.0 * 9.85); + const double clay_scaled = (clay - (17.41 - 2.0 * 4.69)) / (4.0 * 4.69); + const double response_scaled = + 0.872 - 0.565 * bd_scaled - 0.413 * silt_scaled + 0.236 * clay_scaled; + return 4.0 * 0.25 * response_scaled + 0.37 - 2.0 * 0.25; +} + +/** + * @brief Estimate saturated hydraulic conductivity using reconstructed M2-4. + * @param bulk_density Soil bulk density measured on undisturbed cores. (g/cm^3) + * @param silt Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @param clay Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @return Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + * + * @details Prediction target: + * Saturated hydraulic conductivity + * @note Mean coefficients of the top 75 percent, ranked by descending R-squared (Section 3.3). + * @note Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + * predictors and response, as a reviewed reconstruction. + * @warning The publication does not explicitly confirm Table 1 statistics as the fitted + * scaling constants or the application of response scaling. This reconstruction has not been + * verified against author software. + * @warning Observed ranges describe the sampled soils; predictions are not clamped. + */ +static inline double calc_ptf_zhao2016_m2_4(double bulk_density, double silt, double clay) { + const double bd_scaled = (bulk_density - (1.32 - 2.0 * 0.14)) / (4.0 * 0.14); + const double silt_scaled = (silt - (63.33 - 2.0 * 9.85)) / (4.0 * 9.85); + const double clay_scaled = (clay - (17.41 - 2.0 * 4.69)) / (4.0 * 4.69); + const double response_scaled = + 0.877 - 0.572 * bd_scaled - 0.417 * silt_scaled + 0.237 * clay_scaled; + return 4.0 * 0.25 * response_scaled + 0.37 - 2.0 * 0.25; +} + +/** + * @brief Estimate saturated hydraulic conductivity using reconstructed M2-5. + * @param bulk_density Soil bulk density measured on undisturbed cores. (g/cm^3) + * @param silt Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @param clay Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @return Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + * + * @details Prediction target: + * Saturated hydraulic conductivity + * @note Mean coefficients of all 400 PTFs, ranked by descending R-squared (Section 3.3). + * @note Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + * predictors and response, as a reviewed reconstruction. + * @warning The publication does not explicitly confirm Table 1 statistics as the fitted + * scaling constants or the application of response scaling. This reconstruction has not been + * verified against author software. + * @warning Observed ranges describe the sampled soils; predictions are not clamped. + */ +static inline double calc_ptf_zhao2016_m2_5(double bulk_density, double silt, double clay) { + const double bd_scaled = (bulk_density - (1.32 - 2.0 * 0.14)) / (4.0 * 0.14); + const double silt_scaled = (silt - (63.33 - 2.0 * 9.85)) / (4.0 * 9.85); + const double clay_scaled = (clay - (17.41 - 2.0 * 4.69)) / (4.0 * 4.69); + const double response_scaled = + 0.882 - 0.581 * bd_scaled - 0.422 * silt_scaled + 0.240 * clay_scaled; + return 4.0 * 0.25 * response_scaled + 0.37 - 2.0 * 0.25; +} + +/** + * @brief Estimate saturated hydraulic conductivity using reconstructed M2-6. + * @param bulk_density Soil bulk density measured on undisturbed cores. (g/cm^3) + * @param silt Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @param clay Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). + * (%) + * @return Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + * + * @details Prediction target: + * Saturated hydraulic conductivity + * @note Lowest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). + * @note Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + * predictors and response, as a reviewed reconstruction. + * @warning The publication does not explicitly confirm Table 1 statistics as the fitted + * scaling constants or the application of response scaling. This reconstruction has not been + * verified against author software. + * @warning Observed ranges describe the sampled soils; predictions are not clamped. + */ +static inline double calc_ptf_zhao2016_m2_6(double bulk_density, double silt, double clay) { + const double bd_scaled = (bulk_density - (1.32 - 2.0 * 0.14)) / (4.0 * 0.14); + const double silt_scaled = (silt - (63.33 - 2.0 * 9.85)) / (4.0 * 9.85); + const double clay_scaled = (clay - (17.41 - 2.0 * 4.69)) / (4.0 * 4.69); + const double response_scaled = + 0.891 - 0.637 * bd_scaled - 0.470 * silt_scaled + 0.316 * clay_scaled; + return 4.0 * 0.25 * response_scaled + 0.37 - 2.0 * 0.25; +} + +#endif diff --git a/targets/ptfkit-native/tests/c/zhao2016.c b/targets/ptfkit-native/tests/c/zhao2016.c new file mode 100644 index 0000000..f00be4d --- /dev/null +++ b/targets/ptfkit-native/tests/c/zhao2016.c @@ -0,0 +1,68 @@ +/* @generated by ptfkit-codegen; DO NOT EDIT. */ + +#include +#include "support/close_enough.h" + +int main() { + { + const double result = calc_ptf_zhao2016_m2_1(1.32, 63.33, 17.41); + assert_close(result, 0.378, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "published_predictor_means"); + } + { + const double result = calc_ptf_zhao2016_m2_1(1.2, 60.0, 20.0); + assert_close(result, 0.561576533395387, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "interior_soil"); + } + { + const double result = calc_ptf_zhao2016_m2_2(1.32, 63.33, 17.41); + assert_close(result, 0.371, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "published_predictor_means"); + } + { + const double result = calc_ptf_zhao2016_m2_2(1.2, 60.0, 20.0); + assert_close(result, 0.5567321826328834, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "interior_soil"); + } + { + const double result = calc_ptf_zhao2016_m2_3(1.32, 63.33, 17.41); + assert_close(result, 0.371, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "published_predictor_means"); + } + { + const double result = calc_ptf_zhao2016_m2_3(1.2, 60.0, 20.0); + assert_close(result, 0.5595593556871192, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "interior_soil"); + } + { + const double result = calc_ptf_zhao2016_m2_4(1.32, 63.33, 17.41); + assert_close(result, 0.371, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "published_predictor_means"); + } + { + const double result = calc_ptf_zhao2016_m2_4(1.2, 60.0, 20.0); + assert_close(result, 0.5615354864546015, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "interior_soil"); + } + { + const double result = calc_ptf_zhao2016_m2_5(1.32, 63.33, 17.41); + assert_close(result, 0.3705, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "published_predictor_means"); + } + { + const double result = calc_ptf_zhao2016_m2_5(1.2, 60.0, 20.0); + assert_close(result, 0.5638008258201379, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "interior_soil"); + } + { + const double result = calc_ptf_zhao2016_m2_6(1.32, 63.33, 17.41); + assert_close(result, 0.3655, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "published_predictor_means"); + } + { + const double result = calc_ptf_zhao2016_m2_6(1.2, 60.0, 20.0); + assert_close(result, 0.5853502159254489, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "interior_soil"); + } + return 0; +} diff --git a/targets/ptfkit-native/tests/cpp/zhao2016.cpp b/targets/ptfkit-native/tests/cpp/zhao2016.cpp new file mode 100644 index 0000000..975aa29 --- /dev/null +++ b/targets/ptfkit-native/tests/cpp/zhao2016.cpp @@ -0,0 +1,73 @@ +/* @generated by ptfkit-codegen; DO NOT EDIT. */ + +#ifdef IMPORT_UMBRELLA +import ptfkit; +#else +import ptfkit.zhao2016; +#endif + +#include "support/close_enough.h" + +int main() { + { + const auto result = ptfkit::zhao2016::calc_ptf_zhao2016_m2_1(1.32, 63.33, 17.41); + assert_close(result, 0.378, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "published_predictor_means"); + } + { + const auto result = ptfkit::zhao2016::calc_ptf_zhao2016_m2_1(1.2, 60.0, 20.0); + assert_close(result, 0.561576533395387, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "interior_soil"); + } + { + const auto result = ptfkit::zhao2016::calc_ptf_zhao2016_m2_2(1.32, 63.33, 17.41); + assert_close(result, 0.371, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "published_predictor_means"); + } + { + const auto result = ptfkit::zhao2016::calc_ptf_zhao2016_m2_2(1.2, 60.0, 20.0); + assert_close(result, 0.5567321826328834, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "interior_soil"); + } + { + const auto result = ptfkit::zhao2016::calc_ptf_zhao2016_m2_3(1.32, 63.33, 17.41); + assert_close(result, 0.371, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "published_predictor_means"); + } + { + const auto result = ptfkit::zhao2016::calc_ptf_zhao2016_m2_3(1.2, 60.0, 20.0); + assert_close(result, 0.5595593556871192, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "interior_soil"); + } + { + const auto result = ptfkit::zhao2016::calc_ptf_zhao2016_m2_4(1.32, 63.33, 17.41); + assert_close(result, 0.371, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "published_predictor_means"); + } + { + const auto result = ptfkit::zhao2016::calc_ptf_zhao2016_m2_4(1.2, 60.0, 20.0); + assert_close(result, 0.5615354864546015, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "interior_soil"); + } + { + const auto result = ptfkit::zhao2016::calc_ptf_zhao2016_m2_5(1.32, 63.33, 17.41); + assert_close(result, 0.3705, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "published_predictor_means"); + } + { + const auto result = ptfkit::zhao2016::calc_ptf_zhao2016_m2_5(1.2, 60.0, 20.0); + assert_close(result, 0.5638008258201379, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "interior_soil"); + } + { + const auto result = ptfkit::zhao2016::calc_ptf_zhao2016_m2_6(1.32, 63.33, 17.41); + assert_close(result, 0.3655, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "published_predictor_means"); + } + { + const auto result = ptfkit::zhao2016::calc_ptf_zhao2016_m2_6(1.2, 60.0, 20.0); + assert_close(result, 0.5853502159254489, 0.0001, 0.01, "saturated_hydraulic_conductivity", + "millimeter_per_minute", "registry", "interior_soil"); + } + return 0; +} diff --git a/targets/ptfkit-py/src/ptfkit/_ptfkit.pyi b/targets/ptfkit-py/src/ptfkit/_ptfkit.pyi index fa0c8d2..84d1bbb 100644 --- a/targets/ptfkit-py/src/ptfkit/_ptfkit.pyi +++ b/targets/ptfkit-py/src/ptfkit/_ptfkit.pyi @@ -127,3 +127,9 @@ calc_ptf_vereecken1989: ufunc calc_ptf_vereecken1989_detailed: ufunc calc_ptf_wang2012: ufunc calc_ptf_weber2020: ufunc +calc_ptf_zhao2016_m2_1: ufunc +calc_ptf_zhao2016_m2_2: ufunc +calc_ptf_zhao2016_m2_3: ufunc +calc_ptf_zhao2016_m2_4: ufunc +calc_ptf_zhao2016_m2_5: ufunc +calc_ptf_zhao2016_m2_6: ufunc diff --git a/targets/ptfkit-py/src/ptfkit/ptfkit.c b/targets/ptfkit-py/src/ptfkit/ptfkit.c index 7d621be..6842698 100644 --- a/targets/ptfkit-py/src/ptfkit/ptfkit.c +++ b/targets/ptfkit-py/src/ptfkit/ptfkit.c @@ -29,6 +29,7 @@ #include "vereecken1989.c" #include "wang2012.c" #include "weber2020.c" +#include "zhao2016.c" static struct PyModuleDef module_def = {PyModuleDef_HEAD_INIT, "_ptfkit", NULL, -1, NULL}; @@ -130,5 +131,9 @@ PyMODINIT_FUNC PyInit__ptfkit(void) { Py_DECREF(module); return NULL; } + if (ptfkit_register_zhao2016(module) < 0) { + Py_DECREF(module); + return NULL; + } return module; } diff --git a/targets/ptfkit-py/src/ptfkit/zhao2016.c b/targets/ptfkit-py/src/ptfkit/zhao2016.c new file mode 100644 index 0000000..e9515f9 --- /dev/null +++ b/targets/ptfkit-py/src/ptfkit/zhao2016.c @@ -0,0 +1,319 @@ +/* @generated by ptfkit-codegen; DO NOT EDIT. */ +#include +#include "ufunc.h" + +static const int calc_ptf_zhao2016_m2_1_types[] = {NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE}; +static int calc_ptf_zhao2016_m2_1_contiguous_loop(PyArrayMethod_Context *context, char *const *data, + const npy_intp *dimensions, + const npy_intp *strides, + NpyAuxData *transferdata) { + (void)context; + (void)strides; + (void)transferdata; + const double *in_bulk_density = (const double *)data[0]; + const double *in_silt = (const double *)data[1]; + const double *in_clay = (const double *)data[2]; + double *out_ks = (double *)data[3]; + for (npy_intp index = 0; index < dimensions[0]; index++) { + const double bulk_density = in_bulk_density[index]; + const double silt = in_silt[index]; + const double clay = in_clay[index]; + const double ptfkit_result = calc_ptf_zhao2016_m2_1(bulk_density, silt, clay); + out_ks[index] = ptfkit_result; + } + return 0; +} + +static int calc_ptf_zhao2016_m2_1_strided_loop(PyArrayMethod_Context *context, char *const *data, + const npy_intp *dimensions, const npy_intp *strides, + NpyAuxData *transferdata) { + (void)context; + (void)transferdata; + for (npy_intp index = 0; index < dimensions[0]; index++) { + const double bulk_density = *(const double *)(data[0] + index * strides[0]); + const double silt = *(const double *)(data[1] + index * strides[1]); + const double clay = *(const double *)(data[2] + index * strides[2]); + const double ptfkit_result = calc_ptf_zhao2016_m2_1(bulk_density, silt, clay); + *(double *)(data[3] + index * strides[3]) = ptfkit_result; + } + return 0; +} +static PyType_Slot calc_ptf_zhao2016_m2_1_slots[] = { + {NPY_METH_strided_loop, calc_ptf_zhao2016_m2_1_strided_loop}, + {NPY_METH_contiguous_loop, calc_ptf_zhao2016_m2_1_contiguous_loop}, + {0, NULL}, +}; +static PyArrayMethod_Spec calc_ptf_zhao2016_m2_1_spec = { + .name = "calc_ptf_zhao2016_m2_1", + .nin = 3, + .nout = 1, + .casting = NPY_SAME_KIND_CASTING, + .slots = calc_ptf_zhao2016_m2_1_slots, +}; + +static const int calc_ptf_zhao2016_m2_2_types[] = {NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE}; +static int calc_ptf_zhao2016_m2_2_contiguous_loop(PyArrayMethod_Context *context, char *const *data, + const npy_intp *dimensions, + const npy_intp *strides, + NpyAuxData *transferdata) { + (void)context; + (void)strides; + (void)transferdata; + const double *in_bulk_density = (const double *)data[0]; + const double *in_silt = (const double *)data[1]; + const double *in_clay = (const double *)data[2]; + double *out_ks = (double *)data[3]; + for (npy_intp index = 0; index < dimensions[0]; index++) { + const double bulk_density = in_bulk_density[index]; + const double silt = in_silt[index]; + const double clay = in_clay[index]; + const double ptfkit_result = calc_ptf_zhao2016_m2_2(bulk_density, silt, clay); + out_ks[index] = ptfkit_result; + } + return 0; +} + +static int calc_ptf_zhao2016_m2_2_strided_loop(PyArrayMethod_Context *context, char *const *data, + const npy_intp *dimensions, const npy_intp *strides, + NpyAuxData *transferdata) { + (void)context; + (void)transferdata; + for (npy_intp index = 0; index < dimensions[0]; index++) { + const double bulk_density = *(const double *)(data[0] + index * strides[0]); + const double silt = *(const double *)(data[1] + index * strides[1]); + const double clay = *(const double *)(data[2] + index * strides[2]); + const double ptfkit_result = calc_ptf_zhao2016_m2_2(bulk_density, silt, clay); + *(double *)(data[3] + index * strides[3]) = ptfkit_result; + } + return 0; +} +static PyType_Slot calc_ptf_zhao2016_m2_2_slots[] = { + {NPY_METH_strided_loop, calc_ptf_zhao2016_m2_2_strided_loop}, + {NPY_METH_contiguous_loop, calc_ptf_zhao2016_m2_2_contiguous_loop}, + {0, NULL}, +}; +static PyArrayMethod_Spec calc_ptf_zhao2016_m2_2_spec = { + .name = "calc_ptf_zhao2016_m2_2", + .nin = 3, + .nout = 1, + .casting = NPY_SAME_KIND_CASTING, + .slots = calc_ptf_zhao2016_m2_2_slots, +}; + +static const int calc_ptf_zhao2016_m2_3_types[] = {NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE}; +static int calc_ptf_zhao2016_m2_3_contiguous_loop(PyArrayMethod_Context *context, char *const *data, + const npy_intp *dimensions, + const npy_intp *strides, + NpyAuxData *transferdata) { + (void)context; + (void)strides; + (void)transferdata; + const double *in_bulk_density = (const double *)data[0]; + const double *in_silt = (const double *)data[1]; + const double *in_clay = (const double *)data[2]; + double *out_ks = (double *)data[3]; + for (npy_intp index = 0; index < dimensions[0]; index++) { + const double bulk_density = in_bulk_density[index]; + const double silt = in_silt[index]; + const double clay = in_clay[index]; + const double ptfkit_result = calc_ptf_zhao2016_m2_3(bulk_density, silt, clay); + out_ks[index] = ptfkit_result; + } + return 0; +} + +static int calc_ptf_zhao2016_m2_3_strided_loop(PyArrayMethod_Context *context, char *const *data, + const npy_intp *dimensions, const npy_intp *strides, + NpyAuxData *transferdata) { + (void)context; + (void)transferdata; + for (npy_intp index = 0; index < dimensions[0]; index++) { + const double bulk_density = *(const double *)(data[0] + index * strides[0]); + const double silt = *(const double *)(data[1] + index * strides[1]); + const double clay = *(const double *)(data[2] + index * strides[2]); + const double ptfkit_result = calc_ptf_zhao2016_m2_3(bulk_density, silt, clay); + *(double *)(data[3] + index * strides[3]) = ptfkit_result; + } + return 0; +} +static PyType_Slot calc_ptf_zhao2016_m2_3_slots[] = { + {NPY_METH_strided_loop, calc_ptf_zhao2016_m2_3_strided_loop}, + {NPY_METH_contiguous_loop, calc_ptf_zhao2016_m2_3_contiguous_loop}, + {0, NULL}, +}; +static PyArrayMethod_Spec calc_ptf_zhao2016_m2_3_spec = { + .name = "calc_ptf_zhao2016_m2_3", + .nin = 3, + .nout = 1, + .casting = NPY_SAME_KIND_CASTING, + .slots = calc_ptf_zhao2016_m2_3_slots, +}; + +static const int calc_ptf_zhao2016_m2_4_types[] = {NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE}; +static int calc_ptf_zhao2016_m2_4_contiguous_loop(PyArrayMethod_Context *context, char *const *data, + const npy_intp *dimensions, + const npy_intp *strides, + NpyAuxData *transferdata) { + (void)context; + (void)strides; + (void)transferdata; + const double *in_bulk_density = (const double *)data[0]; + const double *in_silt = (const double *)data[1]; + const double *in_clay = (const double *)data[2]; + double *out_ks = (double *)data[3]; + for (npy_intp index = 0; index < dimensions[0]; index++) { + const double bulk_density = in_bulk_density[index]; + const double silt = in_silt[index]; + const double clay = in_clay[index]; + const double ptfkit_result = calc_ptf_zhao2016_m2_4(bulk_density, silt, clay); + out_ks[index] = ptfkit_result; + } + return 0; +} + +static int calc_ptf_zhao2016_m2_4_strided_loop(PyArrayMethod_Context *context, char *const *data, + const npy_intp *dimensions, const npy_intp *strides, + NpyAuxData *transferdata) { + (void)context; + (void)transferdata; + for (npy_intp index = 0; index < dimensions[0]; index++) { + const double bulk_density = *(const double *)(data[0] + index * strides[0]); + const double silt = *(const double *)(data[1] + index * strides[1]); + const double clay = *(const double *)(data[2] + index * strides[2]); + const double ptfkit_result = calc_ptf_zhao2016_m2_4(bulk_density, silt, clay); + *(double *)(data[3] + index * strides[3]) = ptfkit_result; + } + return 0; +} +static PyType_Slot calc_ptf_zhao2016_m2_4_slots[] = { + {NPY_METH_strided_loop, calc_ptf_zhao2016_m2_4_strided_loop}, + {NPY_METH_contiguous_loop, calc_ptf_zhao2016_m2_4_contiguous_loop}, + {0, NULL}, +}; +static PyArrayMethod_Spec calc_ptf_zhao2016_m2_4_spec = { + .name = "calc_ptf_zhao2016_m2_4", + .nin = 3, + .nout = 1, + .casting = NPY_SAME_KIND_CASTING, + .slots = calc_ptf_zhao2016_m2_4_slots, +}; + +static const int calc_ptf_zhao2016_m2_5_types[] = {NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE}; +static int calc_ptf_zhao2016_m2_5_contiguous_loop(PyArrayMethod_Context *context, char *const *data, + const npy_intp *dimensions, + const npy_intp *strides, + NpyAuxData *transferdata) { + (void)context; + (void)strides; + (void)transferdata; + const double *in_bulk_density = (const double *)data[0]; + const double *in_silt = (const double *)data[1]; + const double *in_clay = (const double *)data[2]; + double *out_ks = (double *)data[3]; + for (npy_intp index = 0; index < dimensions[0]; index++) { + const double bulk_density = in_bulk_density[index]; + const double silt = in_silt[index]; + const double clay = in_clay[index]; + const double ptfkit_result = calc_ptf_zhao2016_m2_5(bulk_density, silt, clay); + out_ks[index] = ptfkit_result; + } + return 0; +} + +static int calc_ptf_zhao2016_m2_5_strided_loop(PyArrayMethod_Context *context, char *const *data, + const npy_intp *dimensions, const npy_intp *strides, + NpyAuxData *transferdata) { + (void)context; + (void)transferdata; + for (npy_intp index = 0; index < dimensions[0]; index++) { + const double bulk_density = *(const double *)(data[0] + index * strides[0]); + const double silt = *(const double *)(data[1] + index * strides[1]); + const double clay = *(const double *)(data[2] + index * strides[2]); + const double ptfkit_result = calc_ptf_zhao2016_m2_5(bulk_density, silt, clay); + *(double *)(data[3] + index * strides[3]) = ptfkit_result; + } + return 0; +} +static PyType_Slot calc_ptf_zhao2016_m2_5_slots[] = { + {NPY_METH_strided_loop, calc_ptf_zhao2016_m2_5_strided_loop}, + {NPY_METH_contiguous_loop, calc_ptf_zhao2016_m2_5_contiguous_loop}, + {0, NULL}, +}; +static PyArrayMethod_Spec calc_ptf_zhao2016_m2_5_spec = { + .name = "calc_ptf_zhao2016_m2_5", + .nin = 3, + .nout = 1, + .casting = NPY_SAME_KIND_CASTING, + .slots = calc_ptf_zhao2016_m2_5_slots, +}; + +static const int calc_ptf_zhao2016_m2_6_types[] = {NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE}; +static int calc_ptf_zhao2016_m2_6_contiguous_loop(PyArrayMethod_Context *context, char *const *data, + const npy_intp *dimensions, + const npy_intp *strides, + NpyAuxData *transferdata) { + (void)context; + (void)strides; + (void)transferdata; + const double *in_bulk_density = (const double *)data[0]; + const double *in_silt = (const double *)data[1]; + const double *in_clay = (const double *)data[2]; + double *out_ks = (double *)data[3]; + for (npy_intp index = 0; index < dimensions[0]; index++) { + const double bulk_density = in_bulk_density[index]; + const double silt = in_silt[index]; + const double clay = in_clay[index]; + const double ptfkit_result = calc_ptf_zhao2016_m2_6(bulk_density, silt, clay); + out_ks[index] = ptfkit_result; + } + return 0; +} + +static int calc_ptf_zhao2016_m2_6_strided_loop(PyArrayMethod_Context *context, char *const *data, + const npy_intp *dimensions, const npy_intp *strides, + NpyAuxData *transferdata) { + (void)context; + (void)transferdata; + for (npy_intp index = 0; index < dimensions[0]; index++) { + const double bulk_density = *(const double *)(data[0] + index * strides[0]); + const double silt = *(const double *)(data[1] + index * strides[1]); + const double clay = *(const double *)(data[2] + index * strides[2]); + const double ptfkit_result = calc_ptf_zhao2016_m2_6(bulk_density, silt, clay); + *(double *)(data[3] + index * strides[3]) = ptfkit_result; + } + return 0; +} +static PyType_Slot calc_ptf_zhao2016_m2_6_slots[] = { + {NPY_METH_strided_loop, calc_ptf_zhao2016_m2_6_strided_loop}, + {NPY_METH_contiguous_loop, calc_ptf_zhao2016_m2_6_contiguous_loop}, + {0, NULL}, +}; +static PyArrayMethod_Spec calc_ptf_zhao2016_m2_6_spec = { + .name = "calc_ptf_zhao2016_m2_6", + .nin = 3, + .nout = 1, + .casting = NPY_SAME_KIND_CASTING, + .slots = calc_ptf_zhao2016_m2_6_slots, +}; + +int ptfkit_register_zhao2016(PyObject *module) { + if (ptfkit_add_ufunc(module, "calc_ptf_zhao2016_m2_1", calc_ptf_zhao2016_m2_1_types, 3, 1, + &calc_ptf_zhao2016_m2_1_spec) < 0) + return -1; + if (ptfkit_add_ufunc(module, "calc_ptf_zhao2016_m2_2", calc_ptf_zhao2016_m2_2_types, 3, 1, + &calc_ptf_zhao2016_m2_2_spec) < 0) + return -1; + if (ptfkit_add_ufunc(module, "calc_ptf_zhao2016_m2_3", calc_ptf_zhao2016_m2_3_types, 3, 1, + &calc_ptf_zhao2016_m2_3_spec) < 0) + return -1; + if (ptfkit_add_ufunc(module, "calc_ptf_zhao2016_m2_4", calc_ptf_zhao2016_m2_4_types, 3, 1, + &calc_ptf_zhao2016_m2_4_spec) < 0) + return -1; + if (ptfkit_add_ufunc(module, "calc_ptf_zhao2016_m2_5", calc_ptf_zhao2016_m2_5_types, 3, 1, + &calc_ptf_zhao2016_m2_5_spec) < 0) + return -1; + if (ptfkit_add_ufunc(module, "calc_ptf_zhao2016_m2_6", calc_ptf_zhao2016_m2_6_types, 3, 1, + &calc_ptf_zhao2016_m2_6_spec) < 0) + return -1; + return 0; +} diff --git a/targets/ptfkit-py/src/ptfkit/zhao2016.py b/targets/ptfkit-py/src/ptfkit/zhao2016.py new file mode 100644 index 0000000..1aa7cd0 --- /dev/null +++ b/targets/ptfkit-py/src/ptfkit/zhao2016.py @@ -0,0 +1,375 @@ +# @generated by ptfkit-codegen; DO NOT EDIT. + +# ruff: noqa: I001 + +r"""Saturated hydraulic conductivity PTFs for the Loess Plateau of China. + +Reference: + Zhao, C., Shao, M., Jia, X., Nasir, M., & Zhang, C. (2016). Using pedotransfer functions to + estimate soil hydraulic conductivity in the Loess Plateau of China. CATENA, 143, 1-6. + https://doi.org/10.1016/j.catena.2016.03.037 + [DOI: 10.1016/j.catena.2016.03.037](https://doi.org/10.1016/j.catena.2016.03.037) + +Territory + +: Typical Loess Plateau of China, covering approximately 430,000 square kilometers. + +Dataset + +: 729 samples from 243 sites, sampled in 2012 at depths of 0-10, 10-20, and 20-40 cm. Each of 400 + random calibration-validation splits used 583 development records and 146 validation records + (Section 2.3.1). + +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, overload + +from ptfkit._dispatch import call as _call +from ptfkit._ptfkit import ( + calc_ptf_zhao2016_m2_1 as _calc_ptf_zhao2016_m2_1, + calc_ptf_zhao2016_m2_2 as _calc_ptf_zhao2016_m2_2, + calc_ptf_zhao2016_m2_3 as _calc_ptf_zhao2016_m2_3, + calc_ptf_zhao2016_m2_4 as _calc_ptf_zhao2016_m2_4, + calc_ptf_zhao2016_m2_5 as _calc_ptf_zhao2016_m2_5, + calc_ptf_zhao2016_m2_6 as _calc_ptf_zhao2016_m2_6, +) + + +if TYPE_CHECKING: + from numpy import floating + from numpy.typing import ArrayLike, NDArray + +__all__ = [ + 'calc_ptf_zhao2016_m2_1', + 'calc_ptf_zhao2016_m2_2', + 'calc_ptf_zhao2016_m2_3', + 'calc_ptf_zhao2016_m2_4', + 'calc_ptf_zhao2016_m2_5', + 'calc_ptf_zhao2016_m2_6', +] + + +@overload +def calc_ptf_zhao2016_m2_1(*, bulk_density: float, silt: float, clay: float) -> floating: ... + + +@overload +def calc_ptf_zhao2016_m2_1( + *, + bulk_density: ArrayLike, + silt: ArrayLike, + clay: ArrayLike, + out: NDArray[floating] | None = None, +) -> NDArray[floating]: ... + + +def calc_ptf_zhao2016_m2_1( + *, + bulk_density: float | ArrayLike, + silt: float | ArrayLike, + clay: float | ArrayLike, + out: NDArray[floating] | None = None, +) -> floating | NDArray[floating]: + """Estimate saturated hydraulic conductivity using reconstructed M2-1. + + Arguments: + bulk_density: Soil bulk density measured on undisturbed cores. (g/cm^3) + silt: Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + clay: Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + out: Optional output arrays for in-place calculation. + + Returns: + ks: Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + + Notes: + Prediction target: Saturated hydraulic conductivity + Highest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + predictors and response, as a reviewed reconstruction. + + Warning: + The publication does not explicitly confirm Table 1 statistics as the fitted scaling + constants or the application of response scaling. This reconstruction has not been + verified against author software. + Observed ranges describe the sampled soils; predictions are not clamped. + + """ + return _call( + _calc_ptf_zhao2016_m2_1, + bulk_density, + silt, + clay, + out=out, + ) + + +@overload +def calc_ptf_zhao2016_m2_2(*, bulk_density: float, silt: float, clay: float) -> floating: ... + + +@overload +def calc_ptf_zhao2016_m2_2( + *, + bulk_density: ArrayLike, + silt: ArrayLike, + clay: ArrayLike, + out: NDArray[floating] | None = None, +) -> NDArray[floating]: ... + + +def calc_ptf_zhao2016_m2_2( + *, + bulk_density: float | ArrayLike, + silt: float | ArrayLike, + clay: float | ArrayLike, + out: NDArray[floating] | None = None, +) -> floating | NDArray[floating]: + """Estimate saturated hydraulic conductivity using reconstructed M2-2. + + Arguments: + bulk_density: Soil bulk density measured on undisturbed cores. (g/cm^3) + silt: Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + clay: Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + out: Optional output arrays for in-place calculation. + + Returns: + ks: Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + + Notes: + Prediction target: Saturated hydraulic conductivity + Mean coefficients of the top 25 percent, ranked by descending R-squared (Section 3.3). + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + predictors and response, as a reviewed reconstruction. + + Warning: + The publication does not explicitly confirm Table 1 statistics as the fitted scaling + constants or the application of response scaling. This reconstruction has not been + verified against author software. + Observed ranges describe the sampled soils; predictions are not clamped. + + """ + return _call( + _calc_ptf_zhao2016_m2_2, + bulk_density, + silt, + clay, + out=out, + ) + + +@overload +def calc_ptf_zhao2016_m2_3(*, bulk_density: float, silt: float, clay: float) -> floating: ... + + +@overload +def calc_ptf_zhao2016_m2_3( + *, + bulk_density: ArrayLike, + silt: ArrayLike, + clay: ArrayLike, + out: NDArray[floating] | None = None, +) -> NDArray[floating]: ... + + +def calc_ptf_zhao2016_m2_3( + *, + bulk_density: float | ArrayLike, + silt: float | ArrayLike, + clay: float | ArrayLike, + out: NDArray[floating] | None = None, +) -> floating | NDArray[floating]: + """Estimate saturated hydraulic conductivity using reconstructed M2-3. + + Arguments: + bulk_density: Soil bulk density measured on undisturbed cores. (g/cm^3) + silt: Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + clay: Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + out: Optional output arrays for in-place calculation. + + Returns: + ks: Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + + Notes: + Prediction target: Saturated hydraulic conductivity + Mean coefficients of the top 50 percent, ranked by descending R-squared (Section 3.3). + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + predictors and response, as a reviewed reconstruction. + + Warning: + The publication does not explicitly confirm Table 1 statistics as the fitted scaling + constants or the application of response scaling. This reconstruction has not been + verified against author software. + Observed ranges describe the sampled soils; predictions are not clamped. + + """ + return _call( + _calc_ptf_zhao2016_m2_3, + bulk_density, + silt, + clay, + out=out, + ) + + +@overload +def calc_ptf_zhao2016_m2_4(*, bulk_density: float, silt: float, clay: float) -> floating: ... + + +@overload +def calc_ptf_zhao2016_m2_4( + *, + bulk_density: ArrayLike, + silt: ArrayLike, + clay: ArrayLike, + out: NDArray[floating] | None = None, +) -> NDArray[floating]: ... + + +def calc_ptf_zhao2016_m2_4( + *, + bulk_density: float | ArrayLike, + silt: float | ArrayLike, + clay: float | ArrayLike, + out: NDArray[floating] | None = None, +) -> floating | NDArray[floating]: + """Estimate saturated hydraulic conductivity using reconstructed M2-4. + + Arguments: + bulk_density: Soil bulk density measured on undisturbed cores. (g/cm^3) + silt: Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + clay: Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + out: Optional output arrays for in-place calculation. + + Returns: + ks: Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + + Notes: + Prediction target: Saturated hydraulic conductivity + Mean coefficients of the top 75 percent, ranked by descending R-squared (Section 3.3). + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + predictors and response, as a reviewed reconstruction. + + Warning: + The publication does not explicitly confirm Table 1 statistics as the fitted scaling + constants or the application of response scaling. This reconstruction has not been + verified against author software. + Observed ranges describe the sampled soils; predictions are not clamped. + + """ + return _call( + _calc_ptf_zhao2016_m2_4, + bulk_density, + silt, + clay, + out=out, + ) + + +@overload +def calc_ptf_zhao2016_m2_5(*, bulk_density: float, silt: float, clay: float) -> floating: ... + + +@overload +def calc_ptf_zhao2016_m2_5( + *, + bulk_density: ArrayLike, + silt: ArrayLike, + clay: ArrayLike, + out: NDArray[floating] | None = None, +) -> NDArray[floating]: ... + + +def calc_ptf_zhao2016_m2_5( + *, + bulk_density: float | ArrayLike, + silt: float | ArrayLike, + clay: float | ArrayLike, + out: NDArray[floating] | None = None, +) -> floating | NDArray[floating]: + """Estimate saturated hydraulic conductivity using reconstructed M2-5. + + Arguments: + bulk_density: Soil bulk density measured on undisturbed cores. (g/cm^3) + silt: Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + clay: Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + out: Optional output arrays for in-place calculation. + + Returns: + ks: Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + + Notes: + Prediction target: Saturated hydraulic conductivity + Mean coefficients of all 400 PTFs, ranked by descending R-squared (Section 3.3). + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + predictors and response, as a reviewed reconstruction. + + Warning: + The publication does not explicitly confirm Table 1 statistics as the fitted scaling + constants or the application of response scaling. This reconstruction has not been + verified against author software. + Observed ranges describe the sampled soils; predictions are not clamped. + + """ + return _call( + _calc_ptf_zhao2016_m2_5, + bulk_density, + silt, + clay, + out=out, + ) + + +@overload +def calc_ptf_zhao2016_m2_6(*, bulk_density: float, silt: float, clay: float) -> floating: ... + + +@overload +def calc_ptf_zhao2016_m2_6( + *, + bulk_density: ArrayLike, + silt: ArrayLike, + clay: ArrayLike, + out: NDArray[floating] | None = None, +) -> NDArray[floating]: ... + + +def calc_ptf_zhao2016_m2_6( + *, + bulk_density: float | ArrayLike, + silt: float | ArrayLike, + clay: float | ArrayLike, + out: NDArray[floating] | None = None, +) -> floating | NDArray[floating]: + """Estimate saturated hydraulic conductivity using reconstructed M2-6. + + Arguments: + bulk_density: Soil bulk density measured on undisturbed cores. (g/cm^3) + silt: Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + clay: Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + out: Optional output arrays for in-place calculation. + + Returns: + ks: Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + + Notes: + Prediction target: Saturated hydraulic conductivity + Lowest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). + Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both + predictors and response, as a reviewed reconstruction. + + Warning: + The publication does not explicitly confirm Table 1 statistics as the fitted scaling + constants or the application of response scaling. This reconstruction has not been + verified against author software. + Observed ranges describe the sampled soils; predictions are not clamped. + + """ + return _call( + _calc_ptf_zhao2016_m2_6, + bulk_density, + silt, + clay, + out=out, + ) diff --git a/targets/ptfkit-py/tests/test_zhao2016.py b/targets/ptfkit-py/tests/test_zhao2016.py new file mode 100644 index 0000000..3038656 --- /dev/null +++ b/targets/ptfkit-py/tests/test_zhao2016.py @@ -0,0 +1,350 @@ +# @generated by ptfkit-codegen; DO NOT EDIT. +from __future__ import annotations + +import pytest + +from _helpers import assert_close, prepare_vector_case +from ptfkit.zhao2016 import ( + calc_ptf_zhao2016_m2_1, + calc_ptf_zhao2016_m2_2, + calc_ptf_zhao2016_m2_3, + calc_ptf_zhao2016_m2_4, + calc_ptf_zhao2016_m2_5, + calc_ptf_zhao2016_m2_6, +) + + +CASES_CALC_PTF_ZHAO2016_M2_1 = [ + ({'bulk_density': 1.32, 'clay': 17.41, 'silt': 63.33}, {'ks': 0.378}), + ({'bulk_density': 1.2, 'clay': 20.0, 'silt': 60.0}, {'ks': 0.561576533395387}), +] +CASES_CALC_PTF_ZHAO2016_M2_1_IDS = [ + 'published_predictor_means', + 'interior_soil', +] + + +@pytest.mark.parametrize( + ('inputs', 'expected'), CASES_CALC_PTF_ZHAO2016_M2_1, ids=CASES_CALC_PTF_ZHAO2016_M2_1_IDS +) +def test_calc_ptf_zhao2016_m2_1_verification(inputs: dict[str, float], expected: dict[str, float]): + result = calc_ptf_zhao2016_m2_1(**inputs) + + assert_close( + result, + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +def test_calc_ptf_zhao2016_m2_1_array(): + inputs, expected, _out = prepare_vector_case(CASES_CALC_PTF_ZHAO2016_M2_1) + result = calc_ptf_zhao2016_m2_1(**inputs, out=None) + assert_close( + result[0], + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +def test_calc_ptf_zhao2016_m2_1_out(): + inputs, expected, out = prepare_vector_case(CASES_CALC_PTF_ZHAO2016_M2_1) + result = calc_ptf_zhao2016_m2_1(**inputs, out=out) + assert result is out + assert_close( + result[0], + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +CASES_CALC_PTF_ZHAO2016_M2_2 = [ + ({'bulk_density': 1.32, 'clay': 17.41, 'silt': 63.33}, {'ks': 0.371}), + ({'bulk_density': 1.2, 'clay': 20.0, 'silt': 60.0}, {'ks': 0.5567321826328834}), +] +CASES_CALC_PTF_ZHAO2016_M2_2_IDS = [ + 'published_predictor_means', + 'interior_soil', +] + + +@pytest.mark.parametrize( + ('inputs', 'expected'), CASES_CALC_PTF_ZHAO2016_M2_2, ids=CASES_CALC_PTF_ZHAO2016_M2_2_IDS +) +def test_calc_ptf_zhao2016_m2_2_verification(inputs: dict[str, float], expected: dict[str, float]): + result = calc_ptf_zhao2016_m2_2(**inputs) + + assert_close( + result, + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +def test_calc_ptf_zhao2016_m2_2_array(): + inputs, expected, _out = prepare_vector_case(CASES_CALC_PTF_ZHAO2016_M2_2) + result = calc_ptf_zhao2016_m2_2(**inputs, out=None) + assert_close( + result[0], + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +def test_calc_ptf_zhao2016_m2_2_out(): + inputs, expected, out = prepare_vector_case(CASES_CALC_PTF_ZHAO2016_M2_2) + result = calc_ptf_zhao2016_m2_2(**inputs, out=out) + assert result is out + assert_close( + result[0], + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +CASES_CALC_PTF_ZHAO2016_M2_3 = [ + ({'bulk_density': 1.32, 'clay': 17.41, 'silt': 63.33}, {'ks': 0.371}), + ({'bulk_density': 1.2, 'clay': 20.0, 'silt': 60.0}, {'ks': 0.5595593556871192}), +] +CASES_CALC_PTF_ZHAO2016_M2_3_IDS = [ + 'published_predictor_means', + 'interior_soil', +] + + +@pytest.mark.parametrize( + ('inputs', 'expected'), CASES_CALC_PTF_ZHAO2016_M2_3, ids=CASES_CALC_PTF_ZHAO2016_M2_3_IDS +) +def test_calc_ptf_zhao2016_m2_3_verification(inputs: dict[str, float], expected: dict[str, float]): + result = calc_ptf_zhao2016_m2_3(**inputs) + + assert_close( + result, + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +def test_calc_ptf_zhao2016_m2_3_array(): + inputs, expected, _out = prepare_vector_case(CASES_CALC_PTF_ZHAO2016_M2_3) + result = calc_ptf_zhao2016_m2_3(**inputs, out=None) + assert_close( + result[0], + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +def test_calc_ptf_zhao2016_m2_3_out(): + inputs, expected, out = prepare_vector_case(CASES_CALC_PTF_ZHAO2016_M2_3) + result = calc_ptf_zhao2016_m2_3(**inputs, out=out) + assert result is out + assert_close( + result[0], + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +CASES_CALC_PTF_ZHAO2016_M2_4 = [ + ({'bulk_density': 1.32, 'clay': 17.41, 'silt': 63.33}, {'ks': 0.371}), + ({'bulk_density': 1.2, 'clay': 20.0, 'silt': 60.0}, {'ks': 0.5615354864546015}), +] +CASES_CALC_PTF_ZHAO2016_M2_4_IDS = [ + 'published_predictor_means', + 'interior_soil', +] + + +@pytest.mark.parametrize( + ('inputs', 'expected'), CASES_CALC_PTF_ZHAO2016_M2_4, ids=CASES_CALC_PTF_ZHAO2016_M2_4_IDS +) +def test_calc_ptf_zhao2016_m2_4_verification(inputs: dict[str, float], expected: dict[str, float]): + result = calc_ptf_zhao2016_m2_4(**inputs) + + assert_close( + result, + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +def test_calc_ptf_zhao2016_m2_4_array(): + inputs, expected, _out = prepare_vector_case(CASES_CALC_PTF_ZHAO2016_M2_4) + result = calc_ptf_zhao2016_m2_4(**inputs, out=None) + assert_close( + result[0], + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +def test_calc_ptf_zhao2016_m2_4_out(): + inputs, expected, out = prepare_vector_case(CASES_CALC_PTF_ZHAO2016_M2_4) + result = calc_ptf_zhao2016_m2_4(**inputs, out=out) + assert result is out + assert_close( + result[0], + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +CASES_CALC_PTF_ZHAO2016_M2_5 = [ + ({'bulk_density': 1.32, 'clay': 17.41, 'silt': 63.33}, {'ks': 0.3705}), + ({'bulk_density': 1.2, 'clay': 20.0, 'silt': 60.0}, {'ks': 0.5638008258201379}), +] +CASES_CALC_PTF_ZHAO2016_M2_5_IDS = [ + 'published_predictor_means', + 'interior_soil', +] + + +@pytest.mark.parametrize( + ('inputs', 'expected'), CASES_CALC_PTF_ZHAO2016_M2_5, ids=CASES_CALC_PTF_ZHAO2016_M2_5_IDS +) +def test_calc_ptf_zhao2016_m2_5_verification(inputs: dict[str, float], expected: dict[str, float]): + result = calc_ptf_zhao2016_m2_5(**inputs) + + assert_close( + result, + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +def test_calc_ptf_zhao2016_m2_5_array(): + inputs, expected, _out = prepare_vector_case(CASES_CALC_PTF_ZHAO2016_M2_5) + result = calc_ptf_zhao2016_m2_5(**inputs, out=None) + assert_close( + result[0], + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +def test_calc_ptf_zhao2016_m2_5_out(): + inputs, expected, out = prepare_vector_case(CASES_CALC_PTF_ZHAO2016_M2_5) + result = calc_ptf_zhao2016_m2_5(**inputs, out=out) + assert result is out + assert_close( + result[0], + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +CASES_CALC_PTF_ZHAO2016_M2_6 = [ + ({'bulk_density': 1.32, 'clay': 17.41, 'silt': 63.33}, {'ks': 0.3655}), + ({'bulk_density': 1.2, 'clay': 20.0, 'silt': 60.0}, {'ks': 0.5853502159254489}), +] +CASES_CALC_PTF_ZHAO2016_M2_6_IDS = [ + 'published_predictor_means', + 'interior_soil', +] + + +@pytest.mark.parametrize( + ('inputs', 'expected'), CASES_CALC_PTF_ZHAO2016_M2_6, ids=CASES_CALC_PTF_ZHAO2016_M2_6_IDS +) +def test_calc_ptf_zhao2016_m2_6_verification(inputs: dict[str, float], expected: dict[str, float]): + result = calc_ptf_zhao2016_m2_6(**inputs) + + assert_close( + result, + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +def test_calc_ptf_zhao2016_m2_6_array(): + inputs, expected, _out = prepare_vector_case(CASES_CALC_PTF_ZHAO2016_M2_6) + result = calc_ptf_zhao2016_m2_6(**inputs, out=None) + assert_close( + result[0], + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) + + +def test_calc_ptf_zhao2016_m2_6_out(): + inputs, expected, out = prepare_vector_case(CASES_CALC_PTF_ZHAO2016_M2_6) + result = calc_ptf_zhao2016_m2_6(**inputs, out=out) + assert result is out + assert_close( + result[0], + expected['ks'], + absolute=0.0001, + relative=0.01, + quantity='saturated_hydraulic_conductivity', + unit='millimeter_per_minute', + source='registry', + ) diff --git a/targets/ptfkit-rs/src/lib.rs b/targets/ptfkit-rs/src/lib.rs index 20b82da..5e8164c 100644 --- a/targets/ptfkit-rs/src/lib.rs +++ b/targets/ptfkit-rs/src/lib.rs @@ -19,6 +19,7 @@ pub mod varallyai1982; pub mod vereecken1989; pub mod wang2012; pub mod weber2020; +pub mod zhao2016; #[cfg(test)] mod test_support; diff --git a/targets/ptfkit-rs/src/zhao2016.rs b/targets/ptfkit-rs/src/zhao2016.rs new file mode 100644 index 0000000..70f0af7 --- /dev/null +++ b/targets/ptfkit-rs/src/zhao2016.rs @@ -0,0 +1,417 @@ +// @generated by ptfkit-codegen; DO NOT EDIT. + +#![doc = r"Saturated hydraulic conductivity PTFs for the Loess Plateau of China. + +# Reference + +Zhao, C., Shao, M., Jia, X., Nasir, M., & Zhang, C. (2016). Using pedotransfer functions to +estimate soil hydraulic conductivity in the Loess Plateau of China. CATENA, 143, 1-6. +https://doi.org/10.1016/j.catena.2016.03.037 +DOI: 10.1016/j.catena.2016.03.037 (https://doi.org/10.1016/j.catena.2016.03.037) + +# Territory + +Typical Loess Plateau of China, covering approximately 430,000 square kilometers. + +# Dataset + +729 samples from 243 sites, sampled in 2012 at depths of 0-10, 10-20, and 20-40 cm. Each of 400 +random calibration-validation splits used 583 development records and 146 validation records +(Section 2.3.1)."] + +#[doc = r"Estimate saturated hydraulic conductivity using reconstructed M2-1. + +# Arguments + + * bulk_density: Soil bulk density measured on undisturbed cores. (g/cm^3) + * silt: Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + * clay: Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + +# Returns + + * ks: Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +# Notes + +Prediction target: Saturated hydraulic conductivity +Highest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). +Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors +and response, as a reviewed reconstruction. + +# Warnings + +The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants +or the application of response scaling. This reconstruction has not been verified against author +software. +Observed ranges describe the sampled soils; predictions are not clamped."] +#[cfg_attr(feature = "inline", inline)] +#[must_use] +pub fn calc_ptf_zhao2016_m2_1(bulk_density: f64, silt: f64, clay: f64) -> f64 { + let bd_scaled = (bulk_density - (1.32f64 - 2.0f64 * 0.14f64)) / (4.0f64 * 0.14f64); + let silt_scaled = (silt - (63.33f64 - 2.0f64 * 9.85f64)) / (4.0f64 * 9.85f64); + let clay_scaled = (clay - (17.41f64 - 2.0f64 * 4.69f64)) / (4.0f64 * 4.69f64); + let response_scaled = + 0.873f64 - 0.555f64 * bd_scaled - 0.399f64 * silt_scaled + 0.224f64 * clay_scaled; + 4.0f64 * 0.25f64 * response_scaled + 0.37f64 - 2.0f64 * 0.25f64 +} +#[cfg(test)] +mod calc_ptf_zhao2016_m2_1_tests { + use super::*; + use crate::test_support::assert_close; + #[test] + fn published_predictor_means() { + let result = calc_ptf_zhao2016_m2_1(1.32f64, 63.33f64, 17.41f64); + assert_close( + result, + 0.378f64, + 0.0001f64, + 0.01f64, + "saturated_hydraulic_conductivity", + "millimeter_per_minute", + "registry", + ); + } + #[test] + fn interior_soil() { + let result = calc_ptf_zhao2016_m2_1(1.2f64, 60f64, 20f64); + assert_close( + result, + 0.561576533395387f64, + 0.0001f64, + 0.01f64, + "saturated_hydraulic_conductivity", + "millimeter_per_minute", + "registry", + ); + } +} +#[doc = r"Estimate saturated hydraulic conductivity using reconstructed M2-2. + +# Arguments + + * bulk_density: Soil bulk density measured on undisturbed cores. (g/cm^3) + * silt: Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + * clay: Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + +# Returns + + * ks: Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +# Notes + +Prediction target: Saturated hydraulic conductivity +Mean coefficients of the top 25 percent, ranked by descending R-squared (Section 3.3). +Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors +and response, as a reviewed reconstruction. + +# Warnings + +The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants +or the application of response scaling. This reconstruction has not been verified against author +software. +Observed ranges describe the sampled soils; predictions are not clamped."] +#[cfg_attr(feature = "inline", inline)] +#[must_use] +pub fn calc_ptf_zhao2016_m2_2(bulk_density: f64, silt: f64, clay: f64) -> f64 { + let bd_scaled = (bulk_density - (1.32f64 - 2.0f64 * 0.14f64)) / (4.0f64 * 0.14f64); + let silt_scaled = (silt - (63.33f64 - 2.0f64 * 9.85f64)) / (4.0f64 * 9.85f64); + let clay_scaled = (clay - (17.41f64 - 2.0f64 * 4.69f64)) / (4.0f64 * 4.69f64); + let response_scaled = + 0.868f64 - 0.557f64 * bd_scaled - 0.408f64 * silt_scaled + 0.231f64 * clay_scaled; + 4.0f64 * 0.25f64 * response_scaled + 0.37f64 - 2.0f64 * 0.25f64 +} +#[cfg(test)] +mod calc_ptf_zhao2016_m2_2_tests { + use super::*; + use crate::test_support::assert_close; + #[test] + fn published_predictor_means() { + let result = calc_ptf_zhao2016_m2_2(1.32f64, 63.33f64, 17.41f64); + assert_close( + result, + 0.371f64, + 0.0001f64, + 0.01f64, + "saturated_hydraulic_conductivity", + "millimeter_per_minute", + "registry", + ); + } + #[test] + fn interior_soil() { + let result = calc_ptf_zhao2016_m2_2(1.2f64, 60f64, 20f64); + assert_close( + result, + 0.5567321826328834f64, + 0.0001f64, + 0.01f64, + "saturated_hydraulic_conductivity", + "millimeter_per_minute", + "registry", + ); + } +} +#[doc = r"Estimate saturated hydraulic conductivity using reconstructed M2-3. + +# Arguments + + * bulk_density: Soil bulk density measured on undisturbed cores. (g/cm^3) + * silt: Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + * clay: Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + +# Returns + + * ks: Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +# Notes + +Prediction target: Saturated hydraulic conductivity +Mean coefficients of the top 50 percent, ranked by descending R-squared (Section 3.3). +Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors +and response, as a reviewed reconstruction. + +# Warnings + +The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants +or the application of response scaling. This reconstruction has not been verified against author +software. +Observed ranges describe the sampled soils; predictions are not clamped."] +#[cfg_attr(feature = "inline", inline)] +#[must_use] +pub fn calc_ptf_zhao2016_m2_3(bulk_density: f64, silt: f64, clay: f64) -> f64 { + let bd_scaled = (bulk_density - (1.32f64 - 2.0f64 * 0.14f64)) / (4.0f64 * 0.14f64); + let silt_scaled = (silt - (63.33f64 - 2.0f64 * 9.85f64)) / (4.0f64 * 9.85f64); + let clay_scaled = (clay - (17.41f64 - 2.0f64 * 4.69f64)) / (4.0f64 * 4.69f64); + let response_scaled = + 0.872f64 - 0.565f64 * bd_scaled - 0.413f64 * silt_scaled + 0.236f64 * clay_scaled; + 4.0f64 * 0.25f64 * response_scaled + 0.37f64 - 2.0f64 * 0.25f64 +} +#[cfg(test)] +mod calc_ptf_zhao2016_m2_3_tests { + use super::*; + use crate::test_support::assert_close; + #[test] + fn published_predictor_means() { + let result = calc_ptf_zhao2016_m2_3(1.32f64, 63.33f64, 17.41f64); + assert_close( + result, + 0.371f64, + 0.0001f64, + 0.01f64, + "saturated_hydraulic_conductivity", + "millimeter_per_minute", + "registry", + ); + } + #[test] + fn interior_soil() { + let result = calc_ptf_zhao2016_m2_3(1.2f64, 60f64, 20f64); + assert_close( + result, + 0.5595593556871192f64, + 0.0001f64, + 0.01f64, + "saturated_hydraulic_conductivity", + "millimeter_per_minute", + "registry", + ); + } +} +#[doc = r"Estimate saturated hydraulic conductivity using reconstructed M2-4. + +# Arguments + + * bulk_density: Soil bulk density measured on undisturbed cores. (g/cm^3) + * silt: Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + * clay: Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + +# Returns + + * ks: Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +# Notes + +Prediction target: Saturated hydraulic conductivity +Mean coefficients of the top 75 percent, ranked by descending R-squared (Section 3.3). +Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors +and response, as a reviewed reconstruction. + +# Warnings + +The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants +or the application of response scaling. This reconstruction has not been verified against author +software. +Observed ranges describe the sampled soils; predictions are not clamped."] +#[cfg_attr(feature = "inline", inline)] +#[must_use] +pub fn calc_ptf_zhao2016_m2_4(bulk_density: f64, silt: f64, clay: f64) -> f64 { + let bd_scaled = (bulk_density - (1.32f64 - 2.0f64 * 0.14f64)) / (4.0f64 * 0.14f64); + let silt_scaled = (silt - (63.33f64 - 2.0f64 * 9.85f64)) / (4.0f64 * 9.85f64); + let clay_scaled = (clay - (17.41f64 - 2.0f64 * 4.69f64)) / (4.0f64 * 4.69f64); + let response_scaled = + 0.877f64 - 0.572f64 * bd_scaled - 0.417f64 * silt_scaled + 0.237f64 * clay_scaled; + 4.0f64 * 0.25f64 * response_scaled + 0.37f64 - 2.0f64 * 0.25f64 +} +#[cfg(test)] +mod calc_ptf_zhao2016_m2_4_tests { + use super::*; + use crate::test_support::assert_close; + #[test] + fn published_predictor_means() { + let result = calc_ptf_zhao2016_m2_4(1.32f64, 63.33f64, 17.41f64); + assert_close( + result, + 0.371f64, + 0.0001f64, + 0.01f64, + "saturated_hydraulic_conductivity", + "millimeter_per_minute", + "registry", + ); + } + #[test] + fn interior_soil() { + let result = calc_ptf_zhao2016_m2_4(1.2f64, 60f64, 20f64); + assert_close( + result, + 0.5615354864546015f64, + 0.0001f64, + 0.01f64, + "saturated_hydraulic_conductivity", + "millimeter_per_minute", + "registry", + ); + } +} +#[doc = r"Estimate saturated hydraulic conductivity using reconstructed M2-5. + +# Arguments + + * bulk_density: Soil bulk density measured on undisturbed cores. (g/cm^3) + * silt: Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + * clay: Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + +# Returns + + * ks: Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +# Notes + +Prediction target: Saturated hydraulic conductivity +Mean coefficients of all 400 PTFs, ranked by descending R-squared (Section 3.3). +Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors +and response, as a reviewed reconstruction. + +# Warnings + +The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants +or the application of response scaling. This reconstruction has not been verified against author +software. +Observed ranges describe the sampled soils; predictions are not clamped."] +#[cfg_attr(feature = "inline", inline)] +#[must_use] +pub fn calc_ptf_zhao2016_m2_5(bulk_density: f64, silt: f64, clay: f64) -> f64 { + let bd_scaled = (bulk_density - (1.32f64 - 2.0f64 * 0.14f64)) / (4.0f64 * 0.14f64); + let silt_scaled = (silt - (63.33f64 - 2.0f64 * 9.85f64)) / (4.0f64 * 9.85f64); + let clay_scaled = (clay - (17.41f64 - 2.0f64 * 4.69f64)) / (4.0f64 * 4.69f64); + let response_scaled = + 0.882f64 - 0.581f64 * bd_scaled - 0.422f64 * silt_scaled + 0.240f64 * clay_scaled; + 4.0f64 * 0.25f64 * response_scaled + 0.37f64 - 2.0f64 * 0.25f64 +} +#[cfg(test)] +mod calc_ptf_zhao2016_m2_5_tests { + use super::*; + use crate::test_support::assert_close; + #[test] + fn published_predictor_means() { + let result = calc_ptf_zhao2016_m2_5(1.32f64, 63.33f64, 17.41f64); + assert_close( + result, + 0.3705f64, + 0.0001f64, + 0.01f64, + "saturated_hydraulic_conductivity", + "millimeter_per_minute", + "registry", + ); + } + #[test] + fn interior_soil() { + let result = calc_ptf_zhao2016_m2_5(1.2f64, 60f64, 20f64); + assert_close( + result, + 0.5638008258201379f64, + 0.0001f64, + 0.01f64, + "saturated_hydraulic_conductivity", + "millimeter_per_minute", + "registry", + ); + } +} +#[doc = r"Estimate saturated hydraulic conductivity using reconstructed M2-6. + +# Arguments + + * bulk_density: Soil bulk density measured on undisturbed cores. (g/cm^3) + * silt: Silt content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + * clay: Clay content measured by laser diffraction using USDA taxonomy (Section 2.2.2). (%) + +# Returns + + * ks: Saturated hydraulic conductivity, measured by the constant-head method. (mm/min) + +# Notes + +Prediction target: Saturated hydraulic conductivity +Lowest-ranked fitted PTF, ranked by descending R-squared (Section 3.3). +Uses Table 1 means and standard deviations for Jia et al. (2012) Equation 3 on both predictors +and response, as a reviewed reconstruction. + +# Warnings + +The publication does not explicitly confirm Table 1 statistics as the fitted scaling constants +or the application of response scaling. This reconstruction has not been verified against author +software. +Observed ranges describe the sampled soils; predictions are not clamped."] +#[cfg_attr(feature = "inline", inline)] +#[must_use] +pub fn calc_ptf_zhao2016_m2_6(bulk_density: f64, silt: f64, clay: f64) -> f64 { + let bd_scaled = (bulk_density - (1.32f64 - 2.0f64 * 0.14f64)) / (4.0f64 * 0.14f64); + let silt_scaled = (silt - (63.33f64 - 2.0f64 * 9.85f64)) / (4.0f64 * 9.85f64); + let clay_scaled = (clay - (17.41f64 - 2.0f64 * 4.69f64)) / (4.0f64 * 4.69f64); + let response_scaled = + 0.891f64 - 0.637f64 * bd_scaled - 0.470f64 * silt_scaled + 0.316f64 * clay_scaled; + 4.0f64 * 0.25f64 * response_scaled + 0.37f64 - 2.0f64 * 0.25f64 +} +#[cfg(test)] +mod calc_ptf_zhao2016_m2_6_tests { + use super::*; + use crate::test_support::assert_close; + #[test] + fn published_predictor_means() { + let result = calc_ptf_zhao2016_m2_6(1.32f64, 63.33f64, 17.41f64); + assert_close( + result, + 0.3655f64, + 0.0001f64, + 0.01f64, + "saturated_hydraulic_conductivity", + "millimeter_per_minute", + "registry", + ); + } + #[test] + fn interior_soil() { + let result = calc_ptf_zhao2016_m2_6(1.2f64, 60f64, 20f64); + assert_close( + result, + 0.5853502159254489f64, + 0.0001f64, + 0.01f64, + "saturated_hydraulic_conductivity", + "millimeter_per_minute", + "registry", + ); + } +}