q02·intermediate

Has methane increased near this oil/gas infrastructure?

atmospheregreenhouse-gasesenergy Datasets: 5 15–45 min depending on plume density

Methane (CH₄) is the main ingredient in natural gas. It's also a strong greenhouse gas, much worse than CO₂ over the short term. When an oil or gas site leaks, methane escapes invisibly into the air, often in a concentrated cloud called a plume. NASA's EMIT instrument, riding on the International Space Station, can spot those plumes from orbit because methane absorbs sunlight at specific colors a normal camera can't see.

Has methane increased near this oil/gas infrastructure?

Methane (CH₄) is the main ingredient in natural gas. It’s also a strong greenhouse gas, much worse than CO₂ over the short term. When an oil or gas site leaks, methane escapes invisibly into the air, often in a concentrated cloud called a plume. NASA’s EMIT instrument, riding on the International Space Station, can spot those plumes from orbit because methane absorbs sunlight at specific colors a normal camera can’t see.

Which data to use, and how

Use this dataset: EMIT L2B Methane Enhancement (short name EMITL2BCH4ENH), which covers August 2022 → today at ~60 m per pixel. “Enhancement” is how much extra methane sits above the background at each spot on the ground. That makes it the most direct way to ask “is there a leak here?” It’s also the freshest product. The tidied-up plume outlines (EMITL2BCH4PLM) lag behind by weeks, so for the latest data start with Enhancement.

Then do four or five steps (the runnable code further down does all of this — this is just the idea):

  1. Pick your facility (its latitude/longitude) and draw a small box around it, a few km on each side, plus the date window you care about.
  2. Find the overpasses. Search EMIT for every time it flew over your box and recorded data.
  3. Look for extra methane. Open each scene, crop it to your box, and add up the excess methane to get a total plume mass per detection.
  4. Turn mass into a leak rate. A still cloud tells you little. You need the wind to know how fast methane is blowing away. Pull wind speed and how deep the air is mixing (MERRA-2, NASA’s weather-history model) for each detection time and use it to estimate a source rate in kilograms per hour.
  5. Chart it. Plot leak rate over time at the facility, and map the plume outlines colored by date.

That’s the whole method. Below, “How a scientist answers this” names the exact tools, and the Run it cell does it live on synthetic data so you can see each step work.

What you can find out

  • Whether NASA caught a methane plume over your exact spot during your date window.
  • How big the leak is. An estimated source strength in kg/hr, from the plume mass combined with wind and mixing depth.
  • How often it leaks. The repeat detection rate, i.e. how many of EMIT’s flyovers found a plume.
  • Whether the leaking has grown or shrunk, in plume size or how often it shows up across the time EMIT has been running.

What it can’t tell you

  • Round-the-clock surveillance. EMIT only passes over a given point roughly every 16 days (often longer). You get snapshots, not a live feed, and a leak could start and stop entirely between visits.
  • Exactly which tank or wellhead. EMIT pixels are ~60 m wide. If several pieces of equipment sit close together, the plume can’t be pinned to a single one.
  • A facility’s total yearly emissions. Adding up a handful of snapshots isn’t the full picture. Filling the gaps between flyovers requires extra models.

Gotchas to watch for

  • EMIT is really a color-of-light camera, not a dedicated methane sensor. The methane number is computed from the light it sees (a technique called a matched filter), so false alarms happen. The fix: trust the quality-assurance (QA) flag and treat weak single detections with caution.
  • Plumes can blur together. In a crowded oilfield, several sources within one 60 m pixel mix into one signal (sub-pixel mixing), so you may be measuring a neighborhood, not one valve.
  • EMIT is blind at night. It’s a passive optical instrument. It needs sunlight, so it only works on the daytime, sunlit side of each orbit. Don’t expect nighttime detections.
  • The pretty plume outlines arrive late. The vector plume product (EMITL2BCH4PLM) is published weeks after the raw Enhancement data. For the most recent answer, use the Enhancement product (EMITL2BCH4ENH) and accept it’s less polished.
  • “Public catalog” data is already double-checked; your own isn’t. The UNEP-IMEO MARS workflow has experts manually verify EMIT plumes before releasing the public polygons. So if you pull the public plume catalog, it’s already quality-controlled. But if you process the Enhancement product yourself, you are doing that vetting, and should flag uncertain hits.

The real-data code

The Run it cell above runs this method on synthetic data with no login. Below is the whole recipe against the real archive: search EMIT over the facility, open each scene, sum the excess methane into a plume mass, pull MERRA-2 wind to turn that mass into a kg/hr leak rate, and plot it over time. It needs a free Earthdata Login.

import earthaccess, numpy as np, xarray as xr
import pandas as pd, matplotlib.pyplot as plt

earthaccess.login(strategy="netrc")

# 1. Facility + a ~5 km box around it, and the EMIT-era window.
facility = (32.65, -103.05)              # (lat, lon) — a Permian Basin site
buf = 0.05
aoi = (facility[1]-buf, facility[0]-buf, facility[1]+buf, facility[0]+buf)  # (W,S,E,N)
window = ("2022-08-01", "2026-05-01")
PIXEL_M = 60.0                           # EMIT ground sampling distance (m)

# 2. Find every EMIT overpass that recorded methane enhancement over the box.
grans = earthaccess.search_data(short_name="EMITL2BCH4ENH",
                                bounding_box=aoi, temporal=window)
print(f"{len(grans)} EMIT enhancement granules over the facility")

