Skip to content

Command-line entry points

Typer command groups and the Streamlit launcher. User-facing command examples live in Using configuration files, Single-row conversion, the config wizard, and the GUI guide.

This committed category page is the canonical mkdocstrings location, so links remain valid in GitLab and on the rendered site. The generated module index mirrors the Python package tree and links back to these canonical API sections without rendering objects twice.

neptoon.cli.cli

cli

core_logger module-attribute

core_logger = get_logger()

app module-attribute

app = Typer()

roving_app module-attribute

roving_app = app

CLI_RECOVERABLE_PROCESSING_ERRORS module-attribute

CLI_RECOVERABLE_PROCESSING_ERRORS = (NeptoonUserFacingError, FileNotFoundError, ImportError, KeyError, OSError, RuntimeError, ValueError)

single_row_app module-attribute

single_row_app = Typer(help='Convert exactly one input row with existing sensor/process YAMLs. This path skips smoothing, interpolation, aggregation and QA.')

main

main(ctx, version=Option(False, '--version', callback=_version_callback, is_eager=True, help='Show the installed Neptoon version and exit.'), processing_config=Option(None, '--processing', '-p', help='Path to the processing configuration YAML file'), sensor_config=Option(None, '--sensor', '-s', help='Path to the sensor configuration YAML file'), save_location=Option(None, '--save-location', help='Override data_storage.save_location for this run. Relative paths resolve against the current working directory.'), workers=Option(None, '--workers', min=1, help='Runtime worker override. For single-sensor runs this enables parallel raw-file parsing when raw_data_parse_options are present.'), no_parallel=Option(False, '--no-parallel', help='Disable runtime parallelism for this run, overriding YAML settings.'), dry_run=Option(False, '--dry-run', help='Load and validate the supplied configs, print a processing summary, and exit without reading raw data or writing outputs.'), show_aggregation=Option(False, '--show-aggregation', help='Print temporal aggregation diagnostics before processing.'), explain_output_columns=Option(False, '--explain-output-columns', help='Print a config-driven explanation of expected output columns.'))

Process CRNS data using configuration files.

Example

neptoon -p /path/to/process.yaml -s /path/to/sensor.yaml

show_literature

show_literature(key=Argument(None, help='Optional literature or method key to display.'), role=Option(None, '--role', help='Filter by implemented, supporting, or related literature.'), topic=Option(None, '--topic', help='Filter by a case-insensitive topic fragment.'), output_format=Option('table', '--format', help='Output format: table, text, json, or bibtex.'))

Show Neptoon's scientific literature registry.

list_dwd_stations

list_dwd_stations(latitude=Option(..., '--latitude', '--lat', help='Latitude of the site in decimal degrees.'), longitude=Option(..., '--longitude', '--lon', help='Longitude of the site in decimal degrees.'), variables=Option('', '--variables', '-v', help='Comma-separated DWD variables to require. Supported: ' + join(sorted(DWD_VARIABLE_SPECS))), max_distance_km=Option(None, '--max-distance-km', help='Optional maximum station distance in kilometres.'), limit=Option(20, '--limit', '-n', min=1, help='Maximum number of stations to print.'), output=Option(None, '--output', '-o', help='Optional CSV output path for the full listed table.'))

List DWD stations sorted by distance to a site.

convert_single_row_with_nmdb

convert_single_row_with_nmdb(processing_config=Option(..., '--processing', '-p', help='Path to the processing configuration YAML file.'), sensor_config=Option(..., '--sensor', '-s', help='Path to the sensor configuration YAML file.'), row_json=Option(None, '--row-json', help='Single input row as a JSON object using the configured input column names.'), row_file=Option(None, '--row-file', help='Path to a one-row CSV or JSON file using the configured input column names.'), timestep_seconds=Option(None, '--timestep-seconds', min=1e-06, help='Integration duration for this row. Required for absolute neutron counts when the config has no elapsed-time columns or output_resolution.'), output=Option(None, '--output', '-o', help='Optional output path. Without this option the row is printed.'), output_format=Option('json', '--output-format', case_sensitive=False, help='Output format: json or csv.'))

Convert one row and fetch/apply configured NMDB incoming correction.

convert_single_row_fixed_incoming

