The command line

Five console scripts, installed by pip install oroscope, and the complete option reference for the search itself at the bottom of this page.

The command line is a convenience, not the primary interface. Everything here is a thin wrapper over a function, and Quickstart shows the same work done from Python, which is how most of it gets used.

Everything here can be done from code

There is no CLI-only behaviour. Every command below is a thin wrapper over a function, and the wrapper’s job is argument parsing and file placement, nothing else. That is a deliberate property, not a coincidence: a parameter sweep, a notebook or a service driving the pipeline in a loop should not have to shell out, and anything the command line can reach that the library cannot is a bug.

Command line

Code

oroscope --config_path run.json

oroscope.find_grand_regions_interactive(**params)

oroscope --generate_config t.json --config_preset arequipa

oroscope.generate_config("t.json", "arequipa")

reading that file back

oroscope.load_config("t.json")

the defaults it contains

oroscope.default_config("arequipa")

--max_memory_gb 6

max_memory_gb=6.0, or oroscope.preflight_memory(dem, ...) on its own

--no_explain

explain=False

the summary a run prints

oroscope.explain_results(results), on any results dictionary

oroscope-crop src dst --north --east

oroscope.crop(src, dst, north, south, west, east)

oroscope-combine a b --labels A B

oroscope.load_run(...) + oroscope.explain_combination(report, runs)

oroscope-sensitivity run.json --sweep min_score 0 0.35

oroscope.run_once(config, out_dir) and oroscope.summarise(results)

oroscope-fetch-dem --open_topography_api_key KEY

oroscope.fetch_dem.download_dem(region, bounds, key, out_dir)

The pipeline returns its results dictionary, so a caller never has to find and re-read the JSON it has just written:

import oroscope

config = oroscope.load_config("config/tambo_colca_config.json")
results = oroscope.find_grand_regions_interactive(
    dem_path="input/dem/colca.tif", run_output_dir="output/scan",
    **{k: v for k, v in config.items()
       if not k.startswith("_")
       and k not in ("dem_path", "print_info",
                     "output_directory_base_with_given_json")})

print(results["results"]["total_capacity"])
print(results["explanation"])

Note

A parameter’s default is the same wherever you read it — off the function signature, off oroscope --help, or out of oroscope.default_config(). They disagreed on ten parameters once, so omitting one meant different things depending on which door you came in by; a test now pins all three together.

oroscope-crop — cut a window out of a DEM

oroscope-crop input/dem/arequipa_SRTMGL1.tif input/dem/colca.tif \
    --north -15.30 --south -15.85 --west -72.40 --east -71.55

The crop carries its own north-west corner, so it stands alone as a georeferenced file. The window is the smallest pixel-aligned box containing what you asked for: the start is floored and the stop ceiled, so you never get less than you requested.

oroscope-combine — overlay two or more searches

oroscope-combine output/grand_colca_config output/tambo_colca_config \
    --labels GRAND TAMBO --out output/combined_colca

Reports terrain viable for each, for both (co-location) and for either, with a membership raster and an overview map — and an account of why the joint area is the size it is, saved as combination_explanation.txt. Co-location is usually decided by slope: a pixel has one slope and both experiments must accept it.

The inputs must be pixel-aligned — same shape, same pixel size, same corner. That is checked and refused rather than resampled, because two runs on differently-cropped DEMs would silently compare the wrong ground.

oroscope-sensitivity — how firm is the answer?

oroscope-sensitivity config/tambo_colca_config.json \
    --sweep min_score 0.0 0.2 0.35 0.5 \
    --sweep min_target_slope_deg 0 15 25 35

Varies one parameter at a time about a baseline and tabulates what moves. Each point runs in its own subprocess, so memory is reclaimed between them and one failed point reports a failed row instead of ending the sweep.

Read this before quoting a capacity. Several criteria sit near cliffs.

oroscope-fetch-dem — download the elevation models

oroscope-fetch-dem --region arequipa --open_topography_api_key YOUR_KEY
oroscope-fetch-dem --region peru                     # key from the environment
oroscope-fetch-dem                                   # all four regions

Fetches a bundled region into input/dem/ and writes a ready-to-run configuration for it.

--region

dataset

size

arequipa

SRTMGL1, 30 m

148 MB

The department. Every published number in this project comes from it or from a crop of it.

ancash

SRTMGL1, 30 m

95 MB

The Cordillera Blanca and the Callejón de Huaylas. Run at the same resolution and criteria as Arequipa, so the two are directly comparable.

lima

SRTMGL1, 30 m

110 MB

Coastal, and a useful contrast: desert shelf rising to the western Andean flank. SRTMGL1, not the AW3D30 it used to fetch — the three department runs are compared against one another, and a dataset difference would sit inside every comparison as a confound.

peru

SRTMGL3, 90 m

302 MB

The whole country. 3 arc-seconds, not by preference — see config/grand_peru_survey.json.

Getting a key. It is free and takes a minute.

  1. Register at OpenTopography and sign in.

  2. Open myOpenTopo Authorizations and API Key from the account menu.

  3. Copy the key.

Pass it as --open_topography_api_key, or set OPENTOPOGRAPHY_API_KEY in the environment — which keeps it out of your shell history, and out of any file that might be committed by accident.

Warning

Requests are capped by area, per dataset: 450,000 km² for every 30 m dataset and 4,050,000 km² for the 90 m ones. Peru’s bounding box is about 2.86 million km², six times over the 30 m limit, which is one of the two reasons peru is 3 arc-seconds. The other is memory.

Run it from src/: it writes to ../input/dem/ and ../config/ by default, both relative to the working directory. Pass --output_dir and --config_dir to run it from anywhere else. Unlike the search, this one is not config-relative — there is no configuration file to be relative to.

The configuration it writes is a default template pointed at the DEM. The tuned configurations that produced this project’s numbers are committed in config/ alongside it, and those are the ones to run.

oroscope-fetch-roads — road geometry for the map

oroscope-fetch-roads --dem input/dem/arequipa_SRTMGL1.tif --places
oroscope --config_path config/grand_colca_config.json \
    --roads_geojson input/roads/arequipa_SRTMGL1.geojson \
    --settlements input/roads/arequipa_SRTMGL1_places.geojson

Downloads roads from OpenStreetMap through Overpass and writes a GeoJSON, so a map can show what a site count cannot: whether the good ground is reachable. Over the Arequipa DEM that is 8,780 roads of motorway through tertiary class.

Drawing, not screening. This changes no result. The searcher has a separate and older facility for access as a criterion--road_map_path takes an aligned distance-to-road raster and --max_road_dist_km cuts on it, appearing in the funnel as road distance — which nothing yet produces and no bundled configuration uses.

--places fetches populated places — city, town, village — into a sibling _places.geojson, which --settlements then marks on the map. This is how to get real town coordinates. The bundled arequipa and lima presets are the handful of named places already curated as RFI zones; anything beyond them should be sourced, not written from memory, because a town in the wrong valley looks exactly like a town in the right one. Over the Arequipa DEM that is 1,268 places, and over the Colca crop it puts Chivay where OSM says it is.

Markers scale with the place class and only the most important few are labelled — every place inside the map gets a marker, but sixty village names over one canyon is not a map. Raise max_labels on oroscope.add_settlements() if you want more.

The bounding box is tiled and fetched a piece at a time, with a pause between requests and a fallback to a second mirror. A single query over the 3.5-degree Arequipa box answers with a gateway timeout; nine smaller ones succeed. Overpass is a shared free service, and the pacing is not optional politeness.

Data is © OpenStreetMap contributors, ODbL. The loader carries that attribution inside the file and both maps print it beneath the axes, so it cannot be separated from the data by copying the picture.

tools/make_animations.py — animations of the mechanism