# 3. Open each scene (gridded HDF5-EOS -> xarray), crop to the box, and integrate the
#    excess methane into a plume mass. Enhancement is in ppm-m; convert with EMIT's
#    constant (0.0429 kg/m2 per ppm-m of CH4) and the 60 m pixel footprint.
PPMM_TO_KG_M2 = 0.0429
detections = []
for g in grans:
    ds = xr.open_dataset(earthaccess.open([g])[0], engine="h5netcdf")
    enh = ds["ch4_enhancement"] if "ch4_enhancement" in ds else ds["enhancement"]
    enh = enh.where((ds.lon >= aoi[0]) & (ds.lon <= aoi[2]) &
                    (ds.lat >= aoi[1]) & (ds.lat <= aoi[3]))
    enh = enh.where(enh > 200)           # keep clear enhancement above background noise
    if not np.isfinite(enh).any():
        continue                          # clean overpass, no plume
    mass_kg = float((enh * PPMM_TO_KG_M2 * PIXEL_M**2).sum())  # ppm-m -> kg over footprint
    t = pd.to_datetime(str(g["umm"]["TemporalExtent"]["RangeDateTime"]["BeginningDateTime"]))
    detections.append((t, mass_kg))

det = pd.DataFrame(detections, columns=["time", "mass_kg"]).sort_values("time")
print(f"{len(det)} of {len(grans)} overpasses showed a plume "
      f"({len(det)/max(len(grans),1):.0%} detection rate)")

# 4. Mass -> leak rate. A still cloud needs the wind to become a rate: rate = mass * U / L,
#    where U is wind speed and L the plume's along-wind length (~box width here). Pull MERRA-2
#    surface wind for each detection day and combine.
def wind_ms(t):
    mg = earthaccess.search_data(short_name="M2I1NXASM", bounding_box=aoi,
                                 temporal=(t.strftime("%Y-%m-%d"), t.strftime("%Y-%m-%d")))
    m = xr.open_dataset(earthaccess.open([mg[0]])[0], engine="h5netcdf").sel(
        lat=facility[0], lon=facility[1], method="nearest").sel(time=t, method="nearest")
    return float(np.hypot(m["U10M"], m["V10M"]))   # 10 m wind speed

L_m = buf * 2 * 111_000                              # box width in metres (plume length scale)
det["wind_ms"] = det["time"].map(wind_ms)
det["rate_kg_hr"] = det["mass_kg"] * det["wind_ms"] / L_m * 3600

# 5. Verdict + plot the leak rate over the EMIT record.
if len(det):
    print(f"VERDICT: {len(det)} plume(s); latest source rate "
          f"{det['rate_kg_hr'].iloc[-1]:,.0f} kg/hr on {det['time'].iloc[-1].date()}")
else:
    print("VERDICT: no methane plume detected over this facility in the window")

plt.plot(det["time"], det["rate_kg_hr"], "o-")
plt.ylabel("estimated source rate (kg/hr)"); plt.xlabel("EMIT overpass")
plt.title("Methane leak rate at facility"); plt.tight_layout(); plt.show()

# Before you trust it: cross-check against the vetted public plume catalog (EMITL2BCH4PLM /
# UNEP-IMEO MARS) — those polygons are manually quality-controlled; your own hits are not.

Where the data comes from

This pulls from a few NASA archives joined through one free Earthdata Login. The methane plumes come from EMIT (stored at the LP DAAC archive). The wind and air-mixing fields come from MERRA-2 (the GES DISC archive). A wider-but-coarser methane view is available from Europe’s TROPOMI / Sentinel-5P (run by ESA but mirrored into Earthdata Search), and some workflows add OCO-3 CO₂ for context. One login covers all of them. See recipes/r02-emit-merra2-fusion.mdx.

Sources

How a scientist answers this
Parameters
Methane column enhancement (ppm-m) from EMIT L2B Methane Enhancement (60 m COG retrievals) and the EMIT L2B Methane Plume Complexes vector product over a facility lat/lon plus a ~5 km buffer; plume source rate (kg/hr) is derived using MERRA-2 planetary-boundary-layer height and 10 m / 850 hPa wind. TROPOMI/Sentinel-5P CH4 (~10 km daily) gives the regional column context, and a detection counts only if the enhancement clears the scene's per-pixel retrieval noise (typically several-sigma above the local background).
Method
For each EMIT overpass, mask the enhancement raster to the AOI, integrate the plume mass, and convert to an emission rate via the Integrated Mass Enhancement (IME) method using boundary-layer wind speed (rate ∝ IME × U / L); then count repeat detections and test for a trend in plume frequency/size over the operational window. Because revisit is sparse (~16 days), treat each pass as an independent snapshot rather than a continuous time series.
Validation
Report the number of clear overpasses and detections (a low repeat rate is sampling, not necessarily absence); cross-check column context against TROPOMI/Sentinel-5P and source-rate estimates against published EMIT/airborne (e.g., AVIRIS-NG) plume inventories; flag wind-speed uncertainty, which dominates the kg/hr error budget.
In plain EnglishLook at NASA's high-resolution methane snapshots over the site, find any plume, and use the wind speed to estimate how fast gas is leaking — then count how often it shows up across many fly-overs. Because the satellite only passes every couple of weeks, these are spot-checks, not constant watching.

Make it yours → Edit the facility coordinates, the buffer radius, the date window, and the wind/PBL source in the notebook to study your own site and period.

🧪 Virtual Mock Lab stand-in data · runs in your browser · no login

A safe place to practise the method on EMITL2BCH4ENH. The code is the real earthaccess workflow, but we feed it stand-in data shaped like the real product — so you can run it, change the numbers, and break it without an account. When you want the real data, use the recipe under “The real-data code” above, or download the notebook below.

editable · runs in your browser

Datasets used

Recipe ready · not yet run The recipe and the Virtual Mock Lab above are ready to use. We haven't yet run this question end-to-end on real data, so it has no verified answer yet — only the questions we've actually computed carry one. That's the honest line between a method and a result.