Mofified 2014/Nov/20 -- I added new functions to orbit_tools.py:
draw_orbit_pha -- a modification of draw_orbit that returns a basemap instance so that you can modify the map (edit the title etc.), redraw it and print it to a file
draw_CloudSat_1Dvar_pha -- like draw_CloudSat_1Dvar but returns the figure instance for future plotting and to print to a file
draw_CloudSat_2Dvar_pha -- like draw_CloudSat_1Dvar but returns a figure instance
CloudSat_tools
;The files required for this notebook are at http://clouds.eos.ubc.ca/~phil/Downloads/a301/radar :
2006303212128_02702_CS_2B-GEOPROF_GRANULE_P_R04_E02.h5
2006303212128_02702_CS_2B-GEOPROF-LIDAR_GRANULE_P2_R04_E02.h5
2006303212128_02702_CS_2C-RAIN-PROFILE_GRANULE_P_R04_E02.h5
2006303212128_02702_CS_ECMWF-AUX_GRANULE_P_R04_E02.h5
Files above are CloudSat L2 and AUX products, Granule 02702, observed on Oct 30 2006. They are archived and downloaded in hdf format and converted to hdf5 files using http://www.hdfgroup.org/h4toh5/download.html
You have already ready the Bulletin of the AMS article article on cloudsat. Make sure you have looked at the dataset descriptions in Table 3, p. 1784 to get an idea of how the datasets are organized into individual files. For some more general background:
CloudSat is a NASA Earth observation satellite, which was launched on a Delta II rocket on April 28, 2006. It uses radar to measure the altitude and properties of clouds, adding to information on the relationship between clouds and climate in order to help resolve questions about global warming.
CloudSat flies in formation in the "A Train", with several other satellites: Aqua, Aura, CALIPSO and the French PARASOL.
The mission was selected under NASA's Earth System Science Pathfinder program in 1999. Ball Aerospace & Technologies Corp. in Boulder, Colorado, designed and built the spacecraft.
CloudSat's primary mission was scheduled to continue for 22 months in order to allow more than one seasonal cycle to be observed.
*CloudSat Project* Page at Dept. of Atmospheric Science, Colorado State U.
CloudSat was selected as a NASA Earth System Science Pathfinder satellite mission in 1999 to provide observations necessary to advance our understanding of cloud abundance, distribution, structure, and radiative properties. Since 2006, CloudSat has flown the first satellite-based millimeter-wavelength cloud radar—a radar that is more than 1000 times more sensitive than existing weather radars. Unlike ground-based weather radars that use centimeter wavelengths to detect raindrop-sized particles, CloudSat's radar allows us to detect the much smaller particles of liquid water and ice that constitute the large cloud masses that make our weather.
CloudSat was co-manifested with the CALIPSO (Cloud-Aerosol Lidar and Infrared Pathfinder Satellite Observations) satellite aboard a Delta II rocket for its launch on 28 April 2006. In a series of maneuvers, CloudSat and CALIPSO joined three satellites already in orbit ( Aqua, PARASOL, and Aura) to form a constellation of satellites known as the A-Train on 1 June 2006. The satellites fly in a nearly circular orbit with an equatorial altitude of approximately 705 km. The orbit is sun-synchronous, maintaining a roughly fixed angle between the orbital plane and the mean solar meridian. CloudSat maintains a close formation with Aqua and a particularly close formation with CALIPSO, providing near-simultaneous and collocated observations with the instruments on these two platforms. Combined data products are in development using data streams from CloudSat + Aqua and CloudSat + CALIPSO.
Register in the **CloudSat Data Processing Center** and look at the data product information.
Here is a list of CloudSat data product with descriptions:
Standard Data Product | Description |
---|---|
1B-CPR | L1B Radar Backscatter Profiles. Including received echo power |
2B-GEOPROF | L2B Cloud Geometrical Profile. Including cloud mask, radar reflectivities |
2B-CLDCLASS | L2B Cloud Classification |
2B-CWC-RO | L2B Radar-only Liquid/Ice Water Content |
2B-TAU | L2B Cloud Optical Depth |
2B-CWC-RVOD | L2B Radar Liquid/Ice Water Content plus Visible Optical Depth |
2B-FLXHR | L2B Radiative fluxes and heating rates |
2B-GEOPROF-LIDAR | L2B CloudSat CPR plus CALIPSO Lidar Cloud mask |
2B-CLDCLASS-LIDAR | L2B Cloud Clasification from CPR and CALIPO Lidar | _
2C-RAIN-PROFILE | L2C Cloud Rain Rate and Liquid/Ice Water Content |
2C-PRECIP-COLUMN | L2C Column Integrated Precipitation |
2C-CLOUDSAT-TRMM | L2C CloudSat Cloud Mask plus L2 TRMM at Orbit Intersections |
Auxiliary Products | Description |
ECMWF-AUX | ECMWF Auxiliary Data (State Variables) |
MODIS-AUX | MODIS Auxiliary Data (Data from 22 MODIS Channels) |
Here we only use Standard L2 datasets 2B-GEOPROF, 2B-GEOPROF-LIDAR, 2C-RAIN-PROFILE and Auxiliary Product ECMWF-AUX.
Enter in the CloudSat **Quicklook Image Archive**, select the date, time and check the orbit track in Granule number, see if the image agrees with your idea or not.
After a careful look, we choose 10/30/2006, Granule 02702.
Once you have made your choice, you can go to **Data Order System**. Do the following steps:
We need two new modules to parse the Cloudsat data files. cloudsat_tool.py is a module that contains read functions for the various cloudsat fields. orbit_tool.py contains functions to plot a Cloudsat orbit on a global map. The routines are in lib/cloudsat, so add this to our path:
In [0]:
import site
site.addsitedir('../lib/cloudsat')
In [0]:
from __future__ import division
from __future__ import print_function
import glob
import h5py
import scipy.io
import numpy as np
#
from matplotlib import pyplot as plt
import orbit_tool as OT
import cloudsat_tool as CT
reload(OT)
reload(CT)
#
In [0]:
% matplotlib inline
Searching required *.h5 files in the data directory.
In [0]:
hdf5_radar=glob.glob('../data/*CS_2B-GEOPROF_GRANULE*.h5')
print("2B-GEOPROF file found\n{}".format(hdf5_radar))
print("==================================================================")
hdf5_lidar=glob.glob('../data/*2B-GEOPROF-LIDAR*.h5')
print("2B-GEOPROF-LIDAR file found\n{}".format(hdf5_lidar))
print("==================================================================")
hdf5_rain=glob.glob('../data/*2C-RAIN-PROFILE*.h5')
print("2C-RAIN-PROFILE file found\n{}".format(hdf5_rain))
print("==================================================================")
hdf5_EC=glob.glob('../data/*ECMWF-AUX*.h5')
print("ECMWF-AUX file found\n{}".format(hdf5_EC))
In [0]:
help(CT.get_geo)
lat, lon, date_day, prof_sec, dem_elev = CT.get_geo(hdf5_radar[0], 1)
In [0]:
help(CT.read_ecmwf)
In [0]:
height, reflect = CT.read_radar(hdf5_radar[0], maskid=2)
CFrac, LayerTop, LayerBase = CT.read_lidar(hdf5_lidar[0], maskid=2)
rain, precli, precice, clw = CT.read_rain(hdf5_rain[0], maskid=2)
P, SLP, T, T2m, SKT, q, O3 = CT.read_ecmwf(hdf5_EC[0], maskid=2)
In [0]:
#help(dOrbit.draw_orbit)
lonlim=[-330, 120]; latlim=[-90, 90]
proj=OT.draw_orbit_pha(hdf5_radar[0], lonlim, latlim, time_step=625, label_step=2)
proj.ax.figure.canvas.draw()
proj.ax.figure.savefig('Cloudsat_orbit.png')
We can restrict that part of the orbit we want to look at using a function in the orbit_tools module called segment_orbit which uses the numpy searchsorted function to select a subset of the orbit
Suppose we want to find only those data points with nadir latitudes in the range:
$35^\circ N < Latitude < 52^\circ N$
In [0]:
xlim_indices = OT.segment_orbit(lat, [35, 52])
Python lets you create a slice object that allows you to keep a slice as a variable, which we'll call segment
In [0]:
segment=slice(xlim_indices[0],xlim_indices[1])
time_seg=date_day[segment]
elev_seg=dem_elev[segment]
lat_seg=lat[segment]
lon_seg=lon[segment];lon_seg=lon_seg[::-1]
height_seg=height[segment, :]
# reflectivity
reflect_seg=reflect[segment, :]
# cloud top height
LayerTop_seg=LayerTop[segment, :]
# rain rate
rain_seg=rain[segment]
# cloud liquid water
clw_seg=clw[segment, :]
# pressure, temperature, humidity
P_seg=P[segment, :]
T_seg=T[segment, :]
q_seg=q[segment, :]
Here is a series of figures of variables in CloudSat products.
Currently, draw_CloudSat_1Dvar
and draw_CloudSat_2Dvar
in orbit_tool
provide a basic visualization of ClouSat variables.
I made them work through following input sequence:
OT.draw_CloudSat_1Dvar(lon, lat, time, 1Dvar, 'var_name ( unit )', 'title_name', 'figures/03_fig_name.png')
OT.draw_CloudSat_2Dvar(lon, lat, height, elev, time, 2Dvar, colormap, \
'var_name ( unit )', 'title_name', '_figures/03_fig_name.png')
For 2-D variables, we need to expand the dimension of geolocation field to 2-D, here we use longitude:
In [0]:
height_mesh, lon_seg_mesh=np.meshgrid(height_seg[0, :], lon_seg)
In [0]:
granule_id=hdf5_radar[0][-40:-35]
orbit_start=time_seg[0].strftime('%Y%M%d')
title="""CloudSat CloudSat Rain Rate starting at {}
for Granule Number: {}
""".format(orbit_start,granule_id)
figure=OT.draw_CloudSat_1Dvar_pha(lon_seg, lat_seg, time_seg, rain_seg,
'CloudSat Rain Rate ( mm/hr )', title)
figure.canvas.draw()
figure.savefig('Cloudsat_rainrate.png')
In [0]:
title="""CloudSat Lidar Cloud Top Height starting at {}
for Granule Number: {}
""".format(orbit_start,granule_id)
figure=OT.draw_CloudSat_1Dvar_pha(lon_seg, lat_seg, time_seg, LayerTop_seg[:, 0], 'Lidar Cloud Top Height( km )', \
title)
figure.canvas.draw()
figure.savefig('lidar_cloudtop.png')
In [0]:
title="""CloudSat Radar reflectivity starting at {}
for Granule Number: {}
""".format(orbit_start,granule_id)
fig=OT.draw_CloudSat_2Dvar_pha(lon_seg_mesh, lat_seg, height_seg, elev_seg, time_seg, reflect_seg, plt.cm.jet,\
'Radar Reflectivity ( dbZ )', title)
fig.canvas.draw()
fig.savefig('Cloudsat_reflect.png')
In [0]:
title="""CloudSat Liquid water starting at {}
for Granule Number: {}
""".format(orbit_start,granule_id)
fig=OT.draw_CloudSat_2Dvar_pha(lon_seg_mesh, lat_seg, height_seg, elev_seg, time_seg, clw_seg/1e3, plt.cm.YlGnBu,\
'Cloud Liquid Water ( $\mathrm{kg/m^3}$ )', title)
fig.canvas.draw()
fig.savefig('Cloudsat_clw.png')
Pressure
In [0]:
title="""CloudSat ECMWF pressure starting at {}
for Granule Number: {}
""".format(orbit_start,granule_id)
fig=OT.draw_CloudSat_2Dvar_pha(lon_seg_mesh, lat_seg, height_seg, elev_seg, time_seg, P_seg, plt.cm.jet,\
'Pressure ( hPa )', title)
fig.canvas.draw()
fig.savefig('Cloudsat_pressure.png')
Temperature
In [0]:
title="""CloudSat ECMWF temperature starting at {}
for Granule Number: {}
""".format(orbit_start,granule_id)
fig=OT.draw_CloudSat_2Dvar_pha(lon_seg_mesh, lat_seg, height_seg, elev_seg, time_seg, T_seg, plt.cm.jet,\
'Temperature ( K )', title)
fig.canvas.draw()
fig.savefig('Cloudsat_temp.png')
Specific Humidity
In [0]:
title="""CloudSat ECMWF specific humidity starting at {}
for Granule Number: {}
""".format(orbit_start,granule_id)
fig=OT.draw_CloudSat_2Dvar_pha(lon_seg_mesh, lat_seg, height_seg, elev_seg, time_seg, q_seg*1e3, plt.cm.gist_ncar_r,\
'Specific Humidity ( g/kg )', title)
fig.canvas.draw()
fig.savefig('Cloudsat_qv.png')
In [0]: