Python Short Demo: Open a Satellite .nc File using the netCDF4 Library

The netCDF4 Python library automatically performs a number of data processing actions when opening a satellite data file. These actions, described below, facilitate the efficient and correct use of satellite data.

Please acknowledge the NOAA/NESDIS/STAR Aerosols and Atmospheric Composition Science Team if using any of this code in your work/research!

# Library to work with netCDF files
from netCDF4 import Dataset

# Open a .nc file ("file_name")
file_id = Dataset(file_name)

Demonstration of how to use the function: The user enters the "directory_path" (directory where the .nc file is located) and "file_name" (name of .nc file). In this example, the directory is assumed to be the current working directory (cwd), set using the pathlib module, and the .nc file is a GOES-17 ABI Mesoscale 1 sector FDC (fire/hot spot characterization) file for Aug 17, 2021 (Julian day 229) at 14:00 UTC.

As demonstrated below, the Dataset constructor in the netCDF4 library reads the file metadata and automatically:

  • Masks values outside the data valid range
  • Masks any invalid "fill" values
  • Applies a "scale factor" and "add offset" to convert any data stored as integers to floating point numbers

The default for the Dataset constructor is to open an .nc file in "read-only" mode, so it is not necessary to explicitly specify mode="r" as an argument if you are opening a .nc file in order to read its contents.

# Import Python packages

# Library to perform array operations
import numpy as np 

# Module to set filesystem paths appropriate for user's operating system
from pathlib import Path

# Enter directory and file name for .nc data file
directory_path = Path.cwd()  # Current working directory
file_name = 'OR_ABI-L2-FDCM1-M6_G17_s20212291400255_e20212291400312_c20212291400457.nc'
file_path = directory_path / file_name

# Open the file using the netCDF4 library
file_id = Dataset(file_path)

# Print the metadata for the "Power" variable
print(file_id.variables['Power'])

<class 'netCDF4._netCDF4.Variable'>
float32 Power(y, x)
    _FillValue: -9.0
    long_name: ABI L2+ Fire-Hot Spot Characterization: Fire Radiative Power
    standard_name: fire_radiative_power
    valid_range: [     0. 200000.]
    units: MW
    resolution: y: 0.000056 rad x: 0.000056 rad
    coordinates: sunglint_angle local_zenith_angle solar_zenith_angle t y x
    grid_mapping: goes_imager_projection
    cell_measures: area: Area
    cell_methods: sunglint_angle: point (no pixel produced) local_zenith_angle: point (good quality pixel produced) solar_zenith_angle: point (good quality pixel produced) t: point
    ancillary_variables: DQF
unlimited dimensions: 
current shape = (500, 500)
filling on

Notice the listed "valid_range" of [0, 200000] and the "_FillValue" of -9.0 for the fire radiative power (FRP) variable. The valid range is the possible valid extent (min/max) of data, and the fill value is the value for invalid data. The Dataset constructor reads the metadata and masks cells in the data array that contain the fill value or contain values above/below the valid range. If we print the data array, we can see masked pixels denoted by two dashes (--). We can also print the maximum and minimum values in the array to confirm they fall within the stated valid range.

# Read in fire radiative power (FRP) data
# Metadata indicates data are 2-dimensional so use [:,:] to extract all data in 2 dimensions
abi_frp = file_id.variables['Power'][:,:]

# Print FRP array
# netCDF4 library automatically masks (--) invalid data & data outside of valid range
print(abi_frp)

# Print max and min of FRP array to check data range
print('The maximum FRP value is', np.max(abi_frp), file_id.variables['Power'].units)
print('The minimum FRP value is', np.min(abi_frp), file_id.variables['Power'].units)

[[-- -- -- ... -- -- --]
 [-- -- -- ... -- -- --]
 [-- -- -- ... -- -- --]
 ...
 [-- -- -- ... -- -- --]
 [-- -- -- ... -- -- --]
 [-- -- -- ... -- -- --]]
The maximum FRP value is 1730.8972 MW
The minimum FRP value is 28.789873 MW