python tools/make_animations.py                    # all eight, MP4 and GIF
python tools/make_animations.py --only the_walk
python tools/make_animations.py --format gif --out docs/source/_static

Eight animations, each showing a process whose intermediate states are the point — anything that is a single state is already a figure in oroscope.figures. Notebook 9 builds all of them and explains what each is for.

the_walk

One backward ray sweeping down through the elevation window: the first intersection sliding along the profile and the column depth accumulating behind it. This is the mechanism the whole search rests on.

the_azimuth_fan

The other half of that mechanism. the_walk sweeps elevation at one bearing; this sweeps the bearing, and reports whether each one finds a wall at the accepted range, the candidate’s own hillside a few hundred metres off, or sky.

the_funnel

The map draining stage by stage. The funnel table says where the candidates went; this shows where on the ground they went.

stride_and_closing

Why a closing element smaller than the stride gap loses the mask. Shown on the Assumptions and limitations page.

product_collapse

Why a threshold on a product is treacherous, and why the reason is dynamic: each component multiplied in walks the population toward zero while the cut stays put. Measured on Colca, 100% of candidates survive the cut before any component and 32% after six — but the fall is not evenly shared, and one component contributes nothing at all.

slope_criterion

Where a criterion bites, as opposed to how much it costs. The accepted mask over Colca as min_target_slope_deg climbs through the wall-slope distribution.

tau_in_rock

More rock is not better. A tau’s energy and survival falling as it burrows, against the depth that maximises production and escape together — 5.7×10⁶ g/cm², about 22 km of standard rock, at 1 EeV.

energy_window

The arrival window narrowing as Earth absorption bites, its lower edge climbing from −4.4° at 100 PeV to −0.9° at 10 EeV.

MP4 needs ffmpeg; GIF falls back to pillow. Outputs land in output/animations/, which is gitignored.

Five of the eight are built from committed code and synthetic terrain and reproduce on any clone. The three that are about what happens on real ground — the_azimuth_fan, product_collapse and slope_criterion — read input/dem/colca.tif when it is present and fall back to synthetic terrain when it is not, saying on the figure which they used.

tools/run_full_dem.py — the full-DEM runs

Not a console script — it lives in the repository, because it is about this project’s own runs rather than about searching in general. For one region it runs GRAND, then TAMBO, then the combination over the whole DEM, and stores the small artefacts for that region’s notebook to read.

Regions come from a table in the file, each needing a DEM in input/dem/ and a config/{grand,tambo}_<region>_full.json pair:

--region

grid

arequipa

129 Mpx, 1 arc-sec

The default. GRAND takes about 25 minutes, TAMBO about one.

ancash

69 Mpx, 1 arc-sec

The Cordillera Blanca. Roughly half the pixels, so roughly half the time.

This was run_arequipa_full.py, which hard-coded one DEM, one store and one pair of configurations. The second region asked for was not a reason to copy two hundred lines.

python tools/run_full_dem.py --dry-run
python tools/run_full_dem.py --region ancash --dry-run

What ``–dry-run`` does. It reports what the real run would cost and then stops, without starting a search, writing a file or touching the store:

DEM:       input/dem/arequipa_SRTMGL1.tif
estimate:  5.08 GiB at downsample_factor 4
available: 6.4 GiB
would run: grand, tambo, then combine
expected:  ~25 min for grand, ~1 min for tambo
store:     results/arequipa_full

Each line answers a question worth answering before committing an hour:

DEM

which file will be searched, and whether it is present at all. A missing DEM is reported here rather than after the first search has started.

estimate and available

the pre-flight memory estimate against what the system reports free. This is the number that decides downsample_factor and candidate_stride: the same DEM needs 7.2 GiB at 1 and 5.1 GiB at 4. Downsampling scales the labelling arrays as its inverse square but leaves the candidates untouched – they are taken on the native grid – and at this scale the candidates dominate, so striding is the stronger lever. The estimate deliberately excludes the memory-mapped DEM, which is file-backed and evictable.

