Source code for download_data
"""download_data.py - Download MASTER FireSense 2023 data from NASA Earthdata.
Downloads the MASTER Level 1B HDF4 files used in this project from the
ORNL DAAC archive. Requires a free NASA Earthdata account.
Dataset: MASTER: FireSense, western US, October 2023
DOI: https://doi.org/10.3334/ORNLDAAC/2330
First-time setup:
1. Create a free account at https://urs.earthdata.nasa.gov/
2. pip install earthaccess
3. python download_data.py
The script will prompt for your Earthdata credentials on first run
and cache them in ~/.netrc for future use.
Usage:
python download_data.py # download all 4 flights (83 files, ~9 GB)
python download_data.py --flight 04 # download only flight 24-801-04
python download_data.py --list # list available files without downloading
"""
import os
import sys
import argparse
import earthaccess
# ORNL DAAC dataset DOI for MASTER FireSense 2023
DATASET_DOI = "10.3334/ORNLDAAC/2330"
# Flights used in this project (Kaibab Plateau, Arizona)
FLIGHTS = {
"03": {"id": "2480103", "description": "Pre-burn (day), 9 lines", "files": 9},
"04": {"id": "2480104", "description": "Burn flight 1 (day), 40 lines", "files": 40},
"05": {"id": "2480105", "description": "Burn flight 2 (night), 16 lines", "files": 16},
"06": {"id": "2480106", "description": "Burn flight 3 (day), 18 lines", "files": 18},
}
OUTPUT_DIR = "ignite_fire_data"
[docs]
def search_flight_files(flight_id):
"""Search for MASTER L1B HDF files for a specific flight."""
results = earthaccess.search_data(
doi=DATASET_DOI,
granule_name=f"MASTERL1B_{flight_id}_*",
)
return results
[docs]
def list_files(flights_to_list):
"""List available files for the specified flights."""
total = 0
for fnum, info in sorted(flights_to_list.items()):
print(f"\nFlight 24-801-{fnum} ({info['description']}):")
results = search_flight_files(info["id"])
for r in results:
name = r["meta"]["native-id"] if "meta" in r else str(r)
print(f" {name}")
print(f" Found: {len(results)} files")
total += len(results)
print(f"\nTotal: {total} files")
[docs]
def download_files(flights_to_download):
"""Download HDF files for the specified flights."""
os.makedirs(OUTPUT_DIR, exist_ok=True)
total_files = 0
for fnum, info in sorted(flights_to_download.items()):
print(f"\n{'=' * 60}")
print(f"Flight 24-801-{fnum}: {info['description']}")
print(f"{'=' * 60}")
results = search_flight_files(info["id"])
if not results:
print(f" No files found for flight {fnum}. Skipping.")
continue
print(f" Found {len(results)} files. Downloading...")
downloaded = earthaccess.download(results, OUTPUT_DIR)
print(f" Downloaded {len(downloaded)} files to {OUTPUT_DIR}/")
total_files += len(downloaded)
print(f"\n{'=' * 60}")
print(f"Done. {total_files} files downloaded to {OUTPUT_DIR}/")
print(f"\nNext steps:")
print(f" python mosaic_flight.py # build mosaics")
print(f" python realtime_fire.py # real-time simulation")
print(f" python plot_burn_locations.py # burn analysis plots")
[docs]
def main():
parser = argparse.ArgumentParser(
description="Download MASTER FireSense 2023 data from NASA Earthdata.",
epilog="Requires a free NASA Earthdata account: https://urs.earthdata.nasa.gov/",
)
parser.add_argument(
"--flight",
choices=["03", "04", "05", "06"],
help="Download only this flight (default: all 4 flights)",
)
parser.add_argument(
"--list",
action="store_true",
help="List available files without downloading",
)
args = parser.parse_args()
# Authenticate (prompts on first run, caches in ~/.netrc)
print("Authenticating with NASA Earthdata...")
earthaccess.login(strategy="interactive", persist=True)
print("Authenticated.\n")
# Select flights
if args.flight:
flights = {args.flight: FLIGHTS[args.flight]}
else:
flights = FLIGHTS
print("MASTER FireSense 2023 - Kaibab Plateau Prescribed Burns")
print(f"Dataset DOI: https://doi.org/{DATASET_DOI}")
print(f"Flights: {', '.join(f'24-801-{f}' for f in sorted(flights))}")
if args.list:
list_files(flights)
else:
download_files(flights)
if __name__ == "__main__":
main()