# Print the metadata for the "x" variable
print(file_id.variables['x'])

<class 'netCDF4._netCDF4.Variable'>
int16 x(x)
    scale_factor: 5.6e-05
    add_offset: 0.022988
    units: rad
    axis: X
    long_name: GOES fixed grid projection x-coordinate
    standard_name: projection_x_coordinate
unlimited dimensions: 
current shape = (500,)
filling on, default _FillValue of -32767 used

Notice that the GOES fixed grid projection x-coordinate variable is stored in the .nc file as a 16-bit integer ("int16"), and the metadata includes a "scale_factor" and "add_offset" that can be used to convert the stored integers to floating point numbers ("float"). The Dataset constructor does this conversion automatically, multiplying the stored integers in the array by the "scale_factor" and adding the "add_offset". If we print the data array, we can see the values are indeed floating point numbers, and we can check the data type of an entry in the array to be certain it is "float".

# Read in GOES ABI fixed grid projection x-coordinate data
# Metadata indicates data are 1-dimensional so use [:] to extract all data in 1 dimension
x_coordinate = file_id.variables['x'][:]

# Metadata indicates data are stored as integers ("int16") in the .nc file
# netCDF4 library automatically applies "scale_factor" and "add_offset" to covnvert stored integers to floats
# Check data type of first value in array to confirm
print('Array data values are type', type(x_coordinate[0]))

# Print x-coordinate array
print(x_coordinate)

Array data values are type <class'numpy.float32'>