would run

which searches, honouring --only. --only grand runs one and skips the combination.

expected

the wall time to expect per search, so a run is not started ten minutes before you need the machine.

store

where the artefacts will land — the results JSON, provenance and explanation, a few hundred kilobytes that notebook 8 reads.

In a dry run no memory cap is applied, since nothing is allocated. The real run caps the process’s address space so a search that outgrows the machine fails with MemoryError naming itself rather than letting the kernel’s OOM killer choose a victim.

Then, for real:

python tools/run_full_dem.py                     # arequipa, the default
python tools/run_full_dem.py --region ancash

or one experiment at a time:

python tools/run_full_dem.py --region ancash --only grand

Afterwards, refresh the cross-region table:

python tools/compare_regions.py

Run it when a configuration changes, not otherwise. The store carries a manifest naming the configurations and the time, so a stale one is detectable rather than merely suspected — which matters, because the whole premise of storing rather than recomputing is that nobody looks again.

Where things are resolved from

Four sources, first match wins:

  1. An option you actually typed. This beats everything, and announces itself when it overrides a configuration file.

  2. The configuration file given with --config_path.

  3. ``config/fallbacks.json``, if present. Every value taken from here is announced, because a fallback is the least visible input the tool has.

  4. The built-in default.

Only the DEM is genuinely required: origin_lat/origin_lon are read from the file’s own GeoTIFF tiepoint, and a supplied origin disagreeing with the file by more than ~100 m is reported rather than silently honoured.

Note

Paths in a configuration are relative to the configuration file, not to the working directory, so a search runs the same from anywhere. "dem_path": "../input/dem/colca.tif" in config/ means input/dem/colca.tif in the repository whether you are standing in the root, in src/ or elsewhere; the outputs follow the same rule. Absolute paths are left alone, and a path that resolves only against the working directory still works, with a warning — the old behaviour, kept so this does not break a setup that relied on it.

This replaces the long-standing requirement to cd src first.

Every option, in full

The search accepts 87 options. Every one is also a parameter of oroscope.find_grand_regions_interactive under the same name, except the five negative-form flags — --require_sky, --nearest_sampling, --no_geomagnetic, --include_near_field, --no_print_info, --no_explain — whose positive forms (require_terrain, bilinear_sampling, use_geomagnetic, exclude_near_field, print_info, explain) are what the function takes.

Generated from the parser, so it cannot drift from the code: a test asserts that every option below exists and that every option that exists appears below.

Every option (87 of them)

Option

Type

Default

What it does

--dem_path

string

Path to the Digital Elevation Model (.tif) file.

--origin_lat

float

Reference origin latitude (e.g., -10.228).

--origin_lon

float

Reference origin longitude (e.g., -78.076).

--target_antennas

int

10000

Total target capacity for the array (default: 10000).

--min_width_km

float

2.0

Minimum acceptable width of the array site in km (default: 2.0).

--min_altitude

float

Minimum allowable altitude in meters (optional).

--max_altitude

float

Maximum allowable altitude in meters (optional).

--antenna_spacing_km

float

1.0

Distance between antennas in km (default: 1.0).

--min_dist_km

float

10.0

Minimum required distance to target mountain in km (default: 10.0).

--max_dist_km

float

80.0

Maximum required distance to target mountain in km (default: 80.0).

--grid_type

square / hex

hex

Antenna layout grid type (default: ‘hex’).

--min_slope_deg

float

3.0

Minimum terrain steepness in degrees (default: 3.0).

--max_slope_deg

float

25.0

Maximum terrain steepness in degrees (default: 25.0).

--downsample_factor

int

4

Internal capacity mask downsampling factor for processing speed (default: 4).

--cell_size_deg

float

Map resolution in degrees per pixel. Defaults to reading the DEM’s GeoTIFF tags.

--slope_baseline_m

float

Ground distance in metres over which slope is measured. Default: the DEM’s native resolution.

--candidate_stride