convert_single_row_fixed_incoming(processing_config=Option(..., '--processing', '-p', help='Path to the processing configuration YAML file.'), sensor_config=Option(..., '--sensor', '-s', help='Path to the sensor configuration YAML file.'), row_json=Option(None, '--row-json', help='Single input row as a JSON object using the configured input column names.'), row_file=Option(None, '--row-file', help='Path to a one-row CSV or JSON file using the configured input column names.'), timestep_seconds=Option(None, '--timestep-seconds', min=1e-06, help='Integration duration for this row. Required for absolute neutron counts when the config has no elapsed-time columns or output_resolution.'), output=Option(None, '--output', '-o', help='Optional output path. Without this option the row is printed.'), output_format=Option('json', '--output-format', case_sensitive=False, help='Output format: json or csv.'))

Convert one row with incoming-neutron correction fixed to factor 1.

inspect_aggregation

inspect_aggregation(processing_config=Option(..., '--processing', '-p', help='Path to the processing configuration YAML file.'), sensor_config=Option(..., '--sensor', '-s', help='Path to the sensor configuration YAML file.'), save_location=Option(None, '--save-location', help='Optional data_storage.save_location override used for config validation.'))

Show how the supplied configs will aggregate neutron data.

explain_output_columns_command

explain_output_columns_command(processing_config=Option(..., '--processing', '-p', help='Path to the processing configuration YAML file.'), sensor_config=Option(..., '--sensor', '-s', help='Path to the sensor configuration YAML file.'), save_location=Option(None, '--save-location', help='Optional data_storage.save_location override used for config validation.'))

Explain the main output columns implied by the supplied configs.

estimate_kalman_params_command