[0.022988 0.023044 0.0231   0.023156 0.023212 0.023268 0.023324 0.02338
 0.023436 0.023492 0.023548 0.023604 0.02366  0.023716 0.023772 0.023828
 0.023884 0.02394  0.023996 0.024052 0.024108 0.024164 0.02422  0.024276
 0.024332 0.024388 0.024444 0.0245   0.024556 0.024612 0.024668 0.024724
 0.02478  0.024836 0.024892 0.024948 0.025004 0.02506  0.025116 0.025172
 0.025228 0.025284 0.02534  0.025396 0.025452 0.025508 0.025564 0.02562
 0.025676 0.025732 0.025788 0.025844 0.0259   0.025956 0.026012 0.026068
 0.026124 0.02618  0.026236 0.026292 0.026348 0.026404 0.02646  0.026516
 0.026572 0.026628 0.026684 0.02674  0.026796 0.026852 0.026908 0.026964
 0.02702  0.027076 0.027132 0.027188 0.027244 0.0273   0.027356 0.027412
 0.027468 0.027524 0.02758  0.027636 0.027692 0.027748 0.027804 0.02786
 0.027916 0.027972 0.028028 0.028084 0.02814  0.028196 0.028252 0.028308
 0.028364 0.02842  0.028476 0.028532 0.028588 0.028644 0.0287   0.028756
 0.028812 0.028868 0.028924 0.02898  0.029036 0.029092 0.029148 0.029204
 0.02926  0.029316 0.029372 0.029428 0.029484 0.02954  0.029596 0.029652
 0.029708 0.029764 0.02982  0.029876 0.029932 0.029988 0.030044 0.0301
 0.030156 0.030212 0.030268 0.030324 0.03038  0.030436 0.030492 0.030548
 0.030604 0.03066  0.030716 0.030772 0.030828 0.030884 0.03094  0.030996
 0.031052 0.031108 0.031164 0.03122  0.031276 0.031332 0.031388 0.031444
 0.0315   0.031556 0.031612 0.031668 0.031724 0.03178  0.031836 0.031892
 0.031948 0.032004 0.03206  0.032116 0.032172 0.032228 0.032284 0.03234
 0.032396 0.032452 0.032508 0.032564 0.03262  0.032676 0.032732 0.032788
 0.032844 0.0329   0.032956 0.033012 0.033068 0.033124 0.03318  0.033236
 0.033292 0.033348 0.033404 0.03346  0.033516 0.033572 0.033628 0.033684
 0.03374  0.033796 0.033852 0.033908 0.033964 0.03402  0.034076 0.034132
 0.034188 0.034244 0.0343   0.034356 0.034412 0.034468 0.034524 0.03458
 0.034636 0.034692 0.034748 0.034804 0.03486  0.034916 0.034972 0.035028
 0.035084 0.03514  0.035196 0.035252 0.035308 0.035364 0.03542  0.035476
 0.035532 0.035588 0.035644 0.0357   0.035756 0.035812 0.035868 0.035924
 0.03598  0.036036 0.036092 0.036148 0.036204 0.03626  0.036316 0.036372
 0.036428 0.036484 0.03654  0.036596 0.036652 0.036708 0.036764 0.03682
 0.036876 0.036932 0.036988 0.037044 0.0371   0.037156 0.037212 0.037268
 0.037324 0.03738  0.037436 0.037492 0.037548 0.037604 0.03766  0.037716
 0.037772 0.037828 0.037884 0.03794  0.037996 0.038052 0.038108 0.038164
 0.03822  0.038276 0.038332 0.038388 0.038444 0.0385   0.038556 0.038612
 0.038668 0.038724 0.03878  0.038836 0.038892 0.038948 0.039004 0.03906
 0.039116 0.039172 0.039228 0.039284 0.03934  0.039396 0.039452 0.039508
 0.039564 0.03962  0.039676 0.039732 0.039788 0.039844 0.0399   0.039956
 0.040012 0.040068 0.040124 0.04018  0.040236 0.040292 0.040348 0.040404
 0.04046  0.040516 0.040572 0.040628 0.040684 0.04074  0.040796 0.040852
 0.040908 0.040964 0.04102  0.041076 0.041132 0.041188 0.041244 0.0413
 0.041356 0.041412 0.041468 0.041524 0.04158  0.041636 0.041692 0.041748
 0.041804 0.04186  0.041916 0.041972 0.042028 0.042084 0.04214  0.042196
 0.042252 0.042308 0.042364 0.04242  0.042476 0.042532 0.042588 0.042644
 0.0427   0.042756 0.042812 0.042868 0.042924 0.04298  0.043036 0.043092
 0.043148 0.043204 0.04326  0.043316 0.043372 0.043428 0.043484 0.04354
 0.043596 0.043652 0.043708 0.043764 0.04382  0.043876 0.043932 0.043988
 0.044044 0.0441   0.044156 0.044212 0.044268 0.044324 0.04438  0.044436
 0.044492 0.044548 0.044604 0.04466  0.044716 0.044772 0.044828 0.044884
 0.04494  0.044996 0.045052 0.045108 0.045164 0.04522  0.045276 0.045332
 0.045388 0.045444 0.0455   0.045556 0.045612 0.045668 0.045724 0.04578
 0.045836 0.045892 0.045948 0.046004 0.04606  0.046116 0.046172 0.046228
 0.046284 0.04634  0.046396 0.046452 0.046508 0.046564 0.04662  0.046676
 0.046732 0.046788 0.046844 0.0469   0.046956 0.047012 0.047068 0.047124
 0.04718  0.047236 0.047292 0.047348 0.047404 0.04746  0.047516 0.047572
 0.047628 0.047684 0.04774  0.047796 0.047852 0.047908 0.047964 0.04802
 0.048076 0.048132 0.048188 0.048244 0.0483   0.048356 0.048412 0.048468
 0.048524 0.04858  0.048636 0.048692 0.048748 0.048804 0.04886  0.048916
 0.048972 0.049028 0.049084 0.04914  0.049196 0.049252 0.049308 0.049364
 0.04942  0.049476 0.049532 0.049588 0.049644 0.0497   0.049756 0.049812
 0.049868 0.049924 0.04998  0.050036 0.050092 0.050148 0.050204 0.05026
 0.050316 0.050372 0.050428 0.050484 0.05054  0.050596 0.050652 0.050708
 0.050764 0.05082  0.050876 0.050932]