int

5

Keep every Nth candidate pixel before ray tracing (default: 5). Use 1 for no thinning.

--tile_size

int

2048

Size of the square memory chunk for RAM management (default: 2048).

--num_cores

int

-1

Number of CPU cores to use. Set to -1 to use all available cores (default: -1).

--energy_min_pev

float

Lower tau energy in PeV. With –energy_max_pev, derives the decay-baseline distance window.

--energy_max_pev

float

Upper tau energy in PeV.

--n_azimuths

int

9

Azimuths scanned per candidate in scan mode (default: 9).

--azimuth_half_width_deg

float

60.0

Half-width of the azimuth fan about the aspect. Use -1 for a full 360 sweep (default: 60).

--elev_min_deg

float

-3.0

Lower edge of the accepted arrival elevation window (default: -3).

--elev_max_deg

float

3.0

Upper edge of the accepted arrival elevation window (default: +3).

--n_elev_bins

int

12

Elevation bins across the window (default: 12). Nearly free: cost scales with azimuths.

--min_column_depth_gcm2

float

0.0

Column depth a direction must have to count, in g/cm2 (default: 0).

--require_sky

flag

off

Invert the test: accept directions that reach clear sky, for cosmic-ray style channels.

--fresnel_frequency_mhz

float

Radio band for the Fresnel clearance measurement, e.g. 50. Omitted skips the second pass.

--antenna_height_m

float

2.0

Antenna height above ground, for the Fresnel measurement (default: 2).

--include_near_field

flag

off (feature on)

Measure Fresnel clearance from the antenna outward instead of skipping the near field. Included for study: the result is then dominated by ground beside the antenna rather than by intervening terrain.

--fresnel_near_field_m

float

500.0

Skip this much of the path when measuring Fresnel clearance (default: 500). Below ~500 m the measure is dominated by ground beside the antenna rather than by intervening terrain.

--nearest_sampling

flag

off (feature on)

Sample terrain profiles at pixel centres instead of interpolating. Faster, but treats terrain as blocky, which over-estimates how much it blocks a ray.

--muon_shielding_km

float

Rock overburden required along the arrival direction to reject atmospheric muons, in km (TAMBO quotes >4). A floor on column depth, not a band.

--geomag_declination_deg

float

Geomagnetic declination, degrees east of north. Defaults to the Arequipa IGRF 2026 value (-6.9); supply the IGRF value for other regions.

--geomag_inclination_deg

float

Geomagnetic inclination, degrees, positive downward. Defaults to a centered-dipole estimate at the DEM’s own centre, so it follows the site automatically.

--no_geomagnetic

flag

off (feature on)

Ignore the geomagnetic angle and weight all directions equally.

--grammage_mode

radio / particle

radio

How atmospheric depth is scored. ‘radio’ is a maturity threshold, since emission comes from shower maximum and then propagates through transparent air. ‘particle’ is a band, since particle content dies after maximum (default: radio).

--grammage_band_gcm2

float ×2

Atmospheric depth band scoring 1 in ‘particle’ mode, in g/cm2. Defaults to (X_max, 4*X_max) = (700, 2800), which suits a long path to a distant target. A short crossing gives far less: Colca supplies about 170 g/cm2, so a detector there sees a shower that is still developing and this band must be lowered or nothing scores.

--grammage_maturity_gcm2

float

Atmospheric depth at which the ‘radio’ maturity ramp reaches 1, in g/cm2 (default: X_max = 700).

--decay_energy_pev

float

Tau energy, in PeV, at which to score the probability that it decays in the gap with room left for a shower. Left out by default because the probability is strongly energy-dependent and one number cannot stand in for a spectrum. Matters most across a canyon: at 1 EeV the decay length is ~49 km against a ~3 km crossing.

--max_range_km

float

How far to walk each profile, in km. Defaults to max_dist_km. Worth setting larger for a short-range search: column depth accumulates over the whole walk, so tying the two makes the reported depth a property of where the walk stopped rather than of the target’s thickness.

