Walkthrough
Getting set up
- Follow the installation page first.
- This guide assumes you installed SEALS using the devstack layout — its own project folder under
~/Files/, with the repo inside it at~/Files/seals/seals.
Explore the SEALS code
- The repo root
seals/holds more than the library — docs, tests, scripts - The library itself is the
seals/sealssubdirectory. The nesting looks redundant but is how Python packaging works - Inside it,
__init__.pyis what makes the directory importable as a package - The modules are split by what they hold:
seals_main.py,seals_tasks.py,seals_generate_base_data.py— task functions, the actual model logicseals_initialize_project.py— the task-tree buildersseals_utils.py— helpersrun_seals_standard.py— the run file
Run files
- You do not run
seals_main.pydirectly - A run file configures a project and executes a task tree built from the library’s task functions
- Two ship with SEALS, both in
seals/seals:run_seals_standard.py— three scenarios, 2030 and 2050run_seals_standard_test.py— the same pipeline pared to a baseline, one BAU scenario, one year, Rwanda. Start here
- Open
run_seals_standard.py. It is about 60 lines and has three parts
Part 1: the task tree
build_task_tree(p)answers one question: what is this pipeline?- It contains nothing but tree construction. For stock SEALS it is one line, delegating to the shared library builder
- Compose extra library subtrees or your own tasks here if your project diverges
def build_task_tree(p):
seals_initialize_project.build_standard_task_tree(p)Part 2: run_project
run_project(p)answers how is it executed? It takes onlyp- The rule that decides what goes where:
run_project(p)sets what no variant ever changes — base data location, processing resolution- the caller sets what a variant might — project name, run mode, scenarios CSV
- When a constant starts varying, it moves one line up into the caller. There is no signature to edit and no default to keep in sync
def run_project(p):
p.run_in_parallel = 1 # before the tree: it has parallel iterators
build_task_tree(p)
p.skip_tasks(p.tasks_to_skip)
p.base_data_dir = os.path.join(p.user_dir, 'Files', 'base_data')
p.processing_resolution = 1.0
p.scenario_definitions_path = os.path.join(p.input_dir, p.scenario_definitions_filename)
seals_initialize_project.initialize_scenario_definitions(p)
seals_initialize_project.set_advanced_options(p)
p.execute()
return pPart 3: the __main__ guard
- This is where the project is configured — two lines of actual choice
- The guard is mandatory: importing a run file must never start a run. That is what lets a second run file import this pipeline instead of copying it
if __name__ == '__main__':
p = hb.ProjectFlow(project_name='seals_standard', run_mode='check')
p.scenario_definitions_filename = 'standard_scenarios.csv'
run_project(p)The p object
hb.ProjectFlow()is a class — a recipe for an object. Calling it produces an object, which we assign toppcarries the project’s attributes:p.base_data_dir,p.scenario_definitions_filename, and so on- It also has methods that act on it:
p.add_task(),p.skip_tasks(),p.get_path(),p.execute() - Every task receives
pand reads its configuration from it. That is how configuration set in__main__reaches code deep in the library
Where the project directory goes
- Not into the repo. Because the run file sits inside a cloned repo, ProjectFlow places the project dir just outside it, at
~/Files/seals/projects/<project_name>/ - You do not compute this path yourself, and you should not save data in
seals/seals run_modedecides how much prior work is reused:'check'— reuse the stable dir, recompute only what is missing (the default)'fresh_intermediate'— redo all computation, keepinput/(test projects only)'full'— a fresh timestamped dir; everything re-runs
Scenario definitions
The scenarios CSV
- The scenarios CSV specifies the runs you want. Each row is one scenario
- As the model iterates, it re-hydrates
pfrom the row it is on — which is why scenario-varying values belong in the CSV and not in the run file - The tracked copy lives in
input_template/beside the run file. ProjectFlow copies anything missing into the project’sinput/on first run and never overwrites your working copy - If the named file is nowhere to be found, SEALS generates a default so a first run still works
p.scenario_definitions_filename = 'standard_scenarios.csv'Scenario types
scenario_typeis a column in the CSV, not something a run file setsbaseline— the observed anchor; not downscaled, supplies base-year LULCpolicy— a trajectory to downscale, compared against a counterfactualbau— business-as-usual, being deprecated in favour ofbaseline; it still appears in shipped CSVs- Full column reference: Custom scenarios
Automatically downloading data
- Paths in the CSV are ref_paths — relative locations resolved by
p.get_path(), which searches the projectinput/dir, thenbase_data, then a cloud bucket, downloading what is missing - NOTE: The first run downloads a lot of data. The default bucket is public and requires no credentials, but it is large and the download may take hours. Also note that you may need to restart the run file after it all downloads.
p.base_data_diris where those downloads land. Point it somewhere with room for very large files; the same base data serves every project- The directory must be named
base_datato match the bucket convention - The default bucket is public — no credentials needed
p.base_data_dir = os.path.join(p.user_dir, 'Files', 'base_data')Running it
Run the model
conda activate <your_env>
cd seals/seals
python run_seals_standard_test.py- On startup SEALS prints the task tree it is about to compute
- To understand the model in depth, read the task functions behind those names
- Run the same command a second time: it finishes almost immediately, because every task is behind an existence check and completed work is skipped
Find the output
- Go to
~/Files/seals/projects/seals_standard_test/intermediate/ - There is one directory per task in the tree
- The downscaled maps are in
stitched_lulc_simplified_scenarios/, for example:
lulc_esa_seals7_ssp2_rcp45_luh2-message_bau_2030.tif
- Open it in QGIS alongside the base-year LULC and compare — that is your high-resolution land-use change projection
Next
SEALS is customized be adding or changing scenarios in the scenarios CSV. See Custom scenarios for the rules and conventions.