Ignorar navegação

GOES-16

SatelliteImagery EarthObservation AIforEarth NOAA

Imagens meteorológicas do satélite GOES-16.

O programa GOES-R (Satélite Ambiental Operacional Geoestacionário) cria imagens de fenômenos meteorológicos de um conjunto de satélites em órbitas geoestacionárias. O satélite GOES-16 é o primeiro dos quatro satélites GOES-R planejados. A órbita do GOES-16 oferece uma exibição das Américas.

Este conjunto de dados atualmente inclui o produto ABI-L2-MCMIPF (Advanced Baseline Imager, Level 2, Cloud and Moisture Imagery e Full-disk), bem como o produto ABI-L1b-RadF (Advanced Baseline Imager, Level 1b e Full-disk). Podemos integrar outros produtos GOES-16 e GOES-17 mediante solicitação. Entre em contato com aiforearthdatasets@microsoft.com se você estiver interessado em usar dados adicionais do GOES no Azure.

Este conjunto de dados está disponível no Azure graças ao Programa de Big Data da NOAA.

Recursos de Armazenamento

Os dados são armazenados em blobs no formato NetCDF (um blob por imagem) no data center da região Leste dos EUA, no seguinte contêiner de blob:

https://goes.blob.core.windows.net/noaa-goes16

Dentro desse contêiner, os dados são nomeados como:

[product]/[year]/[day]/[hour]/[filename]

  • product é o nome de um produto. Atualmente, os produtos ABI-L2-MCMIPF e ABI-L1b-RadF estão disponíveis no Azure
  • o campo year corresponde a um ano com quatro dígitos
  • day é um código de dia do ano com três dígitos, começando com 001
  • hour é um código de hora do dia com dois dígitos, começando com 00
  • filename codifica o produto, a data e a hora. Os detalhes estão disponíveis no Guia do Usuário do GOES

Por exemplo, este arquivo:

https://goes.blob.core.windows.net/noaa-goes16/ABI-L2-MCMIPF/2020/003/00/OR_ABI-L2-MCMIPF-M6_G16_s20200030000215_e20200030009534_c20200030010031.nc

…contém dados de 3 de janeiro de 2020, entre meia-noite e 1h UTC (hora 00).

Os canais de dados e os comprimentos de onda estão descritos aqui.

Veja um exemplo de Python completo de como acessar e plotar uma imagem do GOES-16 no notebook disponível em “Acesso a dados”.

Também fornecemos um token SAS (assinatura de acesso compartilhado) somente leitura para permitir acesso aos dados do GOES-16 por meio, por exemplo, do BlobFuse, que permite montar contêineres de blob como unidades:

st=2020-04-11T23%3A55%3A25Z&se=2032-04-12T23%3A55%3A00Z&sp=rl&sv=2018-03-28&sr=c&sig=IVSoHKVscKyu8K99I7xfman%2Bzp0ISkFbnbAqE6wkv6A%3D

As instruções de montagem para o Linux podem ser encontradas aqui.

O processamento em grande escala utilizando esse conjunto de dados tem desempenho melhor no data center do Azure da região Leste dos EUA, no qual os dados estão armazenados. Se você estiver usando os dados do GOES para aplicativos de ciência ambiental, considere se inscrever em uma concessão do AI for Earth para compatibilidade com seus requisitos de computação.

Citação

Se você usar esses dados em uma publicação, cite como:

GOES-R Series Program, (2019): NOAA GOES-R Series Advanced Baseline Imager (ABI) Level 0 Data. [indicar o subconjunto usado]. Centros Nacionais para Informações Ambientais da NOAA. doi:10.25921/tvws-w071.

Imagem bonita


Imagem da umidade nas Américas em 2 de janeiro de 2020.

Contact

Para perguntas sobre este conjunto de dados, entre em contato com aiforearthdatasets@microsoft.com.

Avisos