estimate_kalman_params_command(input_path=Option(..., '--input', '-i', exists=True, help='Processed Neptoon output table to analyse. CSV, JSON/JSONL and Parquet are supported.'), soil_moisture_column=Option(None, '--soil-moisture-column', help='Column containing the processed soil-moisture time series. For normal Neptoon output this is inferred automatically.'), timestamp_column=Option(None, '--timestamp-column', help='Timestamp column. If omitted, common names such as timestamp/date_time are inferred.'), precipitation_column=Option(None, '--precipitation-column', help='Optional precipitation column used for rainfall-event detection. Common Neptoon names are inferred.'), use_precipitation=Option(False, '--use-precipitation', help='Use a precipitation column if one can be inferred from the Neptoon output. Equivalent to choosing precipitation/combined mode without typing the column name.'), soil_probe_column=Option(None, '--soil-probe-column', help='Optional near-surface TDR/TDT/FDR soil-moisture column used for wetting-edge detection. This column is never inferred automatically.'), use_soil_probe=Option(False, '--use-soil-probe', help='Use the explicitly provided --soil-probe-column for wetting-edge detection. Soil-probe column names are site-specific and are not inferred automatically.'), uncertainty_column=Option(None, '--uncertainty-column', help='Optional soil-moisture uncertainty column. If omitted, common Neptoon names are inferred.'), counts_sum_column=Option(None, '--counts-sum-column', help='Optional neutron counts-sum diagnostic column. If omitted, *_counts_sum is inferred.'), elapsed_time_column=Option(None, '--elapsed-time-column', help='Optional neutron elapsed/live-time sum column. If omitted, *_elapsed_time_sum is inferred.'), coverage_column=Option(None, '--coverage-column', help='Optional aggregation coverage column used when estimating Poisson measurement noise.'), measurement_noise_mode=Option('auto', '--measurement-noise-mode', case_sensitive=False, help='Measurement-noise source: auto, from_uncertainty, poisson, or short_term.'), mode=Option('auto', '--mode', case_sensitive=False, help='Event mode: auto, precipitation, soil_probe, or combined.'), model=Option('single_store', '--model', case_sensitive=False, help='Kalman model family to parameterise: single_store or two_store.'), output_yaml=Option(Path('kalman_params.yaml'), '--output-yaml', '-o', help='YAML parameter fragment to write.'), events_output=Option(None, '--events-output', help="CSV event-table output. Defaults to '<output-yaml stem>_events.csv'."), diagnostics_output=Option(None, '--diagnostics-output', help="CSV diagnostics output. Defaults to '<output-yaml stem>_diagnostics.csv'."), report_output=Option(None, '--report-output', help='Optional PDF/PNG/JPG/SVG diagnostic report output.'), rain_threshold_mm=Option(0.1, '--rain-threshold-mm', min=0.0, help='Precipitation amount per time step that marks rain.'), min_event_sum_mm=Option(0.5, '--min-event-sum-mm', min=0.0, help='Minimum precipitation sum for a rainfall event.'), event_gap_hours=Option(2.0, '--event-gap-hours', min=0.0, help='Maximum gap between wet steps that still belongs to the same event.'), response_window_hours=Option(12.0, '--response-window-hours', min=0.1, help='Window after an event used to measure soil-moisture response for parameter estimation.'), response_kernel_hours=Option(4.0, '--response-kernel-hours', min=0.0, help='Symmetric response-kernel half-width around sub-daily precipitation events used for dynamic Kalman process noise.'), precipitation_resolution=Option('auto', '--precipitation-resolution', case_sensitive=False, help='Precipitation timing resolution for event support: auto, subdaily or daily.'), fusion_max_lag_hours=Option(6.0, '--fusion-max-lag-hours', min=0.0, help='Maximum lag for pairing precipitation and soil-probe events in combined mode.'), drydown_min_hours=Option(12.0, '--drydown-min-hours', min=0.1, help='Minimum duration of a drydown segment.'), drydown_max_hours=Option(240.0, '--drydown-max-hours', min=1.0, help='Maximum duration considered after an event when fitting drydowns.'), min_drydown_drop=Option(0.005, '--min-drydown-drop', min=0.0, help='Minimum soil-moisture decrease required for a drydown fit.'), residual_quantile=Option(0.05, '--residual-quantile', min=0.0, max=0.5, help='Lower soil-moisture quantile used as residual/background moisture.'), probe_min_delta=Option(None, '--probe-min-delta', min=0.0, help='Minimum positive TDR/TDT jump. If omitted, a robust noise-based threshold is used.'), probe_min_slope_per_hour=Option(None, '--probe-min-slope-per-hour', min=0.0, help='Minimum positive TDR/TDT slope. If omitted, a robust noise-based threshold is used.'), probe_pre_smoothing_window=Option(3, '--probe-pre-smoothing-window', min=1, help='Short median window applied to the soil-probe column before edge detection.'), process_noise_base=Option(None, '--process-noise-base', min=0.0, help='Optional override for the dynamic-Q baseline process noise.'), wetting_event_multiplier=Option(None, '--wetting-event-multiplier', min=0.0, help='Optional dynamic-Q multiplier during detected wetting events.'), drydown_multiplier=Option(None, '--drydown-multiplier', min=0.0, help='Optional dynamic-Q multiplier during drydown/background periods.'), unexplained_spike_multiplier=Option(None, '--unexplained-spike-multiplier', min=0.0, help='Optional dynamic-Q multiplier for positive spikes without event support.'), unexplained_spike_sigma_threshold=Option(4.0, '--unexplained-spike-sigma-threshold', min=0.1, help='Robust-sigma threshold used to count positive spikes not explained by events.'), overwrite=Option(False, '--overwrite', help='Overwrite existing output files.'))

Estimate Kalman soil-moisture filter parameters from a processed Neptoon output.

process_multi_sensor

process_multi_sensor(config=Argument(..., help='Path to a config: multi_sensor YAML file.'), save_location=Option(None, '--save-location', help='Override shared.save_location for this multi-sensor run.'), workers=Option(None, '--workers', min=1, help='Enable multi-sensor process-pool execution with this worker limit.'), no_parallel=Option(False, '--no-parallel', help='Disable multi-sensor parallel execution for this run.'))

Process multiple sensor configs and create one combined report.

process_data

process_data(processing_config, sensor_config, save_location=None, *, workers=None, no_parallel=False, dry_run=False, show_aggregation=False, explain_output_columns=False)

Process the data using the supplied config file locations.

neptoon.cli.launcher

launcher

core_logger module-attribute

core_logger = get_logger()

app module-attribute

app = Typer()

find_streamlit_executable

find_streamlit_executable()

Find streamlit executable in the current Python environment.

main

main()

Launch the neptoon GUI application.

neptoon.cli.rs

rs

Typer CLI for remote-sensing preflight.

This is the mechanism behind "it just works": Neptoon tells you what is available at your site instead of leaving you to research it.

