# Land Subsidence Susceptibility Mapping for the Coastal States of Southern Nigeria
Analysis code for the manuscript:
> Ugwu, O. J., Njoku, R. E., Ahuchaogu, E. U., & Uzoeshi, S. M. (2026).> *Land Subsidence Susceptibility Mapping and Screening-Level Relative Sea> Level Change Scenarios for the Coastal States of Southern Nigeria Using> GIS-Based Multi-Criteria Decision Analysis.* Remote Sensing Applications:> Society and Environment. Manuscript RSASE-D-26-00979.
Corresponding author: Okwudili John Ugwu, Department of Surveying andGeoinformatics, Federal University of Technology Owerri (FUTO), Nigeria.okwudili.ugwu@futo.edu.ng
---
## What this study is, and is not
This is a **screening-level** assessment. It derives a spatially continuousSubsidence Susceptibility Index (SSI) by GIS-based Multi-Criteria DecisionAnalysis and rescales it into relative-sea-level-equivalent units using an**assumed** scale factor.
The scale factor is not calibrated against measured vertical land motion, andno such measurement is used anywhere in the study. The rescaled values areconditional illustrations, not estimates: every absolute quantity reported —the RSLC range, the amplification ratio, the cumulative values, and thepopulations above any threshold — is a linear function of that assumption.What does not depend on it is the **ordering of locations**, which is thebasis of the framework's intended use: identifying where vertical-land-motionmeasurement should be prioritised.
The population figures are **co-location** with the susceptibility classes,not an exposure assessment. No coastal connectivity, inundation pathway orflood-protection information is modelled.
## Analysis domain
Six of the eight Nigerian littoral states — Lagos, Ogun, Ondo, Delta, Bayelsaand Rivers — totalling **65,840 km²** over **5,378,411** valid cells at 0.001°(~110 m). Akwa Ibom and Cross River lie east of the extent of the iSDAsoilclay layer (F1, ~7.6°E), the least spatially extensive of the six inputs, andare outside the domain. The domain is administratively bounded and is not aphysically defined coastal zone.
---
## Repository contents
### Scripts (`04_Scripts/`)
Seventeen scripts. Run the numbered pipeline in order; `00` may be run at anytime.
| Script | Produces ||---|---|| `00_input_provenance.py` | `INPUT_CHECKSUMS.txt` — SHA-256 manifest of every third-party input file || `01_prepare_factors.py` | Base preparation for F3, F5, F6; clipped and normalised. Does **not** write F2 || `01b_fix_f4_elevation.py` | F4 inverse-elevation layer from FABDEM || `01c_fix_f6_lithology.py` | F6 lithology score from GLiM || `01f_revised_f1_clay_content.py` | F1 clay-content layer from iSDAsoil || `01g_f2_ogim.py` | F2 well-proximity layer from OGIM v2.7 — the **sole** producer of `F2_oil_wells_distance_norm.tif` || `02_ahp_weights_revised.py` | AHP weights and consistency ratio; writes `ahp_weights_revised.json` and manuscript Fig. 4 || `03_compute_ssi_revised.py` | `SSI_continuous_revised.tif`, `SSI_classified_revised.tif` || `04_compute_rslc.py` | `RSLC_rate_map.tif`, cumulative rasters, manuscript Fig. 8 || `05_consistency_checks.py` | Checks C1–C7; manuscript Fig. 10 and Supplementary Fig. S2 || `06_exposure.py` | Population and urbanised-area co-location; per-state table; manuscript Table 6 || `07_factor_correlation.py` | Factor correlation matrices (Supplementary Table S2) || `08_generate_maps.py` | Cartographic maps: manuscript Figs 1, 5, 6, 7 || `09_factor_and_exposure_maps.py` | Factor-layer and co-location figures: manuscript Figs 3, 9 || `10_workflow_diagram.py` | Methodology workflow diagram: manuscript Fig. 2 || `11_lecz_subdomain.py` | Low Elevation Coastal Zone subset by class (Supplementary Table S3) || `12_monte_carlo_sensitivity.py` | Global weight sensitivity, check C8; manuscript Fig. 11 |
### Figure files to manuscript figure numbers
The output filenames do **not** all match the manuscript figure numbers.
| Manuscript | File | Written by ||---|---|---|| Fig. 1 | `Fig01_study_area.png` | `08` || Fig. 2 | `Fig02_methodology_workflow.png` / `.pdf` | `10` || Fig. 3 | `Fig03_factor_layers.png` | `09` || Fig. 4 | `Fig04_ahp_weights.png` / `.pdf` | `02` || Fig. 5 | `Fig06_SSI_continuous.png` | `08` || Fig. 6 | `Fig04_SSI_classified.png` | `08` || Fig. 7 | `Fig05_RSLC_rate.png` | `08` || Fig. 8 | `Fig08_rslc_projections_panel.png` | `04` || Fig. 9 | `Fig09_exposure.png` | `09` || Fig. 10 | `Fig10_consistency_sensitivity_checks.png` | `05` || Fig. 11 | `Fig11_spatial_sensitivity.png` | `12` || Supp. Fig. S2 | `FigS2_descriptive_checks.png` | `05` |
Two further files are produced that are **not** manuscript figures.`04_compute_rslc.py` writes `Fig07_rslc_rate_map.png`, a plain quick-lookversion of the same RSLC field; the manuscript uses the cartographic versionfrom `08`. `02_ahp_weights_revised.py` writes`figS_ahp_weight_revision_history.png`, documenting the provenance of theweight revision.
### Files included in this deposit
This repository contains **analysis code and documentation only**. The inputdatasets are third-party products that we cannot redistribute; the derivedrasters and result tables are regenerated by running the pipeline.
| File | Description ||---|---|| `04_Scripts/` | The seventeen scripts listed above, plus `environment.yml` || `INPUT_CHECKSUMS.txt` | Filename, byte size, modification date and SHA-256 for every input file used, with source identifier and access date. Generated by `00_input_provenance.py`; re-run it on an independent download to verify byte-for-byte || `data/data_sources.csv` | Every input dataset: version, native resolution, period, preprocessing, download link || `data/AHP_matrix.csv` | The full 6x6 pairwise comparison matrix (input to `02`) || `data/Table_S2_factor_correlations.csv` | Pearson correlation matrix (Supplementary Table S2) || `data/Table_S2_factor_correlations_spearman.csv` | Spearman correlation matrix || `README.md` | This file || `LICENSE` | MIT licence for the code |
### Outputs the scripts generate
Running the pipeline writes these into a local `03_Results/` directory. Theyare **not** part of this deposit.
| Output | Written by ||---|---|| `F1_clay_content_norm.tif` through `F6_lithology_score_norm.tif` | `01*` || `SSI_continuous_revised.tif`, `SSI_classified_revised.tif` | `03` || `RSLC_rate_map.tif` and cumulative rasters | `04` || `ahp_weights_revised.json` | `02` || `consistency_checks_results.csv`, `broadened_sensitivity.csv`, `scale_factor_sensitivity.csv`, `rslc_class_by_scale_factor.csv`, `morans_i_results.csv`, `city_point_extractions.csv` | `05` || `population_exposure.csv`, `state_exposure.csv`, `ssi_class_areas.csv`, `table6_exposure_by_class.csv` | `06` || `lecz_subdomain_areas.csv`, `lecz_subdomain_population.csv` | `11` || `mc_instability_by_class.csv`, `mc_class_transition_matrix.csv`, `mc_leave_one_out.csv`, `SSI_class_instability.tif` | `12` || All manuscript figures (see mapping above) | `02`, `04`, `05`, `08`, `09`, `10`, `12` |
---
## Input datasets (not redistributed here)
Versions, resolutions, periods, access dates and download links are in`data/data_sources.csv`; exact filenames and checksums are in`INPUT_CHECKSUMS.txt`.
| Factor / use | Dataset | Version | Native resolution | Period ||---|---|---|---|---|| F1 clay content | iSDAsoil 0-20 cm clay | v0.13 | 30 m | 2001-2017 || F2 well proximity | OGIM | v2.7 | point vector | v2.7 release || F3 water-storage trend | GSFC GRACE/GRACE-FO Mascon | RL06 v2.0 | ~300 km effective | 2002-04 to 2025-05 || F4 inverse elevation | FABDEM | v1.2 | 30 m | 2020 || F5 low-lying terrain proximity | derived from FABDEM (elevation below 2 m) | v1.2 | 30 m | 2020 || F6 lithology | GLiM (Hartmann and Moosdorf, 2012) | as published | 0.5 degree | not applicable || Population / co-location | WorldPop Nigeria, constrained | 2020 | 100 m | 2020 |
FABDEM is distributed as one-degree tiles. Twenty-four tiles overlap theanalysis extent, and `INPUT_CHECKSUMS.txt` records only those.
---
## How to reproduce
```conda env create -f 04_Scripts/environment.ymlconda activate nigeria_insar```
Download the input datasets listed in `data/data_sources.csv` into`01_Factor_Layers/` and `02_Study_Area/`, then run:
```python 04_Scripts/01_prepare_factors.pypython 04_Scripts/01b_fix_f4_elevation.pypython 04_Scripts/01c_fix_f6_lithology.pypython 04_Scripts/01f_revised_f1_clay_content.pypython 04_Scripts/01g_f2_ogim.pypython 04_Scripts/02_ahp_weights_revised.pypython 04_Scripts/03_compute_ssi_revised.pypython 04_Scripts/04_compute_rslc.pypython 04_Scripts/05_consistency_checks.pypython 04_Scripts/06_exposure.pypython 04_Scripts/07_factor_correlation.pypython 04_Scripts/08_generate_maps.pypython 04_Scripts/09_factor_and_exposure_maps.pypython 04_Scripts/10_workflow_diagram.pypython 04_Scripts/11_lecz_subdomain.pypython 04_Scripts/12_monte_carlo_sensitivity.py```
### Project paths
No absolute paths are hard-coded. Each script resolves the project root fromthe `PAPER_C_ROOT` environment variable if set, and otherwise derives it fromthe script's own location, assuming the script sits in `/04_Scripts/`.To keep the data elsewhere:
```Windows: set PAPER_C_ROOT=D:\path\to\Paper_C_RSLCLinux: export PAPER_C_ROOT=/path/to/Paper_C_RSLC```
FABDEM tiles may be held outside the project tree; the folders searched arelisted in `FABDEM_SEARCH` near the top of `01b_fix_f4_elevation.py`.
### What the reproduction check does and does not show
`05_consistency_checks.py` recomputes the SSI from the six factor layers andthe AHP weights and compares it against the `SSI_continuous_revised.tif`written earlier by `03`. Run end to end, the maximum absolute difference isabout 1.5e-07, which is single-precision rounding.
This demonstrates **internal computational consistency** — that the pipelinereproduces its own output. It is not an external reproduction test and saysnothing about accuracy. Neither the inputs nor the derived rasters aredeposited, so the check requires obtaining the input datasets first.
### Key results these scripts reproduce
* AHP: Consistency Ratio 0.0125; weights F2 0.397, F4 0.250, F3 0.160, F1 0.097, F5 0.060, F6 0.037* SSI: 0.080 to 0.930 (mean 0.550, SD 0.252) over 5,378,411 cells* Rescaled RSLC: 4.30 to 17.04 mm/yr at the assumed scale factor a = 15 mm/yr, intercept zero* Domain: 65,840 km²; classes Very High 15,695.6 km² (23.84%) to Very Low 5,808.3 km² (8.82%)* Co-located population: 41,344,645 total; 24,607,733 (59.5%) at RSLC at or above 10 mm/yr; 8,444,872 (20.4%) at or above 15 mm/yr* Urbanised-area proxy (at or above 300 persons/km²): 6,273.8 km² total; 2,931.3 km² (46.7%) at RSLC at or above 10 mm/yr* Sensitivity: classification changes 8.3% (remove F3), 8.3% (remove F5), 26.6% (quintile thresholds), 27.1% (rank normalisation), 29.9% (remove F2); ordering of locations essentially invariant under joint weight perturbation, minimum Spearman 0.9987 over 500 realisations
---
## Notes on two factors
**F2 (well proximity)** is produced only by `01g_f2_ogim.py`;`01_prepare_factors.py` does not write it. The layer is an inverted distanceto mapped wells with no decay function and no cutoff. It does not measureextraction volume, reservoir depth, production history or compaction.
**F5 (low-lying terrain proximity)** is an inverted distance to terrain below2 m elevation in FABDEM. It is **not** a hydrographic channel network, andbecause it thresholds the same elevation model as F4 it is partly derivativeof that factor. Removing it changes 8.3% of classifications.
## Declaration of generative AI in the research process
The analysis scripts in this repository were drafted with the assistance of alarge language model and were subsequently reviewed, corrected, and executedby the authors. All numerical results reported in the associated manuscriptwere independently recomputed from the source datasets by the correspondingauthor and verified against the input rasters. The authors take fullresponsibility for the code, the data-processing decisions, and every resultreported.
## Licence
Code in this repository: MIT (see `LICENSE`). Input datasets are notredistributed here and retain their original providers' licences, recorded in`data/data_sources.csv`.