Como encontrar URLs de OPeNDAP de NASA Earthdata#
Este tutorial demuestra cómo encontrar URLs OPeNDAP desde el Common Metadata Repository (CMR). El CMR es la API de NASA Earthdata para consultar datasets disponibles a través de muchos servicios de descarga y subconjunto, incluido OPeNDAP. La API de CMR es compleja y amplia, y con pydap.client.get_cmr_urls las personas usuarias pueden consultar y recuperar URLs OPeNDAP.
Requisitos para ejecutar este notebook
Tener una cuenta Earth Data Login
Conocer el Collection Concept ID (CCID), o Digital Object Identifier (DOI), de la colección de interés.
Note
Desde la perspectiva de NASA, una colección es un dataset (a diferencia de un gránulo, que puede entenderse como un archivo individual y que, en conjunto con otros, describe la colección). Por ello, el CCID o DOI son identificadores únicos de ese dataset archivado.
Objetivos
Usar PyDAP para descubrir todas las URLs opendap en dos casos de estudio simples:
Descubrir todas las URLs OPeNDAP posibles asociadas con un Collection Concept ID específico (y DOI).
Descubrir todas las URLs OPeNDAP de una colección que coincidan con un rango temporal y una caja espacial de interés. Estos parámetros, y otros, son ampliamente usados por CMR (y Earthdata Search) para filtrar el número de resultados posibles al consultar el CMR, reduciendo así la búsqueda.
Autor: Miguel Jimenez-Urias, ‘25
from pydap.client import get_cmr_urls
import pydap
import datetime as dt
print("pydap version: ", pydap.__version__)
pydap version: 3.5.11.dev1+ge35cae66d
1) Descubrir datos diarios de clorofila a 4 km desde PACE (Nivel 3)#
En este ejemplo nos interesa recuperar TODAS las URLs de gránulos desde OPeNDAP asociadas con una colección de PACE. Para esta colección, el CMR devuelve varias versiones de los datos con respecto a la siguiente variable:
Gridded Chlorophyll A, Version 3.1
PACE_ccid = "C3620140255-OB_CLOUD" # <--- This concept collection ID can be found of the Mission page for PACE.
urls = get_cmr_urls(ccid=PACE_ccid, limit=1000) # limit by default = 50
urls[:10]
['https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0701/PACE_OCI.20250701.L3m.DAY.CHL.V3_1.chlor_a.4km.NRT.nc',
'https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0701/PACE_OCI.20250701.L3m.DAY.CHL.V3_1.chlor_a.0p1deg.NRT.nc',
'https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0702/PACE_OCI.20250702.L3m.DAY.CHL.V3_1.chlor_a.0p1deg.NRT.nc',
'https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0702/PACE_OCI.20250702.L3m.DAY.CHL.V3_1.chlor_a.4km.NRT.nc',
'https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0703/PACE_OCI.20250703.L3m.DAY.CHL.V3_1.chlor_a.0p1deg.NRT.nc',
'https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0703/PACE_OCI.20250703.L3m.DAY.CHL.V3_1.chlor_a.4km.NRT.nc',
'https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0704/PACE_OCI.20250704.L3m.DAY.CHL.V3_1.chlor_a.0p1deg.NRT.nc',
'https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0704/PACE_OCI.20250704.L3m.DAY.CHL.V3_1.chlor_a.4km.NRT.nc',
'https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0705/PACE_OCI.20250705.L3m.DAY.CHL.V3_1.chlor_a.0p1deg.NRT.nc',
'https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0705/PACE_OCI.20250705.L3m.DAY.CHL.V3_1.chlor_a.4km.NRT.nc']
Identificar los archivos de interés#
No todas las URLs anteriores se pueden agregar en una sola colección. Aunque describen las mismas variables, estas estan interpoladas sobre distintos rangos temporales. Queremos datos diarios a resolución de 4 km. Como esta información está codificada en la URL, podemos usar una list comprehension para filtrar más nuestros resultados.
pace_urls = [url for url in urls if '4km' in url and "DAY" in url]
pace_urls[:4]
['https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0701/PACE_OCI.20250701.L3m.DAY.CHL.V3_1.chlor_a.4km.NRT.nc',
'https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0702/PACE_OCI.20250702.L3m.DAY.CHL.V3_1.chlor_a.4km.NRT.nc',
'https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0703/PACE_OCI.20250703.L3m.DAY.CHL.V3_1.chlor_a.4km.NRT.nc',
'https://oceandata.sci.gsfc.nasa.gov/opendap/PACE_OCI/L3SMI/2025/0704/PACE_OCI.20250704.L3m.DAY.CHL.V3_1.chlor_a.4km.NRT.nc']
print("We found ", len(pace_urls), " relevant OPeNDAP urls from PACE")
We found 228 relevant OPeNDAP urls from PACE
2) Acceder a datos swath de ECOSTRESS (datos Nivel 2)#
En este ejemplo filtraremos el resultado del CMR para devolver solo URLs de gránulos que tengan datos en un área específica de interés.
Land Surface Temperature
Swath de datos durante marzo de 2025, en una caja delimitadora definida abajo:
bounding_box = [-128.847656,41.112469,-107.050781,46.679594]
Note
Puedes usar una aplicación web, como bbox finder, geojson o Earthdata Search, para construir polígonos. Ten en cuenta que la API de CMR requiere, para una caja delimitadora, el siguiente patrón: [West_Longitude, South_Latitude, East_Longitude, North_Latitude]
ECOSTRESS_ccid = "C2076114664-LPCLOUD"
bounding_box = [-128.847656,41.112469,-107.050781,46.679594]
time_range = [dt.datetime(2025, 3, 1), dt.datetime(2025, 3, 31)]
urls = get_cmr_urls(ccid=ECOSTRESS_ccid, bounding_box=bounding_box, time_range=time_range, limit=500)
print("Found ", len(urls), "relevant opendap urls for ECOSTRESS data")
Found 194 relevant opendap urls for ECOSTRESS data
urls[:6]
['https://opendap.earthdata.nasa.gov/collections/C2076114664-LPCLOUD/granules/ECOv002_L2_LSTE_37709_001_20250301T092419_0713_01',
'https://opendap.earthdata.nasa.gov/collections/C2076114664-LPCLOUD/granules/ECOv002_L2_LSTE_37712_008_20250301T141617_0713_01',
'https://opendap.earthdata.nasa.gov/collections/C2076114664-LPCLOUD/granules/ECOv002_L2_LSTE_37723_006_20250302T070023_0713_01',
'https://opendap.earthdata.nasa.gov/collections/C2076114664-LPCLOUD/granules/ECOv002_L2_LSTE_37723_007_20250302T070115_0713_01',
'https://opendap.earthdata.nasa.gov/collections/C2076114664-LPCLOUD/granules/ECOv002_L2_LSTE_37724_005_20250302T083359_0713_01',
'https://opendap.earthdata.nasa.gov/collections/C2076114664-LPCLOUD/granules/ECOv002_L2_LSTE_37724_007_20250302T083600_0713_01']
Warning
El CMR devuelve URLs OPeNDAP con datos que caen dentro de nuestra caja delimitadora. Sin embargo, todavía no se ha realizado ningún subconjunto. Para descargar solo los datos que caen dentro del área de interés, la persona usuaria aún necesita subdividir los datos dentro de cada archivo. CMR solo filtra por metadatos. Es decir, por ejemplo, en uno de esos archivos remotos puede haber solo un punto de datos dentro de la caja delimitadora, mientras que en otro archivo remoto es posible que la mayoría de los datos caigan dentro de la caja delimitadora.