Skip to content

Process configuration

Overview

The process configuration file tells neptoon which processing steps to apply to a sensor time series. The main sections are config, neutron_quality_assessment, correction_steps, data_smoothing, kalman_soil_moisture, temporal_aggregation, and external_soil_moisture_processing. Sensor metadata, raw-file parsing, input-column mappings, external meteorology, and output storage are configured in the sensor YAML. Below is an example process file which you can use as a starting point for your own sensor.

The legacy top-level working_directory key is still accepted for compatibility but is deprecated. Relative paths now resolve against the YAML file containing them. A kalman_parameter_estimation metadata block produced by the standalone parameter tool is accepted so its YAML can be copied into a process configuration; the runtime filter settings remain under kalman_soil_moisture.

Cosmos Standard

The standard configuration is based on established CRNS processing methods and can be used as a starting point. Site-specific choices and future methods may require different settings.

The below processing yaml will be up to date with the current standard.

config: process

correction_steps:
  air_humidity:
    method: rosolem_2013
  air_pressure:
    method: tirado_bueno_2021
  incoming_radiation:
    method: mcjannet_desilets_2023
    reference_neutron_monitor:
      station: JUNG
      resolution: 60
      nmdb_table: revori
      request_timeout: 30
      allow_cache_fallback: true
  above_ground_biomass:
    method: none
  soil_moisture_estimation:
    method: desilets_etal_2010

data_smoothing:
  smooth_corrected_neutrons: true
  settings:
    algorithm: rolling_mean
    window: 12h
    min_proportion_good_data: 0.7

temporal_aggregation:
  aggregate_data: false

Configuration quick reference guide

Neutron Quality Assessment

Raw Neutron Quality Control Parameters

Here we conduct spike detection to account for problems in the raw count rate. There are a few algorithms to choose from, however we currently recommend using spike_offset with the defaults set to what you can see in the above yaml file. This follows the current literature by identifying spikes as anything >20% of previous value.

Parameter Required Type Example Description
spike_offset.threshold_relative Yes list [0.2, -0.2] Maximum percent (as decimal) that an observation can jump, before being designated a spike. Add two values in list format (with square brackets []), one with a positive sign and one with a negative sign. Advised to stick to uniform.
spike_offset.window Yes integer 12h The window to use to identify whether a spike as returned back to base line after a plateau of spikes
spike_offset.severity No string warning Scientific severity of flagged values: error (default) or warning.
spike_offset.action No string keep Action for flagged values: keep, mask, or raise. If omitted, warnings default to keep and errors to mask.

Corrected Neutron Quality Control Parameters

These are some quality checks we do on corrected neutrons based on the literature.

It's recommended to not touch this section unless you are experimenting.

Parameter Required Type Example Description
greater_than_N0.percent_maximum Yes float 1.075 Maximum allowed neutron count as percentage of N0 (Köhli 2021)
below_N0_factor.percent_minimum Yes float 0.3 Minimum allowed neutron count as percentage of N0

Correction Steps

The following section is for applying corrections to the neutron count rate to account for additional influences, besides soil moisture, that influence the count rate.

If you wish to turn off a particular correction - set the method to "none".

Air Humidity Correction

Air humidity corrections can be left as the example values shown below when being applied as these are based on the literature.