--roads_geojson

str

GeoJSON of road geometry to draw on the map, from oroscope-fetch-roads. Distinct from --road_map_path, which is a distance-to-road raster used to screen candidates: this one only draws, and changes no result. Only roads intersecting the map are drawn and counted.

--settlements

str

auto

Named places to mark on the map. auto uses whichever curated list has points inside the DEM; or give a preset (arequipa, lima), none, or an explicit list of (latitude, longitude, name) in a configuration file. The bundled coordinates are the ones already curated as RFI exclusion zones, not a second set sourced separately.

--decay_weight_by

str

flux

What weights the spectrum-folded decay probability. flux (the default) asks what fraction of arriving neutrinos decay usefully, and is what every published number here was computed with. acceptance asks the same over the energies the detector responds to, with no assumed spectrum — useful precisely because the spectral index is an assumption. flux_times_acceptance is the event-rate integrand itself. The latter two require --decay_response_csv.

--decay_response_csv

str

Two-column CSV of energy in PeV against relative detector response A(E), for the acceptance weightings. data/ holds the published integral curves; oroscope.aperture.infer_response() recovers A(E) from one by dividing out the geometric model.

--score_percentile

float

Keep this percentage of viable candidates, ranked by score, instead of cutting at an absolute –min_score. Preferred: the default score is a product whose distribution piles up near zero, so an absolute threshold sits on a cliff, while a percentile is scale-free.

--stop_at_target

flag

off

In distributed mode, stop selecting sites once target_antennas is reached. Sites are ranked by capacity, so this reports the best sites for the array actually wanted rather than every patch of qualifying ground.

--max_memory_gb

float

Ceiling on this process’s address space, in GiB. Defaults to 80%% of what the system reports available, so a search that outgrows the machine fails with MemoryError instead of inviting the OOM killer to choose a victim. 0 disables the cap.

--decay_energy_min_pev

float

Lower end of the tau energy range for the decay term. With –decay_energy_max_pev this folds the decay probability over a power-law spectrum, which is the defensible form: the probability runs over three decades across one experiment’s reach, so a single energy chooses the answer rather than approximating it.

--decay_energy_max_pev

float

Upper end of that range, in PeV.

--decay_spectral_index

float ×1–2

Spectral index gamma in dN/dE ~ E^-gamma for the folded decay term (default: 2.0). Give one value to pin the spectrum, or two to marginalise uniformly over that range when the index is not known – a flat prior says so rather than pretending to a value. A softer spectrum weights low energies, where the tau decays readily, so it drives the term toward 1.

--shower_development_m

float

3000.0

Path the shower needs after the tau decays, in metres (default: 3000). Used both by the decay term and as the far endpoint of the Fresnel clearance measurement.

--gap_close_km

float

Size of the morphological closing element that fills gaps between accepted pixels, in km. Defaults to antenna_spacing_km, which couples two unrelated things. Closing more than doubles the reported area on real terrain (measured 2.35x at Colca), so this is worth setting deliberately; 0 disables it.

--min_target_slope_deg

float

Require the terrain a ray strikes to be at least this steep, measured along the arrival azimuth. Unset by default, which asks only that rock is present – true almost everywhere in the Andes. TAMBO’s tau exits a canyon wall, so this is what separates a canyon from a hillside.

--max_target_slope_deg

float

Upper bound on the struck terrain’s slope along the arrival azimuth. Unset by default. Note a ceiling does not empty the result: a flat valley floor passes any ceiling, so this removes walls rather than everything.

--grammage_band_fraction

float

When the shower band is derived from an energy range, the fraction of peak particle content that still counts as a usable shower (default: 0.1). Lower admits younger and older showers, so it widens the band and accepts narrower canyons.

--shower_elongation_rate_gcm2

float

How much deeper shower maximum sits per decade of primary energy, in g/cm2 (default: 55, the usual hadronic value; a purely electromagnetic cascade is nearer 85).