neptoon rs catalog answers, offline, what applies at a coordinate, at what resolution and at what access effort. neptoon rs check runs the whole preflight for an existing configuration without running the pipeline: what would be chosen, what would be substituted, what would be missing, and what a free registration would add.

One behaviour is documented rather than hidden: the spatial check has two stages, and only the second reads the values. Without network access these commands answer from the declared extents alone, and they say so.

app module-attribute

app = Typer(help='Inspect and preflight remote-sensing reference data.')

list_remote_sensing_catalog

list_remote_sensing_catalog(latitude=Option(None, '--lat', '--latitude', help='Station latitude in degrees.'), longitude=Option(None, '--lon', '--longitude', help='Station longitude in degrees.'), start=Option(None, '--from', '--start', help='Start of the period, YYYY or YYYY-MM-DD.'), end=Option(None, '--to', '--end', help='End of the period, YYYY or YYYY-MM-DD.'), variable=Option(None, '--variable', help='Show only products serving this variable.'))

List catalogued products, optionally filtered to a site and period.

Runs entirely offline. Whether a product actually holds data at the point is decided by reading the values when it is fetched.

check_remote_sensing_config

check_remote_sensing_config(sensor_config=Argument(..., help='Path to the sensor YAML configuration to preflight.'), start=Option(None, '--from', '--start', help='Start of the period to preflight, YYYY or YYYY-MM-DD. Defaults to the install date.'), end=Option(None, '--to', '--end', help='End of the period to preflight, YYYY or YYYY-MM-DD. Give it the last timestamp you will process; without it today is assumed and said so.'), processing_config=Option(None, '--processing', help="Optional processing YAML. Supply it when a correction is fed from remote sensing: the verdict differs, because a correction input may not borrow an epoch beyond the product's extent."))

Preflight a sensor configuration without running the pipeline.

Reports which product each requested variable resolves to and why, what would be substituted or left missing, and what a credential would add.

The answer belongs to a period, not only to a coordinate: temporal fit is part of the ranking. A sensor configuration declares where it starts and not where it ends, so the end is yours to give, and the period this ran against is printed either way.

It can also belong to a use. The same biomass product is a reference series when no biomass correction is active and a correction input when one is, and the two get different answers: a correction input may not borrow an epoch from outside the product's extent, and its cells have to be fine enough for the footprint. Pass --processing to preflight the run you will actually make rather than the configuration in isolation.

show_remote_sensing_auth

show_remote_sensing_auth(provider=Argument(None, help='Provider to describe. Omit to list every credentialed provider.'))

Show credential status and the exact setup step for a provider.

The token-free path needs none of this: credentials extend the product set rather than gating the feature.

neptoon.roving.cli

cli

Typer commands for the explicit roving workflow.

app module-attribute

app = Typer(help='Validate and process roving CRNS configurations.')

grid_app module-attribute

grid_app = Typer(help='Convert and inspect lightweight roving grid adapters.')

convert_roving_grid

convert_roving_grid(input_path=Argument(..., help='Input grid path.'), output_path=Argument(..., help='Output grid path.'), input_backend=Option('auto', '--input-backend', help='auto, npz_grid, tabular_grid, npy_json, tifffile_grid, or rasterio.'), output_backend=Option('auto', '--output-backend', help='auto, npz_grid, tabular_grid, or npy_json.'), name=Option(None, '--name', help='Optional grid name.'), kind=Option('continuous', '--kind', help='continuous or categorical.'), crs=Option(None, '--crs', help='Override/set CRS, e.g. EPSG:32632.'), nodata=Option(None, '--nodata', help='Override/set nodata value.'), x_column=Option('x', '--x-column', help='Tabular x column.'), y_column=Option('y', '--y-column', help='Tabular y column.'), value_column=Option('value', '--value-column', help='Tabular value column.'), band=Option(1, '--band', min=1, help='Rasterio band to read.'), dropna=Option(False, '--dropna', help='Drop NaN cells in tabular outputs.'))

Convert local grid data into a lightweight roving runtime format.

fetch_roving_dem