Köhli et al., 2021 method for neutron conversion

  • If you are using the koehli_etal_2021 method for neutron to soil moisture conversion - set the method to "none". The humidity correction is integrated to this method already. (If you forget neptoon will disapply this correction during neutron conversion, but it's best to not apply it in the first place)
Parameter Required Type Example Description
method No string "rosolem_2013" or "none" Method used for humidity correction
coefficient No float 0.0054 Correction coefficient for humidity. Legacy omega is accepted and normalised to this field.
humidity_ref No float 0 Reference absolute humidity value in g/m³

Thermal-neutron humidity correction

This optional correction produces a humidity-corrected thermal-neutron product. It is separate from the epithermal humidity correction above.

Parameter Required Type Default Description
method No string none rasche_2023 or none.
coefficient No float 0.0021 Thermal-neutron humidity coefficient in m³/g.
humidity_ref No float 0 Reference absolute humidity in g/m³.
thermal_neutron_column No string/null null Optional input override; otherwise the canonical thermal-neutron column is used.
output_column No string/null null Optional corrected-output column override.
correction_factor_column No string/null null Optional correction-factor column override.
missing_thermal_policy No string skip skip the product when thermal data are absent, or raise.
overwrite No boolean false Allow an existing output column to be replaced.
correction_steps:
  thermal_neutron_humidity:
    method: rasche_2023
    missing_thermal_policy: skip

Air Pressure Correction

Air pressure correction - usually keep this enabled because CRNS count rates are sensitive to atmospheric pressure changes.

Parameter Required Type Example Description
method Yes string "desilets_zreda_2003" or "desilets_2021" or "tirado_bueno_2021" or "none" Method used for pressure correction
dunai_inclination No float - Inclination parameter for dunai method

Incoming Intensity Correction

Parameter Required Type Example Description
method Yes string "hawdon_2014" or
"zreda_2012" or
"mcjannet_desilets_2023" or
"none"
Method used for incoming intensity correction
reference_value No float 160.88 Fixed positive incoming-neutron reference. Preferred when a known monitor mean should be used. Mutually exclusive with reference_column.
reference_column No string "ref" DataFrame column containing a fixed or time-varying reference. Mutually exclusive with reference_value.
reference_neutron_monitor.station Yes string "AATB" or
"INVK" or
"JUNG" or
"KERG" or
"KIEL" or
"MXCO" or
"NEWK" or
"OULU" or
"PSNM" or
"SOPO" or
"TERA" or
"THUL"
Reference neutron monitor station
reference_neutron_monitor.resolution Yes integer 60 Time resolution in minutes
reference_neutron_monitor.nmdb_table Yes string "revori" or "ori" NMDB table name (revori recommended)
reference_neutron_monitor.request_timeout No float 30 HTTPS request timeout in seconds.
reference_neutron_monitor.https_proxy No string/null null Optional HTTPS proxy URL. Legacy http_proxy is accepted as an alias.
reference_neutron_monitor.try_without_proxy No boolean true Retry directly if a configured proxy fails.
reference_neutron_monitor.allow_cache_fallback No boolean true Use cached NMDB data when refreshing missing dates fails.
reference_neutron_monitor.max_nearest_timedelta No string 3D Maximum time distance when attaching the nearest NMDB observation.

If neither reference_value nor reference_column is configured, Neptoon first uses the legacy sensor_info.reference_incoming_neutron_value value when present and otherwise falls back to the station-specific NMDB reference registry. Internally all three incoming-radiation corrections read a DataFrame column; a fixed numeric value is materialized into the canonical reference_incoming_neutron_value column before correction.

Above Ground Biomass Correction

Parameter Required Type Example Description
method No string "baatz_2015" or "morris_2024" or "none" Method used for biomass correction
biomass_units No string "method_expected", "kg_m2", or "bwe_mm" Units of the above_ground_biomass input column. baatz_2015 expects above-ground biomass in kg m^-2; morris_2024 expects biomass water equivalent in mm. If the supplied units do not match the selected method, Neptoon converts with BWE mm = AGB kg m^-2 × 0.494.

Example:

correction_steps:
  above_ground_biomass:
    method: morris_2024
    biomass_units: kg_m2  # converted internally to biomass water equivalent in mm

Soil Moisture Estimation

Here we state how Neptoon converts corrected neutrons to soil moisture. Use desilets_etal_2010 for the classic calibration curve, koehli_etal_2021 for the UTS 2021 formulation, or koehli_etal_2025 / koehli_etal_2025_approximation for the newer UTS 2025 formulations. The 2021 and 2025 methods use separate parameter families. koehli_etal_2021_parameterset controls the Köhli 2021 UTS family. koehli_etal_2025_parameterset selects the inverse Köhli 2025 detector-response set. calibration_profile can select a method- and parameter-set-specific calibration record from the sensor YAML. An opt-in method: auto resolves the method only when a calibration profile is explicit, marked as the sensor default, or is the sole profile present; it never guesses a method from legacy N0 alone.

Parameter Required Type Example Description
method Yes string "desilets_etal_2010", "koehli_etal_2021", "koehli_etal_2025", "koehli_etal_2025_approximation", "auto", or "none" Method for converting neutrons to soil moisture. auto is conservative and requires an explicit/default/unique sensor calibration profile.
koehli_etal_2021_parameterset No string "Mar21_mcnp_drf" Parameter set for Koehli-style conversions where applicable. Use "Mar21_mcnp_drf" unless you have a reason to select a different published parameterisation.
koehli_etal_2025_parameterset No string "normresponse_endf8" Köhli 2025 inverse-UTS equation set. Each set contains A, beta, B, lambda, and the two UTS humidity coefficients. All equation sets use the neutral default I_D = 1; the detector-specific I_D belongs in the selected calibration profile or sensor_info.N0. The neutral value is appropriate only when I is already normalized. Legacy names remain accepted with their original response-shape coefficients.
koehli_etal_2025_humidity_correction No string "uts_2025" Humidity factor inside I_N = (I / I_D) C_h. uts_2025 evaluates 1 + c_h1 h + c_h2 h² with the coefficients from the selected parameter set. rosolem_2013 selects the legacy linear factor and none disables the internal factor.
koehli_etal_2025_reference_abs_air_humidity No float 0.0 Reference absolute humidity in g/m³ used only with rosolem_2013.
calibration_profile No string/null null Select a named entry from sensor_config.soil_moisture_calibrations; legacy profile is accepted as an alias.

Data Smoothing

In this section we state whether to do smoothing on the neutron data, and how to do it. The boolean statement is required. If this is set to true then the further options need to be set too, otherwise they can be left blank.

Parameter Required Type Example Description
smooth_corrected_neutrons Yes boolean true Enable smoothing for corrected neutron counts
smooth_soil_moisture Yes boolean false Enable smoothing for soil moisture data
settings.algorithm No string "rolling_mean" Smoothing algorithm selection
settings.window No string 12h or 12hours or 1day or 1d or 30min or 30m Window size for smoothing operation, provided as a string which neptoon will automatically parse into a timedelta window
settings.alignment No string centered Rolling-mean placement. centered uses observations on both sides and is the retrospective default; trailing uses only current and earlier values for causal processing. centred and case variants are accepted as input aliases.
settings.min_proportion_good_data No float 0.7 Minimum proportion of valid data required inside a smoothing window.
settings.poly_order Required for Savitzky-Golay integer 2 Polynomial order for savitzky_golay/legacy savitsky_golay.
settings.insufficient_data_policy No string skip Behaviour when Savitzky-Golay has too few valid observations: skip, raise, or fallback_rolling_mean.

Supported algorithms are rolling_mean and Savitzky-Golay. Both spellings savitzky_golay and the legacy savitsky_golay are accepted; the model normalises them internally. Windows use pandas-compatible durations such as 12h, 1d, or 30min. Rolling means use centered by default for retrospective processing. Choose trailing explicitly for causal/operational processing. The spelling centred, case variants, and an explicit YAML null are accepted and normalised to centered.

Temporal Aggregation

Temporal aggregation converts the input time series to a coarser time resolution, for example from logger intervals or 15 minute data to hourly data. The output_resolution should be larger than the original timestep resolution of your data; neptoon does not use this setting for downscaling.

Alignment is separate from aggregation. Alignment places the data on a regular grid at rounded time points without changing the physical resolution, for example from 15:04 to 15:00. Neutron and product columns are interpolated onto the grid, observed meteorological columns are snapped to the nearest real observation, and any observed-data gap longer than max_alignment_gap_hours is left as NaN rather than interpolated across. Alignment and aggregation are implemented in pandas/NumPy.

When align_timestamps and aggregate_data are both enabled and output_resolution is configured, neptoon aligns to the output grid by default. This avoids creating artificial gaps for sensors with strongly variable acquisition intervals before the aggregation step. Set alignment_resolution: inferred to keep the legacy median-input-cadence behaviour, or set an explicit value such as alignment_resolution: 3h to choose the alignment grid directly. For strongly variable sensor acquisition, direct aggregation with align_timestamps: false is often the safest workflow.

Parameter Required Type Example Description
aggregate_data Yes boolean true or false Whether to aggregate data
output_resolution No string 1h or None Desired time step of output data. Should be pandas style FreqStr (e.g., 1h, 1m)
aggregate_method No string bagg Method for data aggregation
aggregate_func No string mean Function used for aggregation
aggregate_maxna_fraction No float 0.3 Maximum allowed fraction of NA values in the aggregation period
absolute_count_min_coverage_fraction No float 0.25 Minimum live-time coverage required for aggregated absolute_count neutron bins. With explicit elapsed-time columns, Neptoon computes rates from events divided by elapsed time, keeps coverage as a diagnostic, and sets the working neutron-rate column to NaN when coverage is below this threshold.
align_timestamps Yes boolean true or false Whether to align timestamps
alignment_method No string time Method for timestamp alignment
alignment_resolution No string output, inferred, 3h or None Grid used for timestamp alignment. output uses output_resolution; inferred/None infers the median input cadence; explicit durations are accepted. Runtime defaults to output when aggregation and output_resolution are enabled.

Variable acquisition intervals

For a sensor whose acquisition interval changes strongly over time, avoid aligning to an inferred input cadence before aggregation. For example, if the logger cadence changes from about 35 minutes to almost 3 hours and the desired product is a 3-hour series, use direct aggregation:

temporal_aggregation:
  aggregate_data: true
  output_resolution: 3h
  align_timestamps: false

If timestamp alignment is still needed, align to the aggregation grid instead of the inferred input cadence:

temporal_aggregation:
  aggregate_data: true
  output_resolution: 3h
  align_timestamps: true
  alignment_resolution: output

Neptoon logs a warning when the inferred timestamp intervals are highly variable, because the median cadence may not be representative for alignment.

Aggregating absolute_count neutron data

When the sensor config declares neutron data as absolute_count and provides elapsed-time columns through neutron_count_elapsed_time_columns or the legacy key nsecs_columns, neptoon treats temporal aggregation differently from a simple sum. Counts are converted to rates with the measured live time before detector/tube rates are combined.

For each aggregation bin and each detector/tube, neptoon computes:

rate_i = sum(counts_i) / sum(elapsed_seconds_i) * target_period_seconds

For an hourly output resolution this becomes:

counts_per_hour_i = sum(counts_i) / sum(elapsed_seconds_i) * 3600

The working neutron column is then the sum of the detector/tube rates:

counts_per_hour = sum(counts_per_hour_i)

Neptoon also computes a coverage fraction for each aggregation bin:

coverage_fraction = elapsed_seconds / expected_elapsed_seconds

Coverage is kept as a diagnostic when explicit elapsed-time columns are available. The working rate is not masked solely because tubes have different elapsed times; if tubes counted for different durations, each tube contributes its own events-per-time rate. After rate-first aggregation, bins with coverage_fraction < absolute_count_min_coverage_fraction are masked by setting the working neutron-rate column to NaN.

For diagnostics, neptoon keeps additional columns for each live-time-normalised working neutron column. See Columns in neptoon for the meaning of the *_counts_sum, *_elapsed_time_sum, and *_coverage_fraction columns. You can inspect the configured aggregation behaviour before processing with neptoon inspect-aggregation -p process.yaml -s sensor.yaml.

Kalman filtering of corrected neutron counts

The optional kalman_soil_moisture section enables production Kalman filtering after neutron corrections and before soil-moisture conversion. Despite the section name, the filter is applied to the corrected, unsmoothed epithermal neutron-count column, not to raw neutron counts and not to an already-smoothed neutron column. By default the correction-only column, usually corrected_epithermal_neutrons, remains unchanged. The filtered signal is written to a separate final column, usually corrected_epithermal_neutrons_kalman, and downstream soil-moisture conversion uses that final column.

A typical workflow is:

normal Neptoon run → estimate-kalman-params → review diagnostics → enable kalman_soil_moisture

Minimal process YAML fragment:

data_smoothing:
  smooth_corrected_neutrons: false

kalman_soil_moisture:
  enabled: true
  parameter_file: ./kalman_params.yaml

Additional top-level filter options include:

Parameter Default Description
target_column null Optional explicit corrected-neutron input column.
replace_signal_column false Replace the correction-only signal instead of writing a separate filtered column.
output_column_suffix _kalman Suffix used when the filtered signal is written to a separate column.
observations.signal_column null Explicit corrected, unsmoothed neutron signal; defaults to the standard corrected epithermal column.
observations.measurement_uncertainty_column null Optional per-row measurement-uncertainty column used by uncertainty-driven observation noise.
observations.counts_sum_column null Optional aggregated neutron-event sum used for Poisson noise.
observations.elapsed_time_column null Optional aggregated live-time column used together with event sums.
observations.coverage_column null Optional live-time coverage fraction used by the observation model and diagnostics.
observations.measurement_noise_mode auto Select automatic, uncertainty-column, Poisson, or short-term observation noise.
observations.recommended_signal_stage corrected_unsmoothed Metadata describing the expected processing stage of the signal.
diagnostics.save_columns false Keep filter gain, innovation, Q/R, and event columns in processed output.

The parameter_file can be the YAML written by neptoon estimate-kalman-params. You can also copy the generated kalman_soil_moisture block directly into the process YAML and override individual values such as model.process_noise.wetting_event_multiplier or event_detection.precipitation.response_kernel_hours. For precipitation-driven events, the default response kernel is ±4 h; this avoids assuming that rainfall and the CRNS response occur in exactly the same hour. If only daily precipitation totals are available, use event_detection.precipitation.precipitation_resolution: daily or generate the parameter file with --precipitation-resolution daily, so Neptoon treats the whole wet day as event-supported. Set kalman_soil_moisture.diagnostics.save_columns: true only when you explicitly want diagnostic gain/innovation/Q/R/event columns in the output table. See Kalman parameter estimation tool for the full workflow.

Soil organic carbon convention

soil_organic_carbon_conversion controls the permanent organic hydrogen pool and is used identically during calibration and soil-moisture production. The supported soc_to_som_2x_then_0_556 convention evaluates SOC * 2 * 0.556. The former direct-TOC option is no longer supported because it is not used by the Neptoon scientific workflow.

Soil-moisture uncertainty setting

Neptoon reports uncertainty classes separately:

  • smv_statistical_uncertainty contains only neutron counting statistics.
  • smv_statistical_uncertainty_lower and _upper contain value minus/plus the statistical standard uncertainty.
  • smv_systematic_uncertainty contains calibration-parameter uncertainty, soil-property uncertainty, configured correction-factor uncertainty, and any direct systematic soil-moisture contribution supplied in volumetric soil moisture.
  • smv_systematic_uncertainty_lower and _upper contain value minus/plus the systematic standard uncertainty.
  • Systematic uncertainty columns are only created when at least one positive systematic uncertainty is explicitly defined.
  • Zero, missing, or undefined systematic uncertainty is not written and does not create a plot band.
  • smv_total_uncertainty is only created when a systematic component exists and is the derived quadrature combination of statistical and systematic uncertainty.
  • smv_counting_uncertainty is retained as a backward-compatible alias of the statistical column.

Report figures draw the statistical and systematic bands independently rather than hiding them in one combined band. Text output may therefore be represented as value ± statistical (stat.) ± systematic (sys.).

correction_factor_relative_uncertainty is an optional one-standard-deviation relative systematic uncertainty for the combined neutron-correction factors. A direct YAML systematic_uncertainty.soil_moisture value uses volumetric_soil_moisture (m3/m3) by default. All uncertainty originating from calibration, including N0 or Köhli-2025 I_D uncertainty, is classified as systematic rather than counting-statistical.

Snow masking

snow_mask flags the timestamps at which a gridded snow series reports snow on the ground. Snow is hydrogen above the detector, so a CRNS under a snowpack reads wetter soil than it has. Neptoon neither corrects for this nor removes the affected values: a snow correction needs the snow water mass, its layering and its position relative to the detector, and the snow quantity actually available without credentials is a reanalysis depth over a 9 km cell, which is not evidence enough to delete a measurement on your behalf.

Nothing is removed. The soil moisture you get is the soil moisture you would have had without the flag. One column says where snow was found, and dropping those hours is your decision:

# != True keeps the hours the snow series could not answer for; == False would
# drop them as well, which is a different decision.
clean = data[data["rs_mask_snow"] != True]

Corrected neutron counts are not flagged either. Snow does not invalidate the neutron measurement, only the conversion from neutrons to soil moisture, and the counts are the evidence for the snow.

Parameter Default Description
enabled false Flag the timestamps where the snow value reaches the threshold.
source era5_land_snow_depth Column the flag reads: era5_land_snow_depth or era5_land_snow_water_equivalent.
snow_depth_threshold_m none Snow depth in metres at or above which the timestamp is flagged. Required for the snow-depth source.
snow_water_equivalent_threshold_mm none Snow water equivalent in millimetres at or above which the timestamp is flagged. Required for the water-equivalent source.

The threshold has no default

Enabling snow_mask without stating the threshold is a configuration error that names the missing field. This is deliberate. The threshold decides how much of a record is called into question, and where the snow line falls depends on detector height, canopy and site. Neptoon has measured what a silently defaulted constant of this kind costs elsewhere: a declared static biomass value moved mean volumetric soil moisture by 0.0187 m³/m³, against 0.0074 m³/m³ for the choice of satellite product. A threshold belonging to the other source does not satisfy the requirement, and a threshold left in the file that nothing applies to is refused rather than ignored.

Snow depth is the second-best quantity, and why it is the default

The physically correct quantity is snow water equivalent, because that is the hydrogen mass. Snow density ranges roughly 100 to 500 kg/m³, so 0.20 m of snow is anywhere between 20 and 100 mm of water. No source Neptoon can reach without credentials serves snow water equivalent: the Open-Meteo archive accepts the variable and answers null for every archive model, the Copernicus CDS point time-series collection does not offer it at all, and the token-free copies that do carry it are whole-globe chunked datasets costing gigabytes for a single station year. Snow depth is served, so it is the default, and the run output states the density ambiguity rather than leaving it to be discovered. The water-equivalent source is accepted for a record that carries that column from another route.

Example

The snow column has to be attached before it can be read, which means enabling ERA5-Land snow depth in the sensor YAML external_meteo section:

# sensor.yaml
external_meteo:
  - enabled: true
    provider: era5_land
    include_snow_depth: true
# process.yaml
config: process

snow_mask:
  enabled: true
  source: era5_land_snow_depth
  snow_depth_threshold_m: 0.02

If flagging is enabled and the snow column is absent, the run stops with an actionable configuration error rather than continuing. Skipping quietly would be worse: with no snow values the flag is empty, and an empty flag is indistinguishable in the output from a winter without snow.

What appears in the output

One column, rs_mask_snow, with three states:

Value Meaning
True The snow value reached the threshold at this timestamp.
False A snow value was read and stayed below the threshold.
empty The snow series has no value here, so the question was never answered.

The third state is the reason the column is not a plain boolean. A reanalysis gap, a period outside the product or a cloudy overpass would otherwise print as "checked, snow-free", which is not recoverable from the output afterwards.

Like the other remote-sensing provenance markers this is an ordinary data column, exported and filterable, and it takes part in no quality assessment. When output is aggregated to a coarser resolution it aggregates as a logical OR, so a daily row built from one hour under snow says so — and because the condition is evaluated before aggregation, a short snow event cannot be averaged away.

The processing output states how many rows were flagged and repeats that the values were kept. The report PDF ends its soil-moisture section with a bar plot of the snow series, the flagged hours in the alert colour, above the soil moisture that stands.

The data audit records the source column, the threshold and its unit, whether the quantity was a water equivalent, and how many rows were flagged, evaluated, and left unevaluated for want of a snow value.

External soil-moisture processing

external_soil_moisture_processing controls independent reference-sensor filtering, aggregation and the final left join to the CRNS time index. It is used together with the sensor YAML external_soil_moisture section.

Parameter Default Description
enabled false Enable processing when the sensor section is also enabled.
validity_period.start/end null Optional inclusive observation window.
validity_period.time_zone UTC Zone for naive validity timestamps.
quality_control.minimum/maximum 0.0 / 1.0 Physical range after unit conversion to m³/m³.
quality_control.replace_outside_range_with_nan true Mask invalid values before aggregation.
temporal.output_resolution 1h Independent external-sensor resampling interval.
temporal.aggregation mean mean, median, min, or max.
temporal.minimum_coverage_fraction 0.5 Minimum fraction of expected valid samples per bin.
merge.tolerance null Optional nearest-time tolerance such as 45min.
merge.interpolate false Must remain false in the first implementation.
derived_series [] Row-wise aggregates selected by depth and/or sensor ID.
crns_weighted_mean.enabled false Create a strict complete-case CRNS-equivalent mean from every configured source column.
crns_weighted_mean.column_name smv_crns_weighted_mean Output column for the weighted reference series.
crns_weighted_mean.bulk_density_g_cm3 null Optional D86 bulk-density override; otherwise use sensor_info.avg_dry_soil_bulk_density.
crns_weighted_mean.absolute_air_humidity_g_m3 null Optional radial-weighting humidity override.
crns_weighted_mean.atmospheric_pressure_hpa null Optional distance-rescaling pressure override.
crns_weighted_mean.vegetation_height_m 0.0 Vegetation height used in Schrön distance rescaling.
crns_weighted_mean.convergence_tolerance 0.01 Relative iterative weighting convergence threshold.
crns_weighted_mean.max_iterations 100 Maximum iterations per complete timestamp.

See External soil-moisture time series for a complete two-file example and generated column names.