A MICROSOFT FORNECE O AZURE OPEN DATASETS NO ESTADO EM QUE SE ENCONTRA. A MICROSOFT NÃO OFERECE GARANTIAS OU COBERTURAS, EXPRESSAS OU IMPLÍCITAS, EM RELAÇÃO AO USO DOS CONJUNTOS DE DADOS. ATÉ O LIMITE PERMITIDO PELA LEGISLAÇÃO LOCAL, A MICROSOFT SE EXIME DE TODA A RESPONSABILIDADE POR DANOS OU PERDAS, INCLUSIVE DIRETOS, CONSEQUENTES, ESPECIAIS, INDIRETOS, ACIDENTAIS OU PUNITIVOS, RESULTANTES DO USO DOS CONJUNTOS DE DADOS.

Esse conjunto de dados é fornecido de acordo com os termos originais com que a Microsoft recebeu os dados de origem. O conjunto de dados pode incluir dados originados da Microsoft.

Access

Available inWhen to use
Azure Notebooks

Quickly explore the dataset with Jupyter notebooks hosted on Azure or your local machine.

Select your preferred service:

Azure Notebooks

Azure Notebooks

Package: Language: Python

Demo notebook for accessing GOES-16 data on Azure

This notebook provides an example of accessing GOES-16 data from blob storage on Azure, including (1) finding the data file corresponding to a date and time, (2) retrieving that file from blob storage, and (3) opening the downloaded file using the xarray library, and (4) rendering the image.

GOES-16 data are stored in the East US data center, so this notebook will run most efficiently on Azure compute located in East US. We recommend that substantial computation depending on GOES-16 data also be situated in East US. If you are using GOES-16 data for environmental science applications, consider applying for an AI for Earth grant to support your compute requirements.

Imports and environment

In [1]:
# Mostly-standard imports
import os
import tempfile
import numpy as np
import shutil
import urllib
import matplotlib.pyplot as plt

# Less-common-but-still-pip-installable imports
import xarray
from azure.storage.blob import ContainerClient

# pip install progressbar2, not progressbar
import progressbar

# Storage locations are documented at http://aka.ms/ai4edata-goes16
goes_account_name = 'goes'
goes_container_name = 'noaa-goes16'
goes_account_url = 'https://' + goes_account_name + '.blob.core.windows.net'
goes_blob_root = goes_account_url + '/' + goes_container_name + '/'

# Create a ContainerClient to enumerate blobs
goes_container_client = ContainerClient(account_url=goes_account_url, 
                                         container_name=goes_container_name,
                                         credential=None)

temp_dir = os.path.join(tempfile.gettempdir(),'goes')
os.makedirs(temp_dir,exist_ok=True)

%matplotlib inline

Functions

In [3]:
class DownloadProgressBar():
    """
    https://stackoverflow.com/questions/37748105/how-to-use-progressbar-module-with-urlretrieve
    """
    
    def __init__(self):
        self.pbar = None

    def __call__(self, block_num, block_size, total_size):
        if not self.pbar:
            self.pbar = progressbar.ProgressBar(max_value=total_size)
            self.pbar.start()
            
        downloaded = block_num * block_size
        if downloaded < total_size:
            self.pbar.update(downloaded)
        else:
            self.pbar.finish()
            

def download_url(url, destination_filename=None, progress_updater=None, force_download=False):
    """
    Download a URL to a temporary file
    """
    
    # This is not intended to guarantee uniqueness, we just know it happens to guarantee
    # uniqueness for this application.
    if destination_filename is None:
        url_as_filename = url.replace('://', '_').replace('/', '_')    
        destination_filename = \
            os.path.join(temp_dir,url_as_filename)
    if (not force_download) and (os.path.isfile(destination_filename)):
        print('Bypassing download of already-downloaded file {}'.format(
            os.path.basename(url)))
        return destination_filename
    print('Downloading file {} to {}'.format(os.path.basename(url),
                                             destination_filename),end='')
    urllib.request.urlretrieve(url, destination_filename, progress_updater)  
    assert(os.path.isfile(destination_filename))
    nBytes = os.path.getsize(destination_filename)
    print('...done, {} bytes.'.format(nBytes))
    return destination_filename

Choose a GOES data file for a known time

In [5]:
# Data are stored as product/year/day/hour/filename
product = 'ABI-L2-MCMIPF'
syear = '2020'; sday = '002'; shour = '14';

