Changes between Initial Version and Version 1 of PointObservationConventions


Ignore:
Timestamp:
10/23/08 15:39:13 (11 years ago)
Author:
caron
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • PointObservationConventions

    v1 v1  
     1= 5.8 Point Observation Data =
     2
     3Section 5 explains how to specify Coordinate Systems using coordinate variables and auxilary coordinate variables. This section extends and modifies that framework for point observational data.
     4
     5== Overview ==
     6
     7A point observation is a data measurement at a specific time and location. Each kind of measured data is placed in a data variable. The time and location values are placed into coordinate variables and auxiliary coordinate variables.
     8
     9Point data files contain collections of point observation data of one of the following feature types:
     10
     11    * point: one or more parameters measured at one point in time and space
     12    * stationTimeSeries: a time-series of data points at the same location, with varying time
     13    * trajectory: a connected set of data points along a 1D curve in time and space
     14    * profile: a set of data points along a vertical line
     15    * stationProfileTimeSeries: a time-series of profiles at a named location
     16    * section:  a collection of profiles which originate along a trajectory.
     17
     18You cannot mix multiple types of data in the same file. A global attribute CF:pointFeature indicates the feature type used in a particular file.
     19
     20There are several ways to represent point data in the classic netCDF model:
     21
     22    * multidimensional (rectangular array) representation
     23    * contiguous ragged array representation
     24    * non-contiguous ragged array representation
     25
     26The following subsections detail each point feature types and show examples of the possible representations of each.
     27
     28== 5.8.1 Point Data ==
     29
     30To represent data at scattered, unconnected points, both data and coordinates use the same, single dimension. The coordinates attribute is used on the data variables to unambiguously identify the time, lat, lon and height auxilary coordinate variables.
     31
     32
     33{{{
     34dimensions:
     35  obs = 1234 ;
     36
     37variables:
     38  double time(obs) ;
     39    time:long_name = "time of measurement" ;
     40    time:units = "days since 1970-01-01 00:00:00" ;
     41  float lon(obs) ;
     42    lon:long_name = "longitude of the observation";
     43    lon:units = "degrees_east";
     44  float lat(obs) ;
     45    lat:long_name = "latitude of the observation" ;
     46    lat:units = "degrees_north" ;
     47  float alt(obs) ;
     48    alt:long_name = "altitude above MSL" ;
     49    alt:units = "m";
     50    alt:positive = "up";
     51
     52  float humidity(obs) ;
     53    humidity:long_name = "specific humidity" ;
     54    humidity:coordinates = "time lat lon alt" ;
     55  float temp(obs) ;
     56    temp:long_name = "temperature" ;
     57    temp:units = "Celsius" ;
     58    temp:coordinates = "time lat lon alt" ;
     59
     60attributes:
     61  :CF\:pointFeature = "point";
     62}}}
     63
     64
     65In this example, the humidity(i) and temp(i) data are associated with the coordinate values time(i), lat(i), lon(i), and optionally alt(i). The obs dimension may use the unlimited dimension or not. If the time coordinate is ordered, the obs dimension may be named time (making time a coordinate variable rather than an auxiliary variable).
     66
     67== 5.8.2 Time series of Station Data ==
     68
     69Point data may be taken at a set of named locations called stations. The set of observations at a particular station, if ordered by time, is a time series, and the file contains a collection of time series of station data.
     70
     71=== 5.8.2.1 Multidimensional representation ===
     72
     73When the number of observations at each station is the same, one can use the multidimensional representation.
     74
     75
     76{{{
     77dimensions:
     78  station = UNLIMITED ;
     79  obs = 13 ;
     80
     81variables:
     82  float lon(station) ;
     83    lon:long_name = "station longitude";
     84    lon:units = "degrees_east";
     85  float lat(station) ;
     86    lat:long_name = "station latitude" ;
     87    lat:units = "degrees_north" ;
     88  float alt(station) ;
     89    alt:long_name = "altitude above MSL" ;
     90    alt:units = "m" ;
     91  char station_name(station, name_strlen) ;
     92    station_name:long_name = "station name" ;
     93  int station_info(station) ;
     94    station_name:long_name = "any kind of station info" ;
     95
     96  double time(station, obs) ;
     97    time:long_name = "time of measurement" ;
     98    time:units = "days since 1970-01-01 00:00:00" ;
     99    time:missing_value = -999.9;
     100  float humidity(station, obs) ;
     101    humidity:long_name = "specific humidity" ;
     102    humidity:coordinates = "time lat lon alt" ;
     103    humidity:_FillValue = -999.9;
     104  float temp(station, obs) ;
     105    temp:long_name = "temperature" ;
     106    temp:units = "Celsius" ;
     107    temp:coordinates = "time lat lon alt" ;
     108    temp:_FillValue = -999.9;
     109
     110attributes:
     111    :CF\:pointFeature = "stationTimeSeries";
     112}}}
     113
     114
     115The humidity(s,i) and temp(s,i) data are associated with the coordinate values time(s,i), lat(s), lon(s), and optionally alt(s). The station dimension may be the unlimited dimension or not. All variables that have station as their single dimension are considered to be station information.
     116
     117The time coordinate may use a missing value, which indicates that data is missing for that station and obs index. This allows one to have a variable number of observations at different stations, at the cost of some wasted space. The data variables may also use missing data values, to indicate that just that data variable is missing.
     118
     119Note that this is a generalization of Example 5.4, which assumes that all the stations have observations with the same time coordinates.
     120
     121=== 5.8.2.2 Ragged array (contiguous) representation ===
     122
     123When the number of observations at each station vary, one can use the ragged array representation. If you are able to store all the observations for one station contiguously, then add a field specifying the number of observations for each station.
     124
     125
     126{{{
     127dimensions:
     128  station = 23 ;
     129  obs = 1234 ;
     130
     131variables:
     132  float lon(station) ;
     133    lon:long_name = "station longitude";
     134    lon:units = "degrees_east";
     135  float lat(station) ;
     136    lat:long_name = "station latitude" ;
     137    lat:units = "degrees_north" ;
     138  float alt(station) ;
     139    alt:long_name = "altitude above MSL" ;
     140    alt:units = "m" ;
     141  char station_name(station, name_strlen) ;
     142    station_name:long_name = "station name" ;
     143  int station_info(station) ;
     144    station_name:long_name = "some kind of station info" ;
     145  int nobs(station) ;
     146    nobs:long_name = "number of observations for this station " ;
     147    nobs:standard_name = ragged_rowSize" ;
     148
     149  double time(obs) ;
     150    time:long_name = "time of measurement" ;
     151    time:units = "days since 1970-01-01 00:00:00" ;
     152  float humidity(obs) ;
     153    humidity:long_name = "specific humidity" ;
     154    humidity:coordinates = "time lat lon alt" ;
     155    humidity:_FillValue = -999.9;
     156  float temp(obs) ;
     157    temp:long_name = "temperature" ;
     158    temp:units = "Celsius" ;
     159    temp:coordinates = "time lat lon alt" ;
     160    temp:_FillValue = -999.9;
     161
     162attributes:
     163    :CF\:pointFeature = "stationTimeSeries";
     164}}}
     165
     166
     167Then for each station with index stn, its observations go from
     168
     169
     170{{{
     171  rowStart(stn) to rowStart(stn+1)-1
     172
     173where
     174
     175  rowStart(stn) = 0 if stn = 0   
     176  rowStart(stn) = rowStart(stn-1) + nobs(stn-1) if i > 0
     177
     178}}}
     179
     180The rowSize variable contains the number of observations for each station, and is identified by having a standard_name of "ragged_rowSize". It must have the station dimension as its single dimension.
     181
     182=== 5.8.2.3 Ragged array (non-contiguous) representation ===
     183
     184When the number of observations at each station vary, and the observations cannot be written in order, one can use the non-contiguous ragged array representation. Add a parentIndex field specifying the station index that the observation belongs to:
     185
     186
     187{{{
     188dimensions:
     189  station = 23 ;
     190  obs = UNLIMITED ;
     191
     192variables:
     193  float lon(station) ;
     194    lon:long_name = "station longitude";
     195    lon:units = "degrees_east";
     196  float lat(station) ;
     197    lat:long_name = "station latitude" ;
     198    lat:units = "degrees_north" ;
     199  float alt(station) ;
     200    alt:long_name = "altitude above MSL" ;
     201    alt:units = "m" ;
     202  char station_name(station, name_strlen) ;
     203    station_name:long_name = "station name" ;
     204  int station_info(station) ;
     205    station_name:long_name = "some kind of station info" ;
     206
     207  int stationIndex(obs) ;
     208    stationIndex:long_name = "which station this obs is for" ;
     209    stationIndex:standard_name = "ragged_parentIndex" ;
     210  double time(obs) ;
     211    time:long_name = "time of measurement" ;
     212    time:units = "days since 1970-01-01 00:00:00" ;
     213  float humidity(obs) ;
     214    humidity:long_name = "specific humidity" ;
     215    humidity:coordinates = "time lat lon alt" ;
     216    humidity:_FillValue = -999.9;
     217  float temp(obs) ;
     218    temp:long_name = "temperature" ;
     219    temp:units = "Celsius" ;
     220    temp:coordinates = "time lat lon alt" ;
     221    temp:_FillValue = -999.9;
     222
     223attributes:
     224    :CF\:pointFeature = "stationTimeSeries";
     225}}}
     226
     227
     228The humidity(i) and temp(i) data are associated with the coordinate values time(i), lat(s), lon(s), and optionally alt(s), where s = stationIndex(i). The stationIndex variable is identified by having a standard_name of "ragged_parentIndex". It must have the obs dimension as its single dimension.
     229
     230All variables that have station as their only dimension are considered to be information about that station. The obs dimension may use the unlimited dimension or not.
     231
     232=== 5.8.2.4 Single station ===
     233
     234When there is only a single station in the file, one can can use any of the above representations, with number of stations = 1. One can also use scalar coordinates:
     235
     236
     237{{{
     238dimensions:
     239  obs = 13 ;
     240
     241variables:
     242  float lon ;
     243    lon:long_name = "station longitude";
     244    lon:units = "degrees_east";
     245  float lat ;
     246    lat:long_name = "station latitude" ;
     247    lat:units = "degrees_north" ;
     248  float alt ;
     249    alt:long_name = "altitude above MSL" ;
     250    alt:units = "m" ;
     251
     252  double time(obs) ;
     253    time:long_name = "time of measurement" ;
     254    time:units = "days since 1970-01-01 00:00:00" ;
     255    time:missing_value = -999.9;
     256  float humidity(obs) ;
     257    humidity:long_name = "specific humidity" ;
     258    humidity:coordinates = "time lat lon alt" ;
     259    humidity:_FillValue = -999.9;
     260  float temp(obs) ;
     261    temp:long_name = "temperature" ;
     262    temp:units = "Celsius" ;
     263    temp:coordinates = "time lat lon alt" ;
     264    temp:_FillValue = -999.9;
     265
     266attributes:
     267    :CF\:pointFeature = "stationTimeSeries";
     268}}}
     269
     270
     271== 5.8.3 Trajectory Data ==
     272
     273Point data may be taken along a flight path or ship path, constituting a connected set of points called a trajectory.
     274
     275=== 5.8.3.1 Single Trajectory ===
     276
     277When a single trajectory is stored in a file, the representation is straightforward:
     278
     279
     280{{{
     281dimensions:
     282  time = 1000 ;
     283
     284variables:
     285  double time(time) ;
     286    time:long_name = "time" ;
     287    time:units = "days since 1970-01-01 00:00:00" ;
     288  float lon(time) ;
     289    lon:long_name = "longitude" ;
     290    lon:units = "degrees_east" ;
     291  float lat(time) ;
     292    lat:long_name = "latitude" ;
     293    lat:units = "degrees_north" ;
     294  float z(time) ;
     295    z:long_name = "height above mean sea level" ;
     296    z:units = "km" ;
     297    z:positive = "up" ;
     298
     299  float O3(time) ;
     300    O3:long_name = "ozone concentration" ;
     301    O3:units = "1e-9" ;
     302    O3:coordinates = "time lon lat z" ;
     303
     304  float NO3(time) ;
     305    NO3:long_name = "NO3 concentration" ;
     306    NO3:units = "1e-9" ;
     307    NO3:coordinates = "time lon lat z" ;
     308
     309attributes:
     310  :CF\:pointFeature = "trajectory";
     311}}}
     312
     313
     314The NO3(n) and O3(n) data is associated with the coordinate values time(n), z(n), lat(n), and lon(n). The time coordinate should be ordered, so it is appropriate to use a coordinate variable for time. The time dimension may be unlimited or not.
     315
     316Note that structurally this looks like unconnected point data as in example 5.8.1. The presence of the :CF\:pointFeature = "trajectory" global attribute indicates that in fact the points are connected along a trajectory.
     317
     318Note that this is the same as Example 5.5.
     319
     320=== 5.8.3.2 Multidimensional representation ===
     321
     322When storing multiple trajectories in the same file, and the number of observations in each trajectory is the same, one can use the multidimensional representation.
     323
     324
     325{{{
     326dimensions:
     327  obs = 1000 ;
     328  trajectory = 77 ;
     329
     330variables:
     331  char trajectory(trajectory, name_strlen) ;
     332    trajectory:long_name = "trajectory name" ;
     333  int trajectory_info(trajectory) ;
     334    trajectory_name:long_name = "some kind of trajectory info"
     335
     336  double time(trajectory, obs) ;
     337    time:long_name = "time" ;
     338    time:units = "days since 1970-01-01 00:00:00" ;
     339  float lon(trajectory, obs) ;
     340    lon:long_name = "longitude" ;
     341    lon:units = "degrees_east" ;
     342  float lat(trajectory, obs) ;
     343    lat:long_name = "latitude" ;
     344    lat:units = "degrees_north" ;
     345
     346  float z(trajectory, obs) ;
     347    z:long_name = "height above mean sea level" ;
     348    z:units = "km" ;
     349    z:positive = "up" ;
     350
     351  float O3(trajectory, obs) ;
     352    O3:long_name = "ozone concentration" ;
     353    O3:units = "1e-9" ;
     354    O3:coordinates = "time lon lat z" ;
     355
     356  float NO3(trajectory, obs) ;
     357    NO3:long_name = "NO3 concentration" ;
     358    NO3:units = "1e-9" ;
     359    NO3:coordinates = "time lon lat z" ;
     360
     361attributes:
     362  :CF\:pointFeature = "trajectory";
     363}}}
     364
     365
     366The NO3(t,i) and O3(t,i) data are associated with the coordinate values time(t,i), lat(t,i), lon(t,i), and alt(t,i). The trajectory dimension may be the unlimited dimension or not. All variables that have trajectory as their only dimension are considered to be information about that trajectory.
     367
     368The time coordinate may use a missing value, which indicates that data is missing for that trajectory and obs index. This allows one to have a variable number of observations for different trajectories, at the cost of some wasted space. The data variables may also use missing data values.
     369
     370=== 5.8.3.3 Ragged array (contiguous) representation ===
     371
     372When the number of observations for each trajectory varies, one can use the contiguous ragged array representation. One stores the set of observation for each trajectory contiguously along the obs dimension, and adds a rowSize variable specifying the number of observations for each trajectory:
     373
     374
     375{{{
     376dimensions:
     377  obs = UNLIMITED ;
     378  trajectory = 77 ;
     379
     380variables:
     381  char trajectory(trajectory, name_strlen) ;
     382    trajectory:long_name = "trajectory name" ;
     383  int trajectory_info(trajectory) ;
     384    trajectory_name:long_name = "some kind of trajectory info" ;
     385
     386  int rowSize(trajectory) ;
     387    rowSize:long_name = "number of obs for this trajectory " ;
     388    rowSize:standard_name = "ragged_rowSize" ;
     389  double time(obs) ;
     390    time:long_name = "time" ;
     391    time:units = "days since 1970-01-01 00:00:00" ;
     392  float lon(obs) ;
     393    lon:long_name = "longitude" ;
     394    lon:units = "degrees_east" ;
     395  float lat(obs) ;
     396    lat:long_name = "latitude" ;
     397    lat:units = "degrees_north" ;
     398  float z(obs) ;
     399    z:long_name = "height above mean sea level" ;
     400    z:units = "km" ;
     401    z:positive = "up" ;
     402
     403  float O3(obs) ;
     404    O3:long_name = "ozone concentration" ;
     405    O3:units = "1e-9" ;
     406    O3:coordinates = "time lon lat z" ;
     407
     408  float NO3(obs) ;
     409    NO3:long_name = "NO3 concentration" ;
     410    NO3:units = "1e-9" ;
     411    NO3:coordinates = "time lon lat z" ;
     412
     413attributes:
     414  :CF\:pointFeature = "trajectory";
     415}}}
     416
     417
     418The O3(i) and NO3(i) data are associated with the coordinate values time(i), lat(i), lon(i), and alt(i). All observations for one trajectory are contiguous along the obs dimension, and should be time ordered. All variables that have trajectory as their single dimension are considered to be information about that trajectory. The obs dimension may use the unlimited dimension or not.
     419
     420The rowSize variable contains the number of observations for each trajectory, and is identified by having a standard_name of "ragged_rowSize". It must have the trajectory dimension as its single dimension.
     421
     422=== 5.8.3.4 Ragged array (non-contiguous) representation ===
     423
     424When the number of observations at each trajectory vary, and the observations cannot be written in order, one can use the non-contiguous ragged array representation. Add a parentIndex field specifying the trajectory index that the observation belongs to:
     425
     426
     427{{{
     428dimensions:
     429  obs = UNLIMITED ;
     430  trajectory = 77 ;
     431
     432variables:
     433  char trajectory(trajectory, name_strlen) ;
     434    trajectory:long_name = "trajectory name" ;
     435  int trajectory_info(trajectory) ;
     436    trajectory_name:long_name = "some kind of trajectory info" ;
     437
     438  int trajectory_index(obs) ;
     439    trajectory_index:long_name = "index of trajectory this obs belongs to " ;
     440    trajectory_index:standard_name = "ragged_parentIndex" ;
     441  double time(obs) ;
     442    time:long_name = "time" ;
     443    time:units = "days since 1970-01-01 00:00:00" ;
     444  float lon(obs) ;
     445    lon:long_name = "longitude" ;
     446    lon:units = "degrees_east" ;
     447  float lat(obs) ;
     448    lat:long_name = "latitude" ;
     449    lat:units = "degrees_north" ;
     450  float z(obs) ;
     451    z:long_name = "height above mean sea level" ;
     452    z:units = "km" ;
     453    z:positive = "up" ;
     454
     455  float O3(obs) ;
     456    O3:long_name = "ozone concentration" ;
     457    O3:units = "1e-9" ;
     458    O3:coordinates = "time lon lat z" ;
     459
     460  float NO3(obs) ;
     461    NO3:long_name = "NO3 concentration" ;
     462    NO3:units = "1e-9" ;
     463    NO3:coordinates = "time lon lat z" ;
     464
     465attributes:
     466  :CF\:pointFeature = "trajectory";
     467}}}
     468
     469
     470The O3(i) and NO3(i) data are associated with the coordinate values time(i), lat(i), lon(i), and alt(i). All observations for one trajectory will have the same trajectory index value, and should be time ordered. All variables that have trajectory as their single dimension are considered to be information about that trajectory. The obs dimension may use the unlimited dimension or not.
     471
     472The parentIndex variable is identified by having a standard_name of "ragged_parentIndex". It must have the obs dimension as its single dimension.
     473
     474 
     475== 5.8.4 Profile Data ==
     476
     477A series of connected observations along a vertical line, like an atmospheric or ocean sounding, is called a profile.
     478
     479=== 5.8.4.1 Single Profile ===
     480
     481When a single profile is stored in a file, the representation is straightforward:
     482
     483
     484{{{
     485dimensions:
     486  z = 42 ;
     487
     488variables:
     489  float z(z) ;
     490    z:long_name = "height above mean sea level" ;
     491    z:units = "km" ;
     492    z:positive = "up" ;
     493
     494  double time;
     495    time:long_name = "time" ;
     496    time:units = "days since 1970-01-01 00:00:00" ;
     497  float lon;
     498    lon:long_name = "longitude" ;
     499    lon:units = "degrees_east" ;
     500  float lat;
     501    lat:long_name = "latitude" ;
     502    lat:units = "degrees_north" ;
     503
     504  float pressure(z) ;
     505    pressure:long_name = "pressure level" ;
     506    pressure:units = "hPa" ;
     507    pressure:coordinates = "time lon lat z" ;
     508
     509  float temperature(z) ;
     510    temperature:long_name = "skin temperature" ;
     511    temperature:units = "Celsius" ;
     512    temperature:coordinates = "time lon lat z" ;
     513
     514  float humidity(z) ;
     515    humidity:long_name = "relative humidity" ;
     516    humidity:units = "%" ;
     517    humidity:coordinates = "time lon lat z" ;
     518
     519attributes:
     520  :CF\:pointFeature = "profile";
     521}}}
     522
     523
     524The pressure(i), temperature(i), and humidity(i) data is associated with the coordinate values time, z(i), lat, and lon. The z coordinate must be ordered. The time coordinate may depend on z also, eg may be time(z).
     525
     526=== 5.8.4.2 Multidimensional representation ===
     527
     528When storing multiple profiles in the same file, and the vertical levels in each profile are the same, one can use the multidimensional representation:
     529
     530
     531{{{
     532dimensions:
     533  z = 42 ;
     534  profile = 142 ;
     535
     536variables:
     537  float z(z) ;
     538    z:long_name = "height above mean sea level" ;
     539    z:units = "km" ;
     540    z:positive = "up" ;
     541
     542  double time(profile);
     543    time:long_name = "time" ;
     544    time:units = "days since 1970-01-01 00:00:00" ;
     545  float lon(profile);
     546    lon:long_name = "longitude" ;
     547    lon:units = "degrees_east" ;
     548  float lat(profile);
     549    lat:long_name = "latitude" ;
     550    lat:units = "degrees_north" ;
     551
     552  float pressure(profile, z) ;
     553    pressure:long_name = "pressure level" ;
     554    pressure:units = "hPa" ;
     555    pressure:coordinates = "time lon lat z" ;
     556
     557  float temperature(profile, z) ;
     558    temperature:long_name = "skin temperature" ;
     559    temperature:units = "Celsius" ;
     560    temperature:coordinates = "time lon lat z" ;
     561
     562  float humidity(profile, z) ;
     563    humidity:long_name = "relative humidity" ;
     564    humidity:units = "%" ;
     565    humidity:coordinates = "time lon lat z" ;
     566
     567attributes:
     568  :CF\:pointFeature = "profile";
     569}}}
     570
     571
     572The pressure(p,i), temperature(p,i), and humidity(p,i) data is associated with the coordinate values time(p), z(i), lat(p), and lon(p). If the vertical coordinates differ for each profile, but the number of levels are the same, one can use z(profile, z), but the z coordinate must be ordered for each profile.
     573
     574The profile dimension may be the unlimited dimension or not. All variables that have profile as their only dimension are considered to be profile information.
     575
     576
     577The time coordinate may depend on z also, eg time(p,z). The time coordinate may use a missing value, which indicates that data is missing for that profile and obs index. This allows one to have a variable number of observations for different profiles, at the cost of some wasted space. The data variables may also use missing data values.
     578
     579=== 5.8.4.3 Ragged array (contiguous) representation ===
     580
     581When the number of vertical levels for each profile varies, one can use the contiguous ragged array representation. One stores the set of observation for each profile contiguously along the obs dimension, and adds a rowSize variable specifying the number of observations for each profile:
     582
     583
     584{{{
     585dimensions:
     586  obs = UNLIMITED ;
     587  profiles = 142 ;
     588
     589variables:
     590  double time(profile);
     591    time:long_name = "time" ;
     592    time:units = "days since 1970-01-01 00:00:00" ;
     593  float lon(profile);
     594    lon:long_name = "longitude" ;
     595    lon:units = "degrees_east" ;
     596  float lat(profile);
     597    lat:long_name = "latitude" ;
     598    lat:units = "degrees_north" ;
     599  int rowSize(profile) ;
     600    rowSize:long_name = "number of obs for this profile " ;
     601    rowSize:standard_name = "ragged_rowSize" ;
     602
     603  float z(obs) ;
     604    z:long_name = "height above mean sea level" ;
     605    z:units = "km" ;
     606    z:positive = "up" ;
     607
     608  float pressure(obs) ;
     609    pressure:long_name = "pressure level" ;
     610    pressure:units = "hPa" ;
     611    pressure:coordinates = "time lon lat z" ;
     612
     613  float temperature(obs) ;
     614    temperature:long_name = "skin temperature" ;
     615    temperature:units = "Celsius" ;
     616    temperature:coordinates = "time lon lat z" ;
     617
     618  float humidity(obs) ;
     619    humidity:long_name = "relative humidity" ;
     620    humidity:units = "%" ;
     621    humidity:coordinates = "time lon lat z" ;
     622
     623attributes:
     624  :CF\:pointFeature = "profile";
     625}}}
     626
     627
     628The pressure(i), temperature(i), and humidity(i) data is associated with the coordinate values time(p), z(i), lat(p), and lon(p), where p=profile_index(i). The time coordinate may depend on z also, eg time(p,z).
     629
     630=== 5.8.4.4 Ragged array (non-contiguous) representation ===
     631
     632When the number of vertical levels for each profile varies, and one cant write them contiguously, one can use the non-contiguous ragged array representation. Add a parentIndex field specifying the profile index that the observation belongs to:
     633
     634
     635{{{
     636dimensions:
     637  obs = UNLIMITED ;
     638  profiles = 142 ;
     639
     640variables:
     641  double time(profile);
     642    time:long_name = "time" ;
     643    time:units = "days since 1970-01-01 00:00:00" ;
     644  float lon(profile);
     645    lon:long_name = "longitude" ;
     646    lon:units = "degrees_east" ;
     647  float lat(profile);
     648    lat:long_name = "latitude" ;
     649    lat:units = "degrees_north" ;
     650  int parentIndex(obs) ;
     651    parentIndex:long_name = "index of profile " ;
     652    parentIndex:standard_name = "ragged_parentIndex" ;
     653
     654  float z(obs) ;
     655    z:long_name = "height above mean sea level" ;
     656    z:units = "km" ;
     657    z:positive = "up" ;
     658
     659  float pressure(obs) ;
     660    pressure:long_name = "pressure level" ;
     661    pressure:units = "hPa" ;
     662    pressure:coordinates = "time lon lat z" ;
     663
     664  float temperature(obs) ;
     665    temperature:long_name = "skin temperature" ;
     666    temperature:units = "Celsius" ;
     667    temperature:coordinates = "time lon lat z" ;
     668
     669  float humidity(obs) ;
     670    humidity:long_name = "relative humidity" ;
     671    humidity:units = "%" ;
     672    humidity:coordinates = "time lon lat z" ;
     673
     674attributes:
     675  :CF\:pointFeature = "profile";
     676}}}
     677
     678
     679The pressure(i), temperature(i), and humidity(i) data is associated with the coordinate values time(p), z(i), lat(p), and lon(p), where p=parentIndex(i). The time coordinate may depend on z also, eg time(p,z).
     680
     681== 5.8.5 Station Profile Data ==
     682
     683When profiles are taken at a set of stations, one gets a time series of profiles at each station, called a stationProfileTimeSeries.
     684
     685=== 5.8.5.1 Profile time series at a single station ===
     686
     687If there is only one station in a file, and the vertical levels are the same for each profile, one can use a representation that is a variant of Example 5.8.4.2:
     688
     689
     690{{{
     691dimensions:
     692  z = 42 ;
     693  time = UNLIMITED ;
     694
     695variables:
     696  float z(z) ;
     697    z:long_name = "height above mean sea level" ;
     698    z:units = "km" ;
     699    z:positive = "up" ;
     700
     701  double time(time);
     702    time:long_name = "time" ;
     703    time:units = "days since 1970-01-01 00:00:00" ;
     704  float lon;
     705    lon:long_name = "longitude" ;
     706    lon:units = "degrees_east" ;
     707  float lat;
     708    lat:long_name = "latitude" ;
     709    lat:units = "degrees_north" ;
     710
     711  float pressure(time, z) ;
     712    pressure:long_name = "pressure level" ;
     713    pressure:units = "hPa" ;
     714    pressure:coordinates = "time lon lat z" ;
     715
     716  float temperature(time, z) ;
     717    temperature:long_name = "skin temperature" ;
     718    temperature:units = "Celsius" ;
     719    temperature:coordinates = "time lon lat z" ;
     720
     721  float humidity(time, z) ;
     722    humidity:long_name = "relative humidity" ;
     723    humidity:units = "%" ;
     724    humidity:coordinates = "time lon lat z" ;
     725
     726attributes:
     727  :CF\:pointFeature = "stationProfileTimeSeries";
     728}}}
     729
     730
     731The pressure(i,j), temperature(i,j), and humidity(i,j) data are associated with the coordinate values time(i), z(j), lat, and lon.
     732
     733=== 5.8.5.2 Multidimensional representation ===
     734
     735When storing time series of profiles at multiple stations in the same file, if there are the same number of time points and vertical levels for every profile, one can use the multidimensional representation.
     736
     737
     738{{{
     739dimensions:
     740  station = 22 ;
     741  time = 30 ;
     742  z = 42 ;
     743
     744variables:
     745  float lon(station) ;
     746    lon:long_name = "station longitude";
     747    lon:units = "degrees_east";
     748  float lat(station) ;
     749    lat:long_name = "station latitude" ;
     750    lat:units = "degrees_north" ;
     751  char station_name(station, name_strlen) ;
     752    station_name:long_name = "station name" ;
     753  int station_info(station) ;
     754    station_name:long_name = "some kind of station info" ;
     755
     756  float z(z) ;
     757    z:long_name = "height above mean sea level" ;
     758    z:units = "km" ;
     759    z:positive = "up" ;
     760
     761  double time(station, time) ;
     762    time:long_name = "time of measurement" ;
     763    time:units = "days since 1970-01-01 00:00:00" ;
     764    time:missing_value = -999.9;
     765
     766  float pressure(station, time, z) ;
     767    pressure:long_name = "pressure level" ;
     768    pressure:units = "hPa" ;
     769    pressure:coordinates = "time lon lat z" ;
     770
     771  float temperature(station, time, z) ;
     772    temperature:long_name = "skin temperature" ;
     773    temperature:units = "Celsius" ;
     774    temperature:coordinates = "time lon lat z" ;
     775
     776  float humidity(station, time, z) ;
     777    humidity:long_name = "relative humidity" ;
     778    humidity:units = "%" ;
     779    humidity:coordinates = "time lon lat z" ;
     780
     781attributes:
     782 :CF\:pointFeature = "stationProfileTimeSeries";
     783}}}
     784
     785
     786The pressure(s,p,i), temperature(s,p,i), and humidity(s,p,i) data is associated with the coordinate values time(s,p), z(i), lat(s), and lon(s).
     787
     788=== 5.8.5.3 Ragged array of multidimensional profiles ===
     789
     790When the number of profiles for each station varies, one can use (continguous or non-contiguous) ragged arrays for the time series. If each profile has the same number of vertical levels, a multidimensional profile representation can be usedd. Here is the contiguous form:
     791
     792
     793{{{
     794dimensions:
     795  station = 22 ;
     796  profile = UNLIMITED ;
     797  z = 42 ;
     798
     799variables:
     800  float z(z) ;
     801    z:long_name = "height above mean sea level" ;
     802    z:units = "km" ;
     803    z:positive = "up" ;
     804
     805  float lon(station) ;
     806    lon:long_name = "station longitude";
     807    lon:units = "degrees_east";
     808  float lat(station) ;
     809    lat:long_name = "station latitude" ;
     810    lat:units = "degrees_north" ;
     811  char station_name(station, name_strlen) ;
     812    station_name:long_name = "station name" ;
     813  int station_info(station) ;
     814    station_name:long_name = "some kind of station info" ;
     815  int rowSize(station) ;
     816    rowSize:long_name = "number of profiles for this station " ;
     817    rowSize:standard_name = "ragged_rowSize" ;
     818  double time(profile);
     819    time:long_name = "time" ;
     820    time:units = "days since 1970-01-01 00:00:00" ;
     821  float pressure(profile, z) ;
     822    pressure:long_name = "pressure level" ;
     823    pressure:units = "hPa" ;
     824    pressure:coordinates = "time lon lat z" ;
     825
     826  float temperature(profile, z) ;
     827    temperature:long_name = "skin temperature" ;
     828    temperature:units = "Celsius" ;
     829    temperature:coordinates = "time lon lat z" ;
     830
     831  float humidity(profile, z) ;
     832    humidity:long_name = "relative humidity" ;
     833    humidity:units = "%" ;
     834    humidity:coordinates = "time lon lat z" ;
     835
     836attributes:
     837  :CF\:pointFeature = "stationProfileTimeSeries";
     838}}}
     839
     840
     841The pressure(p,z), temperature(p,z), and humidity(p,z) data is associated with the coordinate values time(p), z(z), lat(s), and lon(s).
     842
     843=== 5.8.5.4 Ragged array of ragged array ===
     844
     845If the number of vertical levels for the profiles also varies significantly, one can also turn the profiles into a ragged array. Here we show the non-contiguous form:
     846
     847
     848{{{
     849dimensions:
     850  obs = UNLIMITED ;
     851  station = 142 ;
     852
     853variables:
     854  float lon(station) ;
     855    lon:long_name = "station longitude";
     856    lon:units = "degrees_east";
     857  float lat(station) ;
     858    lat:long_name = "station latitude" ;
     859    lat:units = "degrees_north" ;
     860  float alt(station) ;
     861    alt:long_name = "altitude above MSL" ;
     862    alt:units = "m" ;
     863  char station_name(station, name_strlen) ;
     864    station_name:long_name = "station name" ;
     865  int station_info(station) ;
     866    station_name:long_name = "some kind of station info" ;
     867  int stationIndex(profile) ;
     868    stationIndex:long_name = "station index for this profile" ;
     869    stationIndex:standard_name = "ragged_parentIndex" ;
     870  double time(profile);
     871    time:long_name = "time" ;
     872    time:units = "days since 1970-01-01 00:00:00" ;
     873  int profileIndex(obs) ;
     874    profileIndex:long_name = "profile index for this level" ;
     875    profileIndex:standard_name = "ragged_parentIndex" ;
     876
     877  float z(obs) ;
     878    z:long_name = "height above mean sea level" ;
     879    z:units = "km" ;
     880    z:positive = "up" ;
     881
     882  float pressure(obs) ;
     883    pressure:long_name = "pressure level" ;
     884    pressure:units = "hPa" ;
     885    pressure:coordinates = "time lon lat z" ;
     886
     887  float temperature(obs) ;
     888    temperature:long_name = "skin temperature" ;
     889    temperature:units = "Celsius" ;
     890    temperature:coordinates = "time lon lat z" ;
     891
     892  float humidity(obs) ;
     893    humidity:long_name = "relative humidity" ;
     894    humidity:units = "%" ;
     895    humidity:coordinates = "time lon lat z" ;
     896
     897attributes:
     898  :CF\:pointFeature = "stationProfileTimeSeries";
     899}}}
     900
     901
     902The pressure(i), temperature(i), and humidity(i) data is associated with the coordinate values time(p), z(i), lat(s), and lon(s), where p = profileIndex(i), and s = stationIndex(p).
     903
     904== 5.8.6 Section Profile Data ==
     905
     906When profiles are taken along a trajectory, one gets a time series of profiles called a section. This looks like a collection of profiles (see 5.8.4.2), except that the profile location are a connected set of points along a trajectory.
     907
     908=== 5.8.6.1 Multidimensional representation ===
     909
     910If the vertical levels are the same for each profile, one can use a multidimensional representation:
     911
     912
     913{{{
     914dimensions:
     915  z = 42 ;
     916  time = UNLIMITED ;
     917
     918variables:
     919  float z(z) ;
     920    z:long_name = "height above mean sea level" ;
     921    z:units = "km" ;
     922    z:positive = "up" ;
     923
     924  double time(time);
     925    time:long_name = "time" ;
     926    time:units = "days since 1970-01-01 00:00:00" ;
     927  float lon(time);
     928    lon:long_name = "longitude" ;
     929    lon:units = "degrees_east" ;
     930  float lat(time);
     931    lat:long_name = "latitude" ;
     932    lat:units = "degrees_north" ;
     933
     934  float pressure(time, z) ;
     935    pressure:long_name = "pressure level" ;
     936    pressure:units = "hPa" ;
     937    pressure:coordinates = "time lon lat z" ;
     938
     939  float temperature(time, z) ;
     940    temperature:long_name = "skin temperature" ;
     941    temperature:units = "Celsius" ;
     942    temperature:coordinates = "time lon lat z" ;
     943
     944  float humidity(time, z) ;
     945    humidity:long_name = "relative humidity" ;
     946    humidity:units = "%" ;
     947    humidity:coordinates = "time lon lat z" ;
     948
     949attributes:
     950  :CF\:pointFeature = "section";
     951}}}
     952
     953
     954The pressure(i,j), temperature(i,j), and humidity(i,j) data is associated with the coordinate values time(i), z(j), lat(i), and lon(i).
     955
     956=== 5.8.6.2 Ragged Array ===
     957
     958When the vertical levels vary across profiles, one can use(continguous or non-contiguous) ragged arrays to connect the observations to the profiles. Here we show the non-contiguous case:
     959
     960
     961{{{
     962dimensions:
     963  obs = UNLIMITED ;
     964  profile = 123
     965
     966variables:
     967  double time(profile);
     968    time:long_name = "time" ;
     969    time:units = "days since 1970-01-01 00:00:00" ;
     970  float lon(profile);
     971    lon:long_name = "longitude" ;
     972    lon:units = "degrees_east" ;
     973  float lat(profile);
     974    lat:long_name = "latitude" ;
     975    lat:units = "degrees_north" ;
     976  int profileIndex(obs) ;
     977    profileIndex:long_name = "profile index for this level" ;
     978    profileIndex:standard_name = "ragged_parentIndex" ;
     979
     980  float z(obs) ;
     981    z:long_name = "height above mean sea level" ;
     982    z:units = "km" ;
     983    z:positive = "up" ;
     984
     985  float pressure(obs) ;
     986    pressure:long_name = "pressure level" ;
     987    pressure:units = "hPa" ;
     988    pressure:coordinates = "time lon lat z" ;
     989
     990  float temperature(obs) ;
     991    temperature:long_name = "skin temperature" ;
     992    temperature:units = "Celsius" ;
     993    temperature:coordinates = "time lon lat z" ;
     994
     995  float humidity(obs) ;
     996    humidity:long_name = "relative humidity" ;
     997    humidity:units = "%" ;
     998    humidity:coordinates = "time lon lat z" ;
     999
     1000attributes:
     1001  :CF\:pointFeature = "profileSection";
     1002}}}
     1003
     1004
     1005The pressure(i), temperature(i), and humidity(i) data is associated with the coordinate values time(p), z(i), lat(p), and lon(p), where p = profile_index(i).