--shower_lambda_gcm2

float

Gaisser-Hillas interaction length setting how fast the shower profile rises and falls, in g/cm2 (default: 70).

--solid_angle_half_fraction

float

Fraction of the sky the azimuth fan and arrival window could accept that scores 0.5 (default: 0.076). Dimensionless and therefore portable: unlike --solid_angle_half_sr it does not have to be re-tuned when the fan width or the elevation window changes.

--solid_angle_half_sr

float

Accepted solid angle scoring 0.5, in steradians (default: 0.0167). This is a GRAND-scale value: an experiment looking across a canyon sees far more sky, and leaving it at the default saturates the term so it stops discriminating. It is calibrated against the reported solid angle, which depends on azimuth_half_width_deg and the elevation window – change either and this wants re-checking.

--distance_band_m

float ×2

Exit-point distance band scoring 1, in metres. Defaults to the configured decay-baseline window.

--clearance_full_at

float

Fresnel clearance ratio, in first-Fresnel radii, that scores 1 (default: 1.0).

--score_weights

string

Per-component weights for –score_composition weighted, as name=value pairs, e.g. ‘shower=2,solid_angle=1,depth=0.5’. Components not named default to weight 1; a weight of 0 excludes a component. Names are checked against the score components and a misspelling is refused, because a dropped weight changes every number in the run and leaves no trace in the output.

--nu_interaction_length_gcm2

float

Neutrino interaction length for the Earth-chord attenuation term, g/cm2 (order 1e8 near an EeV). Omitted reports the chord without weighting by it.

--refraction_k

float

Refraction k-factor for the RADIO path only (default: 4/3). Particle trajectories always use the true Earth radius, since neutrinos and taus are not refracted.

--depth_band_gcm2

float ×2

Column depth band scoring 1, in g/cm2. The tau must be produced and must escape, so this is a band, not a floor.

--score_composition

product / mean / min

product

How component scores combine (default: product).

--min_score

float

0.0

Discard candidates scoring below this (default: 0, keep all).

--rfi_zones

string

none

Can be preset (‘lima’, ‘arequipa’) or a valid JSON string outlining custom exclusion zones.

--road_map_path

string

Path to a raster mapping distance-to-roads (optional).

--max_road_dist_km

float

20.0

Maximum distance allowed from a road in km (default: 20.0).

--search_mode

single / distributed

distributed

‘single’ finds one monolithic site, ‘distributed’ allows sub-arrays.

--min_sub_array_size

int

500

Minimum required capacity for a sub-array to be considered valid (default: 500).

--min_aspect_deg

float

Minimum bound for site facing direction in degrees (0-360).

--max_aspect_deg

float

Maximum bound for site facing direction in degrees (0-360).

--region_name

string

Cosmetic region name to print on the final visualization chart.

--generate_kml

flag

off

Include this flag to generate a Google Earth KML file of the findings.

--no_print_info

flag

off (feature on)

Include this flag to skip printing the detailed explanatory text.

--no_explain

flag

off (feature on)

Skip the plain-language summary of the run. It is printed by default, and saved as explanation.txt beside the results: what was found, which constraint set the size of the answer, what held the surviving sites back, and which of the numbers are assumptions rather than measurements. A results file can be re-explained at any time with explain.explain_results().

--config_path

string

Path to external JSON configuration file.

--output_directory_base_with_given_json

string

../output/

Base directory for outputs when a JSON config is supplied (default: ../output/).

--output_image_format

string

png

Format of the saved map visual, e.g., png, pdf, svg (default: png).

--resume

flag

off

Include this flag to resume a previous run from the ray-tracing checkpoint.

--resume_dir

string

Path to an output folder from a previously failed run to resume from the ray-tracing checkpoint.

--generate_config

string

Supply a filepath to generate a default JSON config template and exit.

--config_preset

default / lima / arequipa

default

Optional presets to inject when using –generate_config.