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(first setup with special optical unit: 2010-02-10 to 2012-03-10)BCO.ceilometer_c2(second setup with standard unit: 2011-01-22 to 2011-10-01)BCO.ceilometer_c3(second setup with standard unit, but providing high resolution signal as well: 2015-07-26 to now)
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.to_dask()
ds.sel(time="2011-01").cbh.resample(time="1h").mean().plot.line(x="time")
/builds/tco/bco/docs/.venv/lib/python3.14/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.lines.Line2D at 0x7fa75077ecf0>,
<matplotlib.lines.Line2D at 0x7fa75076d160>,
<matplotlib.lines.Line2D at 0x7fa75076d2b0>]
The full dataset:
ds
<xarray.Dataset> Size: 3GB
Dimensions: (time: 700092, range: 1024, layer: 3)
Coordinates:
* time (time) datetime64[ns] 6MB 2011-01-22T20:44:22.937000 .....
* range (range) float32 4kB 15.0 30.0 45.0 ... 1.534e+04 1.536e+04
* layer (layer) int32 12B 0 1 2
lat float64 8B ...
lon float64 8B ...
sensor_alt int64 8B ...
Data variables: (12/31)
average_time (time) int32 3MB dask.array<chunksize=(700092,), meta=np.ndarray>
azimuth float32 4B ...
base (time) float32 3MB dask.array<chunksize=(700092,), meta=np.ndarray>
bcc (time) int8 700kB dask.array<chunksize=(700092,), meta=np.ndarray>
beta_raw (time, range) float32 3GB dask.array<chunksize=(131072, 32), meta=np.ndarray>
cbe (time, layer) float32 8MB dask.array<chunksize=(131072, 3), meta=np.ndarray>
... ...
temp_ext (time) float64 6MB dask.array<chunksize=(700092,), meta=np.ndarray>
temp_int (time) float64 6MB dask.array<chunksize=(700092,), meta=np.ndarray>
voe (time) int16 1MB dask.array<chunksize=(700092,), meta=np.ndarray>
vor (time) int16 1MB dask.array<chunksize=(700092,), meta=np.ndarray>
wavelength float32 4B ...
zenith float32 4B ...
Attributes:
Conventions: CF-1.12
_logical_cutoff_date: 2011-10-01T00:00:00Z
bcoproc_version: 0.0.0.post2032.dev0+46ab43c
featureType: timeSeriesProfile
institution: Max Planck Institute for Meteorology, Hamburg
license: CC0-1.0
location: The Barbados Cloud Observatory (BCO), Deebles Poin...
platform: BCO
source: CHM 15k (Campbell Scientific, Jenoptik)
summary: This dataset contains measurements of cloud proper...
title: Ceilometer data from BCO (Level 1)
tool_versions: {"Python": "3.11.2 (main, Apr 28 2025, 14:11:48) [...- time: 700092
- range: 1024
- layer: 3
- 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]') - 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) - layer(layer)int320 1 2
- axis :
- layer
- long_name :
- Layer index
- units :
- index
array([0, 1, 2], dtype=int32)
- lat()float64...
- long_name :
- north latitude
- units :
- degree_north
- valid_max :
- 90.0
- valid_min :
- -90.0
[1 values with dtype=float64]
- lon()float64...
- long_name :
- east longitude
- units :
- degree_east
- valid_max :
- 180.0
- valid_min :
- -180.0
[1 values with dtype=float64]
- sensor_alt()int64...
- long_name :
- height above mean sea level
- standard_name :
- altitude
- units :
- m
[1 values with dtype=int64]
- average_time(time)int32dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- average time per record
- units :
- ms
Array Chunk Bytes 2.67 MiB 2.67 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int32 numpy.ndarray - azimuth()float32...
- long_name :
- laser direction of site
- units :
- degree_clockwise
[1 values with dtype=float32]
- base(time)float32dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- Daylight correction factor, photons per shot
- units :
- counts
Array Chunk Bytes 2.67 MiB 2.67 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type float32 numpy.ndarray - bcc(time)int8dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- Base Cloud Cover
- standard_name :
- cloud_area_fraction
Array Chunk Bytes 683.68 kiB 683.68 kiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int8 numpy.ndarray - beta_raw(time, range)float32dask.array<chunksize=(131072, 32), meta=np.ndarray>
- long_name :
- background substracted and normilised by laser shot number and stddev
- units :
- SNR
Array Chunk Bytes 2.67 GiB 16.00 MiB Shape (700092, 1024) (131072, 32) Dask graph 192 chunks in 2 graph layers Data type float32 numpy.ndarray - cbe(time, layer)float32dask.array<chunksize=(131072, 3), meta=np.ndarray>
- long_name :
- cloud base height variation
- units :
- m
Array Chunk Bytes 8.01 MiB 1.50 MiB Shape (700092, 3) (131072, 3) Dask graph 6 chunks in 2 graph layers Data type float32 numpy.ndarray - cbh(time, layer)float32dask.array<chunksize=(131072, 3), meta=np.ndarray>
- axis :
- range
- long_name :
- cloud base height
- standard_name :
- cloud_base_altitude
- units :
- m
Array Chunk Bytes 8.01 MiB 1.50 MiB Shape (700092, 3) (131072, 3) Dask graph 6 chunks in 2 graph layers Data type float32 numpy.ndarray - cde(time, layer)float32dask.array<chunksize=(131072, 3), meta=np.ndarray>
- long_name :
- cloud depth variation
- units :
- m
Array Chunk Bytes 8.01 MiB 1.50 MiB Shape (700092, 3) (131072, 3) Dask graph 6 chunks in 2 graph layers Data type float32 numpy.ndarray - cdp(time, layer)float32dask.array<chunksize=(131072, 3), meta=np.ndarray>
- long_name :
- cloud depth
- units :
- m
Array Chunk Bytes 8.01 MiB 1.50 MiB Shape (700092, 3) (131072, 3) Dask graph 6 chunks in 2 graph layers Data type float32 numpy.ndarray - error_ext(time)int32dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- 31 Bit ServiceCode
Array Chunk Bytes 2.67 MiB 2.67 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int32 numpy.ndarray - laser_pulses(time)int32dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- number of laser pulses averaged per record
- units :
- unitless
Array Chunk Bytes 2.67 MiB 2.67 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int32 numpy.ndarray - life_time(time)int32dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- h
- units :
- Laser fife time
Array Chunk Bytes 2.67 MiB 2.67 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int32 numpy.ndarray - mxd(time)int16dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- maximum detection height
- units :
- m
Array Chunk Bytes 1.34 MiB 1.34 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int16 numpy.ndarray - nn1(time)int16dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- NN1
- units :
- NAN
Array Chunk Bytes 1.34 MiB 1.34 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int16 numpy.ndarray - pbl(time, layer)float32dask.array<chunksize=(131072, 3), meta=np.ndarray>
- axis :
- range
- long_name :
- Aerosol Layer in PBL
- units :
- m
Array Chunk Bytes 8.01 MiB 1.50 MiB Shape (700092, 3) (131072, 3) Dask graph 6 chunks in 2 graph layers Data type float32 numpy.ndarray - pbs(time, layer)float32dask.array<chunksize=(131072, 3), meta=np.ndarray>
- long_name :
- Quality score for aerosol Layer in PBL
Array Chunk Bytes 8.01 MiB 1.50 MiB Shape (700092, 3) (131072, 3) Dask graph 6 chunks in 2 graph layers Data type float32 numpy.ndarray - range_gate()float32...
- long_name :
- length of range gate, binwidth
- units :
- m
[1 values with dtype=float32]
- sci(time)int8dask.array<chunksize=(700092,), meta=np.ndarray>
- definition :
- 0: nothing 1: rain 2: fog 3: snow
- long_name :
- Sky Condition Index
Array Chunk Bytes 683.68 kiB 683.68 kiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int8 numpy.ndarray - sensor_serial_no(time)uint16dask.array<chunksize=(700092,), 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 1.34 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type uint16 numpy.ndarray - state_detector(time)int16dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- quality of detector signal - 255 max
- units :
- unitless
Array Chunk Bytes 1.34 MiB 1.34 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int16 numpy.ndarray - state_laser(time)int16dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- laser quality index - 255 max
- units :
- unitless
Array Chunk Bytes 1.34 MiB 1.34 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int16 numpy.ndarray - state_optics(time)int16dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- transmission of optics
- units :
- unitless
Array Chunk Bytes 1.34 MiB 1.34 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int16 numpy.ndarray - stddev(time)float32dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- Standard Deviation raw signal, photons/ shot
- units :
- counts
Array Chunk Bytes 2.67 MiB 2.67 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type float32 numpy.ndarray - tcc(time)int8dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- Total Cloud Cover
Array Chunk Bytes 683.68 kiB 683.68 kiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int8 numpy.ndarray - temp_det(time)float64dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- detector temperature
- units :
- K
Array Chunk Bytes 5.34 MiB 5.34 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type float64 numpy.ndarray - temp_ext(time)float64dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- external temperature
- units :
- K
Array Chunk Bytes 5.34 MiB 5.34 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type float64 numpy.ndarray - temp_int(time)float64dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- internal temperature
- units :
- K
Array Chunk Bytes 5.34 MiB 5.34 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type float64 numpy.ndarray - voe(time)int16dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- vertical optical range error
- units :
- m
Array Chunk Bytes 1.34 MiB 1.34 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int16 numpy.ndarray - vor(time)int16dask.array<chunksize=(700092,), meta=np.ndarray>
- long_name :
- vertical optical range
- units :
- m
Array Chunk Bytes 1.34 MiB 1.34 MiB Shape (700092,) (700092,) Dask graph 1 chunks in 2 graph layers Data type int16 numpy.ndarray - wavelength()float32...
- long_name :
- laser wavelength
- units :
- nm
[1 values with dtype=float32]
- zenith()float32...
- long_name :
- laser direction of site
- units :
- degree
[1 values with dtype=float32]
- Conventions :
- CF-1.12
- _logical_cutoff_date :
- 2011-10-01T00:00:00Z
- bcoproc_version :
- 0.0.0.post2032.dev0+46ab43c
- featureType :
- timeSeriesProfile
- institution :
- Max Planck Institute for Meteorology, Hamburg
- license :
- CC0-1.0
- location :
- The Barbados Cloud Observatory (BCO), Deebles Point, Barbados, West Indies
- platform :
- BCO
- source :
- CHM 15k (Campbell Scientific, Jenoptik)
- summary :
- This dataset contains measurements of cloud properties from a ceilometer probing vertically up to 15 km.
- title :
- Ceilometer data from BCO (Level 1)
- tool_versions :
- {"Python": "3.11.2 (main, Apr 28 2025, 14:11:48) [GCC 12.2.0]", "six": "1.17.0", "bcoproc": "0.0.0.post2032.dev0+46ab43c", "bcologs": "0.0.0.post2032.dev0+46ab43c", "flox": "0.11.2", "click": "8.1.8", "MarkupSafe": "3.0.3", "xarray": "2025.4.0", "jinja2": "3.1.6", "iniconfig": "2.1.0", "numpy_groupies": "0.11.3", "idna": "3.10", "multidict": "6.4.3", "propcache": "0.3.1", "netcdf4": "1.7.2", "aiohttp": "3.11.18", "tzdata": "2025.2", "importlib_metadata": "8.7.0", "aiosignal": "1.3.2", "toolz": "1.0.0", "zipp": "3.21.0", "packaging": "25.0", "pluggy": "1.5.0", "frozenlist": "1.6.0", "pandas": "2.2.3", "yarl": "1.20.0", "aiohappyeyeballs": "2.6.1", "attrs": "25.3.0", "partd": "1.4.2", "python-dateutil": "2.9.0.post0", "pyyaml": "6.0.2", "cftime": "1.6.4.post1", "pytz": "2025.2", "pendulum": "3.1.0", "certifi": "2025.4.26", "numpy": "2.2.5", "scipy": "1.17.1", "dask": "2025.4.1", "ruff": "0.13.0", "locket": "1.0.0", "cloudpickle": "3.1.1", "datarecords": "0.0.0.post2032.dev0+46ab43c", "pytest": "8.3.5", "fsspec": "2025.3.2"}