Ceilometer#
Instrumentation#
The first Ceilometer from JenOptik (CHX090102) was installed with a special optical unit in 2010, but this setup proved to suffer from signal loss. As a result, a standard CHM15k was installed in 2011, and the original unit was removed in 2012. The CHM15k setup has been in operation from 2011 until now with time-varying serial numbers (CHM090102, then CHM140102, CHM170159, and CHM200113).
One near infrared laser probes the sky vertically from the instrument to about 15 km above it. Targets like aerosol layers and clouds show up as echoes with certain backscatter intensity and signal extinction. Molecular absorption and Rayleigh scattering by air molecules is negligible at a wavelength of 1064 nm, so the CHM 15k works based on a photon counting method. Photon counting is more accurate and sensitive than analog measurement techniques, which makes it well suited for applications such as this one with a small count rate. The distance from ground is calculated from the travelling time of the laser pulses.
Data Availability#
The data is available as .zarr files in the catalog as:
BCO.ceilometer_c1_v1(first setup with special optical unit: 2010-02-10 to 2012-03-10)BCO.ceilometer_c2_v1(second setup with standard unit: 2011-01-22 to 2011-10-01)BCO.ceilometer_c3_v1(second setup with standard unit, but providing high resolution signal as well: 2015-07-26 to now, pending discovery of other configurations)
Sample Plot#
Plot cloud base height for each cloud layer for the first period of the instrument’s operation in 2011:
import intake
cat = intake.open_catalog("https://tcodata.mpimet.mpg.de/catalog.yaml")
ds = cat.BCO.ceilometer_c2_v1.to_dask()
ds.sel(time="2011-01").cbh.plot(x='time', y='layer')
/builds/tco/bco/docs/.venv/lib/python3.12/site-packages/intake_xarray/base.py:21: FutureWarning: The return type of `Dataset.dims` will be changed to return a set of dimension names in future, in order to be more consistent with `DataArray.dims`. To access a mapping from dimension names to lengths, please use `Dataset.sizes`.
'dims': dict(self._ds.dims),
<matplotlib.collections.QuadMesh at 0x7f843d1316d0>
The full dataset:
ds
<xarray.Dataset> Size: 3GB
Dimensions: (time: 700092, range: 1024, layer: 3)
Coordinates:
lat float64 8B ...
* layer (layer) int32 12B 0 1 2
lon float64 8B ...
* range (range) float32 4kB 15.0 30.0 45.0 ... 1.534e+04 1.536e+04
sensor_alt int64 8B ...
* time (time) datetime64[ns] 6MB 2011-01-22T20:44:22.937000 .....
Data variables: (12/31)
average_time (time) int32 3MB dask.array<chunksize=(262144,), meta=np.ndarray>
azimuth (time) float32 3MB dask.array<chunksize=(262144,), meta=np.ndarray>
base (time) float32 3MB dask.array<chunksize=(262144,), meta=np.ndarray>
bcc (time) int8 700kB dask.array<chunksize=(262144,), meta=np.ndarray>
beta_raw (time, range) float32 3GB dask.array<chunksize=(8192, 32), meta=np.ndarray>
cbe (time, layer) float32 8MB dask.array<chunksize=(8192, 3), meta=np.ndarray>
... ...
temp_ext (time) float64 6MB dask.array<chunksize=(262144,), meta=np.ndarray>
temp_int (time) float64 6MB dask.array<chunksize=(262144,), meta=np.ndarray>
voe (time) int16 1MB dask.array<chunksize=(262144,), meta=np.ndarray>
vor (time) int16 1MB dask.array<chunksize=(262144,), meta=np.ndarray>
wavelength (time) float32 3MB dask.array<chunksize=(262144,), meta=np.ndarray>
zenith (time) float32 3MB dask.array<chunksize=(262144,), meta=np.ndarray>
Attributes:
_logical_cutoff_date: 2011-10-02T00:00:00Z- time: 700092
- range: 1024
- layer: 3
- lat()float64...
- long_name :
- north latitude
- units :
- degree_north
- valid_max :
- 90.0
- valid_min :
- -90.0
[1 values with dtype=float64]
- layer(layer)int320 1 2
- axis :
- layer
- long_name :
- Layer index
- units :
- index
array([0, 1, 2], dtype=int32)
- lon()float64...
- long_name :
- east longitude
- units :
- degree_east
- valid_max :
- 180.0
- valid_min :
- -180.0
[1 values with dtype=float64]
- range(range)float3215.0 30.0 ... 1.534e+04 1.536e+04
- axis :
- Z
- long_name :
- distance from lidar
- units :
- m
array([1.5000e+01, 3.0000e+01, 4.5000e+01, ..., 1.5330e+04, 1.5345e+04, 1.5360e+04], shape=(1024,), dtype=float32) - sensor_alt()int64...
- long_name :
- height above mean sea level
- standard_name :
- altitude
- units :
- m
[1 values with dtype=int64]
- time(time)datetime64[ns]2011-01-22T20:44:22.937000 ... 2...
- axis :
- T
- standard_name :
- time
- units_metadata :
- leap_seconds: utc
array(['2011-01-22T20:44:22.937000000', '2011-01-22T20:44:52.734000000', '2011-01-22T20:45:22.515000000', ..., '2011-09-30T18:38:01.140000000', '2011-09-30T18:38:31.453000000', '2011-09-30T18:39:01.312000000'], shape=(700092,), dtype='datetime64[ns]')
- average_time(time)int32dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- average time per record
- units :
- ms
Array Chunk Bytes 2.67 MiB 1.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int32 numpy.ndarray - azimuth(time)float32dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- laser direction of site
- units :
- degree_clockwise
Array Chunk Bytes 2.67 MiB 1.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type float32 numpy.ndarray - base(time)float32dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- Daylight correction factor, photons per shot
- units :
- counts
Array Chunk Bytes 2.67 MiB 1.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type float32 numpy.ndarray - bcc(time)int8dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- Base Cloud Cover
- standard_name :
- cloud_area_fraction
Array Chunk Bytes 683.68 kiB 256.00 kiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int8 numpy.ndarray - beta_raw(time, range)float32dask.array<chunksize=(8192, 32), meta=np.ndarray>
- long_name :
- background substracted and normilised by laser shot number and stddev
- units :
- SNR
Array Chunk Bytes 2.67 GiB 1.00 MiB Shape (700092, 1024) (8192, 32) Dask graph 2752 chunks in 2 graph layers Data type float32 numpy.ndarray - cbe(time, layer)float32dask.array<chunksize=(8192, 3), meta=np.ndarray>
- long_name :
- cloud base height variation
- units :
- m
Array Chunk Bytes 8.01 MiB 96.00 kiB Shape (700092, 3) (8192, 3) Dask graph 86 chunks in 2 graph layers Data type float32 numpy.ndarray - cbh(time, layer)float32dask.array<chunksize=(8192, 3), meta=np.ndarray>
- axis :
- range
- long_name :
- cloud base height
- standard_name :
- cloud_base_altitude
- units :
- m
Array Chunk Bytes 8.01 MiB 96.00 kiB Shape (700092, 3) (8192, 3) Dask graph 86 chunks in 2 graph layers Data type float32 numpy.ndarray - cde(time, layer)float32dask.array<chunksize=(8192, 3), meta=np.ndarray>
- long_name :
- cloud depth variation
- units :
- m
Array Chunk Bytes 8.01 MiB 96.00 kiB Shape (700092, 3) (8192, 3) Dask graph 86 chunks in 2 graph layers Data type float32 numpy.ndarray - cdp(time, layer)float32dask.array<chunksize=(8192, 3), meta=np.ndarray>
- long_name :
- cloud depth
- units :
- m
Array Chunk Bytes 8.01 MiB 96.00 kiB Shape (700092, 3) (8192, 3) Dask graph 86 chunks in 2 graph layers Data type float32 numpy.ndarray - error_ext(time)int32dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- 31 Bit ServiceCode
Array Chunk Bytes 2.67 MiB 1.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int32 numpy.ndarray - laser_pulses(time)int32dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- number of laser pulses averaged per record
- units :
- unitless
Array Chunk Bytes 2.67 MiB 1.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int32 numpy.ndarray - life_time(time)int32dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- h
- units :
- Laser fife time
Array Chunk Bytes 2.67 MiB 1.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int32 numpy.ndarray - mxd(time)int16dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- maximum detection height
- units :
- m
Array Chunk Bytes 1.34 MiB 512.00 kiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int16 numpy.ndarray - nn1(time)int16dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- NN1
- units :
- NAN
Array Chunk Bytes 1.34 MiB 512.00 kiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int16 numpy.ndarray - pbl(time, layer)float32dask.array<chunksize=(8192, 3), meta=np.ndarray>
- axis :
- range
- long_name :
- Aerosol Layer in PBL
- units :
- m
Array Chunk Bytes 8.01 MiB 96.00 kiB Shape (700092, 3) (8192, 3) Dask graph 86 chunks in 2 graph layers Data type float32 numpy.ndarray - pbs(time, layer)float32dask.array<chunksize=(8192, 3), meta=np.ndarray>
- long_name :
- Quality score for aerosol Layer in PBL
Array Chunk Bytes 8.01 MiB 96.00 kiB Shape (700092, 3) (8192, 3) Dask graph 86 chunks in 2 graph layers Data type float32 numpy.ndarray - range_gate(time)float32dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- length of range gate, binwidth
- units :
- m
Array Chunk Bytes 2.67 MiB 1.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type float32 numpy.ndarray - sci(time)int8dask.array<chunksize=(262144,), meta=np.ndarray>
- definition :
- 0: nothing 1: rain 2: fog 3: snow
- long_name :
- Sky Condition Index
Array Chunk Bytes 683.68 kiB 256.00 kiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int8 numpy.ndarray - sensor_serial_no(time)uint16dask.array<chunksize=(262144,), meta=np.ndarray>
- flag_meanings :
- ['CHX090102', 'CHM090102', 'CHM170159', 'CHM140102', 'CHM200113', 'unknown']
- flag_values :
- [1, 2, 3, 4, 5, 0]
Array Chunk Bytes 1.34 MiB 512.00 kiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type uint16 numpy.ndarray - state_detector(time)int16dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- quality of detector signal - 255 max
- units :
- unitless
Array Chunk Bytes 1.34 MiB 512.00 kiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int16 numpy.ndarray - state_laser(time)int16dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- laser quality index - 255 max
- units :
- unitless
Array Chunk Bytes 1.34 MiB 512.00 kiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int16 numpy.ndarray - state_optics(time)int16dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- transmission of optics
- units :
- unitless
Array Chunk Bytes 1.34 MiB 512.00 kiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int16 numpy.ndarray - stddev(time)float32dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- Standard Deviation raw signal, photons/ shot
- units :
- counts
Array Chunk Bytes 2.67 MiB 1.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type float32 numpy.ndarray - tcc(time)int8dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- Total Cloud Cover
Array Chunk Bytes 683.68 kiB 256.00 kiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int8 numpy.ndarray - temp_det(time)float64dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- detector temperature
- units :
- K
Array Chunk Bytes 5.34 MiB 2.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type float64 numpy.ndarray - temp_ext(time)float64dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- external temperature
- units :
- K
Array Chunk Bytes 5.34 MiB 2.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type float64 numpy.ndarray - temp_int(time)float64dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- internal temperature
- units :
- K
Array Chunk Bytes 5.34 MiB 2.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type float64 numpy.ndarray - voe(time)int16dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- vertical optical range error
- units :
- m
Array Chunk Bytes 1.34 MiB 512.00 kiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int16 numpy.ndarray - vor(time)int16dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- vertical optical range
- units :
- m
Array Chunk Bytes 1.34 MiB 512.00 kiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type int16 numpy.ndarray - wavelength(time)float32dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- laser wavelength
- units :
- nm
Array Chunk Bytes 2.67 MiB 1.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type float32 numpy.ndarray - zenith(time)float32dask.array<chunksize=(262144,), meta=np.ndarray>
- long_name :
- laser direction of site
- units :
- degree
Array Chunk Bytes 2.67 MiB 1.00 MiB Shape (700092,) (262144,) Dask graph 3 chunks in 2 graph layers Data type float32 numpy.ndarray
- layerPandasIndex
PandasIndex(Index([0, 1, 2], dtype='int32', name='layer'))
- rangePandasIndex
PandasIndex(Index([ 15.0, 30.0, 45.0, 60.0, 75.0, 90.0, 105.0, 120.0, 135.0, 150.0, ... 15225.0, 15240.0, 15255.0, 15270.0, 15285.0, 15300.0, 15315.0, 15330.0, 15345.0, 15360.0], dtype='float32', name='range', length=1024)) - timePandasIndex
PandasIndex(DatetimeIndex(['2011-01-22 20:44:22.937000', '2011-01-22 20:44:52.734000', '2011-01-22 20:45:22.515000', '2011-01-22 20:45:52.812000', '2011-01-22 20:46:22.609000', '2011-01-22 20:46:52.890000', '2011-01-22 20:47:22.687000', '2011-01-22 20:47:52.484000', '2011-01-22 20:48:22.781000', '2011-01-22 20:48:52.609000', ... '2011-09-30 18:33:10.593000', '2011-09-30 18:33:40.890000', '2011-09-30 18:34:10.562000', '2011-09-30 18:34:40.578000', '2011-09-30 18:35:10.359000', '2011-09-30 18:35:40.171000', '2011-09-30 18:37:31.250000', '2011-09-30 18:38:01.140000', '2011-09-30 18:38:31.453000', '2011-09-30 18:39:01.312000'], dtype='datetime64[ns]', name='time', length=700092, freq=None))
- _logical_cutoff_date :
- 2011-10-02T00:00:00Z