탐색 건너뛰기

GOES-16

SatelliteImagery EarthObservation AIforEarth NOAA

GOES-16 위성의 기상 이미지.

GOES-R(정지 운용 환경 위성) 프로그램은 정지 궤도의 위성에서 보내는 기상 현상을 이미지로 만듭니다. GOES-16 위성은 계획된 4개의 GOES-R 위성 중 첫 번째이며, GOES-16의 궤도는 아메리카 대륙을 보여 줍니다.

이 데이터 세트에는 현재 ABI-L2-MCMIPF 제품(Advanced Baseline Imager, 2, Cloud and Moisture Imagery, Full-disk) 및 ABI-L1b-RadF 제품(Advanced Baseline Imager, 1b, Full-disk)이 포함됩니다. 요청 시 다른 GOES-16 및 GOES-17 제품을 온보딩할 수 있습니다. Azure에서 추가 GOES 데이터를 사용하려면 aiforearthdatasets@microsoft.com으로 문의하세요.

이 데이터 세트는 NOAA Big Data Program(NOAA 빅 데이터 프로그램) 덕분에 Azure에서 사용 가능합니다.

스토리지 리소스

데이터는 미국 동부 데이터 센터에 있는 다음 Blob 컨테이너의 Blob(이미지당 Blob 하나)에 NetCDF 형식으로 저장됩니다.

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

해당 컨테이너 내에서 데이터의 이름은 다음과 같이 지정됩니다.

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

  • 제품은 제품 이름입니다. 현재 ABI-L2-MCMIPF 및 ABI-L1b-RadF를 Azure에서 사용할 수 있습니다.
  • year는 4자리 연도입니다.
  • day는 001로 시작하는 3자리 연간 일자 코드입니다.
  • hour는 00으로 시작하는 2자리 시간 코드입니다.
  • filename은 제품, 날짜 및 시간을 인코딩합니다. 자세한 내용은 GOES Users’ Guide(GOES 사용자 가이드)를 참조하세요.

예를 들어 이 파일에는

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

2020년 1월 3일 자정에서 새벽 1시 UTC(hour 00) 사이의 데이터가 들어 있습니다.

데이터 채널 및 wavelength는 여기에 설명되어 있습니다.

GOES-16 이미지에 액세스하고 GOES-16 이미지를 그리는 전체 Python 예제는 “데이터 액세스” 아래에서 제공되는 Notebook에서 사용할 수 있습니다.

또한 Blob 컨테이너를 드라이브로 탑재할 수 있게 해주는 BlobFuse 등을 통해 GOES-16 데이터에 액세스할 수 있는 읽기 전용 SAS(공유 액세스 서명) 토큰을 제공합니다.

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

Linux용 탑재 지침은 여기에 있습니다.

이 데이터 세트를 사용한 대규모 처리는 데이터가 저장된 미국 동부 Azure 데이터 센터에서 가장 잘 수행됩니다. 환경 과학 응용 분야에 GOES 데이터를 사용 중인 경우 컴퓨팅 요구 사항을 지원하려면 AI for Earth 보조금 신청을 고려해 보세요.

인용

이 데이터를 게시물에서 사용하려는 경우 다음과 같이 인용하세요.

GOES-R 시리즈 프로그램,(2019): NOAA GOES-R 시리즈 ABI(Advanced Baseline Imager) 레벨 0 데이터. [사용한 하위 집합을 나타냅니다]. NOAA National Centers for Environmental Information. doi:10.25921/tvws-w071.

멋진 사진


2020년 1월 2일 아메리카의 수분 이미지입니다.

연락처

이 데이터 세트에 대한 질문이 있는 경우 aiforearthdatasets@microsoft.com으로 문의하세요.

알림

Microsoft는 Azure Open Datasets를 “있는 그대로” 제공합니다. Microsoft는 귀하의 데이터 세트 사용과 관련하여 어떠한 명시적이거나 묵시적인 보증, 보장 또는 조건을 제공하지 않습니다. 귀하가 거주하는 지역의 법규가 허용하는 범위 내에서 Microsoft는 귀하의 데이터 세트 사용으로 인해 발생하는 일체의 직접적, 결과적, 특별, 간접적, 부수적 또는 징벌적 손해 또는 손실을 비롯한 모든 손해 또는 손실에 대한 모든 책임을 부인합니다.

이 데이터 세트는 Microsoft가 원본 데이터를 받은 원래 사용 약관에 따라 제공됩니다. 데이터 세트에는 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)