# There will be several scans this hour, we'll take the first
scan_index = 0

prefix = product + '/' + syear + '/' + sday + '/' + shour + '/'
print('Finding blobs matching prefix: {}'.format(prefix))
generator = goes_container_client.list_blobs(name_starts_with=prefix)
blobs = []
for blob in generator:
    blobs.append(blob.name)
print('Found {} scans'.format(len(blobs)))

scan_url = goes_blob_root + blobs[scan_index]
Finding blobs matching prefix: ABI-L2-MCMIPF/2020/002/14/
Found 6 scans

Load the image

In [7]:
# GOES-16 MCMIPF files are ~300MB.  Not too big to fit in memory, so sometimes it may be 
# preferable to download to file first, sometimes it will be better to load straight to 
# memory.
download_to_file = True

if download_to_file:
    
    filename = download_url(scan_url,progress_updater=DownloadProgressBar())
    from datetime import datetime
    dataset = xarray.open_dataset(filename)    

else:
    
    import netCDF4
    import requests
    
    # If you know of a good way to show a progress bar with requests.get (i.e., without writing
    # to file), we're all ears, email aiforearthdatasets@microsoft.com!
    print('Downloading {} to memory...'.format(os.path.basename(scan_url)))
    response = requests.get(scan_url)
    print('Finished downloading')
    nc4_ds = netCDF4.Dataset(os.path.basename(scan_url), memory = response.content)
    store = xarray.backends.NetCDF4DataStore(nc4_ds)
    dataset = xarray.open_dataset(store)
Bypassing download of already-downloaded file OR_ABI-L2-MCMIPF-M6_G16_s20200021400218_e20200021409537_c20200021410039.nc

Explore the xarray dataset and prepare to plot the image

In [8]:
print('Scan starts at: {}'.format(dataset.time_coverage_start))
print('Scan ends at: {}'.format(dataset.time_coverage_end))

# Bands are documented at:
#
# https://www.ncdc.noaa.gov/data-access/satellite-data/goes-r-series-satellites/glossary
#
# We'll use the red/"veggie"/blue bands with wavelengths 0.64, 0.86, and 0.47, respectively.
#
# This is close enough to RGB for today, but there's a great tutorial on getting closer to
# true color (and doing other fancy rendering tricks with GOES data!) here:
#
# https://unidata.github.io/python-gallery/examples/mapping_GOES16_TrueColor.html
#
r = dataset['CMI_C02'].data; r = np.clip(r, 0, 1)
g = dataset['CMI_C03'].data; g = np.clip(g, 0, 1)
b = dataset['CMI_C01'].data; b = np.clip(r, 0, 1)

# Brighten the image a bit for to look more stylish
gamma = 2.5; r = np.power(r, 1/gamma); g = np.power(g, 1/gamma); b = np.power(b, 1/gamma)

# Create a single RGB image for plotting
rgb = np.dstack((r, g, b))
Scan starts at: 2020-01-02T14:00:21.8Z
Scan ends at: 2020-01-02T14:09:53.7Z

Plot the image

In [10]:
fig = plt.figure(figsize=(7.5, 7.5), dpi=100)

# This definitely looks slicker with fancy borders on, at the cost of some extra
# imports.
show_fancy_borders = True

if not show_fancy_borders:
    
    plt.imshow(rgb); ax = plt.gca(); ax.axis('off');

else:
    
    import metpy
    import cartopy.crs as ccrs

    # Pick an arbitrary channel to get the x/y coordinates and projection information 
    # associated with the scan
    dummy_channel = dataset.metpy.parse_cf('CMI_C01')
    x = dummy_channel.x; y = dummy_channel.y

    ax = fig.add_subplot(1, 1, 1, projection=dummy_channel.metpy.cartopy_crs)
    ax.imshow(rgb, origin='upper', extent=(x.min(), x.max(), y.min(), y.max()))
    ax.coastlines(resolution='50m', color='black')
    ax.add_feature(ccrs.cartopy.feature.BORDERS);

Clean up temporary files

In [ ]:
shutil.rmtree(temp_dir)