Ignora esplorazione

GOES-16

SatelliteImagery EarthObservation AIforEarth NOAA

Immagini meteorologiche dal satellite GOES-16.

Il programma GOES-R (Geostationary Operational Environmental Satellite) crea immagini di fenomeni meteorologici da un set di satelliti in orbita geostazionaria. Il satellite GOES-16 è il primo di quattro satelliti GOES-R pianificati. L’orbita di GOES-16 fornisce una panoramica delle Americhe.

Questo set di dati include attualmente il prodotto ABI-L2-MCMIPF (Advanced Baseline Imager, Level 2, Cloud and Moisture Imagery, Full-disk) e il prodotto ABI-L1b-RadF (Advanced Baseline Imager, Level 1b, Full-disk). È possibile eseguire l’onboarding di altri prodotti GOES-16 e GOES-17 su richiesta. Contatta aiforearthdatasets@microsoft.com se sei interessato a usare dati di GOES aggiuntivi in Azure.

Questo set di dati è disponibile in Azure grazie al NOAA Big Data Program.

Risorse di archiviazione

I dati vengono archiviati in BLOB in formato NetCDF (un BLOB per immagine) nel data center dell’area Stati Uniti orientali nel contenitore BLOB seguente:

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

Entro tale contenitori i dati sono denominati come:

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

  • product corrisponde al nome del prodotto. ABI-L2-MCMIPF e ABI-L1b-RadF sono attualmente disponibili in Azure
  • year indica l’anno in quattro cifre
  • day è un codice di tre cifre che indica il giorno dell’anno, a partire da 001
  • hour è un codice di due cifre che indica l’ora del giorno, a partire da 00
  • filename codifica il prodotto, la data e l’ora. I dettagli sono disponibili nella guida per gli utenti di GOES

Ad esempio, questo file:

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

…contiene dati dal 3 gennaio 2020, per un intervallo di tempo compreso tra mezzanotte e l’1:00 UTC (ora 00).

I canali di dati e le lunghezze d’onda sono illustrati qui.

Un esempio Python completo per l’accesso e il tracciamento di un’immagine GOES-16 è disponibile nel notebook fornito in “Accesso ai dati”.

È disponibile anche un token di firma di accesso condiviso di sola lettura per consentire l’accesso ai dati GOES-16 tramite ad esempio BlobFuse, che ti permette di montare i contenitori BLOB come unità:

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

Le istruzioni di montaggio per Linux sono disponibili qui.

L’elaborazione su larga scala con questo set di dati risulta ottimale nel data center dell’area Stati Uniti orientali, in cui sono archiviati i dati. Se usi i dati GOES per applicazioni correlate alle scienze ambientali, prendi in considerazione la richiesta di una sovvenzione di AI for Earth per supportare i tuoi requisiti di calcolo.

Citazione

Se usi questi dati in una pubblicazione, includi questa citazione:

GOES-R Series Program, (2019): NOAA GOES-R Series Advanced Baseline Imager (ABI) Level 0 Data. [indica il subset usato]. NOAA National Centers for Environmental Information. doi:10.25921/tvws-w071.

Immagine piacevole


Immagini relative al tasso di umidità delle Americhe il 2 gennaio 2020.

Contatto

Se hai domande su questo set di dati, contatta aiforearthdatasets@microsoft.com.

Notifiche

MICROSOFT FORNISCE I SET DI DATI APERTI DI AZURE “COSÌ COME SONO”. MICROSOFT NON OFFRE ALCUNA GARANZIA O CONDIZIONE ESPLICITA O IMPLICITA RELATIVAMENTE ALL’USO DEI SET DI DATI DA PARTE DELL’UTENTE. NELLA MISURA MASSIMA CONSENTITA DALLE LEGGI LOCALI, MICROSOFT NON RICONOSCE ALCUNA RESPONSABILITÀ RELATIVAMENTE A DANNI O PERDITE COMMERCIALI, INCLUSI I DANNI DIRETTI, CONSEQUENZIALI, SPECIALI, INDIRETTI, INCIDENTALI O PUNITIVI DERIVANTI DALL’USO DEI SET DI DATI DA PARTE DELL’UTENTE.

Questo set di dati viene fornito in conformità con le condizioni originali in base alle quali Microsoft ha ricevuto i dati di origine. Il set di dati potrebbe includere dati provenienti 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)