fetch_roving_dem(config=Argument(..., help='Roving YAML config used to read the track.'), output_path=Argument(..., help='Output .npz DEM cache path.'), source=Option('aws_copernicus_glo90', '--source', help='aws_copernicus_glo30, aws_copernicus_glo90, opentopography_copernicus_glo30, opentopography_copernicus_glo90, opentopography_nasadem, opentopography_srtm_gl1, or opentopography_srtm_gl3.'), buffer_m=Option(500.0, '--buffer-m', min=0.0, help='Track buffer in metres.'), api_key=Option(None, '--api-key', help='OpenTopography API key.'), timeout_s=Option(120, '--timeout-s', min=1, help='Download timeout.'), overwrite=Option(False, '--overwrite', help='Overwrite an existing DEM cache.'), name=Option('dem', '--name', help='Grid name stored in the .npz metadata.'), south=Option(None, '--south', help='Manual WGS84 south bound.'), north=Option(None, '--north', help='Manual WGS84 north bound.'), west=Option(None, '--west', help='Manual WGS84 west bound.'), east=Option(None, '--east', help='Manual WGS84 east bound.'))

Fetch a track-buffered online DEM and cache it as a roving .npz grid.

inspect_roving_grid

inspect_roving_grid(path=Argument(..., help='Grid path to inspect.'), backend=Option('auto', '--backend', help='auto, npz_grid, tabular_grid, npy_json, tifffile_grid, or rasterio.'), x_column=Option('x', '--x-column', help='Tabular x column.'), y_column=Option('y', '--y-column', help='Tabular y column.'), value_column=Option('value', '--value-column', help='Tabular value column.'))

Print basic metadata for a lightweight roving grid.

validate_roving_config

validate_roving_config(config=Argument(..., help='Path to a roving YAML config.'), check_files=Option(False, '--check-files/--schema-only', help='Also fail when referenced input files do not exist.'))

Validate a roving YAML config without running the workflow.

process_roving_config

process_roving_config(config=Argument(..., help='Path to a roving YAML config.'), output_dir=Option(None, '--output-dir', '-o', help='Override outputs.directory for this run.'), workers=Option(None, '--workers', min=1, help='Enable parallel terminal roving products with this worker limit.'), no_parallel=Option(False, '--no-parallel', help='Disable parallel terminal roving products for this run.'), buildings=Option(None, '--buildings/--no-buildings', help='Override 3D terrain building rendering for this run.'), building_source=Option(None, '--building-source', help='Override building source: auto, local, citygml, lod2_de, overture, openstreetmap, wfs, ogc_api.'), building_state=Option(None, '--building-state', help='German state code used by official LoD2 source selection, e.g. HE.'), building_auto_state=Option(None, '--building-auto-state/--no-building-auto-state', help='Allow/disable automatic German state detection from the requested coordinates.'), building_offline=Option(None, '--building-offline/--building-online', help='Control building offline policy. Normal processing remains local/cache-only; remote access occurs only during explicit cache preparation.'), terrain_roads=Option(None, '--terrain-roads/--no-terrain-roads', help='Show/hide the configured road network on the 3D terrain map.'))

Run the explicit roving workflow and write configured outputs.

create_roving_map

create_roving_map(config=Argument(..., help='Path to a roving YAML config.'), output_dir=Option(None, '--output-dir', '-o', help='Override outputs.directory for map output.'), value_column=Option(None, '--value-column', help='Override maps.value_column for this run.'), html=Option(True, '--html/--no-html', help='Write an HTML map.'), bundle=Option(False, '--bundle', help='Write a ZIP output bundle.'), workers=Option(None, '--workers', min=1, help='Enable parallel terminal roving products with this worker limit.'), no_parallel=Option(False, '--no-parallel', help='Disable parallel terminal roving products for this run.'), buildings=Option(None, '--buildings/--no-buildings', help='Override 3D terrain building rendering for this run.'), building_source=Option(None, '--building-source', help='Override the configured building source for this run.'), building_state=Option(None, '--building-state', help='German state code used by official building source selection.'), building_auto_state=Option(None, '--building-auto-state/--no-building-auto-state', help='Allow/disable automatic German state detection from the requested coordinates.'), building_offline=Option(None, '--building-offline/--building-online', help='Control building offline policy. Normal processing remains local/cache-only; remote access occurs only during explicit cache preparation.'), terrain_roads=Option(None, '--terrain-roads/--no-terrain-roads', help='Show/hide the configured road network on the 3D terrain map.'))

Run roving processing with HTML map output enabled.