From ea41330bafe580f49d3d7b704550d24cda34bc1a Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 28 Sep 2020 17:38:55 +0100 Subject: [PATCH 001/249] TEST! --- ch08.adoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ch08.adoc b/ch08.adoc index 4724d47b..3d0da6a0 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -68,3 +68,6 @@ variables: ---- This information implies that the salinity field should be uncompressed to an array with dimensions `(depth,lat,lon)` . ==== + + +TEST CHANGE From f90ef32bd02d0d181f1f3e8fcd46685af29951d0 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 28 Sep 2020 17:40:50 +0100 Subject: [PATCH 002/249] Transfer from David - initial text --- ch08.adoc | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 3d0da6a0..34295f2a 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -70,4 +70,48 @@ This information implies that the salinity field should be uncompressed to an ar ==== -TEST CHANGE + + + +[[compression-by-coordinate-interpolation, Section 8.3, "Compression by Coordinate Interpolation"]] +=== Compression by Coordinate Interpolation + +For some applications the coordinates of a data variable can require +considerably more storage than the data itself. Space may be saved in +the netCDF file by the storing coordinates at a lower resolution than +the data which they describe. The uncompressed coordinate and +auxiliary coordinate variables can be reconstituted by interpolation, +from the lower resolution coordinate values to the domain of the data +(i.e. the target domain). This process will likely result in a loss in +accuracy (as opposed to precision) in the uncompressed variables, due +to rounding errors in the interpolation calculations, but it assumed +that these errors will be small enough to not be of concern to user of +the uncompressed dataset. + +The lower resolution coordinates are stored in a __tie point +variable__. This terminology is chosen to ackowledge that, whilst the +values of a tie point variable may be a subset of the uncompressed +coordinate values, they can also be different to some or all of them. + +The method used to uncompress the tie point variables is described by +an __interpolation variable__ that acts as a container for the +attributes that define the interpolation technique that should be +used. The variable should be a scalar (i.e. it has no dimensions) of +arbitrary type, and the value of its single element is immaterial. + +To indicate that coordinate interpolation is required, a +**`tie_points`** attribute must be defined for a data variable. This +is a string attribute that both identifies the tie point variables, +and maps non-overlapping subsets of them to their corresponding +interpolation variables. It is blank-separated list of words of the +form "__tie_point_variable: [tie_point_variable: ...] +interpolation_variable [tie_point_variable: [tie_point_variable: ...] +interpolation_variable ...]__". For example, to specify that the tie +point variables **`tp_lat`** and **`tp_lon`** are to be interpolated +according to the interolation variable **`bi_linear`** could be +indicated with **`tp_lat: tp_lon: bi_linear`**. + +The relationship between the tie point locations and the target domain +is defined via __tie point index__ variables. A tie point index +variable has the same dimension as corresponding ti point variable, +ansd contains the zero-based indices if x of the feature of its coors ... From f3f33cc71519e73fb0b7104ac012c76101fdcc82 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 21 Oct 2020 14:13:03 +0200 Subject: [PATCH 003/249] Update ch08.adoc --- ch08.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ch08.adoc b/ch08.adoc index 34295f2a..5eb3708b 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -115,3 +115,5 @@ The relationship between the tie point locations and the target domain is defined via __tie point index__ variables. A tie point index variable has the same dimension as corresponding ti point variable, ansd contains the zero-based indices if x of the feature of its coors ... + +Test change / Anders 21-10-20202 From 618713515cfd525b849a7e4b56858e3f77ab96f2 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 24 Nov 2020 15:12:01 +0100 Subject: [PATCH 004/249] Draft of Ch08 changes for Coordinate Interpolation --- ch08.adoc | 239 +++++++++++++++--- images/regular_and_piecewise_regular_grid.png | Bin 0 -> 77989 bytes 2 files changed, 197 insertions(+), 42 deletions(-) create mode 100644 images/regular_and_piecewise_regular_grid.png diff --git a/ch08.adoc b/ch08.adoc index 5eb3708b..19955f33 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -72,48 +72,203 @@ This information implies that the salinity field should be uncompressed to an ar - [[compression-by-coordinate-interpolation, Section 8.3, "Compression by Coordinate Interpolation"]] === Compression by Coordinate Interpolation -For some applications the coordinates of a data variable can require -considerably more storage than the data itself. Space may be saved in -the netCDF file by the storing coordinates at a lower resolution than -the data which they describe. The uncompressed coordinate and -auxiliary coordinate variables can be reconstituted by interpolation, -from the lower resolution coordinate values to the domain of the data -(i.e. the target domain). This process will likely result in a loss in -accuracy (as opposed to precision) in the uncompressed variables, due -to rounding errors in the interpolation calculations, but it assumed -that these errors will be small enough to not be of concern to user of -the uncompressed dataset. - -The lower resolution coordinates are stored in a __tie point -variable__. This terminology is chosen to ackowledge that, whilst the -values of a tie point variable may be a subset of the uncompressed -coordinate values, they can also be different to some or all of them. - -The method used to uncompress the tie point variables is described by -an __interpolation variable__ that acts as a container for the -attributes that define the interpolation technique that should be -used. The variable should be a scalar (i.e. it has no dimensions) of -arbitrary type, and the value of its single element is immaterial. - -To indicate that coordinate interpolation is required, a -**`tie_points`** attribute must be defined for a data variable. This -is a string attribute that both identifies the tie point variables, -and maps non-overlapping subsets of them to their corresponding -interpolation variables. It is blank-separated list of words of the -form "__tie_point_variable: [tie_point_variable: ...] -interpolation_variable [tie_point_variable: [tie_point_variable: ...] -interpolation_variable ...]__". For example, to specify that the tie -point variables **`tp_lat`** and **`tp_lon`** are to be interpolated -according to the interolation variable **`bi_linear`** could be -indicated with **`tp_lat: tp_lon: bi_linear`**. - -The relationship between the tie point locations and the target domain -is defined via __tie point index__ variables. A tie point index -variable has the same dimension as corresponding ti point variable, -ansd contains the zero-based indices if x of the feature of its coors ... - -Test change / Anders 21-10-20202 +For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to user of the uncompressed dataset. + +The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to ackowledge that, whilst the values of a tie point variable may be a subset of the uncompressed coordinate values, they can also be different to some or all of them. + +Beyond the tie point variables themselves, metadata of the coordinate interpolation is stored in attributes of the data variable and the __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. + +The data variable coordinate interpolation attributes may also be used on a domain variable (see the domain variable issue #??) with the same effect. + +[[compression-by-coordinate-interpolation-variables, Section 8.3.1, "Tie Points, Interpolation Zones and Interpolation Zone Groups"]] +==== Tie Points, Interpolation Zones and Interpolation Zone Groups + +[[img-bnd_2d_coords, figure 3]] +[.text-center] +.When grid discontinuities, such as spatial gaps or overlaps, are present, the grid is divided into multiple Interpolation Zone Groups, each of which is free of grid discontinuities. Otherwise the whole grid is a single Interpolation Zone Group. The Interpolation Zone Groups are futher subdivided into Interpolation Zones for the purpose of coordinate interpolation. +image::images/regular_and_piecewise_regular_grid.png[,100%,pdfwidth=50vw,align="center"] + + + + + +[[compression-by-coordinate-interpolation-variables, Section 8.3.2, "Tie Points Attribute"]] +==== Tie Points Attribute + +To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. + +[[compression-by-coordinate-interpolation-dimensions,Section 8.3.3, "Data Variable Attributes"]] +==== Interpolation and Non-Interpolation Dimensions + +For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie points must share the same set of dimensions. The set of dimensions must contain at least one __interpolation dimension__ and may additionally contain one or more __non-interpolation dimensions__. + +For the interpolation dimensions, where interpolation is applied, the tie point dimension typically differ from the corresponding dimension in the target domain. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point dimension related to the target dimension **`xc`** and **`tp_yc`** is the tie point dimension related to the target dimension **`yc`**. + +For each of the non-interpolation dimensions, the tie point dimension and the corresponding target domain dimension are equal and no interpolation is applied. However, the non-interpolation dimensions impact the interpolation in the way that the interpolation method must repeat the interpolation in the interpolation dimensions, for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimensions, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interploation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. + +The interpolation dimensions and the relationship between tie point dimensions and target domain diemensions must be indicated in the **`tie_point_indices`** attribute, see next section. + +[[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices Attribute"]] +==== Tie Point Indices Attribute + +To indicate the interpolation dimensions and tie point indices, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the target domain interpolation dimensions to the corresponding tie point indices variables. It is a blank-separated list of words of the form "__target_domain_dimension: tie_point_indices_variable [target_domain_dimension: tie_point_indices_variable] ...]__". Continuing the above example, to specify that the target dimension **`xc`** and **`yc`** are asociated with the tie point indices variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. + +The tie point indices variable contains, for each tie point, the zero-based indices of the related point in the target domain. The tie point indices is an integer variable of the corresponding tie point dimension. Continuing the above example, the tie point indices variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. + +For the interpolation dimensions, the relationships between target domain dimensions and the tie point dimensions are defined trough the **`tie_point_indices`** attribute in combination with the tie point indices variables. Each target domain dimension of the **`tie_point_indices`** attribute is related with the dimension of the corresponding tie point indices variable. + +Inclusion of non-interpolation dimensions in the **`tie_point_indices`** attribute is not permitted. + +[caption="Example 8.3. "] +.Two-dimensional tie point interpolation +==== +---- +dimensions: + xc = 30; + yc = 10; + tp_xc = 4 ; + tp_yc = 2 ; + +variables: + // Interpolation variables + char bi_linear ; + interpolation:interpolation_name = "bi_linear" ; + + // Tie point variables + double lat(tp_yc, tp_xc) ; + lat:units = "degrees_north" ; + lat:standard_name = "latitude" ; + double lon(tp_yc, tp_xc) ; + lon:units = "degrees_east" ; + lon:standard_name = "longitude" ; + + // Tie point indices variables + int y_indices(tp_yc) ; + int x_indices(tp_xc) ; + + // Data variable + float Temperature(yc, xc) ; + Temperature:standard_name = "air_temperature" ; + Temperature:units = "K" ; + Temperature:tie_points = "lat: lon: bi_linear" ; + Temperature:tie_point_indices = "yc: y_indices xc: x_indices" ; + +data: + x_indices = 0, 9, 19, 29 ; + y_indices = 0, 9 ; + ... +---- +==== + +[caption="Example 8.4. "] +.One-dimensional tie point interpolation +==== +---- +dimensions: + xc = 30; + yc = 10; + tp_xc = 4 ; + +variables: + // Interpolation variables + char linear ; + interpolation:interpolation_name = "linear" ; + + // Tie point variables + double lat(yc, tp_xc) ; + lat:units = "degrees_north" ; + lat:standard_name = "latitude" ; + double lon(yc, tp_xc) ; + lon:units = "degrees_east" ; + lon:standard_name = "longitude" ; + + // Tie point indices variables + int x_indices(tp_xc) ; + + // Data variable + float Temperature(yc, xc) ; + Temperature:standard_name = "air_temperature" ; + Temperature:units = "K" ; + Temperature:tie_points = "lat: lon: linear" ; + Temperature:tie_point_indices = "xc: x_indices" ; + +data: + x_indices = 0, 9, 19, 29 ; + ... +---- +==== + +[[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Offsets Attribute"]] +==== Tie Point Offsets Attribute + +Additionally to the **`tie_points`** and **`tie_point_indices`** attributes, which are always required for coordinate interpolation, a **`tie_point_offsets`** attribute is required if the tie point coordinate values are not a subset of the target domain coordinate values, but are offset with respect to these. + +The **`tie_point_offsets`** is a string attribute that, limited to horizontal interpolation dimensions, maps target domain dimensions to the corresponding tie point offsets variables. It is a blank-separated list of words of the form "__target_domain_dimension: tie_point_offsets_variable [target_domain_dimension: tie_point_offsets_variable] ...]__". + +This mapping is not part of the interpolation variable because different data variables may apply the same interpolation method, with the same tie points, but with different offsets. + +A tie point offset is a spatial offset, in terms of fraction of target domain grid cell size in the named dimension, between the tie point cells and the corresponding target domain cells. The corresponding target domain cell is defined through the **`tie_point_indices`** attribute. A tie point offset variable may be a scalar, or else its dimensions may include the tie point dimension corresponding to the named target domain dimension, as well as any subset of the non-interpolation dimensions. No other dimensions may be spanned by a tie point offset variable. + +For example, to specify that for both of the target dimensions **`track`** and **`scan`** the offset is contained in the scalar variable **`offset`**, could be indicated with **`track: offset scan: offset`**, where the offset variable is declared as **`double offset`** and could have the value **`offset = 0.5`**. + +[[compression-by-coordinate-interpolation-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] +==== Interpolation Variable + +The method used to uncompress the tie point variables is described by an interpolation variable that acts as a container for the attributes that define the interpolation technique and parameters that should be used. The variable should be a scalar (i.e. it has no dimensions) of arbitrary type, and the value of its single element is immaterial. + +To indicate that a standard interpolation method should be used, the interpolation variable must have a **`interpolation_name`** attribute defined, containing one of the valid values described in Appendix . This appendix also describes the interpolation technique and the interpolation variable attributes for configuring the interpolation process. + +If an interpolation name is not given, the interpolation variable must have a **`description`** attribute defined instead, containing a description of the non-standarised interpolationin attribute (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including a URI, for example). Whilst it is recommended that a standardised interpolation is provided, the alternative is provided to promote interpoperatibily in cases where a well defined user community needs to use sophisticated interpolation techniques that may also be under development. + +The definition of a standard or a non-strndard interpolation method may include instructions to treat groups of particular physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated with considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular standard names). + +In addition to the **`interpolation_name`** or the **`description`** attribute, only two other interpolation variabale attributes are permitted, the **`interpolation_coefficients`** and the **`interpolation_flags`** attributes. + +The **`interpolation_coefficients`** attribute is a string attribute that lists the __interpolation coefficients variables__. The variables refrenced must contain numeric data. It is a blank-separated list of words of the form "__interpolation_coefficients [interpolation_coefficients] ...]__". + +The **`interpolation_flags`** attribute is a string attribute that lists the __interpolation flags variables__. The variables refrenced must be flag variables. It is a blank-separated list of words of the form "__interpolation_flags [interpolation_flags] ...]__". + +The interpolation coefficients variables and the interpolation flags variables must either be scalar, or else their dimensions may include any of the tie point dimensions that are being interpolated, as well as the interpolation zone dimensions corresponding to each tie point dimension. The size of an interpolation zone dimension is equal the number of tie points, minus the number of interpolation zone groups. + +No other dimensions may be spanned by an interpolation coefficients variable or an interpolation flags variable. + + + + + + +The partitioning of metadata between the interpolation variable and the data variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. + +If there is a tie point for every element of a full resolution data dimension, then the tie point indices variable need not be included in the dataset, and may instead be replaced with the name of the corresponding tie point dimension during the usual mapping of data dimensions to tie point indices variables. This indicates that the tie point indices for this data dimension are simply the integers 0 to [size of tie point dimension minus one], and therefore do not need to be stored in a variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as an indices variable. + + + + +When a data variable has subsampled coordinates, it contains + + [REQUIRED] The names of the tie point coordinates and a mapping from + + tie point coordinates to interpolation variables, that describe + how to recreate the full resolution coordinates + + [REQUIRED] A mapping of data variable dimensions to their + corresponding indices variables + + [OPTIONAL] Extra information required to configure the + interpolation process that applies to all of the named + tie point variables. + + + The interpolation variable contains the following information + + [REQUIRED] The name (or description) of the interpolation method + to be used for recreating the full resolution coordinates. + + [OPTIONAL] Extra information required to configure the + interpolation process that applies to all of the named + tie point variables + + Notes diff --git a/images/regular_and_piecewise_regular_grid.png b/images/regular_and_piecewise_regular_grid.png new file mode 100644 index 0000000000000000000000000000000000000000..dde4caba28a810df0ac14fdaf6065c2234973826 GIT binary patch literal 77989 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

VSHVdX7H3hGS9{ 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 Q(4V?GdpH$sK5+W~0FG}BqyPW_ literal 0 HcmV?d00001 From adfa3c21e055f1f9dcece3c1bb6e21aafc7ea562 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 25 Nov 2020 17:45:53 +0100 Subject: [PATCH 005/249] Updte of Draft Ch08 changes for Coordinate Interpolation --- ch08.adoc | 230 ++++++++++++++---- images/regular_and_piecewise_regular_grid.png | Bin 77989 -> 76859 bytes 2 files changed, 179 insertions(+), 51 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 19955f33..42458405 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -70,32 +70,41 @@ This information implies that the salinity field should be uncompressed to an ar ==== - - [[compression-by-coordinate-interpolation, Section 8.3, "Compression by Coordinate Interpolation"]] === Compression by Coordinate Interpolation For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to user of the uncompressed dataset. -The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to ackowledge that, whilst the values of a tie point variable may be a subset of the uncompressed coordinate values, they can also be different to some or all of them. +The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset of the uncompressed coordinate values, they can also be different to some or all of them. Beyond the tie point variables themselves, metadata of the coordinate interpolation is stored in attributes of the data variable and the __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. -The data variable coordinate interpolation attributes may also be used on a domain variable (see the domain variable issue #??) with the same effect. -[[compression-by-coordinate-interpolation-variables, Section 8.3.1, "Tie Points, Interpolation Zones and Interpolation Zone Groups"]] -==== Tie Points, Interpolation Zones and Interpolation Zone Groups -[[img-bnd_2d_coords, figure 3]] -[.text-center] -.When grid discontinuities, such as spatial gaps or overlaps, are present, the grid is divided into multiple Interpolation Zone Groups, each of which is free of grid discontinuities. Otherwise the whole grid is a single Interpolation Zone Group. The Interpolation Zone Groups are futher subdivided into Interpolation Zones for the purpose of coordinate interpolation. -image::images/regular_and_piecewise_regular_grid.png[,100%,pdfwidth=50vw,align="center"] +The data variable coordinate interpolation attributes may also be used on a domain variable (<>) with the same effect. + +[[compression-by-coordinate-tie-points, Section 8.3.1, "Tie Points and Interpolation Zones"]] +==== Tie Points and Interpolation Zones + +Reconstitution of the uncompressed coordinates and auxiliary coordinates is based on interpolation. To accomplish this, the target domain grid is segmented into smaller __interpolation zones__, for each of which the interpolation method can be applied independently. For one dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone. For two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes. For the reconstitution of the uncompressed coordinates and auxiliary coordinates within an interpolation zone, the interpolation method is permitted to access the coordinates of the defining tie points, but not the coordinates of any other tie points. +Although the coordinates and auxiliary coordinates are stored in regular arrays, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the location coordinates or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. +As the interpolation methods relies on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in Figure XX. +Within an interpolation areas, interpolation zones must share tie point with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the to cases shown the lower part of Figure XX. +For each dimension, the indices of the tie points in the target domain are stored in a corresponding tie point indices variable(<>). In the tie point indices variable, two subsequent indices where the value of the second is the equal to the value of the first incremented by one, indicates the location of a interpolation area boundary. + +For each dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. + + +[[interpolation_zone_generation, figure 3]] +[.text-center] +.Process for generating the interpolation zones for a grid without discontinuities and for a grid with discontinuities. +image::images/regular_and_piecewise_regular_grid.png[,100%,pdfwidth=50vw,align="center"] -[[compression-by-coordinate-interpolation-variables, Section 8.3.2, "Tie Points Attribute"]] +[[compression-by-coordinate-tie-points-attribute, Section 8.3.2, "Tie Points Attribute"]] ==== Tie Points Attribute To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. @@ -105,16 +114,16 @@ To indicate that coordinate interpolation is required, a **`tie_points`** attrib For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie points must share the same set of dimensions. The set of dimensions must contain at least one __interpolation dimension__ and may additionally contain one or more __non-interpolation dimensions__. -For the interpolation dimensions, where interpolation is applied, the tie point dimension typically differ from the corresponding dimension in the target domain. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point dimension related to the target dimension **`xc`** and **`tp_yc`** is the tie point dimension related to the target dimension **`yc`**. +For the interpolation dimensions, where interpolation is applied, the tie point dimension typically differ from the corresponding dimension of the target domain. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point dimension related to the target dimension **`xc`** and **`tp_yc`** is the tie point dimension related to the target dimension **`yc`**. -For each of the non-interpolation dimensions, the tie point dimension and the corresponding target domain dimension are equal and no interpolation is applied. However, the non-interpolation dimensions impact the interpolation in the way that the interpolation method must repeat the interpolation in the interpolation dimensions, for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimensions, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interploation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. +For each of the non-interpolation dimensions, the tie point dimension and the corresponding target domain dimension are equal and no interpolation is applied. However, the non-interpolation dimensions impact the interpolation in the way that the interpolation method must repeat the interpolation in the interpolation dimensions, for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. -The interpolation dimensions and the relationship between tie point dimensions and target domain diemensions must be indicated in the **`tie_point_indices`** attribute, see next section. +The interpolation dimensions and the relationship between tie point dimensions and target domain dimensions must be indicated in the **`tie_point_indices`** attribute, see next section. [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices Attribute"]] ==== Tie Point Indices Attribute -To indicate the interpolation dimensions and tie point indices, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the target domain interpolation dimensions to the corresponding tie point indices variables. It is a blank-separated list of words of the form "__target_domain_dimension: tie_point_indices_variable [target_domain_dimension: tie_point_indices_variable] ...]__". Continuing the above example, to specify that the target dimension **`xc`** and **`yc`** are asociated with the tie point indices variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. +To indicate the interpolation dimensions and tie point indices, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the target domain interpolation dimensions to the corresponding tie point indices variables. It is a blank-separated list of words of the form "__target_domain_dimension: tie_point_indices_variable [target_domain_dimension: tie_point_indices_variable] ...]__". Continuing the above example, to specify that the target dimension **`xc`** and **`yc`** are associated with the tie point indices variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. The tie point indices variable contains, for each tie point, the zero-based indices of the related point in the target domain. The tie point indices is an integer variable of the corresponding tie point dimension. Continuing the above example, the tie point indices variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. @@ -212,63 +221,182 @@ This mapping is not part of the interpolation variable because different data va A tie point offset is a spatial offset, in terms of fraction of target domain grid cell size in the named dimension, between the tie point cells and the corresponding target domain cells. The corresponding target domain cell is defined through the **`tie_point_indices`** attribute. A tie point offset variable may be a scalar, or else its dimensions may include the tie point dimension corresponding to the named target domain dimension, as well as any subset of the non-interpolation dimensions. No other dimensions may be spanned by a tie point offset variable. -For example, to specify that for both of the target dimensions **`track`** and **`scan`** the offset is contained in the scalar variable **`offset`**, could be indicated with **`track: offset scan: offset`**, where the offset variable is declared as **`double offset`** and could have the value **`offset = 0.5`**. +For example, to specify that for both of the target dimensions **`track`** and **`scan`** the offset is contained in the scalar variable **`offset`**, could be indicated with **`track: offset scan: offset`**, where the offset variable is declared as **`double offset`** and could have the value **`offset = -0.5`**. [[compression-by-coordinate-interpolation-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] ==== Interpolation Variable -The method used to uncompress the tie point variables is described by an interpolation variable that acts as a container for the attributes that define the interpolation technique and parameters that should be used. The variable should be a scalar (i.e. it has no dimensions) of arbitrary type, and the value of its single element is immaterial. +The method used to uncompress the tie point variables is described by an interpolation variable that acts as a container for the attributes that define the interpolation technique and the parameters that should be used. The variable should be a scalar (i.e. it has no dimensions) of arbitrary type, and the value of its single element is immaterial. To indicate that a standard interpolation method should be used, the interpolation variable must have a **`interpolation_name`** attribute defined, containing one of the valid values described in Appendix . This appendix also describes the interpolation technique and the interpolation variable attributes for configuring the interpolation process. -If an interpolation name is not given, the interpolation variable must have a **`description`** attribute defined instead, containing a description of the non-standarised interpolationin attribute (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including a URI, for example). Whilst it is recommended that a standardised interpolation is provided, the alternative is provided to promote interpoperatibily in cases where a well defined user community needs to use sophisticated interpolation techniques that may also be under development. +If an interpolation name is not given, the interpolation variable must have a **`description`** attribute defined instead, containing a description of the non-standardised interpolation (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including a URI, for example). Whilst it is recommended that a standardised interpolation is provided, the alternative is provided to promote interoperability in cases where a well defined user community needs to use sophisticated interpolation techniques that may also be under development. -The definition of a standard or a non-strndard interpolation method may include instructions to treat groups of particular physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated with considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular standard names). +The definition of a standard or a non-standard interpolation method may include instructions to treat groups of particular physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular standard names). -In addition to the **`interpolation_name`** or the **`description`** attribute, only two other interpolation variabale attributes are permitted, the **`interpolation_coefficients`** and the **`interpolation_flags`** attributes. +In addition to the **`interpolation_name`** or the **`description`** attribute, only two other interpolation variable attributes are permitted, the **`interpolation_coefficients`** and the **`interpolation_flags`** attributes. -The **`interpolation_coefficients`** attribute is a string attribute that lists the __interpolation coefficients variables__. The variables refrenced must contain numeric data. It is a blank-separated list of words of the form "__interpolation_coefficients [interpolation_coefficients] ...]__". +The **`interpolation_coefficients`** attribute is a string attribute that lists the __interpolation coefficients variables__. The variables referenced must contain numeric data. It is a blank-separated list of words of the form "__interpolation_coefficients [interpolation_coefficients] ...]__". -The **`interpolation_flags`** attribute is a string attribute that lists the __interpolation flags variables__. The variables refrenced must be flag variables. It is a blank-separated list of words of the form "__interpolation_flags [interpolation_flags] ...]__". +The **`interpolation_flags`** attribute is a string attribute that lists the __interpolation flags variables__. The variables referenced must be flag variables (<>). It is a blank-separated list of words of the form "__interpolation_flags [interpolation_flags] ...]__". -The interpolation coefficients variables and the interpolation flags variables must either be scalar, or else their dimensions may include any of the tie point dimensions that are being interpolated, as well as the interpolation zone dimensions corresponding to each tie point dimension. The size of an interpolation zone dimension is equal the number of tie points, minus the number of interpolation zone groups. +The interpolation coefficients variables and the interpolation flags variables must either be scalar, or else their dimensions may include any of the tie point dimensions that are being interpolated, as well as the interpolation zone dimensions corresponding to each tie point dimension. The size of an interpolation zone dimension is equal the number of tie points, minus the number of interpolation areas. No other dimensions may be spanned by an interpolation coefficients variable or an interpolation flags variable. - - - - - -The partitioning of metadata between the interpolation variable and the data variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. - If there is a tie point for every element of a full resolution data dimension, then the tie point indices variable need not be included in the dataset, and may instead be replaced with the name of the corresponding tie point dimension during the usual mapping of data dimensions to tie point indices variables. This indicates that the tie point indices for this data dimension are simply the integers 0 to [size of tie point dimension minus one], and therefore do not need to be stored in a variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as an indices variable. +[caption="Example 8.5. "] +.Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation flags attributes. +==== +---- +dimensions : + // VIIRS M-Band (750 m resolution imaging) + m_track = 768 ; + m_scan = 3200 ; + m_channel = 16 ; + + // VIIRS I-Band (375 m resolution imaging) + i_track = 1536 ; + i_scan = 6400 ; + i_channel = 5 ; + + // Tie points and interpolation zones (shared between VIIRS M-Band and I-Band) + tp_track = 96 ; // 48 VIIRS scans + tp_scan = 205 ; + track_interpolation_zone = 48 ; + scan_interpolation_zone = 200 ; + + // Time, stored at scan-start and scan-end of each scan + time_scan = 2; +variables: + // VIIRS M-Band + float m_radiance(m_track, m_scan, m_channel) ; + m_radiance:tie_points = "lat: lon: sen_azi_ang: sen_zen_ang: sol_azi_ang: sol_zen_ang: tp_interpolation t: time_interpolation" ; + m_radiance:tie_point_indices = "m_track: m_track_indices m_scan: m_scan_indices time_scan: m_time_scan_indices" ; + m_radiance:tie_point_offsets = "m_track: offset m_scan: offset" ; + + // VIIRS I-Band + float i_radiance(i_track, i_scan, i_channel) ; + i_radiance:tie_points = "lat: lon: sen_azi_ang: sen_zen_ang: sol_azi_ang: sol_zen_ang: tp_interpolation t: time_interpolation" ; + i_radiance:tie_point_indices = "i_track: i_track_indices i_scan: i_scan_indices time_scan: i_time_scan_indices" ; + i_radiance:tie_point_offsets = "i_track: offset i_scan: offset" ; + + double offset; // = -0.5 + + // Tie point indices + int m_track_indices(tp_track) ; // shared by tp_interpolation and time_interpolation + int m_scan_indices(tp_scan) ; + int m_time_scan_indices(time_scan) + int i_track_indices(tp_track) ; // shared by tp_interpolation and time_interpolation + int i_scan_indices(tp_scan) ; + int i_time_scan_indices(time_scan) + + // Tie points + float lat(tp_track, tp_scan) ; + lat : standard_name = "latitude" ; + lat : units = "degrees_north" ; + float lon(tp_track, tp_scan) ; + lon : standard_name = "longitude" ; + lon : units = "degrees_east" ; + float sen_azi_ang(tp_track, tp_scan) ; + sen_azi_ang : standard_name = "sensor_azimuth_angle" ; + sen_azi_ang : units = "degrees" ; + float sen_zen_ang(tp_track, tp_scan) ; + sen_zen_ang : standard_name = "sensor_zenith_angle" ; + sen_zen_ang : units = "degrees" ; + float sol_azi_ang(tp_track, tp_scan) ; + sol_azi_ang : standard_name = "solar_azimuth_angle" ; + sol_azi_ang : units = "degrees" ; + float sol_zen_ang(tp_track, tp_scan) ; + sol_zen_ang : standard_name = "solar_zenith_angle" ; + sol_zen_ang : units = "degrees" ; + + // Interpolation variable + char tp_interpolation ; + tp_interpolation:interpolation_name = "bi_quadratic_1" ; + tp_interpolation:interpolation_coefficients = "expansion_coefficient_track alignment_coefficient_track expansion_coefficient_scan alignment_coefficient_scan" ; + tp_interpolation:interpolation_flags = "interpolation_zone_flags" ; + + // Interpolation coefficients and flags + short expansion_coefficient_track(track_interpolation_zone, tp_scan) ; + short alignment_coefficient_track(track_interpolation_zone, tp_scan) ; + short expansion_coefficient_scan(tp_track, scan_interpolation_zone) ; + short alignment_coefficient_scan(tp_track, scan_interpolation_zone) ; + byte interpolation_zone_flags(track_interpolation_zone, scan_interpolation_zone) ; + interpolation_zone_flags : valid_range = "1b, 7b" ; + interpolation_zone_flags : flag_masks = "1b, 2b, 4b" ; + interpolation_zone_flags : flag_meanings = "location_use_cartesian sensor_direction_use_cartesian solar_direction_use_cartesian" ; + + // Time tie points + double t(tp_track, time_scan) ; + t : long_name = "time" ; + t : units = "days since 1990-1-1 0:0:0" ; + + // Time interploation variable + char time_interpolation ; + time_interpolation : interpolation_name = "bi_linear" ; +---- +==== +[caption="Example 8.6. "] +.Example demonstrating the combination of grid mapping and coordinate interpolation with time as a non-interpolation dimension. The projection coordinates are 2-D, but are only linearly interpolated in one of their dimensions - the one which is given by the tie_point_indices attribute. +==== +---- +dimensions: + y = 228; + x = 306; + time = 41; -When a data variable has subsampled coordinates, it contains - - [REQUIRED] The names of the tie point coordinates and a mapping from - - tie point coordinates to interpolation variables, that describe - how to recreate the full resolution coordinates - - [REQUIRED] A mapping of data variable dimensions to their - corresponding indices variables - - [OPTIONAL] Extra information required to configure the - interpolation process that applies to all of the named - tie point variables. + // Tie point dimensions + tp_y = 58; + tp_x = 52; +variables: + int lambert_conformal ; + lambert_conformal:grid_mapping_name = "lambert_conformal_conic" ; + lambert_conformal:standard_parallel = 25.0 ; + lambert_conformal:longitude_of_central_meridian = 265.0 ; + lambert_conformal:latitude_of_projection_origin = 25.0 ; - The interpolation variable contains the following information + // Interpolation variables + char spherical_bilinear ; + spherical_bilinear:interpolation_name = "spherical_bilinear" ; + char linear ; + linear:interpolation_name = "linear" ; - [REQUIRED] The name (or description) of the interpolation method - to be used for recreating the full resolution coordinates. - - [OPTIONAL] Extra information required to configure the - interpolation process that applies to all of the named - tie point variables + // Tie point variables + double time(time) ; + time:standard_name = "time" ; + time:units = "days since 2021-03-01" ; + double y(time, tp_y) ; + y:units = "km" ; + y:standard_name = "projection_y_coordinate" ; + double x(time, tp_x) ; + x:units = "km" ; + x:standard_name = "projection_x_coordinate" ; + double lat(time, tp_y, tp_x) ; + lat:units = "degrees_north" ; + lat:standard_name = "latitude" ; + double lon(time, tp_y, tp_x) ; + lon:units = "degrees_east" ; + lon:standard_name = "longitude" ; + + // Tie point index variables + int y_indices(tp_y) ; + y_indices.long_name = "Mapping of y dimension to its ", + "corresponding tie point dimension" ; + int x_indices(tp_x) ; + x_indices.long_name = "Mapping of x dimension to its ", + "corresponding tie point dimension" ; - Notes + // Data variable + float Temperature(time, y, x) ; + Temperature:standard_name = "air_temperature" ; + Temperature:units = "K" ; + Temperature:grid_mapping = "lambert_conformal" ; + Temperature:tie_points = "lat: lon: spherical_bilinear y: x: linear" ; + Temperature:tie_point_indices = "y: y_indices x: x_indices" ; +---- +==== diff --git a/images/regular_and_piecewise_regular_grid.png b/images/regular_and_piecewise_regular_grid.png index dde4caba28a810df0ac14fdaf6065c2234973826..3b6af0d609163ae67013e8297b64263da6531e62 100644 GIT binary patch literal 76859 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 literal 77989 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

VSHVdX7H3hGS9{ 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 Q(4V?GdpH$sK5+W~0FG}BqyPW_ From 1bbd297ee1d943aae831c45967c0b5504dcde73d Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 25 Nov 2020 18:32:37 +0100 Subject: [PATCH 006/249] Updte of Draft Ch08 changes for Coordinate Interpolation --- ch08.adoc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 42458405..45b99f80 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -90,11 +90,11 @@ Reconstitution of the uncompressed coordinates and auxiliary coordinates is base Although the coordinates and auxiliary coordinates are stored in regular arrays, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the location coordinates or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. -As the interpolation methods relies on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in Figure XX. +As the interpolation methods relies on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in Figure <>. -Within an interpolation areas, interpolation zones must share tie point with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the to cases shown the lower part of Figure XX. +Within an interpolation area, interpolation zones must share tie point with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the to cases shown in Figure <>. -For each dimension, the indices of the tie points in the target domain are stored in a corresponding tie point indices variable(<>). In the tie point indices variable, two subsequent indices where the value of the second is the equal to the value of the first incremented by one, indicates the location of a interpolation area boundary. +For each dimension, the indices of the tie points in the target domain are stored in a corresponding tie point indices variable (<>). In the tie point indices variable, two subsequent indices where the value of the second is the equal to the value of the first incremented by one, indicates the location of a interpolation area boundary. For each dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. @@ -131,6 +131,10 @@ For the interpolation dimensions, the relationships between target domain dimens Inclusion of non-interpolation dimensions in the **`tie_point_indices`** attribute is not permitted. +If there is a tie point for every element of a full resolution data dimension, then the tie point indices variable need not be included in the dataset, and may instead be replaced with the name of the corresponding tie point dimension during the usual mapping of data dimensions to tie point indices variables. This indicates that the tie point indices for this data dimension are simply the integers 0 to [size of tie point dimension minus one], and therefore do not need to be stored in a variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as an indices variable. + +(To Do: Add text on super-sampling) + [caption="Example 8.3. "] .Two-dimensional tie point interpolation ==== @@ -244,8 +248,6 @@ The interpolation coefficients variables and the interpolation flags variables m No other dimensions may be spanned by an interpolation coefficients variable or an interpolation flags variable. -If there is a tie point for every element of a full resolution data dimension, then the tie point indices variable need not be included in the dataset, and may instead be replaced with the name of the corresponding tie point dimension during the usual mapping of data dimensions to tie point indices variables. This indicates that the tie point indices for this data dimension are simply the integers 0 to [size of tie point dimension minus one], and therefore do not need to be stored in a variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as an indices variable. - [caption="Example 8.5. "] .Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation flags attributes. ==== From 99c6ecdbb0129d1cfd99f7644760b3e5cdd3660b Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 11:35:45 +0000 Subject: [PATCH 007/249] review 1 --- ch08.adoc | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 45b99f80..01232a83 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -86,13 +86,13 @@ The data variable coordinate interpolation attributes may also be used on a doma [[compression-by-coordinate-tie-points, Section 8.3.1, "Tie Points and Interpolation Zones"]] ==== Tie Points and Interpolation Zones -Reconstitution of the uncompressed coordinates and auxiliary coordinates is based on interpolation. To accomplish this, the target domain grid is segmented into smaller __interpolation zones__, for each of which the interpolation method can be applied independently. For one dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone. For two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes. For the reconstitution of the uncompressed coordinates and auxiliary coordinates within an interpolation zone, the interpolation method is permitted to access the coordinates of the defining tie points, but not the coordinates of any other tie points. +Reconstitution of the uncompressed coordinate and auxiliary coordinate variables is based on interpolation. To accomplish this, the target domain grid is segmented into smaller __interpolation zones__, for each of which the interpolation method can be applied independently. For one dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone. For two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables within an interpolation zone, the interpolation method is permitted to access the coordinates of the defining tie points, but not the coordinates of any other tie points. -Although the coordinates and auxiliary coordinates are stored in regular arrays, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the location coordinates or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. +Although the coordinate and auxiliary coordinate variables are stored in orthogonal multidimensional array representation, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. -As the interpolation methods relies on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in Figure <>. +As the interpolation methods rely on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in Figure <>. -Within an interpolation area, interpolation zones must share tie point with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the to cases shown in Figure <>. +Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in Figure <>. For each dimension, the indices of the tie points in the target domain are stored in a corresponding tie point indices variable (<>). In the tie point indices variable, two subsequent indices where the value of the second is the equal to the value of the first incremented by one, indicates the location of a interpolation area boundary. @@ -112,26 +112,29 @@ To indicate that coordinate interpolation is required, a **`tie_points`** attrib [[compression-by-coordinate-interpolation-dimensions,Section 8.3.3, "Data Variable Attributes"]] ==== Interpolation and Non-Interpolation Dimensions -For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie points must share the same set of dimensions. The set of dimensions must contain at least one __interpolation dimension__ and may additionally contain one or more __non-interpolation dimensions__. +For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required, and may additionally contain one or more non-interpolation dimensions, i.e. those of the target domain for which no coordinate interpolation is required. -For the interpolation dimensions, where interpolation is applied, the tie point dimension typically differ from the corresponding dimension of the target domain. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point dimension related to the target dimension **`xc`** and **`tp_yc`** is the tie point dimension related to the target dimension **`yc`**. +An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables for the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point interpolation dimension related to the interpolation dimension **`xc`**, and **`tp_yc`** is the tie point interpolation dimension related to the interpolation dimension **`yc`**. -For each of the non-interpolation dimensions, the tie point dimension and the corresponding target domain dimension are equal and no interpolation is applied. However, the non-interpolation dimensions impact the interpolation in the way that the interpolation method must repeat the interpolation in the interpolation dimensions, for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. +The presence of non-interpolation dimensions in thtie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. -The interpolation dimensions and the relationship between tie point dimensions and target domain dimensions must be indicated in the **`tie_point_indices`** attribute, see next section. +The interpolation dimensions and the relationship between tie point interpolation dimensions and target domain dimensions must be indicated in the **`tie_point_indices`** attribute, see next section. [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices Attribute"]] ==== Tie Point Indices Attribute -To indicate the interpolation dimensions and tie point indices, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the target domain interpolation dimensions to the corresponding tie point indices variables. It is a blank-separated list of words of the form "__target_domain_dimension: tie_point_indices_variable [target_domain_dimension: tie_point_indices_variable] ...]__". Continuing the above example, to specify that the target dimension **`xc`** and **`yc`** are associated with the tie point indices variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point indices variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point indices is a one-dimensional integer variable that spans a tie point interpolation dimension. For example, the tie point indices variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. -The tie point indices variable contains, for each tie point, the zero-based indices of the related point in the target domain. The tie point indices is an integer variable of the corresponding tie point dimension. Continuing the above example, the tie point indices variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. +NOTE: should we say that the indices must be strictly monotonically (increasing)? + +To indicate which tie point indices variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point indices variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_indices_variable [interpolation_dimension: tie_point_indices_variable] ...]__". Continuing the above example, to specify that the target dimension **`xc`** and **`yc`** are associated with the tie point indices variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. + +The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point indices variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point indicies variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. -For the interpolation dimensions, the relationships between target domain dimensions and the tie point dimensions are defined trough the **`tie_point_indices`** attribute in combination with the tie point indices variables. Each target domain dimension of the **`tie_point_indices`** attribute is related with the dimension of the corresponding tie point indices variable. Inclusion of non-interpolation dimensions in the **`tie_point_indices`** attribute is not permitted. -If there is a tie point for every element of a full resolution data dimension, then the tie point indices variable need not be included in the dataset, and may instead be replaced with the name of the corresponding tie point dimension during the usual mapping of data dimensions to tie point indices variables. This indicates that the tie point indices for this data dimension are simply the integers 0 to [size of tie point dimension minus one], and therefore do not need to be stored in a variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as an indices variable. +If there is a tie point index for every element of an interpolation dimension, then the tie point indices variable need not be included in the dataset, and may instead be replaced with the name of the corresponding tie point interpolation dimension during the usual mapping of interpolation dimensions to tie point indices variables. This indicates that the tie point indices for this data dimension are simply the integers 0 to [size of tie point interpolation dimension minus one], and therefore do not need to be stored in a variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point indices variable. (To Do: Add text on super-sampling) From f434f931223abd2a0b053609da53de3da9d8346b Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 11:58:21 +0000 Subject: [PATCH 008/249] review 1 --- ch08.adoc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 01232a83..a0769d5e 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -77,7 +77,7 @@ For some applications the coordinates of a data variable can require considerabl The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset of the uncompressed coordinate values, they can also be different to some or all of them. -Beyond the tie point variables themselves, metadata of the coordinate interpolation is stored in attributes of the data variable and the __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. +In addition to the tie point variables themselves, metadata defingin the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. @@ -86,9 +86,9 @@ The data variable coordinate interpolation attributes may also be used on a doma [[compression-by-coordinate-tie-points, Section 8.3.1, "Tie Points and Interpolation Zones"]] ==== Tie Points and Interpolation Zones -Reconstitution of the uncompressed coordinate and auxiliary coordinate variables is based on interpolation. To accomplish this, the target domain grid is segmented into smaller __interpolation zones__, for each of which the interpolation method can be applied independently. For one dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone. For two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables within an interpolation zone, the interpolation method is permitted to access the coordinates of the defining tie points, but not the coordinates of any other tie points. +Reconstitution of the uncompressed coordinate and auxiliary coordinate variables is based on interpolation. To accomplish this, the target domain is segmented into smaller __interpolation zones__, for each of which the interpolation method is applied independently. For one dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone; for two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes; etc. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables within an interpolation zone, the interpolation method is permitted to access the coordinates of the defining tie points, but not the coordinates of any other tie points. -Although the coordinate and auxiliary coordinate variables are stored in orthogonal multidimensional array representation, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. +Although the coordinate and auxiliary coordinate variables are stored in orthogonal multidimensional array representation, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates, or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. As the interpolation methods rely on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in Figure <>. @@ -96,7 +96,7 @@ Within an interpolation area, interpolation zones must share tie points with nei For each dimension, the indices of the tie points in the target domain are stored in a corresponding tie point indices variable (<>). In the tie point indices variable, two subsequent indices where the value of the second is the equal to the value of the first incremented by one, indicates the location of a interpolation area boundary. -For each dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. +For each interpolation dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. [[interpolation_zone_generation, figure 3]] @@ -112,7 +112,7 @@ To indicate that coordinate interpolation is required, a **`tie_points`** attrib [[compression-by-coordinate-interpolation-dimensions,Section 8.3.3, "Data Variable Attributes"]] ==== Interpolation and Non-Interpolation Dimensions -For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required, and may additionally contain one or more non-interpolation dimensions, i.e. those of the target domain for which no coordinate interpolation is required. +For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required; and may additionally contain one or more non-interpolation dimensions, i.e. those of the target domain for which no coordinate interpolation is required. An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables for the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point interpolation dimension related to the interpolation dimension **`xc`**, and **`tp_yc`** is the tie point interpolation dimension related to the interpolation dimension **`yc`**. @@ -127,12 +127,12 @@ The relationship between a tie point interpolation dimension and its correspondi NOTE: should we say that the indices must be strictly monotonically (increasing)? -To indicate which tie point indices variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point indices variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_indices_variable [interpolation_dimension: tie_point_indices_variable] ...]__". Continuing the above example, to specify that the target dimension **`xc`** and **`yc`** are associated with the tie point indices variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. +To indicate which tie point indices variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point indices variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_indices_variable [interpolation_dimension: tie_point_indices_variable] ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point indices variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point indices variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point indicies variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. -Inclusion of non-interpolation dimensions in the **`tie_point_indices`** attribute is not permitted. +The reference of non-interpolation dimensions in the **`tie_point_indices`** attribute is not permitted. If there is a tie point index for every element of an interpolation dimension, then the tie point indices variable need not be included in the dataset, and may instead be replaced with the name of the corresponding tie point interpolation dimension during the usual mapping of interpolation dimensions to tie point indices variables. This indicates that the tie point indices for this data dimension are simply the integers 0 to [size of tie point interpolation dimension minus one], and therefore do not need to be stored in a variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point indices variable. From ec21b5ac6b376a9c05fd9d84cf47c5c0c591cc85 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 12:01:44 +0000 Subject: [PATCH 009/249] review 1 --- ch08.adoc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index a0769d5e..758a9650 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -112,14 +112,12 @@ To indicate that coordinate interpolation is required, a **`tie_points`** attrib [[compression-by-coordinate-interpolation-dimensions,Section 8.3.3, "Data Variable Attributes"]] ==== Interpolation and Non-Interpolation Dimensions -For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required; and may additionally contain one or more non-interpolation dimensions, i.e. those of the target domain for which no coordinate interpolation is required. +For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required; and may additionally contain one or more __non-interpolation dimensions__, i.e. those of the target domain for which no coordinate interpolation is required. An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables for the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point interpolation dimension related to the interpolation dimension **`xc`**, and **`tp_yc`** is the tie point interpolation dimension related to the interpolation dimension **`yc`**. The presence of non-interpolation dimensions in thtie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. -The interpolation dimensions and the relationship between tie point interpolation dimensions and target domain dimensions must be indicated in the **`tie_point_indices`** attribute, see next section. - [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices Attribute"]] ==== Tie Point Indices Attribute From eeb94fec6c86dbe026f3f47ca94871d4dbfbdf92 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 12:25:25 +0000 Subject: [PATCH 010/249] review 1 --- ch08.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 758a9650..4e5ba4be 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -77,7 +77,7 @@ For some applications the coordinates of a data variable can require considerabl The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset of the uncompressed coordinate values, they can also be different to some or all of them. -In addition to the tie point variables themselves, metadata defingin the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. +In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. @@ -116,7 +116,7 @@ For each interpolation variable identified in the **`tie_points`** attribute, al An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables for the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point interpolation dimension related to the interpolation dimension **`xc`**, and **`tp_yc`** is the tie point interpolation dimension related to the interpolation dimension **`yc`**. -The presence of non-interpolation dimensions in thtie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. +The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices Attribute"]] ==== Tie Point Indices Attribute @@ -127,7 +127,7 @@ NOTE: should we say that the indices must be strictly monotonically (increasing) To indicate which tie point indices variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point indices variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_indices_variable [interpolation_dimension: tie_point_indices_variable] ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point indices variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. -The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point indices variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point indicies variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. +The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point indices variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point indices variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. The reference of non-interpolation dimensions in the **`tie_point_indices`** attribute is not permitted. From 26c2bc3d2b50660d5d83177ebffe0812644063f7 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 12:36:57 +0000 Subject: [PATCH 011/249] review 1 --- ch08.adoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 4e5ba4be..9ca25579 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -129,10 +129,9 @@ To indicate which tie point indices variable applies to each interpolation dimen The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point indices variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point indices variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. - The reference of non-interpolation dimensions in the **`tie_point_indices`** attribute is not permitted. -If there is a tie point index for every element of an interpolation dimension, then the tie point indices variable need not be included in the dataset, and may instead be replaced with the name of the corresponding tie point interpolation dimension during the usual mapping of interpolation dimensions to tie point indices variables. This indicates that the tie point indices for this data dimension are simply the integers 0 to [size of tie point interpolation dimension minus one], and therefore do not need to be stored in a variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point indices variable. +If there is a tie point index for every element of an interpolation dimension, then the tie point indices variable need not be included in the dataset, as its contains must be the integers 0 to [size of tie point interpolation dimension minus one], and therefore do not need to be stored in a variable. Instead, the **`tie_point_indices`** attribute may associate the interpolation dimension with the tie point dimension dimension, rather than a tie point index variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point indices variable. (To Do: Add text on super-sampling) From 8d43dd62aeb739b6d895511902fd64de346b2438 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 12:45:32 +0000 Subject: [PATCH 012/249] review 1 --- ch08.adoc | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 9ca25579..044b954f 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -94,7 +94,9 @@ As the interpolation methods rely on a certain regularity and continuity of the Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in Figure <>. -For each dimension, the indices of the tie points in the target domain are stored in a corresponding tie point indices variable (<>). In the tie point indices variable, two subsequent indices where the value of the second is the equal to the value of the first incremented by one, indicates the location of a interpolation area boundary. +The relationship betweeFor each interpolation dimension, the indices of the tie points in the target domain are stored in a corresponding tie point index variable (<>). In the tie point indices variable, two subsequent indices where the value of the second is the equal to the value of the first incremented by one, indicates the location of a interpolation area boundary. + +For each dimension, the location of the tie points is defined by a corresponding __tie point index variable__ (<>) For each interpolation dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. @@ -119,19 +121,21 @@ An interpolation dimension typically differs in size from the corresponding tie The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices Attribute"]] -==== Tie Point Indices Attribute +==== Tie Point Indices + +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. For example, the tie point index variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point indices variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point indices is a one-dimensional integer variable that spans a tie point interpolation dimension. For example, the tie point indices variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. +In the tie point index variable, two adjacent indices where the value of the second is the equal to the value of the first incremented by one indicates the location of a interpolation area boundary. NOTE: should we say that the indices must be strictly monotonically (increasing)? -To indicate which tie point indices variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point indices variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_indices_variable [interpolation_dimension: tie_point_indices_variable] ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point indices variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. +To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable] ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. -The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point indices variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point indices variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. +The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point index variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point index variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. The reference of non-interpolation dimensions in the **`tie_point_indices`** attribute is not permitted. -If there is a tie point index for every element of an interpolation dimension, then the tie point indices variable need not be included in the dataset, as its contains must be the integers 0 to [size of tie point interpolation dimension minus one], and therefore do not need to be stored in a variable. Instead, the **`tie_point_indices`** attribute may associate the interpolation dimension with the tie point dimension dimension, rather than a tie point index variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point indices variable. +If there is a tie point index for every element of an interpolation dimension, then the tie point index variable need not be included in the dataset, as its contains must be the integers 0 to [size of tie point interpolation dimension minus one], and therefore do not need to be stored in a variable. Instead, the **`tie_point_indices`** attribute may associate the interpolation dimension with the tie point dimension dimension, rather than a tie point index variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point index variable. (To Do: Add text on super-sampling) @@ -158,7 +162,7 @@ variables: lon:units = "degrees_east" ; lon:standard_name = "longitude" ; - // Tie point indices variables + // Tie point index variables int y_indices(tp_yc) ; int x_indices(tp_xc) ; @@ -198,7 +202,7 @@ variables: lon:units = "degrees_east" ; lon:standard_name = "longitude" ; - // Tie point indices variables + // Tie point index variables int x_indices(tp_xc) ; // Data variable @@ -287,7 +291,7 @@ variables: double offset; // = -0.5 - // Tie point indices + // Tie point index variables int m_track_indices(tp_track) ; // shared by tp_interpolation and time_interpolation int m_scan_indices(tp_scan) ; int m_time_scan_indices(time_scan) From a5fb0578da5833bfb2ac2c7a1033064a285e8b30 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 12:47:33 +0000 Subject: [PATCH 013/249] review 1 --- ch08.adoc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 044b954f..eb9327e5 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -94,9 +94,7 @@ As the interpolation methods rely on a certain regularity and continuity of the Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in Figure <>. -The relationship betweeFor each interpolation dimension, the indices of the tie points in the target domain are stored in a corresponding tie point index variable (<>). In the tie point indices variable, two subsequent indices where the value of the second is the equal to the value of the first incremented by one, indicates the location of a interpolation area boundary. - -For each dimension, the location of the tie points is defined by a corresponding __tie point index variable__ (<>) +For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__ (<>) For each interpolation dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. From 59d24012a00fb6298ca8fc1b5f15935faa07ee4f Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 12:49:39 +0000 Subject: [PATCH 014/249] review 1 --- ch08.adoc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index eb9327e5..fb841490 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -118,15 +118,13 @@ An interpolation dimension typically differs in size from the corresponding tie The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. -[[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices Attribute"]] +[[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. For example, the tie point index variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing. For example, the tie point index variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. In the tie point index variable, two adjacent indices where the value of the second is the equal to the value of the first incremented by one indicates the location of a interpolation area boundary. -NOTE: should we say that the indices must be strictly monotonically (increasing)? - To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable] ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point index variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point index variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. From 554cb61cc113417aecfaa3888df98f77f7e5f67b Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 13:52:56 +0000 Subject: [PATCH 015/249] review 1 --- ch08.adoc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index fb841490..2cc6473f 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -131,7 +131,11 @@ The **`tie_point_indices`** attribute also serves to identify the corresponding The reference of non-interpolation dimensions in the **`tie_point_indices`** attribute is not permitted. -If there is a tie point index for every element of an interpolation dimension, then the tie point index variable need not be included in the dataset, as its contains must be the integers 0 to [size of tie point interpolation dimension minus one], and therefore do not need to be stored in a variable. Instead, the **`tie_point_indices`** attribute may associate the interpolation dimension with the tie point dimension dimension, rather than a tie point index variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point index variable. +If there is a tie point index for every element of an interpolation dimension, then the tie point index variable need not be included in the dataset, as its contents must be the integers 0 to [size of tie point interpolation dimension minus one], and therefore do not need to be stored in a variable. Instead, the **`tie_point_indices`** attribute may associate the interpolation dimension with the tie point dimension dimension, rather than a tie point index variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point index variable. + + +### Only commented up to here + (To Do: Add text on super-sampling) From eccf731fc347701ab3b834b623a6c97556c93fdc Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 17:11:32 +0000 Subject: [PATCH 016/249] review 2 --- ch08.adoc | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 2cc6473f..e21ae38b 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -218,39 +218,41 @@ data: ---- ==== -[[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Offsets Attribute"]] -==== Tie Point Offsets Attribute +[[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Offsets"]] +==== Tie Point Offsets -Additionally to the **`tie_points`** and **`tie_point_indices`** attributes, which are always required for coordinate interpolation, a **`tie_point_offsets`** attribute is required if the tie point coordinate values are not a subset of the target domain coordinate values, but are offset with respect to these. +By default, it is assumed that the tie point coordinates are a subset of the uncompressed coordinates. However, it may be that the tie point coordinates are offset from a subset of the uncompressed coordinates. <>. In this case, the data variable requires a **`tie_point_offsets`** attribute to record the nature of this offset. -The **`tie_point_offsets`** is a string attribute that, limited to horizontal interpolation dimensions, maps target domain dimensions to the corresponding tie point offsets variables. It is a blank-separated list of words of the form "__target_domain_dimension: tie_point_offsets_variable [target_domain_dimension: tie_point_offsets_variable] ...]__". +The **`tie_point_offsets`** attribute is a string attribute maps interpolation dimensions to the corresponding __tie point offset variables__. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_offset_variable [interpolation_dimension: tie_point_offset_variable] ...]__". -This mapping is not part of the interpolation variable because different data variables may apply the same interpolation method, with the same tie points, but with different offsets. +This mapping is not part of the interpolation variable because different data variables may apply the same interpolation method, with the same tie points variables, but with different offsets. -A tie point offset is a spatial offset, in terms of fraction of target domain grid cell size in the named dimension, between the tie point cells and the corresponding target domain cells. The corresponding target domain cell is defined through the **`tie_point_indices`** attribute. A tie point offset variable may be a scalar, or else its dimensions may include the tie point dimension corresponding to the named target domain dimension, as well as any subset of the non-interpolation dimensions. No other dimensions may be spanned by a tie point offset variable. +A tie point offset variable defines a numerical offset in terms of the fraction of the size of a target domain cell along a single dimension. When associated with an interpolation dimension by the **`tie_point_offsets`** attribute, this offset locates the tie point variable coordinates relative to the uncompressed coordinates. A tie point offset variable may be a scalar, or else its dimensions may include the tie point interpolation dimension corresponding to the named interpolation dimension, as well as any subset of the non-interpolation dimensions. No other dimensions may be spanned by a tie point offset variable. -For example, to specify that for both of the target dimensions **`track`** and **`scan`** the offset is contained in the scalar variable **`offset`**, could be indicated with **`track: offset scan: offset`**, where the offset variable is declared as **`double offset`** and could have the value **`offset = -0.5`**. +For example, specifying that for both of the interpolation dimensions **`track`** and **`scan`** the offset is -0.5 (indicating that the tie point coordinates are offset by half a grid cell in each each direction from their corresponding uncompressed corodinates), could be indicated could be indicated with a **`tie_point_offsets`** attribute of **`track: offset scan: offset`**, where **`offset`** is a scalar tie point variable that has the value **`offset = -0.5`**. + +### Anders: what happens if the tie point coordinates are decreasing in index space - does -0.5 still mean offset to the "left", or is it to the "right" in this case?? [[compression-by-coordinate-interpolation-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] ==== Interpolation Variable The method used to uncompress the tie point variables is described by an interpolation variable that acts as a container for the attributes that define the interpolation technique and the parameters that should be used. The variable should be a scalar (i.e. it has no dimensions) of arbitrary type, and the value of its single element is immaterial. -To indicate that a standard interpolation method should be used, the interpolation variable must have a **`interpolation_name`** attribute defined, containing one of the valid values described in Appendix . This appendix also describes the interpolation technique and the interpolation variable attributes for configuring the interpolation process. - -If an interpolation name is not given, the interpolation variable must have a **`description`** attribute defined instead, containing a description of the non-standardised interpolation (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including a URI, for example). Whilst it is recommended that a standardised interpolation is provided, the alternative is provided to promote interoperability in cases where a well defined user community needs to use sophisticated interpolation techniques that may also be under development. +The interpolation method must be identified in one of two ways. Either by the **`interpolation_name`** attribute, which takes a string value that contains the method's name, or else by the **`interpolation_description`** attribute, which takes a string value that contains a non-standardized description of the method. These attributes must not be both set. + +The valid values of **`interpolation_name`** are given in Appendix . This appendix also describes the interpolation technique and optional interpolation variable attributes for configuring the interpolation process. -The definition of a standard or a non-standard interpolation method may include instructions to treat groups of particular physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular standard names). +If a standardized interpolation name is not given, the interpolation variable must have a **`interpolation_description`** attribute defined instead, containing a description of the non-standardised interpolation (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including a URI, for example). Whilst it is recommended that astandardised interpolation is provided, the alternative is provided to promote interoperability in cases where a well defined user community needs to use sophisticated interpolation techniques that may also be under development. -In addition to the **`interpolation_name`** or the **`description`** attribute, only two other interpolation variable attributes are permitted, the **`interpolation_coefficients`** and the **`interpolation_flags`** attributes. +The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). -The **`interpolation_coefficients`** attribute is a string attribute that lists the __interpolation coefficients variables__. The variables referenced must contain numeric data. It is a blank-separated list of words of the form "__interpolation_coefficients [interpolation_coefficients] ...]__". +The interpolation variable attributes **`interpolation_coefficients`** and **`interpolation_flags`** may be used to configure the interpolation process. These attributes name other variables that contain parameters needed to correctly configure the interpolation process. Both of these attributes are a blank-separated list of words of the form "__variable [variable] ...]__". -The **`interpolation_flags`** attribute is a string attribute that lists the __interpolation flags variables__. The variables referenced must be flag variables (<>). It is a blank-separated list of words of the form "__interpolation_flags [interpolation_flags] ...]__". +The variables names by the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must either be scalar, or else their dimensions may include any of the tie point interpolation dimensions, as well any __interpolation zone dimension__ that corresponds to a interpolation dimension. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along particular interpolation dimension. Therefore, if a variable spans a interpolation zone dimension then it allows its parameters to be stored differently for each interpolation zone. -The interpolation coefficients variables and the interpolation flags variables must either be scalar, or else their dimensions may include any of the tie point dimensions that are being interpolated, as well as the interpolation zone dimensions corresponding to each tie point dimension. The size of an interpolation zone dimension is equal the number of tie points, minus the number of interpolation areas. +Note that an interpolation dimension size is the same as the tie point coordinates along the corresponding interpolation dimension, minus the number of interpolation areas. -No other dimensions may be spanned by an interpolation coefficients variable or an interpolation flags variable. +If the interpolation method has been given with an **`interpolation_name`** attribute, then the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must only be present if they are allowed by the interpolation method's description in appendix , and the variable they reference must meet the requirements given in the description [caption="Example 8.5. "] .Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation flags attributes. From cbd9b595ace25046a2f16af5f43ba8d4cdf6b0da Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 17:21:52 +0000 Subject: [PATCH 017/249] review 2 --- ch08.adoc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index e21ae38b..720c149b 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -221,7 +221,7 @@ data: [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Offsets"]] ==== Tie Point Offsets -By default, it is assumed that the tie point coordinates are a subset of the uncompressed coordinates. However, it may be that the tie point coordinates are offset from a subset of the uncompressed coordinates. <>. In this case, the data variable requires a **`tie_point_offsets`** attribute to record the nature of this offset. +By default, it is assumed that the tie point coordinates are a subset of the uncompressed coordinates. However, it may be that the tie point coordinates are offset from a subset of the uncompressed coordinates. In this case, the data variable requires a **`tie_point_offsets`** attribute to record the nature of this offset. The **`tie_point_offsets`** attribute is a string attribute maps interpolation dimensions to the corresponding __tie point offset variables__. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_offset_variable [interpolation_dimension: tie_point_offset_variable] ...]__". @@ -242,7 +242,7 @@ The interpolation method must be identified in one of two ways. Either by the ** The valid values of **`interpolation_name`** are given in Appendix . This appendix also describes the interpolation technique and optional interpolation variable attributes for configuring the interpolation process. -If a standardized interpolation name is not given, the interpolation variable must have a **`interpolation_description`** attribute defined instead, containing a description of the non-standardised interpolation (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including a URI, for example). Whilst it is recommended that astandardised interpolation is provided, the alternative is provided to promote interoperability in cases where a well defined user community needs to use sophisticated interpolation techniques that may also be under development. +If a standardized interpolation name is not given, the interpolation variable must have a **`interpolation_description`** attribute defined instead, containing a description of the non-standardised interpolation (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including a URI, for example). Whilst it is recommended that a standardised interpolation is provided, the alternative is provided to promote interoperability in cases where a well defined user community needs to use sophisticated interpolation techniques that may also be under development. The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). @@ -252,7 +252,9 @@ The variables names by the **`interpolation_coefficients`** and **`interpolation Note that an interpolation dimension size is the same as the tie point coordinates along the corresponding interpolation dimension, minus the number of interpolation areas. -If the interpolation method has been given with an **`interpolation_name`** attribute, then the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must only be present if they are allowed by the interpolation method's description in appendix , and the variable they reference must meet the requirements given in the description +The variables referenced by the **`__interpolation_coefficients__`** attribute must contain numeric data, and the variables referenced by the **`__interpolation_flags__`** attribute contain status flag attributes (<>). + +If the interpolation method has been given with an **`interpolation_name`** attribute, then the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must only be present if they are allowed by the interpolation method's description in appendix , and the variables they reference must meet the requirements given in the description. [caption="Example 8.5. "] .Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation flags attributes. From 71522e084525dc34636c4172cc84df32e0c889a5 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 17:24:19 +0000 Subject: [PATCH 018/249] review 2 --- ch08.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 720c149b..a47aae21 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -248,11 +248,11 @@ The definition of the interpolation method, however it is specified, may include The interpolation variable attributes **`interpolation_coefficients`** and **`interpolation_flags`** may be used to configure the interpolation process. These attributes name other variables that contain parameters needed to correctly configure the interpolation process. Both of these attributes are a blank-separated list of words of the form "__variable [variable] ...]__". -The variables names by the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must either be scalar, or else their dimensions may include any of the tie point interpolation dimensions, as well any __interpolation zone dimension__ that corresponds to a interpolation dimension. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along particular interpolation dimension. Therefore, if a variable spans a interpolation zone dimension then it allows its parameters to be stored differently for each interpolation zone. +The variables named by the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must either be scalar, or else their dimensions may include any of the tie point interpolation dimensions, as well any __interpolation zone dimension__ that corresponds to a interpolation dimension. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along particular interpolation dimension. Therefore, if a variable spans a interpolation zone dimension then it allows its parameters to be stored differently for each interpolation zone. -Note that an interpolation dimension size is the same as the tie point coordinates along the corresponding interpolation dimension, minus the number of interpolation areas. +Note that an interpolation dimension size is the same as the number of tie point coordinates along the corresponding interpolation dimension, minus the number of interpolation areas. -The variables referenced by the **`__interpolation_coefficients__`** attribute must contain numeric data, and the variables referenced by the **`__interpolation_flags__`** attribute contain status flag attributes (<>). +The variables referenced by the **`interpolation_coefficients`** attribute must contain numeric data, and the variables referenced by the **`interpolation_flags`** attribute must contain status flag attributes (<>). If the interpolation method has been given with an **`interpolation_name`** attribute, then the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must only be present if they are allowed by the interpolation method's description in appendix , and the variables they reference must meet the requirements given in the description. From de622df5f5e59983d98cc9355cfe50a5c2d7a983 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 26 Nov 2020 18:09:42 +0000 Subject: [PATCH 019/249] remove placeholder notes --- ch08.adoc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index a47aae21..2409d417 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -134,9 +134,6 @@ The reference of non-interpolation dimensions in the **`tie_point_indices`** att If there is a tie point index for every element of an interpolation dimension, then the tie point index variable need not be included in the dataset, as its contents must be the integers 0 to [size of tie point interpolation dimension minus one], and therefore do not need to be stored in a variable. Instead, the **`tie_point_indices`** attribute may associate the interpolation dimension with the tie point dimension dimension, rather than a tie point index variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point index variable. -### Only commented up to here - - (To Do: Add text on super-sampling) [caption="Example 8.3. "] @@ -231,8 +228,6 @@ A tie point offset variable defines a numerical offset in terms of the fraction For example, specifying that for both of the interpolation dimensions **`track`** and **`scan`** the offset is -0.5 (indicating that the tie point coordinates are offset by half a grid cell in each each direction from their corresponding uncompressed corodinates), could be indicated could be indicated with a **`tie_point_offsets`** attribute of **`track: offset scan: offset`**, where **`offset`** is a scalar tie point variable that has the value **`offset = -0.5`**. -### Anders: what happens if the tie point coordinates are decreasing in index space - does -0.5 still mean offset to the "left", or is it to the "right" in this case?? - [[compression-by-coordinate-interpolation-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] ==== Interpolation Variable From f43a80ff19973573946c8bdd2fe1e2b3e0a0f675 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 27 Nov 2020 15:25:54 +0100 Subject: [PATCH 020/249] Updates after teleconference with @davidhassell --- ch08.adoc | 50 +++++++++++++++++++---------- images/interpolation_variables.png | Bin 0 -> 86842 bytes 2 files changed, 33 insertions(+), 17 deletions(-) create mode 100644 images/interpolation_variables.png diff --git a/ch08.adoc b/ch08.adoc index 2409d417..a33960fe 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -79,7 +79,7 @@ The lower resolution coordinates are stored in __tie point variables__. This ter In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. - +The defined metadata and methods for reconstituting the uncompressed data have been designed to be complete and unambiguous, meaning that that the results of the coordinate reconstitution process by the dat user are well defined and of a predictable accuracy. The data variable coordinate interpolation attributes may also be used on a domain variable (<>) with the same effect. @@ -90,11 +90,13 @@ Reconstitution of the uncompressed coordinate and auxiliary coordinate variables Although the coordinate and auxiliary coordinate variables are stored in orthogonal multidimensional array representation, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates, or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. -As the interpolation methods rely on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in Figure <>. +As the interpolation methods rely on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in <>. + +Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. -Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in Figure <>. +Note that the location of the discontinuities can be based either on knowledge of how the data set was created, e. g. by a remote sensing instrument, or alternatively on numerical analysis of the actual coordinates. -For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__ (<>) +For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__, which also allows the user to determine the location of the grid discontinuities(<>). For each interpolation dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. @@ -107,31 +109,29 @@ image::images/regular_and_piecewise_regular_grid.png[,100%,pdfwidth=50vw,align=" [[compression-by-coordinate-tie-points-attribute, Section 8.3.2, "Tie Points Attribute"]] ==== Tie Points Attribute -To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. +To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. [[compression-by-coordinate-interpolation-dimensions,Section 8.3.3, "Data Variable Attributes"]] ==== Interpolation and Non-Interpolation Dimensions For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required; and may additionally contain one or more __non-interpolation dimensions__, i.e. those of the target domain for which no coordinate interpolation is required. -An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables for the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point interpolation dimension related to the interpolation dimension **`xc`**, and **`tp_yc`** is the tie point interpolation dimension related to the interpolation dimension **`yc`**. +An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point interpolation dimension related to the interpolation dimension **`xc`**, and **`tp_yc`** is the tie point interpolation dimension related to the interpolation dimension **`yc`**. The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing. For example, the tie point index variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas. For example, the tie point index variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. -In the tie point index variable, two adjacent indices where the value of the second is the equal to the value of the first incremented by one indicates the location of a interpolation area boundary. +In the tie point index variable, two adjacent indices that are equal or differ by one indicates the location of a interpolation area boundary relating to an grid discontinuity (<>) -To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable] ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. +To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable] ...__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point index variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point index variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. -The reference of non-interpolation dimensions in the **`tie_point_indices`** attribute is not permitted. - -If there is a tie point index for every element of an interpolation dimension, then the tie point index variable need not be included in the dataset, as its contents must be the integers 0 to [size of tie point interpolation dimension minus one], and therefore do not need to be stored in a variable. Instead, the **`tie_point_indices`** attribute may associate the interpolation dimension with the tie point dimension dimension, rather than a tie point index variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point index variable. +If there is a tie point index for every element of an interpolation dimension, then the tie point index variable need not be included in the dataset, as its contents must be the integers 0 to [size of tie point interpolation dimension minus one (CHANGE!)], and therefore do not need to be stored in a variable. Instead, the **`tie_point_indices`** attribute may associate the interpolation dimension with the tie point dimension dimension, rather than a tie point index variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point index variable. (To Do: Add text on super-sampling) @@ -178,7 +178,7 @@ data: ==== [caption="Example 8.4. "] -.One-dimensional tie point interpolation +.One-dimensional tie point interpolation of two-dimensional domain. ==== ---- dimensions: @@ -220,12 +220,14 @@ data: By default, it is assumed that the tie point coordinates are a subset of the uncompressed coordinates. However, it may be that the tie point coordinates are offset from a subset of the uncompressed coordinates. In this case, the data variable requires a **`tie_point_offsets`** attribute to record the nature of this offset. -The **`tie_point_offsets`** attribute is a string attribute maps interpolation dimensions to the corresponding __tie point offset variables__. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_offset_variable [interpolation_dimension: tie_point_offset_variable] ...]__". +The **`tie_point_offsets`** attribute is a string attribute maps interpolation dimensions to the corresponding __tie point offset variables__. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_offset_variable [interpolation_dimension: tie_point_offset_variable] ...__". This mapping is not part of the interpolation variable because different data variables may apply the same interpolation method, with the same tie points variables, but with different offsets. A tie point offset variable defines a numerical offset in terms of the fraction of the size of a target domain cell along a single dimension. When associated with an interpolation dimension by the **`tie_point_offsets`** attribute, this offset locates the tie point variable coordinates relative to the uncompressed coordinates. A tie point offset variable may be a scalar, or else its dimensions may include the tie point interpolation dimension corresponding to the named interpolation dimension, as well as any subset of the non-interpolation dimensions. No other dimensions may be spanned by a tie point offset variable. +An positive offset value indicates and tie point offset in the positive direction of the corresponding interpolation dimension. An offset is bounded to -1.0 < offset < 1.0; + For example, specifying that for both of the interpolation dimensions **`track`** and **`scan`** the offset is -0.5 (indicating that the tie point coordinates are offset by half a grid cell in each each direction from their corresponding uncompressed corodinates), could be indicated could be indicated with a **`tie_point_offsets`** attribute of **`track: offset scan: offset`**, where **`offset`** is a scalar tie point variable that has the value **`offset = -0.5`**. [[compression-by-coordinate-interpolation-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] @@ -241,11 +243,25 @@ If a standardized interpolation name is not given, the interpolation variable mu The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). -The interpolation variable attributes **`interpolation_coefficients`** and **`interpolation_flags`** may be used to configure the interpolation process. These attributes name other variables that contain parameters needed to correctly configure the interpolation process. Both of these attributes are a blank-separated list of words of the form "__variable [variable] ...]__". +The interpolation variable attributes **`interpolation_coefficients`** and **`interpolation_flags`** may be used to configure the interpolation process. These attributes name other variables that contain parameters needed to correctly configure the interpolation process. Both of these attributes are a blank-separated list of words of the form "__variable [variable] ...__". + +The variables named by the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding interpolation zone dimension, but not both, and may include any of the non-interpolation dimensions. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along the particular interpolation dimension. + +Therefore, if a variable spans all the interpolation zone dimensions then it allows its parameters to be stored differently for each interpolation zone. Similarly, if a variable spans a combination of interpolation zone dimensions and tie point interpolation dimension then it allows parameters to be shared by sets of neighbouring interpolation zones. Note that shared parameters can be used to ensure continuity of the consistency of the reconstituted coordinate values across interpolation zone boundaries. + +An interpolation method is only permitted to access the elements of the variables named by the interpolation_coefficients and interpolation_flags which are associated with the interpolation zone through their indices. + +As an example, for the two-dimensional case, <> shows the interpolation coefficients and interpolation flags variable dimensions in relation to an interpolation zone and its boundaries. + +[[interpolation_variable, figure 4]] +[.text-center] +.Interpolation coefficients and interpolation flags variable dimensions in relation to an interpolation zone and its boundaries. + +image::images/interpolation_variables.png[,100%,pdfwidth=50vw,align="center"] + -The variables named by the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must either be scalar, or else their dimensions may include any of the tie point interpolation dimensions, as well any __interpolation zone dimension__ that corresponds to a interpolation dimension. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along particular interpolation dimension. Therefore, if a variable spans a interpolation zone dimension then it allows its parameters to be stored differently for each interpolation zone. -Note that an interpolation dimension size is the same as the number of tie point coordinates along the corresponding interpolation dimension, minus the number of interpolation areas. +Note that an interpolation zone dimension size is the same as the number of tie point coordinates along the corresponding interpolation dimension, minus the number of interpolation areas. The variables referenced by the **`interpolation_coefficients`** attribute must contain numeric data, and the variables referenced by the **`interpolation_flags`** attribute must contain status flag attributes (<>). diff --git a/images/interpolation_variables.png b/images/interpolation_variables.png new file mode 100644 index 0000000000000000000000000000000000000000..e76842e1e9af1d68f44da15379603ae5e3b207a8 GIT binary patch literal 86842 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

4C5<%o&$1tN`qOQ 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 z Date: Fri, 27 Nov 2020 18:22:57 +0000 Subject: [PATCH 021/249] more text following 2020-11-27 discussions --- ch08.adoc | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index a33960fe..6fe3e2d3 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -79,6 +79,7 @@ The lower resolution coordinates are stored in __tie point variables__. This ter In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. +(TODO - didn't have time to think about this one) The defined metadata and methods for reconstituting the uncompressed data have been designed to be complete and unambiguous, meaning that that the results of the coordinate reconstitution process by the dat user are well defined and of a predictable accuracy. The data variable coordinate interpolation attributes may also be used on a domain variable (<>) with the same effect. @@ -88,19 +89,16 @@ The data variable coordinate interpolation attributes may also be used on a doma Reconstitution of the uncompressed coordinate and auxiliary coordinate variables is based on interpolation. To accomplish this, the target domain is segmented into smaller __interpolation zones__, for each of which the interpolation method is applied independently. For one dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone; for two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes; etc. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables within an interpolation zone, the interpolation method is permitted to access the coordinates of the defining tie points, but not the coordinates of any other tie points. -Although the coordinate and auxiliary coordinate variables are stored in orthogonal multidimensional array representation, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates, or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. +Although the coordinate and auxiliary coordinate variables are stored in orthogonal multidimensional array representation, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates, or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. In such cases the location of the discontinuities in the can be based either on knowledge of how the data set was created, e.g. by a remote sensing instrument, or alternatively by inspection of the actual coordinates. As the interpolation methods rely on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in <>. Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. -Note that the location of the discontinuities can be based either on knowledge of how the data set was created, e. g. by a remote sensing instrument, or alternatively on numerical analysis of the actual coordinates. - -For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__, which also allows the user to determine the location of the grid discontinuities(<>). +For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__, which also determines the location of the interpolation areas (<>). For each interpolation dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. - [[interpolation_zone_generation, figure 3]] [.text-center] .Process for generating the interpolation zones for a grid without discontinuities and for a grid with discontinuities. @@ -109,7 +107,7 @@ image::images/regular_and_piecewise_regular_grid.png[,100%,pdfwidth=50vw,align=" [[compression-by-coordinate-tie-points-attribute, Section 8.3.2, "Tie Points Attribute"]] ==== Tie Points Attribute -To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. +To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. [[compression-by-coordinate-interpolation-dimensions,Section 8.3.3, "Data Variable Attributes"]] ==== Interpolation and Non-Interpolation Dimensions @@ -125,16 +123,14 @@ The presence of non-interpolation dimensions in the tie point variable impacts t The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas. For example, the tie point index variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. -In the tie point index variable, two adjacent indices that are equal or differ by one indicates the location of a interpolation area boundary relating to an grid discontinuity (<>) +In the tie point index variable data, two adjacent indices that are equal, or differ by one, indicates the location of a interpolation area boundary relating to an grid discontinuity (<>) -To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable] ...__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. +To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point index variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point index variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. -If there is a tie point index for every element of an interpolation dimension, then the tie point index variable need not be included in the dataset, as its contents must be the integers 0 to [size of tie point interpolation dimension minus one (CHANGE!)], and therefore do not need to be stored in a variable. Instead, the **`tie_point_indices`** attribute may associate the interpolation dimension with the tie point dimension dimension, rather than a tie point index variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point index variable. - -(To Do: Add text on super-sampling) +### TODO: Add text on super-sampling) [caption="Example 8.3. "] .Two-dimensional tie point interpolation @@ -220,13 +216,13 @@ data: By default, it is assumed that the tie point coordinates are a subset of the uncompressed coordinates. However, it may be that the tie point coordinates are offset from a subset of the uncompressed coordinates. In this case, the data variable requires a **`tie_point_offsets`** attribute to record the nature of this offset. -The **`tie_point_offsets`** attribute is a string attribute maps interpolation dimensions to the corresponding __tie point offset variables__. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_offset_variable [interpolation_dimension: tie_point_offset_variable] ...__". +The **`tie_point_offsets`** attribute is a string attribute maps interpolation dimensions to the corresponding __tie point offset variables__. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_offset_variable [interpolation_dimension: tie_point_offset_variable ...]__". This mapping is not part of the interpolation variable because different data variables may apply the same interpolation method, with the same tie points variables, but with different offsets. -A tie point offset variable defines a numerical offset in terms of the fraction of the size of a target domain cell along a single dimension. When associated with an interpolation dimension by the **`tie_point_offsets`** attribute, this offset locates the tie point variable coordinates relative to the uncompressed coordinates. A tie point offset variable may be a scalar, or else its dimensions may include the tie point interpolation dimension corresponding to the named interpolation dimension, as well as any subset of the non-interpolation dimensions. No other dimensions may be spanned by a tie point offset variable. +A tie point offset variable defines numerical offsets in terms of the fraction of the size of a target domain cell along a single dimension. When associated with an interpolation dimension by the **`tie_point_offsets`** attribute, this offset locates the tie point variable coordinates relative to the uncompressed coordinates. A tie point offset variable may be a scalar, or else its dimensions may include the tie point interpolation dimension corresponding to the named interpolation dimension, as well as any subset of the non-interpolation dimensions. No other dimensions may be spanned by a tie point offset variable. -An positive offset value indicates and tie point offset in the positive direction of the corresponding interpolation dimension. An offset is bounded to -1.0 < offset < 1.0; +An offset value, which must be in the open range `(-1.0, 1.0)`, indicates a tie point offset towards an adjacent element of the corresponding interpolation dimension as follows: A positive offset value indicates a tie point offset towards the next element, and a negative offset indicates a tie point offset towards the previous element. Note that the location of the offset does not depend on the whether the uncompressed coordinates are increasing or decreasing along the interpolation dimension. For example, specifying that for both of the interpolation dimensions **`track`** and **`scan`** the offset is -0.5 (indicating that the tie point coordinates are offset by half a grid cell in each each direction from their corresponding uncompressed corodinates), could be indicated could be indicated with a **`tie_point_offsets`** attribute of **`track: offset scan: offset`**, where **`offset`** is a scalar tie point variable that has the value **`offset = -0.5`**. @@ -243,15 +239,15 @@ If a standardized interpolation name is not given, the interpolation variable mu The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). -The interpolation variable attributes **`interpolation_coefficients`** and **`interpolation_flags`** may be used to configure the interpolation process. These attributes name other variables that contain parameters needed to correctly configure the interpolation process. Both of these attributes are a blank-separated list of words of the form "__variable [variable] ...__". +An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie point coordinates. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation equations, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. -The variables named by the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding interpolation zone dimension, but not both, and may include any of the non-interpolation dimensions. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along the particular interpolation dimension. +The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form "term: variable", where `term` is a case-insensitive keyword that represents one of the terms in the interpolation method definition, and `variable` is the name of the interpolation configuration variable that contains the values for that term. The order of elements is not significant. -Therefore, if a variable spans all the interpolation zone dimensions then it allows its parameters to be stored differently for each interpolation zone. Similarly, if a variable spans a combination of interpolation zone dimensions and tie point interpolation dimension then it allows parameters to be shared by sets of neighbouring interpolation zones. Note that shared parameters can be used to ensure continuity of the consistency of the reconstituted coordinate values across interpolation zone boundaries. +The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. -An interpolation method is only permitted to access the elements of the variables named by the interpolation_coefficients and interpolation_flags which are associated with the interpolation zone through their indices. +The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding __interpolation zone dimension__, but not both, and may include any of the non-interpolation dimensions. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along a particular interpolation dimension. Note that an interpolation zone dimension size is the same as the number of tie point coordinates along the corresponding interpolation dimension, minus the number of interpolation areas. -As an example, for the two-dimensional case, <> shows the interpolation coefficients and interpolation flags variable dimensions in relation to an interpolation zone and its boundaries. +If an interpolation coefficent or configuration variable spans the interpolation zone dimensions corresponding to of all the interpolation dimensions, then it defines a separate value for each interpolation zone. If, however, a variable spans at least tie point interpolation dimension, then each of its values is shared by the interpolation zones that are adjacent in the dimensions defined by tie point interpolation dimensions. The former case is akin to values being defined at the centre of interpolation zones. The latter case is akin to values being defined at interpolation zone boundaries, and therefore equally applicable to both interpolation zones that share that boundary (<>). [[interpolation_variable, figure 4]] [.text-center] @@ -259,13 +255,10 @@ As an example, for the two-dimensional case, <> shows th image::images/interpolation_variables.png[,100%,pdfwidth=50vw,align="center"] +Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the uncompressed coordinates may only access the tie point coordinates that define the extent of the of the interpolation zone, as well as any interpolation coefficient and configuration variables defined for the interpolation zone, including its boundaries. -Note that an interpolation zone dimension size is the same as the number of tie point coordinates along the corresponding interpolation dimension, minus the number of interpolation areas. - -The variables referenced by the **`interpolation_coefficients`** attribute must contain numeric data, and the variables referenced by the **`interpolation_flags`** attribute must contain status flag attributes (<>). - -If the interpolation method has been given with an **`interpolation_name`** attribute, then the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must only be present if they are allowed by the interpolation method's description in appendix , and the variables they reference must meet the requirements given in the description. +### TODO bounds [caption="Example 8.5. "] .Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation flags attributes. @@ -337,10 +330,10 @@ variables: // Interpolation variable char tp_interpolation ; tp_interpolation:interpolation_name = "bi_quadratic_1" ; - tp_interpolation:interpolation_coefficients = "expansion_coefficient_track alignment_coefficient_track expansion_coefficient_scan alignment_coefficient_scan" ; - tp_interpolation:interpolation_flags = "interpolation_zone_flags" ; + tp_interpolation:interpolation_coefficients = "TODO1: expansion_coefficient_track TODO2: alignment_coefficient_track TODO3: expansion_coefficient_scan TODO4: alignment_coefficient_scan" ; + tp_interpolation:interpolation_configuration = "TODO5: interpolation_zone_flags" ; - // Interpolation coefficients and flags + // Interpolation coefficient and configuration variables short expansion_coefficient_track(track_interpolation_zone, tp_scan) ; short alignment_coefficient_track(track_interpolation_zone, tp_scan) ; short expansion_coefficient_scan(tp_track, scan_interpolation_zone) ; From d557d8512e81a88ff57c198b0b555c7cee988940 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Sat, 28 Nov 2020 14:05:55 +0000 Subject: [PATCH 022/249] bounds --- ch08.adoc | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/ch08.adoc b/ch08.adoc index 6fe3e2d3..7c899201 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -260,6 +260,36 @@ Note that the interpolation method is always applied on a per interpolation zone ### TODO bounds + +[[compression-by-coordinate-interpolation-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] +==== "Interpolation of Tie Point Bounds + +If a tie point coordinate variable has cell boundaries bounds then it +must have the attribute **`bounds`** that names the variable that +contains the vertices of the cell boundaries. The bounds should be the +same as the bounds of the corresponding target grid cells, unless +there is a non-zero offset, in which case the offset applies to the +bounds values in exactly the same manner as it does to the cell +corodinates. It is thereforefore likely that tie point cells will be +non-contiguous. + +The target domain cell bounds are calculated by interpolating each +cell bound position independently of the others, using the same +interpolation method and tie point index variables as used for the +cell coordinates. In this case, though, the tie point index variables +are the indentifying target domain cells to which the bounds apply, +rather than bounds values themselves. For instance, in the case of a +two-dimensionsal tie point variable with four-sided cells then the +target domain cell bounds would be calculated with four separate +interpolations, one for each of the bounds positions (following the +notation of <>) `(j-1,i-1), `(j-1,i+1)`, `(j+1,i+1)`, +`(j+1,i-1)`. + +Note that an implementation of the interpolation method is free to +calculate the uncompressed bounds locations in the manner of its +choosing, as a long as the result is formally equivalent to each +bounds position being treated independently. + [caption="Example 8.5. "] .Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation flags attributes. ==== From c0ff742ac91edfd26001cb5f637f8b2271242f01 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Sat, 28 Nov 2020 14:08:14 +0000 Subject: [PATCH 023/249] tidy --- ch08.adoc | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 7c899201..cfacfc33 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -258,37 +258,14 @@ image::images/interpolation_variables.png[,100%,pdfwidth=50vw,align="center"] Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the uncompressed coordinates may only access the tie point coordinates that define the extent of the of the interpolation zone, as well as any interpolation coefficient and configuration variables defined for the interpolation zone, including its boundaries. -### TODO bounds +[[compression-by-coordinate-interpolation-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] +==== Interpolation of Tie Point Bounds +If a tie point coordinate variable has cell boundaries bounds then it must have the attribute **`bounds`** that names the variable that contains the vertices of the cell boundaries. The bounds should be the same as the bounds of the corresponding target grid cells, unless there is a non-zero offset, in which case the offset applies to the bounds values in exactly the same manner as it does to the cell corodinates. It is thereforefore likely that tie point cells will be non-contiguous. -[[compression-by-coordinate-interpolation-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] -==== "Interpolation of Tie Point Bounds - -If a tie point coordinate variable has cell boundaries bounds then it -must have the attribute **`bounds`** that names the variable that -contains the vertices of the cell boundaries. The bounds should be the -same as the bounds of the corresponding target grid cells, unless -there is a non-zero offset, in which case the offset applies to the -bounds values in exactly the same manner as it does to the cell -corodinates. It is thereforefore likely that tie point cells will be -non-contiguous. - -The target domain cell bounds are calculated by interpolating each -cell bound position independently of the others, using the same -interpolation method and tie point index variables as used for the -cell coordinates. In this case, though, the tie point index variables -are the indentifying target domain cells to which the bounds apply, -rather than bounds values themselves. For instance, in the case of a -two-dimensionsal tie point variable with four-sided cells then the -target domain cell bounds would be calculated with four separate -interpolations, one for each of the bounds positions (following the -notation of <>) `(j-1,i-1), `(j-1,i+1)`, `(j+1,i+1)`, -`(j+1,i-1)`. - -Note that an implementation of the interpolation method is free to -calculate the uncompressed bounds locations in the manner of its -choosing, as a long as the result is formally equivalent to each -bounds position being treated independently. +The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the indentifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensionsal tie point variable with four-sided cells then the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. + +Note that an implementation of the interpolation method is free to calculate the uncompressed bounds locations in the manner of its choosing, as a long as the result is formally equivalent to each bounds position being treated independently. [caption="Example 8.5. "] .Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation flags attributes. @@ -360,7 +337,7 @@ variables: // Interpolation variable char tp_interpolation ; tp_interpolation:interpolation_name = "bi_quadratic_1" ; - tp_interpolation:interpolation_coefficients = "TODO1: expansion_coefficient_track TODO2: alignment_coefficient_track TODO3: expansion_coefficient_scan TODO4: alignment_coefficient_scan" ; + tp_interpolation:interpolation_coefficients = "TOO1:D expansion_coefficient_track TODO2: alignment_coefficient_track TODO3: expansion_coefficient_scan TODO4: alignment_coefficient_scan" ; tp_interpolation:interpolation_configuration = "TODO5: interpolation_zone_flags" ; // Interpolation coefficient and configuration variables From 3d98e4aea3bd0e9dd8d2aa3fd99709994b024d6d Mon Sep 17 00:00:00 2001 From: David Hassell Date: Sat, 28 Nov 2020 14:09:21 +0000 Subject: [PATCH 024/249] tidy --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index cfacfc33..6a78de89 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -241,7 +241,7 @@ The definition of the interpolation method, however it is specified, may include An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie point coordinates. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation equations, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. -The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form "term: variable", where `term` is a case-insensitive keyword that represents one of the terms in the interpolation method definition, and `variable` is the name of the interpolation configuration variable that contains the values for that term. The order of elements is not significant. +The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation method definition, and `variable` is the name of the interpolation configuration variable that contains the values for that term. The order of elements is not significant. The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. From 9022788925aa6f4161f0f45529795a61b2e3f9b0 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 08:44:17 +0000 Subject: [PATCH 025/249] tidy --- ch08.adoc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 6a78de89..a9e4e7c5 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -214,7 +214,7 @@ data: [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Offsets"]] ==== Tie Point Offsets -By default, it is assumed that the tie point coordinates are a subset of the uncompressed coordinates. However, it may be that the tie point coordinates are offset from a subset of the uncompressed coordinates. In this case, the data variable requires a **`tie_point_offsets`** attribute to record the nature of this offset. +By default, it is assumed that the tie points are a subset of the uncompressed coordinates. However, it may be that the tie points are offset from a subset of the uncompressed coordinates. In this case, the data variable requires a **`tie_point_offsets`** attribute to record the nature of this offset. The **`tie_point_offsets`** attribute is a string attribute maps interpolation dimensions to the corresponding __tie point offset variables__. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_offset_variable [interpolation_dimension: tie_point_offset_variable ...]__". @@ -224,7 +224,7 @@ A tie point offset variable defines numerical offsets in terms of the fraction o An offset value, which must be in the open range `(-1.0, 1.0)`, indicates a tie point offset towards an adjacent element of the corresponding interpolation dimension as follows: A positive offset value indicates a tie point offset towards the next element, and a negative offset indicates a tie point offset towards the previous element. Note that the location of the offset does not depend on the whether the uncompressed coordinates are increasing or decreasing along the interpolation dimension. -For example, specifying that for both of the interpolation dimensions **`track`** and **`scan`** the offset is -0.5 (indicating that the tie point coordinates are offset by half a grid cell in each each direction from their corresponding uncompressed corodinates), could be indicated could be indicated with a **`tie_point_offsets`** attribute of **`track: offset scan: offset`**, where **`offset`** is a scalar tie point variable that has the value **`offset = -0.5`**. +For example, specifying that for both of the interpolation dimensions **`track`** and **`scan`** the offset is -0.5 (indicating that the tie points are offset by half a grid cell in each each direction from their corresponding uncompressed coordinates), could be indicated could be indicated with a **`tie_point_offsets`** attribute of **`track: offset scan: offset`**, where **`offset`** is a scalar tie point variable that has the value **`offset = -0.5`**. [[compression-by-coordinate-interpolation-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] ==== Interpolation Variable @@ -239,15 +239,15 @@ If a standardized interpolation name is not given, the interpolation variable mu The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). -An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie point coordinates. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation equations, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. +An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie points. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation equations, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation method definition, and `variable` is the name of the interpolation configuration variable that contains the values for that term. The order of elements is not significant. The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. -The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding __interpolation zone dimension__, but not both, and may include any of the non-interpolation dimensions. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along a particular interpolation dimension. Note that an interpolation zone dimension size is the same as the number of tie point coordinates along the corresponding interpolation dimension, minus the number of interpolation areas. +The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding __interpolation zone dimension__, but not both, and may include any of the non-interpolation dimensions. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along a particular interpolation dimension. Note that an interpolation zone dimension size is the same as the number of tie points along the corresponding interpolation dimension, minus the number of interpolation areas. -If an interpolation coefficent or configuration variable spans the interpolation zone dimensions corresponding to of all the interpolation dimensions, then it defines a separate value for each interpolation zone. If, however, a variable spans at least tie point interpolation dimension, then each of its values is shared by the interpolation zones that are adjacent in the dimensions defined by tie point interpolation dimensions. The former case is akin to values being defined at the centre of interpolation zones. The latter case is akin to values being defined at interpolation zone boundaries, and therefore equally applicable to both interpolation zones that share that boundary (<>). +If an interpolation coefficent or configuration variable spans the interpolation zone dimensions corresponding to of all the interpolation dimensions, then it defines a separate value for each interpolation zone. If, however, a variable spans at least one tie point interpolation dimension, then each of its values is shared by the interpolation zones that are adjacent in the dimensions defined by tie point interpolation dimensions. The former case is akin to values being defined at the centre of interpolation zones. The latter case is akin to values being defined at interpolation zone boundaries, and therefore equally applicable to both interpolation zones that share that boundary (<>). [[interpolation_variable, figure 4]] [.text-center] @@ -255,13 +255,13 @@ If an interpolation coefficent or configuration variable spans the interpolation image::images/interpolation_variables.png[,100%,pdfwidth=50vw,align="center"] -Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the uncompressed coordinates may only access the tie point coordinates that define the extent of the of the interpolation zone, as well as any interpolation coefficient and configuration variables defined for the interpolation zone, including its boundaries. +Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the uncompressed coordinates may only access the tie point that define the extent of the of the interpolation zone, as well as any interpolation coefficient and configuration variables defined for the interpolation zone, including its boundaries. [[compression-by-coordinate-interpolation-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds -If a tie point coordinate variable has cell boundaries bounds then it must have the attribute **`bounds`** that names the variable that contains the vertices of the cell boundaries. The bounds should be the same as the bounds of the corresponding target grid cells, unless there is a non-zero offset, in which case the offset applies to the bounds values in exactly the same manner as it does to the cell corodinates. It is thereforefore likely that tie point cells will be non-contiguous. +If a tie point variable has cell boundaries bounds then it must have the attribute **`bounds`** that names the variable that contains the vertices of the cell boundaries. The bounds should be the same as the bounds of the corresponding target grid cells, unless there is a non-zero offset, in which case the offset applies to the bounds values in exactly the same manner as it does to the cell coordinates. It is thereforefore likely that tie point cells will be non-contiguous. The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the indentifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensionsal tie point variable with four-sided cells then the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. From ba66c130807c57a65bf571703e7e2123c44147c0 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 08:46:32 +0000 Subject: [PATCH 026/249] tidy --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index a9e4e7c5..01765341 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -75,7 +75,7 @@ This information implies that the salinity field should be uncompressed to an ar For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to user of the uncompressed dataset. -The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset of the uncompressed coordinate values, they can also be different to some or all of them. +The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset tor superset of the uncompressed coordinate values, they are typically be different to some or all of them. In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. From 8096ce221c09c758e4baf2fd0923d6336b5e206f Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 08:52:35 +0000 Subject: [PATCH 027/249] reproducability --- ch08.adoc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 01765341..43edf0ee 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -75,12 +75,11 @@ This information implies that the salinity field should be uncompressed to an ar For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to user of the uncompressed dataset. -The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset tor superset of the uncompressed coordinate values, they are typically be different to some or all of them. +The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset (or superset, see section <>) of the uncompressed coordinate values, they are typically be different to some or all of them. -In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. +In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is sotred in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. -(TODO - didn't have time to think about this one) -The defined metadata and methods for reconstituting the uncompressed data have been designed to be complete and unambiguous, meaning that that the results of the coordinate reconstitution process by the dat user are well defined and of a predictable accuracy. +The metadata that define the interpolation formula and its inputs are complete, so that the results of the coordinate reconstitution process are well defined and of a predictable accuracy. The data variable coordinate interpolation attributes may also be used on a domain variable (<>) with the same effect. From aa326c7ffe38ee0a107511a0ab190b24a1ebe592 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 08:56:34 +0000 Subject: [PATCH 028/249] offset --- ch08.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 43edf0ee..5a6787f2 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -75,9 +75,9 @@ This information implies that the salinity field should be uncompressed to an ar For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to user of the uncompressed dataset. -The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset (or superset, see section <>) of the uncompressed coordinate values, they are typically be different to some or all of them. +The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset (or superset, see section <) of the uncompressed coordinate values, they are typically be different to some or all of them. -In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is sotred in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. +In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. The metadata that define the interpolation formula and its inputs are complete, so that the results of the coordinate reconstitution process are well defined and of a predictable accuracy. @@ -223,7 +223,7 @@ A tie point offset variable defines numerical offsets in terms of the fraction o An offset value, which must be in the open range `(-1.0, 1.0)`, indicates a tie point offset towards an adjacent element of the corresponding interpolation dimension as follows: A positive offset value indicates a tie point offset towards the next element, and a negative offset indicates a tie point offset towards the previous element. Note that the location of the offset does not depend on the whether the uncompressed coordinates are increasing or decreasing along the interpolation dimension. -For example, specifying that for both of the interpolation dimensions **`track`** and **`scan`** the offset is -0.5 (indicating that the tie points are offset by half a grid cell in each each direction from their corresponding uncompressed coordinates), could be indicated could be indicated with a **`tie_point_offsets`** attribute of **`track: offset scan: offset`**, where **`offset`** is a scalar tie point variable that has the value **`offset = -0.5`**. +For example, specifying that for both of the interpolation dimensions **`track`** and **`scan`** the offset is `-0.5` (indicating that the tie points are offset by half a grid cell along each dimension from their corresponding uncompressed coordinates), could be indicated with a **`tie_point_offsets`** attribute of **`track: offset scan: offset`**, where **`offset`** is a scalar tie point variable that has the value **`offset = -0.5`**. [[compression-by-coordinate-interpolation-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] ==== Interpolation Variable From 7cd6fd24063c067ef18611680c1467c8bc2b6f8d Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 09:04:27 +0000 Subject: [PATCH 029/249] indices --- ch08.adoc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 5a6787f2..6e41d424 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -120,9 +120,23 @@ The presence of non-interpolation dimensions in the tie point variable impacts t [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices"]] ==== Tie Point Indices +ORG The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas. For example, the tie point index variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. -In the tie point index variable data, two adjacent indices that are equal, or differ by one, indicates the location of a interpolation area boundary relating to an grid discontinuity (<>) +The relationship between a tie point interpolation dimension and its +corresponding interpolation dimension is defined with a __tie point +index variable__. This contains zero-based indices that map each +element of a tie point interpolation dimension to its related location +in the corresponding interpolation dimension. The tie point index +variable is a one-dimensional integer variable that spans a tie point +interpolation dimension. The values must be strictly monotonically +increasing within interpolation areas, and two adjacent indices that +are equal, or differ by one, indicates the location of an interpolation +area boundary relating to an grid discontinuity +(<>). For example, the tie point +index variable **`int x_indices(tp_xc)`** for a single interpolation +area could contain the indices **`x_indices = 0, 9, 19, 29`** of the +target domain. To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. From 581953fee9256957dbdd146dfde782d04a7952c3 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 09:04:49 +0000 Subject: [PATCH 030/249] indices --- ch08.adoc | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 6e41d424..4e86ad0f 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -123,20 +123,7 @@ The presence of non-interpolation dimensions in the tie point variable impacts t ORG The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas. For example, the tie point index variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. -The relationship between a tie point interpolation dimension and its -corresponding interpolation dimension is defined with a __tie point -index variable__. This contains zero-based indices that map each -element of a tie point interpolation dimension to its related location -in the corresponding interpolation dimension. The tie point index -variable is a one-dimensional integer variable that spans a tie point -interpolation dimension. The values must be strictly monotonically -increasing within interpolation areas, and two adjacent indices that -are equal, or differ by one, indicates the location of an interpolation -area boundary relating to an grid discontinuity -(<>). For example, the tie point -index variable **`int x_indices(tp_xc)`** for a single interpolation -area could contain the indices **`x_indices = 0, 9, 19, 29`** of the -target domain. +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). For example, the tie point index variable **`int x_indices(tp_xc)`** for a single interpolation area could contain the indices **`x_indices = 0, 9, 19, 29`** of the target domain. To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. From 72a55028d183092af332b677891dd81f23a4033d Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 09:05:00 +0000 Subject: [PATCH 031/249] indices --- ch08.adoc | 3 --- 1 file changed, 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 4e86ad0f..9a7e0108 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -120,9 +120,6 @@ The presence of non-interpolation dimensions in the tie point variable impacts t [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices"]] ==== Tie Point Indices -ORG -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas. For example, the tie point index variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. - The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). For example, the tie point index variable **`int x_indices(tp_xc)`** for a single interpolation area could contain the indices **`x_indices = 0, 9, 19, 29`** of the target domain. To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. From d83e833c029c48babd6f524be61b80df6ea8a1fd Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 09:40:09 +0000 Subject: [PATCH 032/249] super --- ch08.adoc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 9a7e0108..d0b0b43c 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -120,15 +120,19 @@ The presence of non-interpolation dimensions in the tie point variable impacts t [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). For example, the tie point index variable **`int x_indices(tp_xc)`** for a single interpolation area could contain the indices **`x_indices = 0, 9, 19, 29`** of the target domain. +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). -To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. +When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. -The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point index variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point index variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. +Conversely, when tie point variables represent a superset of the uncompressed coordinates, each value of the tie point index variable is the index of the tie point interpolation dimension that corresponds to the corresponding interpolation dimension. This situation could occur when a hierarchy of different resolution representations of data are stored in different data variables. Space can be saved by storing the highest resolution coordinates, and using tie point indices with an interpolation variable to derive the lower resolution coordinates. Such a superset is identifiable there being a unique interpolation area and the size of the tie point interpolation dimension being strictly greater than than the size of interpolation dimension. +For instance, in example <> the tie point variables represent a subset of the target domain and tie point index variable **`int x_indices(tp_xc)`** contains the indices **`x_indices = 0, 9, 19, 29`** that identify location of the interpolation dimension **`xc`** of size 30. However, in example < the tie point index variables represent a superset of the target domain and so in this case the same indices are identifying locations of the tie point interpolation dimension. -### TODO: Add text on super-sampling) +To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. + +The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point index variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point index variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. +[[Two-dimensional-tie-point-interpolation]] [caption="Example 8.3. "] .Two-dimensional tie point interpolation ==== From ba1be47dd8d7b558e8e8e5c9c4044895f32a68a8 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 13:50:09 +0000 Subject: [PATCH 033/249] more text following 2020-11-27 discussions (#3) * more text following 2020-11-27 discussions * bounds * tidy * tidy * tidy * tidy * reproducability * offset * indices * indices * indices * super --- ch08.adoc | 63 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index a33960fe..d0b0b43c 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -75,11 +75,11 @@ This information implies that the salinity field should be uncompressed to an ar For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to user of the uncompressed dataset. -The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset of the uncompressed coordinate values, they can also be different to some or all of them. +The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset (or superset, see section <) of the uncompressed coordinate values, they are typically be different to some or all of them. In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. -The defined metadata and methods for reconstituting the uncompressed data have been designed to be complete and unambiguous, meaning that that the results of the coordinate reconstitution process by the dat user are well defined and of a predictable accuracy. +The metadata that define the interpolation formula and its inputs are complete, so that the results of the coordinate reconstitution process are well defined and of a predictable accuracy. The data variable coordinate interpolation attributes may also be used on a domain variable (<>) with the same effect. @@ -88,19 +88,16 @@ The data variable coordinate interpolation attributes may also be used on a doma Reconstitution of the uncompressed coordinate and auxiliary coordinate variables is based on interpolation. To accomplish this, the target domain is segmented into smaller __interpolation zones__, for each of which the interpolation method is applied independently. For one dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone; for two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes; etc. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables within an interpolation zone, the interpolation method is permitted to access the coordinates of the defining tie points, but not the coordinates of any other tie points. -Although the coordinate and auxiliary coordinate variables are stored in orthogonal multidimensional array representation, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates, or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. +Although the coordinate and auxiliary coordinate variables are stored in orthogonal multidimensional array representation, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates, or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. In such cases the location of the discontinuities in the can be based either on knowledge of how the data set was created, e.g. by a remote sensing instrument, or alternatively by inspection of the actual coordinates. As the interpolation methods rely on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in <>. Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. -Note that the location of the discontinuities can be based either on knowledge of how the data set was created, e. g. by a remote sensing instrument, or alternatively on numerical analysis of the actual coordinates. - -For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__, which also allows the user to determine the location of the grid discontinuities(<>). +For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__, which also determines the location of the interpolation areas (<>). For each interpolation dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. - [[interpolation_zone_generation, figure 3]] [.text-center] .Process for generating the interpolation zones for a grid without discontinuities and for a grid with discontinuities. @@ -109,7 +106,7 @@ image::images/regular_and_piecewise_regular_grid.png[,100%,pdfwidth=50vw,align=" [[compression-by-coordinate-tie-points-attribute, Section 8.3.2, "Tie Points Attribute"]] ==== Tie Points Attribute -To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. +To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. [[compression-by-coordinate-interpolation-dimensions,Section 8.3.3, "Data Variable Attributes"]] ==== Interpolation and Non-Interpolation Dimensions @@ -123,19 +120,19 @@ The presence of non-interpolation dimensions in the tie point variable impacts t [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that map each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas. For example, the tie point index variable **`int x_indices(tp_xc)`** could contain the following indices **`x_indices = 0, 9, 19, 29`** of the target domain. - -In the tie point index variable, two adjacent indices that are equal or differ by one indicates the location of a interpolation area boundary relating to an grid discontinuity (<>) +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). -To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable] ...__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. +When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. -The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point index variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point index variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. +Conversely, when tie point variables represent a superset of the uncompressed coordinates, each value of the tie point index variable is the index of the tie point interpolation dimension that corresponds to the corresponding interpolation dimension. This situation could occur when a hierarchy of different resolution representations of data are stored in different data variables. Space can be saved by storing the highest resolution coordinates, and using tie point indices with an interpolation variable to derive the lower resolution coordinates. Such a superset is identifiable there being a unique interpolation area and the size of the tie point interpolation dimension being strictly greater than than the size of interpolation dimension. -If there is a tie point index for every element of an interpolation dimension, then the tie point index variable need not be included in the dataset, as its contents must be the integers 0 to [size of tie point interpolation dimension minus one (CHANGE!)], and therefore do not need to be stored in a variable. Instead, the **`tie_point_indices`** attribute may associate the interpolation dimension with the tie point dimension dimension, rather than a tie point index variable. In this case, if there is a coordinate variable with the same name as the tie point dimension then the variable is not to be used as a tie point index variable. +For instance, in example <> the tie point variables represent a subset of the target domain and tie point index variable **`int x_indices(tp_xc)`** contains the indices **`x_indices = 0, 9, 19, 29`** that identify location of the interpolation dimension **`xc`** of size 30. However, in example < the tie point index variables represent a superset of the target domain and so in this case the same indices are identifying locations of the tie point interpolation dimension. +To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. -(To Do: Add text on super-sampling) +The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point index variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point index variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. +[[Two-dimensional-tie-point-interpolation]] [caption="Example 8.3. "] .Two-dimensional tie point interpolation ==== @@ -218,17 +215,17 @@ data: [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Offsets"]] ==== Tie Point Offsets -By default, it is assumed that the tie point coordinates are a subset of the uncompressed coordinates. However, it may be that the tie point coordinates are offset from a subset of the uncompressed coordinates. In this case, the data variable requires a **`tie_point_offsets`** attribute to record the nature of this offset. +By default, it is assumed that the tie points are a subset of the uncompressed coordinates. However, it may be that the tie points are offset from a subset of the uncompressed coordinates. In this case, the data variable requires a **`tie_point_offsets`** attribute to record the nature of this offset. -The **`tie_point_offsets`** attribute is a string attribute maps interpolation dimensions to the corresponding __tie point offset variables__. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_offset_variable [interpolation_dimension: tie_point_offset_variable] ...__". +The **`tie_point_offsets`** attribute is a string attribute maps interpolation dimensions to the corresponding __tie point offset variables__. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_offset_variable [interpolation_dimension: tie_point_offset_variable ...]__". This mapping is not part of the interpolation variable because different data variables may apply the same interpolation method, with the same tie points variables, but with different offsets. -A tie point offset variable defines a numerical offset in terms of the fraction of the size of a target domain cell along a single dimension. When associated with an interpolation dimension by the **`tie_point_offsets`** attribute, this offset locates the tie point variable coordinates relative to the uncompressed coordinates. A tie point offset variable may be a scalar, or else its dimensions may include the tie point interpolation dimension corresponding to the named interpolation dimension, as well as any subset of the non-interpolation dimensions. No other dimensions may be spanned by a tie point offset variable. +A tie point offset variable defines numerical offsets in terms of the fraction of the size of a target domain cell along a single dimension. When associated with an interpolation dimension by the **`tie_point_offsets`** attribute, this offset locates the tie point variable coordinates relative to the uncompressed coordinates. A tie point offset variable may be a scalar, or else its dimensions may include the tie point interpolation dimension corresponding to the named interpolation dimension, as well as any subset of the non-interpolation dimensions. No other dimensions may be spanned by a tie point offset variable. -An positive offset value indicates and tie point offset in the positive direction of the corresponding interpolation dimension. An offset is bounded to -1.0 < offset < 1.0; +An offset value, which must be in the open range `(-1.0, 1.0)`, indicates a tie point offset towards an adjacent element of the corresponding interpolation dimension as follows: A positive offset value indicates a tie point offset towards the next element, and a negative offset indicates a tie point offset towards the previous element. Note that the location of the offset does not depend on the whether the uncompressed coordinates are increasing or decreasing along the interpolation dimension. -For example, specifying that for both of the interpolation dimensions **`track`** and **`scan`** the offset is -0.5 (indicating that the tie point coordinates are offset by half a grid cell in each each direction from their corresponding uncompressed corodinates), could be indicated could be indicated with a **`tie_point_offsets`** attribute of **`track: offset scan: offset`**, where **`offset`** is a scalar tie point variable that has the value **`offset = -0.5`**. +For example, specifying that for both of the interpolation dimensions **`track`** and **`scan`** the offset is `-0.5` (indicating that the tie points are offset by half a grid cell along each dimension from their corresponding uncompressed coordinates), could be indicated with a **`tie_point_offsets`** attribute of **`track: offset scan: offset`**, where **`offset`** is a scalar tie point variable that has the value **`offset = -0.5`**. [[compression-by-coordinate-interpolation-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] ==== Interpolation Variable @@ -243,15 +240,15 @@ If a standardized interpolation name is not given, the interpolation variable mu The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). -The interpolation variable attributes **`interpolation_coefficients`** and **`interpolation_flags`** may be used to configure the interpolation process. These attributes name other variables that contain parameters needed to correctly configure the interpolation process. Both of these attributes are a blank-separated list of words of the form "__variable [variable] ...__". +An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie points. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation equations, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. -The variables named by the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding interpolation zone dimension, but not both, and may include any of the non-interpolation dimensions. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along the particular interpolation dimension. +The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation method definition, and `variable` is the name of the interpolation configuration variable that contains the values for that term. The order of elements is not significant. -Therefore, if a variable spans all the interpolation zone dimensions then it allows its parameters to be stored differently for each interpolation zone. Similarly, if a variable spans a combination of interpolation zone dimensions and tie point interpolation dimension then it allows parameters to be shared by sets of neighbouring interpolation zones. Note that shared parameters can be used to ensure continuity of the consistency of the reconstituted coordinate values across interpolation zone boundaries. +The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. -An interpolation method is only permitted to access the elements of the variables named by the interpolation_coefficients and interpolation_flags which are associated with the interpolation zone through their indices. +The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding __interpolation zone dimension__, but not both, and may include any of the non-interpolation dimensions. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along a particular interpolation dimension. Note that an interpolation zone dimension size is the same as the number of tie points along the corresponding interpolation dimension, minus the number of interpolation areas. -As an example, for the two-dimensional case, <> shows the interpolation coefficients and interpolation flags variable dimensions in relation to an interpolation zone and its boundaries. +If an interpolation coefficent or configuration variable spans the interpolation zone dimensions corresponding to of all the interpolation dimensions, then it defines a separate value for each interpolation zone. If, however, a variable spans at least one tie point interpolation dimension, then each of its values is shared by the interpolation zones that are adjacent in the dimensions defined by tie point interpolation dimensions. The former case is akin to values being defined at the centre of interpolation zones. The latter case is akin to values being defined at interpolation zone boundaries, and therefore equally applicable to both interpolation zones that share that boundary (<>). [[interpolation_variable, figure 4]] [.text-center] @@ -259,13 +256,17 @@ As an example, for the two-dimensional case, <> shows th image::images/interpolation_variables.png[,100%,pdfwidth=50vw,align="center"] +Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the uncompressed coordinates may only access the tie point that define the extent of the of the interpolation zone, as well as any interpolation coefficient and configuration variables defined for the interpolation zone, including its boundaries. + +[[compression-by-coordinate-interpolation-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] +==== Interpolation of Tie Point Bounds -Note that an interpolation zone dimension size is the same as the number of tie point coordinates along the corresponding interpolation dimension, minus the number of interpolation areas. +If a tie point variable has cell boundaries bounds then it must have the attribute **`bounds`** that names the variable that contains the vertices of the cell boundaries. The bounds should be the same as the bounds of the corresponding target grid cells, unless there is a non-zero offset, in which case the offset applies to the bounds values in exactly the same manner as it does to the cell coordinates. It is thereforefore likely that tie point cells will be non-contiguous. -The variables referenced by the **`interpolation_coefficients`** attribute must contain numeric data, and the variables referenced by the **`interpolation_flags`** attribute must contain status flag attributes (<>). +The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the indentifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensionsal tie point variable with four-sided cells then the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. -If the interpolation method has been given with an **`interpolation_name`** attribute, then the **`interpolation_coefficients`** and **`interpolation_flags`** attributes must only be present if they are allowed by the interpolation method's description in appendix , and the variables they reference must meet the requirements given in the description. +Note that an implementation of the interpolation method is free to calculate the uncompressed bounds locations in the manner of its choosing, as a long as the result is formally equivalent to each bounds position being treated independently. [caption="Example 8.5. "] .Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation flags attributes. @@ -337,10 +338,10 @@ variables: // Interpolation variable char tp_interpolation ; tp_interpolation:interpolation_name = "bi_quadratic_1" ; - tp_interpolation:interpolation_coefficients = "expansion_coefficient_track alignment_coefficient_track expansion_coefficient_scan alignment_coefficient_scan" ; - tp_interpolation:interpolation_flags = "interpolation_zone_flags" ; + tp_interpolation:interpolation_coefficients = "TOO1:D expansion_coefficient_track TODO2: alignment_coefficient_track TODO3: expansion_coefficient_scan TODO4: alignment_coefficient_scan" ; + tp_interpolation:interpolation_configuration = "TODO5: interpolation_zone_flags" ; - // Interpolation coefficients and flags + // Interpolation coefficient and configuration variables short expansion_coefficient_track(track_interpolation_zone, tp_scan) ; short alignment_coefficient_track(track_interpolation_zone, tp_scan) ; short expansion_coefficient_scan(tp_track, scan_interpolation_zone) ; From 6f9c89d02d3bfdd06d5ec1bef71159bd8bd6b428 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 30 Nov 2020 15:23:41 +0100 Subject: [PATCH 034/249] Update ch08.adoc Minor editorial changes --- ch08.adoc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index d0b0b43c..228f9e9b 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -88,13 +88,13 @@ The data variable coordinate interpolation attributes may also be used on a doma Reconstitution of the uncompressed coordinate and auxiliary coordinate variables is based on interpolation. To accomplish this, the target domain is segmented into smaller __interpolation zones__, for each of which the interpolation method is applied independently. For one dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone; for two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes; etc. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables within an interpolation zone, the interpolation method is permitted to access the coordinates of the defining tie points, but not the coordinates of any other tie points. -Although the coordinate and auxiliary coordinate variables are stored in orthogonal multidimensional array representation, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates, or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. In such cases the location of the discontinuities in the can be based either on knowledge of how the data set was created, e.g. by a remote sensing instrument, or alternatively by inspection of the actual coordinates. +Although the coordinate and auxiliary coordinate variables are stored in orthogonal multidimensional array representation, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates, or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. In such cases the location of the discontinuities in the coordinate values can be based either on knowledge of how the data set was created, e.g. by a remote sensing instrument, or alternatively by inspection of the actual coordinates. As the interpolation methods rely on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in <>. Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. -For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__, which also determines the location of the interpolation areas (<>). +For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__, which also indicates the location of the interpolation areas (<>). For each interpolation dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. @@ -124,7 +124,7 @@ The relationship between a tie point interpolation dimension and its correspondi When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. -Conversely, when tie point variables represent a superset of the uncompressed coordinates, each value of the tie point index variable is the index of the tie point interpolation dimension that corresponds to the corresponding interpolation dimension. This situation could occur when a hierarchy of different resolution representations of data are stored in different data variables. Space can be saved by storing the highest resolution coordinates, and using tie point indices with an interpolation variable to derive the lower resolution coordinates. Such a superset is identifiable there being a unique interpolation area and the size of the tie point interpolation dimension being strictly greater than than the size of interpolation dimension. +Conversely, when tie point variables represent a superset of the uncompressed coordinates, each value of the tie point index variable is the index of the tie point interpolation dimension that corresponds to the corresponding interpolation dimension. This situation could occur when a hierarchy of different resolution representations of data are stored in different data variables. Space can be saved by storing the highest resolution coordinates, and using tie point indices with an interpolation variable to derive the lower resolution coordinates. Such a superset is identifiable by there being a unique interpolation area and the size of the tie point interpolation dimension being strictly greater than than the size of interpolation dimension. For instance, in example <> the tie point variables represent a subset of the target domain and tie point index variable **`int x_indices(tp_xc)`** contains the indices **`x_indices = 0, 9, 19, 29`** that identify location of the interpolation dimension **`xc`** of size 30. However, in example < the tie point index variables represent a superset of the target domain and so in this case the same indices are identifying locations of the tie point interpolation dimension. @@ -223,7 +223,7 @@ This mapping is not part of the interpolation variable because different data va A tie point offset variable defines numerical offsets in terms of the fraction of the size of a target domain cell along a single dimension. When associated with an interpolation dimension by the **`tie_point_offsets`** attribute, this offset locates the tie point variable coordinates relative to the uncompressed coordinates. A tie point offset variable may be a scalar, or else its dimensions may include the tie point interpolation dimension corresponding to the named interpolation dimension, as well as any subset of the non-interpolation dimensions. No other dimensions may be spanned by a tie point offset variable. -An offset value, which must be in the open range `(-1.0, 1.0)`, indicates a tie point offset towards an adjacent element of the corresponding interpolation dimension as follows: A positive offset value indicates a tie point offset towards the next element, and a negative offset indicates a tie point offset towards the previous element. Note that the location of the offset does not depend on the whether the uncompressed coordinates are increasing or decreasing along the interpolation dimension. +An offset value, which must be in the open range `(-1.0, 1.0)`, indicates a tie point offset towards an adjacent element of the corresponding interpolation dimension as follows: A positive offset value indicates a tie point offset towards the next element, and a negative offset indicates a tie point offset towards the previous element. Note that the location of the offset does not depend on whether the uncompressed coordinates are increasing or decreasing along the interpolation dimension. For example, specifying that for both of the interpolation dimensions **`track`** and **`scan`** the offset is `-0.5` (indicating that the tie points are offset by half a grid cell along each dimension from their corresponding uncompressed coordinates), could be indicated with a **`tie_point_offsets`** attribute of **`track: offset scan: offset`**, where **`offset`** is a scalar tie point variable that has the value **`offset = -0.5`**. @@ -248,7 +248,7 @@ The **`interpolation_coefficient`** and **`interpolation_configuration`** attrib The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding __interpolation zone dimension__, but not both, and may include any of the non-interpolation dimensions. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along a particular interpolation dimension. Note that an interpolation zone dimension size is the same as the number of tie points along the corresponding interpolation dimension, minus the number of interpolation areas. -If an interpolation coefficent or configuration variable spans the interpolation zone dimensions corresponding to of all the interpolation dimensions, then it defines a separate value for each interpolation zone. If, however, a variable spans at least one tie point interpolation dimension, then each of its values is shared by the interpolation zones that are adjacent in the dimensions defined by tie point interpolation dimensions. The former case is akin to values being defined at the centre of interpolation zones. The latter case is akin to values being defined at interpolation zone boundaries, and therefore equally applicable to both interpolation zones that share that boundary (<>). +If an interpolation coefficent or configuration variable spans the interpolation zone dimensions corresponding to all of the interpolation dimensions, then it defines a separate value for each interpolation zone. If, however, a variable spans at least one tie point interpolation dimension, then each of its values is shared by the interpolation zones that are adjacent in the dimensions defined by tie point interpolation dimensions. The former case is akin to values being defined at the centre of interpolation zones. The latter case is akin to values being defined at interpolation zone boundaries, and therefore equally applicable to both interpolation zones that share that boundary (<>). [[interpolation_variable, figure 4]] [.text-center] @@ -256,6 +256,7 @@ If an interpolation coefficent or configuration variable spans the interpolation image::images/interpolation_variables.png[,100%,pdfwidth=50vw,align="center"] + Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the uncompressed coordinates may only access the tie point that define the extent of the of the interpolation zone, as well as any interpolation coefficient and configuration variables defined for the interpolation zone, including its boundaries. From 179b78182621956da4b15a53b7d98bf01c524448 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 30 Nov 2020 17:52:16 +0100 Subject: [PATCH 035/249] Remove tie_point_offset attribute --- ch08.adoc | 108 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 56 insertions(+), 52 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 228f9e9b..e7577161 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -120,7 +120,7 @@ The presence of non-interpolation dimensions in the tie point variable impacts t [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices where the value of the second is the equal to the value of the first incremented by one indicates the location of a interpolation area boundary (<>). When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. @@ -165,6 +165,7 @@ variables: Temperature:standard_name = "air_temperature" ; Temperature:units = "K" ; Temperature:tie_points = "lat: lon: bi_linear" ; + Temperature:tie_point_dimensions = "xc: tp_xc yc: tp_y" ; Temperature:tie_point_indices = "yc: y_indices xc: x_indices" ; data: @@ -204,6 +205,7 @@ variables: Temperature:standard_name = "air_temperature" ; Temperature:units = "K" ; Temperature:tie_points = "lat: lon: linear" ; + Temperature:tie_point_dimensions = "xc: tp_xc" ; Temperature:tie_point_indices = "xc: x_indices" ; data: @@ -212,21 +214,6 @@ data: ---- ==== -[[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Offsets"]] -==== Tie Point Offsets - -By default, it is assumed that the tie points are a subset of the uncompressed coordinates. However, it may be that the tie points are offset from a subset of the uncompressed coordinates. In this case, the data variable requires a **`tie_point_offsets`** attribute to record the nature of this offset. - -The **`tie_point_offsets`** attribute is a string attribute maps interpolation dimensions to the corresponding __tie point offset variables__. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_offset_variable [interpolation_dimension: tie_point_offset_variable ...]__". - -This mapping is not part of the interpolation variable because different data variables may apply the same interpolation method, with the same tie points variables, but with different offsets. - -A tie point offset variable defines numerical offsets in terms of the fraction of the size of a target domain cell along a single dimension. When associated with an interpolation dimension by the **`tie_point_offsets`** attribute, this offset locates the tie point variable coordinates relative to the uncompressed coordinates. A tie point offset variable may be a scalar, or else its dimensions may include the tie point interpolation dimension corresponding to the named interpolation dimension, as well as any subset of the non-interpolation dimensions. No other dimensions may be spanned by a tie point offset variable. - -An offset value, which must be in the open range `(-1.0, 1.0)`, indicates a tie point offset towards an adjacent element of the corresponding interpolation dimension as follows: A positive offset value indicates a tie point offset towards the next element, and a negative offset indicates a tie point offset towards the previous element. Note that the location of the offset does not depend on whether the uncompressed coordinates are increasing or decreasing along the interpolation dimension. - -For example, specifying that for both of the interpolation dimensions **`track`** and **`scan`** the offset is `-0.5` (indicating that the tie points are offset by half a grid cell along each dimension from their corresponding uncompressed coordinates), could be indicated with a **`tie_point_offsets`** attribute of **`track: offset scan: offset`**, where **`offset`** is a scalar tie point variable that has the value **`offset = -0.5`**. - [[compression-by-coordinate-interpolation-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] ==== Interpolation Variable @@ -263,7 +250,7 @@ Note that the interpolation method is always applied on a per interpolation zone [[compression-by-coordinate-interpolation-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds -If a tie point variable has cell boundaries bounds then it must have the attribute **`bounds`** that names the variable that contains the vertices of the cell boundaries. The bounds should be the same as the bounds of the corresponding target grid cells, unless there is a non-zero offset, in which case the offset applies to the bounds values in exactly the same manner as it does to the cell coordinates. It is thereforefore likely that tie point cells will be non-contiguous. +If a tie point variable has cell boundaries bounds then it must have the attribute **`bounds`** that names the variable that contains the vertices of the cell boundaries. The bounds should be the same as the bounds of the corresponding target grid cells. It is thereforefore likely that tie point cells will be non-contiguous. The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the indentifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensionsal tie point variable with four-sided cells then the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. @@ -287,8 +274,8 @@ dimensions : // Tie points and interpolation zones (shared between VIIRS M-Band and I-Band) tp_track = 96 ; // 48 VIIRS scans tp_scan = 205 ; - track_interpolation_zone = 48 ; - scan_interpolation_zone = 200 ; + zone_track = 48 ; // track interpolation zone + zone_scan= 200 ; // scan interpolation zone // Time, stored at scan-start and scan-end of each scan time_scan = 2; @@ -296,17 +283,15 @@ dimensions : variables: // VIIRS M-Band float m_radiance(m_track, m_scan, m_channel) ; - m_radiance:tie_points = "lat: lon: sen_azi_ang: sen_zen_ang: sol_azi_ang: sol_zen_ang: tp_interpolation t: time_interpolation" ; - m_radiance:tie_point_indices = "m_track: m_track_indices m_scan: m_scan_indices time_scan: m_time_scan_indices" ; - m_radiance:tie_point_offsets = "m_track: offset m_scan: offset" ; + m_radiance:tie_points = "m_lat: m_lon: m_sen_azi_ang: m_sen_zen_ang: m_sol_azi_ang: m_sol_zen_ang: tp_interpolation t: time_interpolation" ; + m_radiance:tie_point_dimensions = "m_track: tp_track zone_track m_scan: tp_scan zone_scan" ; + m_radiance:tie_point_indices = "m_track: m_track_indices m_scan: m_scan_indices time_scan: m_time_scan_indices" ; // VIIRS I-Band float i_radiance(i_track, i_scan, i_channel) ; - i_radiance:tie_points = "lat: lon: sen_azi_ang: sen_zen_ang: sol_azi_ang: sol_zen_ang: tp_interpolation t: time_interpolation" ; - i_radiance:tie_point_indices = "i_track: i_track_indices i_scan: i_scan_indices time_scan: i_time_scan_indices" ; - i_radiance:tie_point_offsets = "i_track: offset i_scan: offset" ; - - double offset; // = -0.5 + i_radiance:tie_points = "i_lat: i_lon: i_sen_azi_ang: i_sen_zen_ang: i_sol_azi_ang: i_sol_zen_ang: tp_interpolation t: time_interpolation" ; + m_radiance:tie_point_dimensions = "i_track: tp_track zone_track i_scan: tp_scan zone_scan" ; + i_radiance:tie_point_indices = "i_track: zone_track: i_track_indices i_scan: zone_scan: i_scan_indices time_scan: i_time_scan_indices" ; // Tie point index variables int m_track_indices(tp_track) ; // shared by tp_interpolation and time_interpolation @@ -317,37 +302,56 @@ variables: int i_time_scan_indices(time_scan) // Tie points - float lat(tp_track, tp_scan) ; - lat : standard_name = "latitude" ; - lat : units = "degrees_north" ; - float lon(tp_track, tp_scan) ; - lon : standard_name = "longitude" ; - lon : units = "degrees_east" ; - float sen_azi_ang(tp_track, tp_scan) ; - sen_azi_ang : standard_name = "sensor_azimuth_angle" ; - sen_azi_ang : units = "degrees" ; - float sen_zen_ang(tp_track, tp_scan) ; - sen_zen_ang : standard_name = "sensor_zenith_angle" ; - sen_zen_ang : units = "degrees" ; - float sol_azi_ang(tp_track, tp_scan) ; - sol_azi_ang : standard_name = "solar_azimuth_angle" ; - sol_azi_ang : units = "degrees" ; - float sol_zen_ang(tp_track, tp_scan) ; - sol_zen_ang : standard_name = "solar_zenith_angle" ; - sol_zen_ang : units = "degrees" ; + float m_lat(tp_track, tp_scan) ; + m_lat : standard_name = "latitude" ; + m_lat : units = "degrees_north" ; + float m_lon(tp_track, tp_scan) ; + m_lon : standard_name = "longitude" ; + m_lon : units = "degrees_east" ; + float m_sen_azi_ang(tp_track, tp_scan) ; + m_sen_azi_ang : standard_name = "sensor_azimuth_angle" ; + m_sen_azi_ang : units = "degrees" ; + float m_sen_zen_ang(tp_track, tp_scan) ; + m_sen_zen_ang : standard_name = "sensor_zenith_angle" ; + m_sen_zen_ang : units = "degrees" ; + float m_sol_azi_ang(tp_track, tp_scan) ; + m_sol_azi_ang : standard_name = "solar_azimuth_angle" ; + m_sol_azi_ang : units = "degrees" ; + float m_sol_zen_ang(tp_track, tp_scan) ; + m_sol_zen_ang : standard_name = "solar_zenith_angle" ; + m_sol_zen_ang : units = "degrees" ; + + float i_lat(tp_track, tp_scan) ; + i_lat : standard_name = "latitude" ; + i_lat : units = "degrees_north" ; + float i_lon(tp_track, tp_scan) ; + i_lon : standard_name = "longitude" ; + i_lon : units = "degrees_east" ; + float i_sen_azi_ang(tp_track, tp_scan) ; + i_sen_azi_ang : standard_name = "sensor_azimuth_angle" ; + i_sen_azi_ang : units = "degrees" ; + float i_sen_zen_ang(tp_track, tp_scan) ; + i_sen_zen_ang : standard_name = "sensor_zenith_angle" ; + i_sen_zen_ang : units = "degrees" ; + float i_sol_azi_ang(tp_track, tp_scan) ; + i_sol_azi_ang : standard_name = "solar_azimuth_angle" ; + i_sol_azi_ang : units = "degrees" ; + float i_sol_zen_ang(tp_track, tp_scan) ; + i_sol_zen_ang : standard_name = "solar_zenith_angle" ; + i_sol_zen_ang : units = "degrees" ; // Interpolation variable char tp_interpolation ; tp_interpolation:interpolation_name = "bi_quadratic_1" ; - tp_interpolation:interpolation_coefficients = "TOO1:D expansion_coefficient_track TODO2: alignment_coefficient_track TODO3: expansion_coefficient_scan TODO4: alignment_coefficient_scan" ; - tp_interpolation:interpolation_configuration = "TODO5: interpolation_zone_flags" ; + tp_interpolation:interpolation_coefficients = "exp1: expansion1 align1: alignment1 exp2: expansion2 align2:alignment2" ; + tp_interpolation:interpolation_configuration = "flags: interpolation_zone_flags" ; // Interpolation coefficient and configuration variables - short expansion_coefficient_track(track_interpolation_zone, tp_scan) ; - short alignment_coefficient_track(track_interpolation_zone, tp_scan) ; - short expansion_coefficient_scan(tp_track, scan_interpolation_zone) ; - short alignment_coefficient_scan(tp_track, scan_interpolation_zone) ; - byte interpolation_zone_flags(track_interpolation_zone, scan_interpolation_zone) ; + short expansion1(zone_track , tp_scan) ; + short alignment1(zone_track , tp_scan) ; + short expansion2(tp_track, zone_scan) ; + short alignment2(tp_track, zone_scan) ; + byte interpolation_zone_flags(zone_track , zone_scan) ; interpolation_zone_flags : valid_range = "1b, 7b" ; interpolation_zone_flags : flag_masks = "1b, 2b, 4b" ; interpolation_zone_flags : flag_meanings = "location_use_cartesian sensor_direction_use_cartesian solar_direction_use_cartesian" ; From 4c2938a4981060d11b247b7314551e1bef45bb5e Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 17:34:04 +0000 Subject: [PATCH 036/249] tie_point_dimension (1) --- ch08.adoc | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 7161b0e8..979c2229 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -117,10 +117,17 @@ An interpolation dimension typically differs in size from the corresponding tie The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. -[[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices"]] +[[compression-by-coordinate-interpolation-tie-point-dimensions-attribute, Section 8.3.4, "Tie Point Dimensions Attribute"]] +==== Tie Point Dimensions Attribute + +Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones that partition that interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficient or configuation variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. + +Note that an interpolation zone dimension size is, by definition, the same as the number of tie points along the corresponding interpolation dimension, minus the number of interpolation areas. + +[[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. @@ -244,11 +251,15 @@ An interpolation method may require __interpolation coefficient variables__ that The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation method definition, and `variable` is the name of the interpolation configuration variable that contains the values for that term. The order of elements is not significant. -The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. +The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. + +The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding interpolation zone dimension, but not both, and may include any of the non-interpolation dimensions. -The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding __interpolation zone dimension__, but not both, and may include any of the non-interpolation dimensions. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along a particular interpolation dimension. Note that an interpolation zone dimension size is the same as the number of tie points along the corresponding interpolation dimension, minus the number of interpolation areas. +The interpretation of interpolation coefficent and configuration variables depends on the nature of the dimensions that they span: -If an interpolation coefficent or configuration variable spans the interpolation zone dimensions corresponding to all of the interpolation dimensions, then it defines a separate value for each interpolation zone. If, however, a variable spans at least one tie point interpolation dimension, then each of its values is shared by the interpolation zones that are adjacent in the dimensions defined by tie point interpolation dimensions. The former case is akin to values being defined at the centre of interpolation zones. The latter case is akin to values being defined at interpolation zone boundaries, and therefore equally applicable to both interpolation zones that share that boundary (<>). +* If all of the dimensions comprise a subset of the interpolation zone dimensions, then the variable defines a value for every interpolation zone. This case is akin to values being defined at the centre of interpolation zones. + +* If at least one dimension is a tie point interpolation dimension, then the of each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). [[interpolation_variable, figure 4]] [.text-center] From 9841adb1f9b92589e4174b4e40a166f791c96893 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 17:36:42 +0000 Subject: [PATCH 037/249] tie_point_dimension (2) --- ch08.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 979c2229..0476fe39 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -120,9 +120,9 @@ The presence of non-interpolation dimensions in the tie point variable impacts t [[compression-by-coordinate-interpolation-tie-point-dimensions-attribute, Section 8.3.4, "Tie Point Dimensions Attribute"]] ==== Tie Point Dimensions Attribute -Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones that partition that interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficient or configuation variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. +Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficient or configuation variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. -Note that an interpolation zone dimension size is, by definition, the same as the number of tie points along the corresponding interpolation dimension, minus the number of interpolation areas. +Note that an interpolation zone dimension size is, by definition, the same as the size of the corresponding tie point interpolation dimension, minus the number of interpolation areas. [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices From 0cb92e5c3939b4239f5a60d915d8e69796d2e40f Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 17:44:22 +0000 Subject: [PATCH 038/249] tie_point_dimension (3) --- ch08.adoc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 0476fe39..a82b287b 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -122,7 +122,7 @@ The presence of non-interpolation dimensions in the tie point variable impacts t Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficient or configuation variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. -Note that an interpolation zone dimension size is, by definition, the same as the size of the corresponding tie point interpolation dimension, minus the number of interpolation areas. +Note that an interpolation zone dimension has, by definition, the same size as the corresponding tie point interpolation dimension, minus the number of interpolation areas. [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices @@ -257,9 +257,11 @@ The variables named by the **`interpolation_coefficients`** and **`interpolation The interpretation of interpolation coefficent and configuration variables depends on the nature of the dimensions that they span: -* If all of the dimensions comprise a subset of the interpolation zone dimensions, then the variable defines a value for every interpolation zone. This case is akin to values being defined at the centre of interpolation zones. +* If no tie point interpolation dimensions are spanned, then the variable defines a value for every interpolation zone. This case is akin to values being defined at the centre of interpolation zones. -* If at least one dimension is a tie point interpolation dimension, then the of each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). +* If at least one dimension is a tie point interpolation dimension, then each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). + +In both cases, values are broadcast along any interpolation zone dimension s that are not spanned by the variable. [[interpolation_variable, figure 4]] [.text-center] From 907b5964a5fb380644906b7a5ab4e8525238bfa9 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 17:47:03 +0000 Subject: [PATCH 039/249] tie_point_dimension (4) --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index a82b287b..724c9cbb 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -261,7 +261,7 @@ The interpretation of interpolation coefficent and configuration variables depen * If at least one dimension is a tie point interpolation dimension, then each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). -In both cases, values are broadcast along any interpolation zone dimension s that are not spanned by the variable. +In both cases, the implementation of the interpolation method should be broadcast an interpolation coefficent or configuration variable along any interpolation zone dimensions that it does not span. [[interpolation_variable, figure 4]] [.text-center] From 3731c5a410c16e3a7d1e4e98dc1f9150b93b0225 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 17:50:00 +0000 Subject: [PATCH 040/249] tie point --- ch08.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 724c9cbb..15fb2050 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -75,7 +75,7 @@ This information implies that the salinity field should be uncompressed to an ar For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to user of the uncompressed dataset. -The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset (or superset, see section <) of the uncompressed coordinate values, they are typically be different to some or all of them. +The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. @@ -261,7 +261,7 @@ The interpretation of interpolation coefficent and configuration variables depen * If at least one dimension is a tie point interpolation dimension, then each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). -In both cases, the implementation of the interpolation method should be broadcast an interpolation coefficent or configuration variable along any interpolation zone dimensions that it does not span. +In both cases, the implementation of the interpolation method should broadcast an interpolation coefficent or configuration variable along any interpolation zone dimensions that it does not span. [[interpolation_variable, figure 4]] [.text-center] From f2771073036f1882691901f41372d33b4bb9a113 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 17:58:25 +0000 Subject: [PATCH 041/249] tie_point_dimension (5) --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 15fb2050..e80970ef 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -257,7 +257,7 @@ The variables named by the **`interpolation_coefficients`** and **`interpolation The interpretation of interpolation coefficent and configuration variables depends on the nature of the dimensions that they span: -* If no tie point interpolation dimensions are spanned, then the variable defines a value for every interpolation zone. This case is akin to values being defined at the centre of interpolation zones. +* If no tie point interpolation dimensions are spanned, then the variable provides a value for every interpolation zone. This case is akin to values being defined at the centre of interpolation zones. * If at least one dimension is a tie point interpolation dimension, then each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). From 2c73f03be2dc3bbaf279eccfbea1d439a4340246 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 30 Nov 2020 18:13:51 +0000 Subject: [PATCH 042/249] Anders subsampled (#4) * more text following 2020-11-27 discussions * bounds * tidy * tidy * tidy * tidy * reproducability * offset * indices * indices * indices * super * tie_point_dimension (1) * tie_point_dimension (2) * tie_point_dimension (3) * tie_point_dimension (4) * tie point * tie_point_dimension (5) --- ch08.adoc | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index e7577161..a43362c5 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -75,7 +75,7 @@ This information implies that the salinity field should be uncompressed to an ar For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to user of the uncompressed dataset. -The lower resolution coordinates are stored in __tie point variables__. This terminology is chosen to acknowledge that, whilst the values of a tie point variable may be a subset (or superset, see section <) of the uncompressed coordinate values, they are typically be different to some or all of them. +The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. @@ -117,10 +117,17 @@ An interpolation dimension typically differs in size from the corresponding tie The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. -[[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.4, "Tie Point Indices"]] +[[compression-by-coordinate-interpolation-tie-point-dimensions-attribute, Section 8.3.4, "Tie Point Dimensions Attribute"]] +==== Tie Point Dimensions Attribute + +Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficient or configuation variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. + +Note that an interpolation zone dimension has, by definition, the same size as the corresponding tie point interpolation dimension, minus the number of interpolation areas. + +[[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that spans a tie point interpolation dimension. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices where the value of the second is the equal to the value of the first incremented by one indicates the location of a interpolation area boundary (<>). +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. @@ -231,11 +238,17 @@ An interpolation method may require __interpolation coefficient variables__ that The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation method definition, and `variable` is the name of the interpolation configuration variable that contains the values for that term. The order of elements is not significant. -The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. +The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. -The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding __interpolation zone dimension__, but not both, and may include any of the non-interpolation dimensions. An interpolation zone dimension is a dimension whose size is equal to the number of interpolation zones along a particular interpolation dimension. Note that an interpolation zone dimension size is the same as the number of tie points along the corresponding interpolation dimension, minus the number of interpolation areas. +The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding interpolation zone dimension, but not both, and may include any of the non-interpolation dimensions. -If an interpolation coefficent or configuration variable spans the interpolation zone dimensions corresponding to all of the interpolation dimensions, then it defines a separate value for each interpolation zone. If, however, a variable spans at least one tie point interpolation dimension, then each of its values is shared by the interpolation zones that are adjacent in the dimensions defined by tie point interpolation dimensions. The former case is akin to values being defined at the centre of interpolation zones. The latter case is akin to values being defined at interpolation zone boundaries, and therefore equally applicable to both interpolation zones that share that boundary (<>). +The interpretation of interpolation coefficent and configuration variables depends on the nature of the dimensions that they span: + +* If no tie point interpolation dimensions are spanned, then the variable provides a value for every interpolation zone. This case is akin to values being defined at the centre of interpolation zones. + +* If at least one dimension is a tie point interpolation dimension, then each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). + +In both cases, the implementation of the interpolation method should broadcast an interpolation coefficent or configuration variable along any interpolation zone dimensions that it does not span. [[interpolation_variable, figure 4]] [.text-center] @@ -243,7 +256,6 @@ If an interpolation coefficent or configuration variable spans the interpolation image::images/interpolation_variables.png[,100%,pdfwidth=50vw,align="center"] - Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the uncompressed coordinates may only access the tie point that define the extent of the of the interpolation zone, as well as any interpolation coefficient and configuration variables defined for the interpolation zone, including its boundaries. From 3604542f2791a33d1b9672a283caa1bb6fa482aa Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 1 Dec 2020 14:08:25 +0000 Subject: [PATCH 043/249] corrected interpolation_configuration description --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index a43362c5..fa41cb3e 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -236,7 +236,7 @@ The definition of the interpolation method, however it is specified, may include An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie points. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation equations, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. -The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation method definition, and `variable` is the name of the interpolation configuration variable that contains the values for that term. The order of elements is not significant. +The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"item: variable"`, where `item` is a case-insensitive keyword that identies a configuration item defined in the interpolations method's definition, and `variable` is the name of the interpolation configuration variable that contains the values for that item. The order of elements is not significant. The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. From 5aa593831e1cd0b74605affd5ffd8c4b65267dac Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 4 Dec 2020 12:02:53 +0100 Subject: [PATCH 044/249] Delete interpolation_variables.png --- images/interpolation_variables.png | Bin 86842 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 images/interpolation_variables.png diff --git a/images/interpolation_variables.png b/images/interpolation_variables.png deleted file mode 100644 index e76842e1e9af1d68f44da15379603ae5e3b207a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86842 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

4C5<%o&$1tN`qOQ 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 z Date: Fri, 4 Dec 2020 12:03:12 +0100 Subject: [PATCH 045/249] Delete regular_and_piecewise_regular_grid.png --- images/regular_and_piecewise_regular_grid.png | Bin 76859 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 images/regular_and_piecewise_regular_grid.png diff --git a/images/regular_and_piecewise_regular_grid.png b/images/regular_and_piecewise_regular_grid.png deleted file mode 100644 index 3b6af0d609163ae67013e8297b64263da6531e62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76859 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 From b4af414d1279745924c573b2cbd50a0b4931b369 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 4 Dec 2020 12:05:54 +0100 Subject: [PATCH 046/249] Add coordinate interpolation figure --- images/ci_dimensions_overview.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 images/ci_dimensions_overview.svg diff --git a/images/ci_dimensions_overview.svg b/images/ci_dimensions_overview.svg new file mode 100644 index 00000000..b9c05d5c --- /dev/null +++ b/images/ci_dimensions_overview.svg @@ -0,0 +1 @@ +901929Interpolation DimensionSize 3010243Tie Point Interpolation DimensionSize 5102Interpolation Zone DimensionSize 3Tie PointTie Point Indices:x_indices= 0, 9, 19, 20, 29 y_indices= 0, 7, 8, 15Interpolation Areas 210 \ No newline at end of file From e507fb287604e3e98e7907216d69f8baec3330f1 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 4 Dec 2020 12:07:06 +0100 Subject: [PATCH 047/249] Add coordinate interpolation figure --- images/ci_interpolation_zone_generation_process.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 images/ci_interpolation_zone_generation_process.svg diff --git a/images/ci_interpolation_zone_generation_process.svg b/images/ci_interpolation_zone_generation_process.svg new file mode 100644 index 00000000..61a0e7bd --- /dev/null +++ b/images/ci_interpolation_zone_generation_process.svg @@ -0,0 +1 @@ +Grid ofCoordinatesand AuxiliaryCoordinatesInterpolation Areasseparated by Grid DiscontinuitiesInterpolation Zones,sharing TiePoints within but not between,Interpolation AreasGrid(0,0)(0,1)(1,1)(1,0)Grid with DiscontinuitiesCoordinateSpaceIndex Space(0,0)(0,1)(1,1)(1,0)(0,2)(1,2)(0,0)(0,1)(1,1)(1,0)(0,2)(1,2)(0,0)(0,0)(0,0)(0,1)(1,1)(1,0) \ No newline at end of file From 783c6388e310cc0c99f83906c98baf7b7bc8395d Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 4 Dec 2020 12:07:54 +0100 Subject: [PATCH 048/249] Add coordinate interpolation figure --- images/ci_interpolation_coefficeints.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 images/ci_interpolation_coefficeints.svg diff --git a/images/ci_interpolation_coefficeints.svg b/images/ci_interpolation_coefficeints.svg new file mode 100644 index 00000000..9d663102 --- /dev/null +++ b/images/ci_interpolation_coefficeints.svg @@ -0,0 +1 @@ +xyDimension (y_interpolation_zone, x_tie_point_interpolation)Example (1, 2) Dimension (y_tie_point_interpolation, x_interpolation_zone,)Example (2, 0) Dimension (y_interpolation_zone, x_interpolation_zone)Example (0, 1) Dimension (x_interpolation_zone,)Example (1) \ No newline at end of file From bcc3f60fb8f8faad88681434c6ef89a8525a7256 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 4 Dec 2020 12:08:25 +0100 Subject: [PATCH 049/249] Delete ci_interpolation_coefficeints.svg --- images/ci_interpolation_coefficeints.svg | 1 - 1 file changed, 1 deletion(-) delete mode 100644 images/ci_interpolation_coefficeints.svg diff --git a/images/ci_interpolation_coefficeints.svg b/images/ci_interpolation_coefficeints.svg deleted file mode 100644 index 9d663102..00000000 --- a/images/ci_interpolation_coefficeints.svg +++ /dev/null @@ -1 +0,0 @@ -xyDimension (y_interpolation_zone, x_tie_point_interpolation)Example (1, 2) Dimension (y_tie_point_interpolation, x_interpolation_zone,)Example (2, 0) Dimension (y_interpolation_zone, x_interpolation_zone)Example (0, 1) Dimension (x_interpolation_zone,)Example (1) \ No newline at end of file From c1b08821e77f7f5e01a1b8a66b57518c992211e0 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 4 Dec 2020 12:08:48 +0100 Subject: [PATCH 050/249] Add coordinate interpolation figure --- images/ci_interpolation_coefficients.svg | 1 + 1 file changed, 1 insertion(+) create mode 100644 images/ci_interpolation_coefficients.svg diff --git a/images/ci_interpolation_coefficients.svg b/images/ci_interpolation_coefficients.svg new file mode 100644 index 00000000..9d663102 --- /dev/null +++ b/images/ci_interpolation_coefficients.svg @@ -0,0 +1 @@ +xyDimension (y_interpolation_zone, x_tie_point_interpolation)Example (1, 2) Dimension (y_tie_point_interpolation, x_interpolation_zone,)Example (2, 0) Dimension (y_interpolation_zone, x_interpolation_zone)Example (0, 1) Dimension (x_interpolation_zone,)Example (1) \ No newline at end of file From b65b08943647417f675889d2c79a7e6851da18af Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 4 Dec 2020 12:11:06 +0100 Subject: [PATCH 051/249] add updated figure --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index a43362c5..5e950b9f 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -101,7 +101,7 @@ For each interpolation dimension, the number interpolation zones is equal to the [[interpolation_zone_generation, figure 3]] [.text-center] .Process for generating the interpolation zones for a grid without discontinuities and for a grid with discontinuities. -image::images/regular_and_piecewise_regular_grid.png[,100%,pdfwidth=50vw,align="center"] +image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,align="center"] [[compression-by-coordinate-tie-points-attribute, Section 8.3.2, "Tie Points Attribute"]] ==== Tie Points Attribute From 015379ee90931801d0334e6edeff2710d8012512 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 4 Dec 2020 12:32:23 +0100 Subject: [PATCH 052/249] Add and update figures --- ch08.adoc | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 5e950b9f..ff0e760e 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -98,7 +98,7 @@ For each interpolation dimension, the location of the tie points is defined by a For each interpolation dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. -[[interpolation_zone_generation, figure 3]] +[[interpolation_zone_generation, figure 1]] [.text-center] .Process for generating the interpolation zones for a grid without discontinuities and for a grid with discontinuities. image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,align="center"] @@ -122,8 +122,16 @@ The presence of non-interpolation dimensions in the tie point variable impacts t Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficient or configuation variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. +An overview of the different dimensions for coordinate interpolation is shown in figure <>. + Note that an interpolation zone dimension has, by definition, the same size as the corresponding tie point interpolation dimension, minus the number of interpolation areas. + +[[ci_dimensions_overview, figure 2]] +[.text-center] +.Overview of the different dimensions for coordinate interpolation. +image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] + [[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices @@ -246,18 +254,17 @@ The interpretation of interpolation coefficent and configuration variables depen * If no tie point interpolation dimensions are spanned, then the variable provides a value for every interpolation zone. This case is akin to values being defined at the centre of interpolation zones. -* If at least one dimension is a tie point interpolation dimension, then each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). +* If at least one dimension is a tie point interpolation dimension, then each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). In both cases, the implementation of the interpolation method should broadcast an interpolation coefficent or configuration variable along any interpolation zone dimensions that it does not span. -[[interpolation_variable, figure 4]] -[.text-center] -.Interpolation coefficients and interpolation flags variable dimensions in relation to an interpolation zone and its boundaries. - -image::images/interpolation_variables.png[,100%,pdfwidth=50vw,align="center"] - Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the uncompressed coordinates may only access the tie point that define the extent of the of the interpolation zone, as well as any interpolation coefficient and configuration variables defined for the interpolation zone, including its boundaries. +[[ci_interpolation_coefficients, figure 3]] +[.text-center] +.Through combination of dimensions, interpolation coefficients and configuration variables may provide values for each interpolation zone, for couples of neighboring interpolation zones or for multiple interpolation zones sharing a boundary. +image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] + [[compression-by-coordinate-interpolation-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds From 5865826194e315f4f3ce13f6266f96ccb52f9de7 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Fri, 4 Dec 2020 11:33:41 +0000 Subject: [PATCH 053/249] Lossy (#5) * more text following 2020-11-27 discussions * bounds * tidy * tidy * tidy * tidy * reproducability * offset * indices * indices * indices * super * tie_point_dimension (1) * tie_point_dimension (2) * tie_point_dimension (3) * tie_point_dimension (4) * tie point * tie_point_dimension (5) * lossy * lossy * correct typo Co-authored-by: AndersMS <63056394+AndersMS@users.noreply.github.com> --- ch08.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index ff0e760e..7eab7586 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -1,7 +1,7 @@ == Reduction of Dataset Size -There are two methods for reducing dataset size: packing and compression. By packing we mean altering the data in a way that reduces its precision. By compression we mean techniques that store the data more efficiently and result in no precision loss. Compression only works in certain circumstances, e.g., when a variable contains a significant amount of missing or repeated data values. In this case it is possible to make use of standard utilities, e.g., UNIX **`compress`** or GNU **`gzip`** , to compress the entire file after it has been written. In this section we offer an alternative compression method that is applied on a variable by variable basis. This has the advantage that only one variable need be uncompressed at a given time. The disadvantage is that generic utilities that don't recognize the CF conventions will not be able to operate on compressed variables. +There are three methods for reducing dataset size: packing, lossless compression, and lossy compression. By packing we mean altering the data in a way that reduces its precision. By lossless compression we mean techniques that store the data more efficiently and result in no precision loss. By lossy compression we mean techniques that store the data more efficiently but result in some loss in accuracy. Lossless compression only works in certain circumstances, e.g., when a variable contains a significant amount of missing or repeated data values. In this case it is possible to make use of standard utilities, e.g., UNIX **`compress`** or GNU **`gzip`** , to compress the entire file after it has been written. In this section we offer an alternative compression method that is applied on a variable by variable basis. This has the advantage that only one variable need be uncompressed at a given time. The disadvantage is that generic utilities that don't recognize the CF conventions will not be able to operate on compressed variables. @@ -18,8 +18,8 @@ When data to be packed contains missing values the attributes that indicate miss -[[compression-by-gathering, Section 8.2, "Compression by Gathering"]] -=== Compression by Gathering +[[compression-by-gathering, Section 8.2, "Lossless Compression by Gathering"]] +=== Lossless Compression by Gathering To save space in the netCDF file, it may be desirable to eliminate points from data arrays that are invariably missing. Such a compression can operate over one or more adjacent axes, and is accomplished with reference to a list of the points to be stored. The list is constructed by considering a mask array that only includes the axes to be compressed, and then mapping this array onto one dimension without reordering. The list is the set of indices in this one-dimensional mask of the required points. In the compressed array, the axes to be compressed are all replaced by a single axis, whose dimension is the number of wanted points. The wanted points appear along this dimension in the same order they appear in the uncompressed array, with the unwanted points skipped over. Compression and uncompression are executed by looping over the list. @@ -70,8 +70,8 @@ This information implies that the salinity field should be uncompressed to an ar ==== -[[compression-by-coordinate-interpolation, Section 8.3, "Compression by Coordinate Interpolation"]] -=== Compression by Coordinate Interpolation +[[compression-by-coordinate-interpolation, Section 8.3, "Lossy Compression by Coordinate Interpolation"]] +=== Lossy Compression by Coordinate Interpolation For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to user of the uncompressed dataset. From 2c9c89742efebeb82757648d957bbd360bf30230 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 4 Dec 2020 12:37:29 +0100 Subject: [PATCH 054/249] Update figure --- images/ci_dimensions_overview.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/ci_dimensions_overview.svg b/images/ci_dimensions_overview.svg index b9c05d5c..84d68a73 100644 --- a/images/ci_dimensions_overview.svg +++ b/images/ci_dimensions_overview.svg @@ -1 +1 @@ -901929Interpolation DimensionSize 3010243Tie Point Interpolation DimensionSize 5102Interpolation Zone DimensionSize 3Tie PointTie Point Indices:x_indices= 0, 9, 19, 20, 29 y_indices= 0, 7, 8, 15Interpolation Areas 210 \ No newline at end of file +901929Interpolation DimensionSize 3010243Tie Point Interpolation DimensionSize 5102Interpolation Zone DimensionSize 3Tie PointTie Point Indices:x_indices= 0, 9, 19, 20, 29 y_indices= 0, 7, 8, 15Interpolation Areas 210 \ No newline at end of file From bdf23a8cb22d3e4bdc6f66e5e551a461d93630d9 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Fri, 4 Dec 2020 11:47:04 +0000 Subject: [PATCH 055/249] Anders subsampled (#6) * more text following 2020-11-27 discussions * bounds * tidy * tidy * tidy * tidy * reproducability * offset * indices * indices * indices * super * tie_point_dimension (1) * tie_point_dimension (2) * tie_point_dimension (3) * tie_point_dimension (4) * tie point * tie_point_dimension (5) * corrected interpolation_configuration description --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 7eab7586..164483ad 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -244,7 +244,7 @@ The definition of the interpolation method, however it is specified, may include An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie points. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation equations, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. -The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation method definition, and `variable` is the name of the interpolation configuration variable that contains the values for that term. The order of elements is not significant. +The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"item: variable"`, where `item` is a case-insensitive keyword that identies a configuration item defined in the interpolations method's definition, and `variable` is the name of the interpolation configuration variable that contains the values for that item. The order of elements is not significant. The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. From 3f0d5bd3bc64b784e42a2c315a369e732b760365 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 4 Dec 2020 13:39:29 +0100 Subject: [PATCH 056/249] Update figure --- images/ci_interpolation_zone_generation_process.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/ci_interpolation_zone_generation_process.svg b/images/ci_interpolation_zone_generation_process.svg index 61a0e7bd..9a4baf91 100644 --- a/images/ci_interpolation_zone_generation_process.svg +++ b/images/ci_interpolation_zone_generation_process.svg @@ -1 +1 @@ -Grid ofCoordinatesand AuxiliaryCoordinatesInterpolation Areasseparated by Grid DiscontinuitiesInterpolation Zones,sharing TiePoints within but not between,Interpolation AreasGrid(0,0)(0,1)(1,1)(1,0)Grid with DiscontinuitiesCoordinateSpaceIndex Space(0,0)(0,1)(1,1)(1,0)(0,2)(1,2)(0,0)(0,1)(1,1)(1,0)(0,2)(1,2)(0,0)(0,0)(0,0)(0,1)(1,1)(1,0) \ No newline at end of file +Coordinatesand AuxiliaryCoordinatesInterpolation Areasseparated byGrid DiscontinuitiesInterpolation Zones,sharing TiePoints within,but not between,Interpolation AreasGrid(0,0)(0,1)(1,1)(1,0)Grid with DiscontinuitiesCoordinate SpaceIndex Space(0,0)(0,1)(1,1)(1,0)(0,2)(1,2)(0,0)(0,1)(1,1)(1,0)(0,2)(1,2)(0,0)(0,0)(0,0)(0,1)(1,1)(1,0) \ No newline at end of file From fa0375b1f00d1791e64dba85457604c3049d4c7b Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 4 Dec 2020 13:46:13 +0100 Subject: [PATCH 057/249] update figure --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 164483ad..17ec0bc0 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -101,7 +101,7 @@ For each interpolation dimension, the number interpolation zones is equal to the [[interpolation_zone_generation, figure 1]] [.text-center] .Process for generating the interpolation zones for a grid without discontinuities and for a grid with discontinuities. -image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,align="center"] +image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,align="center"] [[compression-by-coordinate-tie-points-attribute, Section 8.3.2, "Tie Points Attribute"]] ==== Tie Points Attribute From 7c5d80d5066a2ba74144c9bfcf7aedf71738c2c3 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 7 Dec 2020 22:19:22 +0100 Subject: [PATCH 058/249] Add table 8.1 Generation of Tie Point Variables and Interpolation Variables --- ch08.adoc | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 17ec0bc0..ef4238da 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -108,7 +108,7 @@ image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,a To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. -[[compression-by-coordinate-interpolation-dimensions,Section 8.3.3, "Data Variable Attributes"]] +[[compression-by-coordinate-interpolation-dimensions,Section 8.3.3, "Interpolation and Non-Interpolation Dimensions"]] ==== Interpolation and Non-Interpolation Dimensions For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required; and may additionally contain one or more __non-interpolation dimensions__, i.e. those of the target domain for which no coordinate interpolation is required. @@ -446,3 +446,53 @@ variables: Temperature:tie_point_indices = "y: y_indices x: x_indices" ; ---- ==== + + +[[Compression-by-coordinate-interpolation-generation-of-tie-points]] +.Generation of Tie Point Variables and Interpolation Variables +[options="header",cols="1,40,20",caption="Table 8.1. "] +|=============== +| Step | Description | Link + +| 1 +| Identify the coordinate and auxillary coordinate variables for which tie point and interpolation variables are required. +| + +| 2 +| Identify non-overlapping subsets of the coordinate variables to be interpolated by the same interpolation method. For each coordinate variable subset, create an interpolation variable and specify the selected interpolation method using the **`interpolation_name`** attribute of the interpolation variable. +| <> + +| 3 +| For each coordinate variable subset, add the coordinates variable subset and the corresponding interpolation variable to the the **`tie_points`** attribute of the data variable. +| <> + + +| 4 +| For each coordinate variable subset, identify the set of interpolation and the set of non-interpolation dimensions. +| <> + +| 5 +| For each set of the interpolation dimensions, identify the interpolation areas and select the interpolation zones and the tie points, taking into account the required coordinate reconstitution accuracy when selecting the density of tie points. +| <> + +| 6 +| For each of the interpolation dimensions, add the interpolation dimension, the corresponding tie point interpolation dimension and, if required by the selected interpolation method, its corresponding interpolation zone dimension to the **`tie_point_dimensions`** attribute of the data variable. +| <> + +| 7 +| For each of the interpolation dimensions, record the location of each identified tie point in a tie point index variable. For each interpolation dimension, add the interpolation dimension and its tie point index variable to the **`tie_point_indices`** attribute of the data variable. +| <> + +| 8 +| For each of the target coordinate and auxillary coordinate variables, create the corresponding tie point coordinate variable and copy the coordinate values from the target domain coordinate variables to the tie point variables for the target domain indices identified by the tie point index variable. Repeat this step for each combination of indices of the non-interpolation dimensions. +| <> + +| 9 +| For each of the target coordinate and auxillary coordinate variable having a **`bounds`** attribute, add the **`bounds`** attribute to the tie point coordinate variable, create the tie point bounds variable and copy the bounds values from the target domain bounds variable to the tie point bounds variable for the target domain indices identified by the tie point index variable. Repeat this step for each combination of indices of the non-interpolation dimensions. +| <> + +| 10 +| Finally, if required by the selected interpolation method, follow the steps defined for the method in Appendix J to create any required interpolation coefficients variables and interpolation configuration variables. As relevant, create the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes and populate them with the interpolation coefficients variables and interpolation configuration variables respectively. +| <> + +|=============== From 3e530ba35b02bfabb84eb1380a8b05fc75db0377 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 8 Dec 2020 17:42:05 +0100 Subject: [PATCH 059/249] Change title to Coordinate Sampling --- appj.adoc | 377 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ch08.adoc | 67 ++-------- 2 files changed, 386 insertions(+), 58 deletions(-) create mode 100644 appj.adoc diff --git a/appj.adoc b/appj.adoc new file mode 100644 index 00000000..6cbc12c8 --- /dev/null +++ b/appj.adoc @@ -0,0 +1,377 @@ + +[[appendix-grid-mappings, Appendix J, Coordinate Interpolation]] + +[appendix] +== Coordinate Interpolation + + +[[table-grid-mapping-attributes]] + + +[[Compression-by-coordinate-interpolation-generation-of-tie-points]] +.Generation of Tie Point Variables and Interpolation Variables +[options="header",cols="1,40,20",caption="Table 8.1. "] +|=============== +| Step | Description | Link + +| 1 +| Identify the coordinate and auxillary coordinate variables for which tie point and interpolation variables are required. +| + +| 2 +| Identify non-overlapping subsets of the coordinate variables to be interpolated by the same interpolation method. For each coordinate variable subset, create an interpolation variable and specify the selected interpolation method using the **`interpolation_name`** attribute of the interpolation variable. +| <> + +| 3 +| For each coordinate variable subset, add the coordinates variable subset and the corresponding interpolation variable to the the **`tie_points`** attribute of the data variable. +| <> + + +| 4 +| For each coordinate variable subset, identify the set of interpolation and the set of non-interpolation dimensions. +| <> + +| 5 +| For each set of the interpolation dimensions, identify the interpolation areas and select the interpolation zones and the tie points, taking into account the required coordinate reconstitution accuracy when selecting the density of tie points. +| <> + +| 6 +| For each of the interpolation dimensions, add the interpolation dimension, the corresponding tie point interpolation dimension and, if required by the selected interpolation method, its corresponding interpolation zone dimension to the **`tie_point_dimensions`** attribute of the data variable. +| <> + +| 7 +| For each of the interpolation dimensions, record the location of each identified tie point in a tie point index variable. For each interpolation dimension, add the interpolation dimension and its tie point index variable to the **`tie_point_indices`** attribute of the data variable. +| <> + +| 8 +| For each of the target coordinate and auxillary coordinate variables, create the corresponding tie point coordinate variable and copy the coordinate values from the target domain coordinate variables to the tie point variables for the target domain indices identified by the tie point index variable. Repeat this step for each combination of indices of the non-interpolation dimensions. +| <> + +| 9 +| For each of the target coordinate and auxillary coordinate variable having a **`bounds`** attribute, add the **`bounds`** attribute to the tie point coordinate variable, create the tie point bounds variable and copy the bounds values from the target domain bounds variable to the tie point bounds variable for the target domain indices identified by the tie point index variable. Repeat this step for each combination of indices of the non-interpolation dimensions. +| <> + +| 10 +| Finally, if required by the selected interpolation method, follow the steps defined for the method in Appendix J to create any required interpolation coefficients variables and interpolation configuration variables. As relevant, create the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes and populate them with the interpolation coefficients variables and interpolation configuration variables respectively. +| <> + +|=============== + + + +|=============== + +Each recognized coordinate interpolation is described in one of the sections below. +Each section contains: the valid name that is used with the +**`tie_point`** attribute; + + + +a list of the specific attributes +that may be used to assign values to the mapping's parameters; the +standard names used to identify the coordinate variables that contain +the mapping's independent variables; and references to the mapping's +definition or other information that may help in using the mapping. +Since the attributes used to set a mapping's parameters may be shared +among several mappings, their definitions are contained in a table in +the final section. +The attributes which describe the ellipsoid and prime meridian may be included, when applicable, with any grid mapping. +These are: + +- `earth_radius` +- `inverse_flattening` +- `longitude_of_prime_meridian` +- `prime_meridian_name` +- `reference_ellipsoid_name` +- `semi_major_axis` +- `semi_minor_axis` + +We have used the FGDC "Content Standard for Digital Geospatial Metadata" <> as a guide in choosing the values for **`grid_mapping_name`** and the attribute names for the parameters describing map projections. + + +=== Linear + +---- + +interpolation_name = linear + +---- + +__Map parameters:__:: +* **`standard_parallel`** - There may be 1 or 2 values. +* **`longitude_of_central_meridian`** +* **`latitude_of_projection_origin`** +* **`false_easting`** - This parameter is optional (default is 0) +* **`false_northing`** - This parameter is optional (default is 0) + +__Map coordinates:__:: The x (abscissa) and y (ordinate) rectangular coordinates are identified by the **`standard_name`** attribute values **`projection_x_coordinate`** and **`projection_y_coordinate`** respectively. + +__Notes:__:: Notes on using the **`PROJ`** software package for computing the mapping may be found at +link:$$https://proj.org/operations/projections/aea.html$$[https://proj.org/operations/projections/aea.html] +and +link:$$http://geotiff.maptools.org/proj_list/albers_equal_area_conic.html$$[http://geotiff.maptools.org/proj_list/albers_equal_area_conic.html]. + + + + + +In the following table the "Type" values are **S** for string and **N** for numeric. + +[[table-grid-mapping-attributes]] +.Grid Mapping Attributes +[options="header",cols="6,1,16",caption="Table F.1. "] +|=============== +| Attribute | Type | Description + +| **`azimuth_of_central_line`** | N +| Specifies a horizontal angle measured in degrees clockwise from North. Used by certain + projections (e.g., Oblique Mercator) to define the orientation of the map projection relative +to a reference direction. + +| **`crs_wkt`** | S +| This optional attribute may be used to specify multiple coordinate system properties + in well-known text (WKT) format. The syntax must conform to the WKT format as specified + in reference <>. Use of the **`crs_wkt`** attribute is described in section 5.6.1. + +| **`earth_radius`** | N +| Used to specify the radius, in metres, of the spherical + figure used to approximate the shape of the Earth. This + attribute should be specified for those projected coordinate + reference systems in which the X-Y cartesian coordinates + have been derived using a spherical Earth approximation. If + the cartesian coordinates were derived using an ellipsoid, + this attribute should not be defined. Example: "6371007", + which is the radius of the GRS 1980 Authalic Sphere. + +| **`false_easting`** | N +| Applied to all abscissa values in the rectangular + coordinates for a map projection in order to eliminate negative numbers. Expressed in + the unit of the coordinate variable identified by the + standard name **`projection_x_coordinate`**. + If **`false_easting`** is not provided it is assumed to be 0. + The formula to convert from the coordinate value as written in the **`projection_x_coordinate`** + (xf) to a value (x0) used in a transformation without **`false_easting`**, i.e. **`false_easting`**= 0, is: + x0 = xf -**`false_easting`** + + + +| **`false_northing`** | N +| Applied to all ordinate values in the rectangular + coordinates for a map projection in order to eliminate negative numbers. Expressed in + the unit of the coordinate variable identified by the + standard name **`projection_y_coordinate`**. + If **`false_northing`** is not provided it is assumed to be 0. + The formula to convert from the coordinate value as written in the **`projection_y_coordinate`** + (yf) to a value (y0) used in a transformation without **`false_northing`**, i.e. **`false_northing`**= 0, is: + y0 = yf -**`false_northing`** + +| **`fixed_angle_axis `** | S +| Indicates the axis on which the view is fixed in a hypothetical gimbal view model of the Earth, as used in the geostationary grid mapping. + It corresponds to the inner-gimbal axis of the gimbal view model, whose axis of rotation moves about the outer-gimbal axis. + This value can adopt two values, "x" or "y", corresponding with the Earth's E-W or N-S axis, respectively. + The counterpart to this attribute is `sweep_angle_axis`. + If set to "x", `sweep_angle_axis` is "y", and vice versa. + If one of the attributes `fixed_angle_axis` or `sweep_angle_axis` is provided, the other is not mandatory, as they can be used to infer each other. + +| **`geographic_crs_name`** | S +| The name of the geographic coordinate reference system. + Corresponds to a OGC WKT GEOGCS node name. + +| **`geoid_name`** | S +| The name of the estimate or model of the geoid being used as a datum, + e.g. GEOID12B. Corresponds to an OGC WKT VERT_DATUM name. The geoid is + the surface of constant geopotential that the ocean would follow if it + were at rest. This attribute and **`geopotential_datum_name`** cannot both be specified. + +| **`geopotential_datum_name`** | S + +| The name of an estimated surface of constant geopotential being used as a datum, + e.g. NAVD88. Such a surface is often called an equipotential surface in geodesy. + Corresponds to an OGC WKT VERT_DATUM name. This attribute and **`geoid_name`** cannot + both be specified. + +| **`grid_mapping_name`** | S +| The name used to identify the grid mapping. + +| **`grid_north_pole_latitude`** | N +| True latitude (degrees_north) of the north pole of the rotated grid. + +| **`grid_north_pole_longitude`** | N +| True longitude (degrees_east) of the north pole of the rotated grid. + +| **`horizontal_datum_name`** | S +| The name of the geodetic (horizontal) datum, which corresponds to the + procedure used to measure positions on the surface of the Earth. Valid datum + names and their associated parameters are given in + https://github.com/cf-convention/cf-conventions/wiki/Mapping-from-CF-Grid-Mapping-Attributes-to-CRS-WKT-Elements + (horiz_datum.csv, OGC_DATUM_NAME column) + and are + obtained by transforming the EPSG name using the following rules (used by OGR + and Cadcorp): convert all non alphanumeric characters (including +) to underscores, + then strip any leading, trailing or repeating underscores. This is to ensure that + named datums can be correctly identified for precise datum transformations + (see https://github.com/cf-convention/cf-conventions/wiki/OGC-WKT-Coordinate-System-Issues for + more details). + Corresponds to a OGC WKT DATUM node name. + +| **`inverse_flattening`** | N +| Used to specify the __inverse__ flattening + (__1/f__) of the ellipsoidal figure + associated with the geodetic datum and used to approximate the shape + of the Earth. The flattening (__f__) of the ellipsoid + is related to the semi-major and semi-minor axes by the formula + __f = (a-b)/a__. In the case + of a spherical Earth this attribute should be omitted or set to zero. + Example: 298.257222101 for the GRS 1980 ellipsoid. (Note: By + convention the dimensions of an ellipsoid are specified using either + the semi-major and semi-minor axis lengths, or the semi-major axis + length and the inverse flattening. If all three attributes are + specified then the supplied values must be consistent with the + aforementioned formula.) + +| **`latitude_of_projection_origin`** | N +| The latitude (degrees_north) chosen as the origin of rectangular + coordinates for a map projection. Domain: + +// The following lines shows how to insert Unicode for <=. A plain '<=' turns into an arrow. +// Except as marked, all work for asciidoctor and none work for asciidoctor-pdf. +// **`-90.0 ≤ latitude_of_projection_origin ≤ 90.0`** + +//doesn't work for asciidoctor **`-90.0 ࣘ latitude_of_projection_origin ࣘ 90.0`** + +// **`-90.0 ≤ latitude_of_projection_origin ≤ 90.0`** + +// **`-90.0 ≤ latitude_of_projection_origin ≤ 90.0`** + +// **`-90.0 ++++++ latitude_of_projection_origin ++++++ 90.0`** + +// **`-90.0 < = latitude_of_projection_origin < = 90.0`** + +// **`-90.0 \<= latitude_of_projection_origin \<= 90.0`** + +// The cleanest-looking, which sometimes works for asciidoctor-pdf: + **`-90.0 \<= latitude_of_projection_origin \<= 90.0`** + +| **`longitude_of_central_meridian`** | N +| The line of longitude (degrees_east) at the center of a map projection + generally used as the basis for constructing the projection. + Domain: + + **`-180.0 \<= longitude_of_central_meridian < 180.0`** + + +| **`longitude_of_prime_meridian`** | N +| Specifies the longitude, with respect to Greenwich, of the prime + meridian associated with the geodetic datum. The prime meridian defines + the origin from which longitude values are determined. Not to be + confused with the projection origin longitude + (cf. **`longitude_of_projection_origin`**, a.k.a. central + meridian) which defines the longitude of the map projection origin. + Domain: + + **`-180.0 \<= longitude_of_prime_meridian < 180.0`** + decimal degrees. + Default = **`0.0`** + +| **`longitude_of_projection_origin`** | N +| The longitude (degrees_east) chosen as the origin of rectangular + coordinates for a map projection. + Domain: + + **`-180.0 \<= longitude_of_projection_origin < 180.0`** + + +| **`north_pole_grid_longitude`** | N +| Longitude (degrees) of the true north pole in the rotated grid. + + +| **`perspective_point_height`** | N +| Records the height, __in metres__, of the map + projection perspective point above the ellipsoid (or sphere). Used + by perspective-type map projections, for example the Vertical + Perspective Projection, which may be used to simulate the view from + a Meteosat satellite. + + +| **`prime_meridian_name`** | S +| The name of the prime meridian associated with the geodetic datum. Valid + names are given in + https://github.com/cf-convention/cf-conventions/wiki/Mapping-from-CF-Grid-Mapping-Attributes-to-CRS-WKT-Elements + (prime_meridian.csv). Corresponds to a OGC WKT PRIMEM node name. + + +|**`projected_crs_name`** | S +| The name of the projected coordinate reference system. Corresponds + to a OGC WKT PROJCS node name. + + +| **`reference_ellipsoid_name`** | S +| The name of the reference ellipsoid. Valid names are given in + https://github.com/cf-convention/cf-conventions/wiki/Mapping-from-CF-Grid-Mapping-Attributes-to-CRS-WKT-Elements + (ellipsoid.csv). + Corresponds to a OGC WKT SPHEROID node name. + + +| **`scale_factor_at_central_meridian`** | N +| A multiplier for reducing a distance obtained from a map by + computation or scaling to the actual distance along the + central meridian. + Domain: **`scale_factor_at_central_meridian > 0.0`** + +| **`scale_factor_at_projection_origin`** | N +| A multiplier for reducing a distance obtained from + a map by computation or scaling to the actual distance + at the projection origin. + Domain: **`scale_factor_at_projection_origin > 0.0`** + + +| **`semi_major_axis`** | N +| Specifies the length, __in metres__, of the semi-major + axis of the ellipsoidal figure associated with the geodetic datum and + used to approximate the shape of the Earth. Commonly denoted using the + symbol __a__. In the case of a spherical Earth + approximation this attribute defines the radius of the Earth. See + also the **`inverse_flattening`** attribute. + +| **`semi_minor_axis`** | N +| Specifies the length, __in metres__, of the semi-minor + axis of the ellipsoidal figure associated with the geodetic datum and + used to approximate the shape of the Earth. Commonly denoted using the + symbol __b__. In the case of a spherical Earth + approximation this attribute should be omitted (the preferred option) + or else set equal to the value of the semi_major_axis attribute. See + also the inverse_flattening attribute. + +| **`standard_parallel`** | N +| Specifies the line, or lines, of latitude at which the developable map + projection surface (plane, cone, or cylinder) touches the reference + sphere or ellipsoid used to represent the Earth. Since there is zero + scale distortion along a standard parallel it is also referred to as + a "latitude of true scale". In the situation where a conical + developable surface intersects the reference ellipsoid there are two + standard parallels, in which case this attribute can be used as a + vector to record both latitude values, with the additional convention + that the standard parallel nearest the pole (N or S) is provided first. + Domain: **`-90.0 <= standard_parallel <= 90.0`** + +| **`straight_vertical_longitude_from_pole`** | N +| The longitude (degrees_east) to be oriented straight up from the North or + South Pole. Domain: **`-180.0 <= straight_vertical_longitude_from_pole < 180.0`** + +| **`sweep_angle_axis `** | S +| Indicates the axis on which the view sweeps in a hypothetical gimbal view model of the Earth, as used in the geostationary grid mapping. + It corresponds to the outer-gimbal axis of the gimbal view model, about whose axis of rotation the gimbal-gimbal axis moves. + This value can adopt two values, "x" or "y", corresponding with the Earth's E-W or N-S axis, respectively. + The counterpart to this attribute is `fixed_angle_axis`. + If set to "x", `fixed_angle_axis` is "y", and vice versa. + If one of the attributes `fixed_angle_axis` or `sweep_angle_axis` is provided, the other is not mandatory, as they can be used to infer each other. + +| **`towgs84`** | N +| This indicates a list of up + to 7 Bursa Wolf transformation parameters., which can be used to approximate a + transformation from the horizontal datum to the WGS84 datum. More precise datum + transformations can be done with datum shift grids. Represented as a double-precision + array, with 3, 6 or 7 values (if there are less than 7 values the remaining are + considered to be zero). Corresponds to a OGC WKT TOWGS84 node. + +|=============== + +Notes: + +. The various **`*_name`** attributes are optional but recommended when +known as they allow for a better description and interoperability with WKT +definitions. +. **`reference_ellipsoid_name`**, **`prime_meridian_name`**, +**`horizontal_datum_name`** and **`geographic_crs_name`** must be all defined if any one + is defined, and if **`projected_crs_name`** is defined then **`geographic_crs_name`** must be also. + + diff --git a/ch08.adoc b/ch08.adoc index ef4238da..21ebed6c 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -70,8 +70,8 @@ This information implies that the salinity field should be uncompressed to an ar ==== -[[compression-by-coordinate-interpolation, Section 8.3, "Lossy Compression by Coordinate Interpolation"]] -=== Lossy Compression by Coordinate Interpolation +[[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Sampling"]] +=== Lossy Compression by Coordinate Sampling For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to user of the uncompressed dataset. @@ -94,7 +94,7 @@ As the interpolation methods rely on a certain regularity and continuity of the Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. -For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__, which also indicates the location of the interpolation areas (<>). +For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__, which also indicates the location of the interpolation areas (<>). For each interpolation dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. @@ -108,7 +108,7 @@ image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,a To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. -[[compression-by-coordinate-interpolation-dimensions,Section 8.3.3, "Interpolation and Non-Interpolation Dimensions"]] +[[compression-by-coordinate-sampling-dimensions,Section 8.3.3, "Interpolation and Non-Interpolation Dimensions"]] ==== Interpolation and Non-Interpolation Dimensions For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required; and may additionally contain one or more __non-interpolation dimensions__, i.e. those of the target domain for which no coordinate interpolation is required. @@ -117,10 +117,10 @@ An interpolation dimension typically differs in size from the corresponding tie The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. -[[compression-by-coordinate-interpolation-tie-point-dimensions-attribute, Section 8.3.4, "Tie Point Dimensions Attribute"]] +[[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.4, "Tie Point Dimensions Attribute"]] ==== Tie Point Dimensions Attribute -Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficient or configuation variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. +Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficient or configuation variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. An overview of the different dimensions for coordinate interpolation is shown in figure <>. @@ -132,7 +132,7 @@ Note that an interpolation zone dimension has, by definition, the same size as t .Overview of the different dimensions for coordinate interpolation. image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] -[[compression-by-coordinate-interpolation-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] +[[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). @@ -229,7 +229,7 @@ data: ---- ==== -[[compression-by-coordinate-interpolation-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] +[[compression-by-coordinate-sampling-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] ==== Interpolation Variable The method used to uncompress the tie point variables is described by an interpolation variable that acts as a container for the attributes that define the interpolation technique and the parameters that should be used. The variable should be a scalar (i.e. it has no dimensions) of arbitrary type, and the value of its single element is immaterial. @@ -266,7 +266,7 @@ Note that the interpolation method is always applied on a per interpolation zone image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] -[[compression-by-coordinate-interpolation-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] +[[compression-by-coordinate-sampling-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds If a tie point variable has cell boundaries bounds then it must have the attribute **`bounds`** that names the variable that contains the vertices of the cell boundaries. The bounds should be the same as the bounds of the corresponding target grid cells. It is thereforefore likely that tie point cells will be non-contiguous. @@ -447,52 +447,3 @@ variables: ---- ==== - -[[Compression-by-coordinate-interpolation-generation-of-tie-points]] -.Generation of Tie Point Variables and Interpolation Variables -[options="header",cols="1,40,20",caption="Table 8.1. "] -|=============== -| Step | Description | Link - -| 1 -| Identify the coordinate and auxillary coordinate variables for which tie point and interpolation variables are required. -| - -| 2 -| Identify non-overlapping subsets of the coordinate variables to be interpolated by the same interpolation method. For each coordinate variable subset, create an interpolation variable and specify the selected interpolation method using the **`interpolation_name`** attribute of the interpolation variable. -| <> - -| 3 -| For each coordinate variable subset, add the coordinates variable subset and the corresponding interpolation variable to the the **`tie_points`** attribute of the data variable. -| <> - - -| 4 -| For each coordinate variable subset, identify the set of interpolation and the set of non-interpolation dimensions. -| <> - -| 5 -| For each set of the interpolation dimensions, identify the interpolation areas and select the interpolation zones and the tie points, taking into account the required coordinate reconstitution accuracy when selecting the density of tie points. -| <> - -| 6 -| For each of the interpolation dimensions, add the interpolation dimension, the corresponding tie point interpolation dimension and, if required by the selected interpolation method, its corresponding interpolation zone dimension to the **`tie_point_dimensions`** attribute of the data variable. -| <> - -| 7 -| For each of the interpolation dimensions, record the location of each identified tie point in a tie point index variable. For each interpolation dimension, add the interpolation dimension and its tie point index variable to the **`tie_point_indices`** attribute of the data variable. -| <> - -| 8 -| For each of the target coordinate and auxillary coordinate variables, create the corresponding tie point coordinate variable and copy the coordinate values from the target domain coordinate variables to the tie point variables for the target domain indices identified by the tie point index variable. Repeat this step for each combination of indices of the non-interpolation dimensions. -| <> - -| 9 -| For each of the target coordinate and auxillary coordinate variable having a **`bounds`** attribute, add the **`bounds`** attribute to the tie point coordinate variable, create the tie point bounds variable and copy the bounds values from the target domain bounds variable to the tie point bounds variable for the target domain indices identified by the tie point index variable. Repeat this step for each combination of indices of the non-interpolation dimensions. -| <> - -| 10 -| Finally, if required by the selected interpolation method, follow the steps defined for the method in Appendix J to create any required interpolation coefficients variables and interpolation configuration variables. As relevant, create the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes and populate them with the interpolation coefficients variables and interpolation configuration variables respectively. -| <> - -|=============== From 3b1a04df1eef26bce6dc5714cb6895632de11b50 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 8 Dec 2020 17:47:13 +0100 Subject: [PATCH 060/249] Fix links in Appendix J --- appj.adoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/appj.adoc b/appj.adoc index 6cbc12c8..05122976 100644 --- a/appj.adoc +++ b/appj.adoc @@ -8,7 +8,7 @@ [[table-grid-mapping-attributes]] -[[Compression-by-coordinate-interpolation-generation-of-tie-points]] +[[compression-by-coordinate-sampling-generation-of-tie-points]] .Generation of Tie Point Variables and Interpolation Variables [options="header",cols="1,40,20",caption="Table 8.1. "] |=============== @@ -20,7 +20,7 @@ | 2 | Identify non-overlapping subsets of the coordinate variables to be interpolated by the same interpolation method. For each coordinate variable subset, create an interpolation variable and specify the selected interpolation method using the **`interpolation_name`** attribute of the interpolation variable. -| <> +| <> | 3 | For each coordinate variable subset, add the coordinates variable subset and the corresponding interpolation variable to the the **`tie_points`** attribute of the data variable. @@ -29,7 +29,7 @@ | 4 | For each coordinate variable subset, identify the set of interpolation and the set of non-interpolation dimensions. -| <> +| <> | 5 | For each set of the interpolation dimensions, identify the interpolation areas and select the interpolation zones and the tie points, taking into account the required coordinate reconstitution accuracy when selecting the density of tie points. @@ -37,23 +37,23 @@ | 6 | For each of the interpolation dimensions, add the interpolation dimension, the corresponding tie point interpolation dimension and, if required by the selected interpolation method, its corresponding interpolation zone dimension to the **`tie_point_dimensions`** attribute of the data variable. -| <> +| <> | 7 | For each of the interpolation dimensions, record the location of each identified tie point in a tie point index variable. For each interpolation dimension, add the interpolation dimension and its tie point index variable to the **`tie_point_indices`** attribute of the data variable. -| <> +| <> | 8 | For each of the target coordinate and auxillary coordinate variables, create the corresponding tie point coordinate variable and copy the coordinate values from the target domain coordinate variables to the tie point variables for the target domain indices identified by the tie point index variable. Repeat this step for each combination of indices of the non-interpolation dimensions. -| <> +| <> | 9 | For each of the target coordinate and auxillary coordinate variable having a **`bounds`** attribute, add the **`bounds`** attribute to the tie point coordinate variable, create the tie point bounds variable and copy the bounds values from the target domain bounds variable to the tie point bounds variable for the target domain indices identified by the tie point index variable. Repeat this step for each combination of indices of the non-interpolation dimensions. -| <> +| <> | 10 | Finally, if required by the selected interpolation method, follow the steps defined for the method in Appendix J to create any required interpolation coefficients variables and interpolation configuration variables. As relevant, create the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes and populate them with the interpolation coefficients variables and interpolation configuration variables respectively. -| <> +| <> |=============== From 0326ddbf831f973e118479086f0a8d722e847d9c Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 8 Dec 2020 18:02:08 +0100 Subject: [PATCH 061/249] Fix link --- ch08.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 21ebed6c..ba5e22b7 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -83,7 +83,7 @@ The metadata that define the interpolation formula and its inputs are complete, The data variable coordinate interpolation attributes may also be used on a domain variable (<>) with the same effect. -[[compression-by-coordinate-tie-points, Section 8.3.1, "Tie Points and Interpolation Zones"]] +[[compression-by-coordinate-sampling-tie-points, Section 8.3.1, "Tie Points and Interpolation Zones"]] ==== Tie Points and Interpolation Zones Reconstitution of the uncompressed coordinate and auxiliary coordinate variables is based on interpolation. To accomplish this, the target domain is segmented into smaller __interpolation zones__, for each of which the interpolation method is applied independently. For one dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone; for two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes; etc. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables within an interpolation zone, the interpolation method is permitted to access the coordinates of the defining tie points, but not the coordinates of any other tie points. @@ -103,7 +103,7 @@ For each interpolation dimension, the number interpolation zones is equal to the .Process for generating the interpolation zones for a grid without discontinuities and for a grid with discontinuities. image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,align="center"] -[[compression-by-coordinate-tie-points-attribute, Section 8.3.2, "Tie Points Attribute"]] +[[compression-by-coordinate-sampling-tie-points-attribute, Section 8.3.2, "Tie Points Attribute"]] ==== Tie Points Attribute To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. @@ -135,7 +135,7 @@ image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. From 8c38db5a3f03fc378f4b81d79a7b6338d66e217b Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 8 Dec 2020 18:04:32 +0100 Subject: [PATCH 062/249] Fix link --- appj.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appj.adoc b/appj.adoc index 05122976..4751d747 100644 --- a/appj.adoc +++ b/appj.adoc @@ -24,7 +24,7 @@ | 3 | For each coordinate variable subset, add the coordinates variable subset and the corresponding interpolation variable to the the **`tie_points`** attribute of the data variable. -| <> +| <> | 4 @@ -33,7 +33,7 @@ | 5 | For each set of the interpolation dimensions, identify the interpolation areas and select the interpolation zones and the tie points, taking into account the required coordinate reconstitution accuracy when selecting the density of tie points. -| <> +| <> | 6 | For each of the interpolation dimensions, add the interpolation dimension, the corresponding tie point interpolation dimension and, if required by the selected interpolation method, its corresponding interpolation zone dimension to the **`tie_point_dimensions`** attribute of the data variable. From 5addde564eb024e98e61aebd78fbde4a1b86aca4 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 9 Dec 2020 15:31:18 +0100 Subject: [PATCH 063/249] Update appj.adoc --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 4751d747..b11f94cc 100644 --- a/appj.adoc +++ b/appj.adoc @@ -1,6 +1,6 @@ [[appendix-grid-mappings, Appendix J, Coordinate Interpolation]] - + [appendix] == Coordinate Interpolation From 67fcb3218cb7e33bf7cb5a08e049279e6ac1b6b3 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 9 Dec 2020 16:45:47 +0100 Subject: [PATCH 064/249] Add appendix J --- cf-conventions.adoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cf-conventions.adoc b/cf-conventions.adoc index c653c34f..787e79b9 100644 --- a/cf-conventions.adoc +++ b/cf-conventions.adoc @@ -105,6 +105,9 @@ include::apph.adoc[] :numbered!: include::appi.adoc[] +:numbered!: +include::appj.adoc[] + :numbered!: include::history.adoc[] From bbcffd8d9242f3c5a5d4b052c21a4c6ea17d688b Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 9 Dec 2020 16:46:23 +0100 Subject: [PATCH 065/249] Update appj.adoc --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index b11f94cc..618825df 100644 --- a/appj.adoc +++ b/appj.adoc @@ -4,7 +4,7 @@ [appendix] == Coordinate Interpolation - + [[table-grid-mapping-attributes]] From 643fcc5712ef758e2004d86387e0f26068d86657 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 9 Dec 2020 16:53:39 +0100 Subject: [PATCH 066/249] Update appj.adoc --- appj.adoc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/appj.adoc b/appj.adoc index 618825df..59b8b03a 100644 --- a/appj.adoc +++ b/appj.adoc @@ -1,8 +1,7 @@ -[[appendix-grid-mappings, Appendix J, Coordinate Interpolation]] - +[[appendix-coordinate-sampling, Appendix J, Coordinate Sampling]] [appendix] -== Coordinate Interpolation +== Coordinate Sampling [[table-grid-mapping-attributes]] From bc7a102c0e25a1f9759124afb1adeace2295fbd0 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 9 Dec 2020 16:56:17 +0100 Subject: [PATCH 067/249] Update appj.adoc --- appj.adoc | 3 --- 1 file changed, 3 deletions(-) diff --git a/appj.adoc b/appj.adoc index 59b8b03a..71756a74 100644 --- a/appj.adoc +++ b/appj.adoc @@ -57,9 +57,6 @@ |=============== - -|=============== - Each recognized coordinate interpolation is described in one of the sections below. Each section contains: the valid name that is used with the **`tie_point`** attribute; From 8761e14d2e794d4d54dfe16c5d8506cff5d1fb2b Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 9 Dec 2020 16:59:24 +0100 Subject: [PATCH 068/249] Update appj.adoc --- appj.adoc | 3 --- 1 file changed, 3 deletions(-) diff --git a/appj.adoc b/appj.adoc index 71756a74..3f056983 100644 --- a/appj.adoc +++ b/appj.adoc @@ -3,9 +3,6 @@ [appendix] == Coordinate Sampling - -[[table-grid-mapping-attributes]] - [[compression-by-coordinate-sampling-generation-of-tie-points]] .Generation of Tie Point Variables and Interpolation Variables From 9a15f30dd606b6fc2ade183b9f4270d21b52f6df Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 9 Dec 2020 17:04:15 +0100 Subject: [PATCH 069/249] Update appj.adoc --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 3f056983..22ca0eb3 100644 --- a/appj.adoc +++ b/appj.adoc @@ -110,7 +110,7 @@ link:$$http://geotiff.maptools.org/proj_list/albers_equal_area_conic.html$$[http In the following table the "Type" values are **S** for string and **N** for numeric. -[[table-grid-mapping-attributes]] +[[table-coordinate-sampling-attributes]] .Grid Mapping Attributes [options="header",cols="6,1,16",caption="Table F.1. "] |=============== From 8a56fea2102c01bf67006e70c283001f46544377 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 9 Dec 2020 17:09:10 +0100 Subject: [PATCH 070/249] Remove domain-variable link --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index ba5e22b7..f6858741 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -81,7 +81,7 @@ In addition to the tie point variables themselves, metadata definging the coordi The metadata that define the interpolation formula and its inputs are complete, so that the results of the coordinate reconstitution process are well defined and of a predictable accuracy. -The data variable coordinate interpolation attributes may also be used on a domain variable (<>) with the same effect. +The data variable coordinate interpolation attributes may also be used on a domain variable (domain-variables) with the same effect. [[compression-by-coordinate-sampling-tie-points, Section 8.3.1, "Tie Points and Interpolation Zones"]] ==== Tie Points and Interpolation Zones From 1700b715f6c9dc15dd32ab3735e7a90138cf0f39 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 9 Dec 2020 17:22:45 +0100 Subject: [PATCH 071/249] Update appj.adoc --- appj.adoc | 288 ------------------------------------------------------ 1 file changed, 288 deletions(-) diff --git a/appj.adoc b/appj.adoc index 22ca0eb3..14f094d4 100644 --- a/appj.adoc +++ b/appj.adoc @@ -6,7 +6,6 @@ [[compression-by-coordinate-sampling-generation-of-tie-points]] .Generation of Tie Point Variables and Interpolation Variables -[options="header",cols="1,40,20",caption="Table 8.1. "] |=============== | Step | Description | Link @@ -81,290 +80,3 @@ These are: We have used the FGDC "Content Standard for Digital Geospatial Metadata" <> as a guide in choosing the values for **`grid_mapping_name`** and the attribute names for the parameters describing map projections. - -=== Linear - ----- - -interpolation_name = linear - ----- - -__Map parameters:__:: -* **`standard_parallel`** - There may be 1 or 2 values. -* **`longitude_of_central_meridian`** -* **`latitude_of_projection_origin`** -* **`false_easting`** - This parameter is optional (default is 0) -* **`false_northing`** - This parameter is optional (default is 0) - -__Map coordinates:__:: The x (abscissa) and y (ordinate) rectangular coordinates are identified by the **`standard_name`** attribute values **`projection_x_coordinate`** and **`projection_y_coordinate`** respectively. - -__Notes:__:: Notes on using the **`PROJ`** software package for computing the mapping may be found at -link:$$https://proj.org/operations/projections/aea.html$$[https://proj.org/operations/projections/aea.html] -and -link:$$http://geotiff.maptools.org/proj_list/albers_equal_area_conic.html$$[http://geotiff.maptools.org/proj_list/albers_equal_area_conic.html]. - - - - - -In the following table the "Type" values are **S** for string and **N** for numeric. - -[[table-coordinate-sampling-attributes]] -.Grid Mapping Attributes -[options="header",cols="6,1,16",caption="Table F.1. "] -|=============== -| Attribute | Type | Description - -| **`azimuth_of_central_line`** | N -| Specifies a horizontal angle measured in degrees clockwise from North. Used by certain - projections (e.g., Oblique Mercator) to define the orientation of the map projection relative -to a reference direction. - -| **`crs_wkt`** | S -| This optional attribute may be used to specify multiple coordinate system properties - in well-known text (WKT) format. The syntax must conform to the WKT format as specified - in reference <>. Use of the **`crs_wkt`** attribute is described in section 5.6.1. - -| **`earth_radius`** | N -| Used to specify the radius, in metres, of the spherical - figure used to approximate the shape of the Earth. This - attribute should be specified for those projected coordinate - reference systems in which the X-Y cartesian coordinates - have been derived using a spherical Earth approximation. If - the cartesian coordinates were derived using an ellipsoid, - this attribute should not be defined. Example: "6371007", - which is the radius of the GRS 1980 Authalic Sphere. - -| **`false_easting`** | N -| Applied to all abscissa values in the rectangular - coordinates for a map projection in order to eliminate negative numbers. Expressed in - the unit of the coordinate variable identified by the - standard name **`projection_x_coordinate`**. - If **`false_easting`** is not provided it is assumed to be 0. - The formula to convert from the coordinate value as written in the **`projection_x_coordinate`** - (xf) to a value (x0) used in a transformation without **`false_easting`**, i.e. **`false_easting`**= 0, is: - x0 = xf -**`false_easting`** - - - -| **`false_northing`** | N -| Applied to all ordinate values in the rectangular - coordinates for a map projection in order to eliminate negative numbers. Expressed in - the unit of the coordinate variable identified by the - standard name **`projection_y_coordinate`**. - If **`false_northing`** is not provided it is assumed to be 0. - The formula to convert from the coordinate value as written in the **`projection_y_coordinate`** - (yf) to a value (y0) used in a transformation without **`false_northing`**, i.e. **`false_northing`**= 0, is: - y0 = yf -**`false_northing`** - -| **`fixed_angle_axis `** | S -| Indicates the axis on which the view is fixed in a hypothetical gimbal view model of the Earth, as used in the geostationary grid mapping. - It corresponds to the inner-gimbal axis of the gimbal view model, whose axis of rotation moves about the outer-gimbal axis. - This value can adopt two values, "x" or "y", corresponding with the Earth's E-W or N-S axis, respectively. - The counterpart to this attribute is `sweep_angle_axis`. - If set to "x", `sweep_angle_axis` is "y", and vice versa. - If one of the attributes `fixed_angle_axis` or `sweep_angle_axis` is provided, the other is not mandatory, as they can be used to infer each other. - -| **`geographic_crs_name`** | S -| The name of the geographic coordinate reference system. - Corresponds to a OGC WKT GEOGCS node name. - -| **`geoid_name`** | S -| The name of the estimate or model of the geoid being used as a datum, - e.g. GEOID12B. Corresponds to an OGC WKT VERT_DATUM name. The geoid is - the surface of constant geopotential that the ocean would follow if it - were at rest. This attribute and **`geopotential_datum_name`** cannot both be specified. - -| **`geopotential_datum_name`** | S - -| The name of an estimated surface of constant geopotential being used as a datum, - e.g. NAVD88. Such a surface is often called an equipotential surface in geodesy. - Corresponds to an OGC WKT VERT_DATUM name. This attribute and **`geoid_name`** cannot - both be specified. - -| **`grid_mapping_name`** | S -| The name used to identify the grid mapping. - -| **`grid_north_pole_latitude`** | N -| True latitude (degrees_north) of the north pole of the rotated grid. - -| **`grid_north_pole_longitude`** | N -| True longitude (degrees_east) of the north pole of the rotated grid. - -| **`horizontal_datum_name`** | S -| The name of the geodetic (horizontal) datum, which corresponds to the - procedure used to measure positions on the surface of the Earth. Valid datum - names and their associated parameters are given in - https://github.com/cf-convention/cf-conventions/wiki/Mapping-from-CF-Grid-Mapping-Attributes-to-CRS-WKT-Elements - (horiz_datum.csv, OGC_DATUM_NAME column) - and are - obtained by transforming the EPSG name using the following rules (used by OGR - and Cadcorp): convert all non alphanumeric characters (including +) to underscores, - then strip any leading, trailing or repeating underscores. This is to ensure that - named datums can be correctly identified for precise datum transformations - (see https://github.com/cf-convention/cf-conventions/wiki/OGC-WKT-Coordinate-System-Issues for - more details). - Corresponds to a OGC WKT DATUM node name. - -| **`inverse_flattening`** | N -| Used to specify the __inverse__ flattening - (__1/f__) of the ellipsoidal figure - associated with the geodetic datum and used to approximate the shape - of the Earth. The flattening (__f__) of the ellipsoid - is related to the semi-major and semi-minor axes by the formula - __f = (a-b)/a__. In the case - of a spherical Earth this attribute should be omitted or set to zero. - Example: 298.257222101 for the GRS 1980 ellipsoid. (Note: By - convention the dimensions of an ellipsoid are specified using either - the semi-major and semi-minor axis lengths, or the semi-major axis - length and the inverse flattening. If all three attributes are - specified then the supplied values must be consistent with the - aforementioned formula.) - -| **`latitude_of_projection_origin`** | N -| The latitude (degrees_north) chosen as the origin of rectangular - coordinates for a map projection. Domain: + -// The following lines shows how to insert Unicode for <=. A plain '<=' turns into an arrow. -// Except as marked, all work for asciidoctor and none work for asciidoctor-pdf. -// **`-90.0 ≤ latitude_of_projection_origin ≤ 90.0`** + -//doesn't work for asciidoctor **`-90.0 ࣘ latitude_of_projection_origin ࣘ 90.0`** + -// **`-90.0 ≤ latitude_of_projection_origin ≤ 90.0`** + -// **`-90.0 ≤ latitude_of_projection_origin ≤ 90.0`** + -// **`-90.0 ++++++ latitude_of_projection_origin ++++++ 90.0`** + -// **`-90.0 < = latitude_of_projection_origin < = 90.0`** + -// **`-90.0 \<= latitude_of_projection_origin \<= 90.0`** + -// The cleanest-looking, which sometimes works for asciidoctor-pdf: - **`-90.0 \<= latitude_of_projection_origin \<= 90.0`** - -| **`longitude_of_central_meridian`** | N -| The line of longitude (degrees_east) at the center of a map projection - generally used as the basis for constructing the projection. - Domain: + - **`-180.0 \<= longitude_of_central_meridian < 180.0`** - - -| **`longitude_of_prime_meridian`** | N -| Specifies the longitude, with respect to Greenwich, of the prime - meridian associated with the geodetic datum. The prime meridian defines - the origin from which longitude values are determined. Not to be - confused with the projection origin longitude - (cf. **`longitude_of_projection_origin`**, a.k.a. central - meridian) which defines the longitude of the map projection origin. - Domain: + - **`-180.0 \<= longitude_of_prime_meridian < 180.0`** - decimal degrees. - Default = **`0.0`** - -| **`longitude_of_projection_origin`** | N -| The longitude (degrees_east) chosen as the origin of rectangular - coordinates for a map projection. - Domain: + - **`-180.0 \<= longitude_of_projection_origin < 180.0`** - - -| **`north_pole_grid_longitude`** | N -| Longitude (degrees) of the true north pole in the rotated grid. - - -| **`perspective_point_height`** | N -| Records the height, __in metres__, of the map - projection perspective point above the ellipsoid (or sphere). Used - by perspective-type map projections, for example the Vertical - Perspective Projection, which may be used to simulate the view from - a Meteosat satellite. - - -| **`prime_meridian_name`** | S -| The name of the prime meridian associated with the geodetic datum. Valid - names are given in - https://github.com/cf-convention/cf-conventions/wiki/Mapping-from-CF-Grid-Mapping-Attributes-to-CRS-WKT-Elements - (prime_meridian.csv). Corresponds to a OGC WKT PRIMEM node name. - - -|**`projected_crs_name`** | S -| The name of the projected coordinate reference system. Corresponds - to a OGC WKT PROJCS node name. - - -| **`reference_ellipsoid_name`** | S -| The name of the reference ellipsoid. Valid names are given in - https://github.com/cf-convention/cf-conventions/wiki/Mapping-from-CF-Grid-Mapping-Attributes-to-CRS-WKT-Elements - (ellipsoid.csv). - Corresponds to a OGC WKT SPHEROID node name. - - -| **`scale_factor_at_central_meridian`** | N -| A multiplier for reducing a distance obtained from a map by - computation or scaling to the actual distance along the - central meridian. - Domain: **`scale_factor_at_central_meridian > 0.0`** - -| **`scale_factor_at_projection_origin`** | N -| A multiplier for reducing a distance obtained from - a map by computation or scaling to the actual distance - at the projection origin. - Domain: **`scale_factor_at_projection_origin > 0.0`** - - -| **`semi_major_axis`** | N -| Specifies the length, __in metres__, of the semi-major - axis of the ellipsoidal figure associated with the geodetic datum and - used to approximate the shape of the Earth. Commonly denoted using the - symbol __a__. In the case of a spherical Earth - approximation this attribute defines the radius of the Earth. See - also the **`inverse_flattening`** attribute. - -| **`semi_minor_axis`** | N -| Specifies the length, __in metres__, of the semi-minor - axis of the ellipsoidal figure associated with the geodetic datum and - used to approximate the shape of the Earth. Commonly denoted using the - symbol __b__. In the case of a spherical Earth - approximation this attribute should be omitted (the preferred option) - or else set equal to the value of the semi_major_axis attribute. See - also the inverse_flattening attribute. - -| **`standard_parallel`** | N -| Specifies the line, or lines, of latitude at which the developable map - projection surface (plane, cone, or cylinder) touches the reference - sphere or ellipsoid used to represent the Earth. Since there is zero - scale distortion along a standard parallel it is also referred to as - a "latitude of true scale". In the situation where a conical - developable surface intersects the reference ellipsoid there are two - standard parallels, in which case this attribute can be used as a - vector to record both latitude values, with the additional convention - that the standard parallel nearest the pole (N or S) is provided first. - Domain: **`-90.0 <= standard_parallel <= 90.0`** - -| **`straight_vertical_longitude_from_pole`** | N -| The longitude (degrees_east) to be oriented straight up from the North or - South Pole. Domain: **`-180.0 <= straight_vertical_longitude_from_pole < 180.0`** - -| **`sweep_angle_axis `** | S -| Indicates the axis on which the view sweeps in a hypothetical gimbal view model of the Earth, as used in the geostationary grid mapping. - It corresponds to the outer-gimbal axis of the gimbal view model, about whose axis of rotation the gimbal-gimbal axis moves. - This value can adopt two values, "x" or "y", corresponding with the Earth's E-W or N-S axis, respectively. - The counterpart to this attribute is `fixed_angle_axis`. - If set to "x", `fixed_angle_axis` is "y", and vice versa. - If one of the attributes `fixed_angle_axis` or `sweep_angle_axis` is provided, the other is not mandatory, as they can be used to infer each other. - -| **`towgs84`** | N -| This indicates a list of up - to 7 Bursa Wolf transformation parameters., which can be used to approximate a - transformation from the horizontal datum to the WGS84 datum. More precise datum - transformations can be done with datum shift grids. Represented as a double-precision - array, with 3, 6 or 7 values (if there are less than 7 values the remaining are - considered to be zero). Corresponds to a OGC WKT TOWGS84 node. - -|=============== - -Notes: - -. The various **`*_name`** attributes are optional but recommended when -known as they allow for a better description and interoperability with WKT -definitions. -. **`reference_ellipsoid_name`**, **`prime_meridian_name`**, -**`horizontal_datum_name`** and **`geographic_crs_name`** must be all defined if any one - is defined, and if **`projected_crs_name`** is defined then **`geographic_crs_name`** must be also. - - From 456c8b5a396189ac5e89d329f04f0fcb5471d85c Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 9 Dec 2020 17:29:34 +0100 Subject: [PATCH 072/249] Update appj.adoc --- appj.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/appj.adoc b/appj.adoc index 14f094d4..ef2ef38a 100644 --- a/appj.adoc +++ b/appj.adoc @@ -6,6 +6,7 @@ [[compression-by-coordinate-sampling-generation-of-tie-points]] .Generation of Tie Point Variables and Interpolation Variables +[options="header",cols="1,16,6",caption="Table J.1. "] |=============== | Step | Description | Link From b2a7ae50114a4192b86aa034699eef2f83f57584 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 14 Dec 2020 15:32:46 +0100 Subject: [PATCH 073/249] Add coordinate reconstitution table --- appj.adoc | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index ef2ef38a..51ed8d1c 100644 --- a/appj.adoc +++ b/appj.adoc @@ -24,7 +24,7 @@ | 4 -| For each coordinate variable subset, identify the set of interpolation and the set of non-interpolation dimensions. +| For each coordinate variable subset, identify the set of interpolation dimensions and the set of non-interpolation dimensions. | <> | 5 @@ -54,6 +54,54 @@ |=============== + +[[compression-by-coordinate-sampling-reconstitution-of-coordinates]] +.Reconstitution of Coordinate and Auxillary Coordinate Variables +[options="header",cols="1,16,6",caption="Table J.1. "] +|=============== +| Step | Description | Link + +| 1 +| From the **`tie_points`** attribute of the data variable, identify the coordinate and auxillary coordinate variable subsets for which tie point interpolation is required. +| <> + +| 2 +| For each coordinate variable subset, identify the set of dimension. Using the **`tie_point_dimensions`** attribute of the data variable, identify the set of interpolation dimensions and the set of non-interpolation dimensions. +| <> + +<> + +| 3 +| From the **`tie_point_dimensions`** attribute of the data variable, identify for each of the interpolation dimensions the corresponding tie point interpolation dimension and, if defined, the corresponding interpolation zone dimension. +| <> + +| 4 +| From the tie point index variables referenced in the **`tie_point_indices`** attribute of the data variable, identify the location of the tie points in the corresponding interpolation dimension. +| <> + +| 5 +| For each of the interpolation dimensions, identify pairs of adjacent indices in the tie point index variable with index values differing by more than one, each index pair defining the extend of an interpolation zone in that dimension. A full interpolation zone is defined by one such index pair per interpolation dimension, with combinations of one index from each pair defining the interpolation zone tie points. +| <> + +| 6 +| From the **`tie_points`** attribute of the data variable, identify the interpolation variable for the coordinate and auxillary coordinate variable subset. From the **`interpolation_name`** attribute of the interpolation variable, identify the interpolation method. +| <> + +| 7 +| As required by the selected interpolation method, identify the interpolation coefficients variables and interpolation configuration variables from the interpolation variable **`interpolation_coefficients`** and **`interpolation_configuration`** attributes respectively. +| <> + +| 8 +| For each of the tie point coordinate and auxillary coordinate variables, create the corresponding target coordinate variable. For each interpolation zone, apply the interpolation method to reconstitute the target domain coordinate values and store these in the target domain coordinate variables. Repeat this step for each combination of indices of the non-interpolation dimensions. +| <> + +| 9 +| For each of the tie point coordinate and auxillary coordinate variables having a **`bounds`** attribute, add the **`bounds`** attribute to the target coordinate variable and create the target domain bounds variable. For each interpolation zone, apply the interpolation method to reconstitute the target domain bound values and store these in the target domain bound variables. Repeat this step for each combination of indices of the non-interpolation dimensions. +| <> + +|=============== + + Each recognized coordinate interpolation is described in one of the sections below. Each section contains: the valid name that is used with the **`tie_point`** attribute; From 8d810929cbc36257d9bc61be6f7b4c5d242ca2aa Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 14 Dec 2020 15:01:44 +0000 Subject: [PATCH 074/249] zone/area rewording --- ch08.adoc | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index f6858741..369fccfd 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -77,7 +77,7 @@ For some applications the coordinates of a data variable can require considerabl The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. -In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. +In addition to the tie point variables themselves, metadata defining the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. The metadata that define the interpolation formula and its inputs are complete, so that the results of the coordinate reconstitution process are well defined and of a predictable accuracy. @@ -86,11 +86,35 @@ The data variable coordinate interpolation attributes may also be used on a doma [[compression-by-coordinate-sampling-tie-points, Section 8.3.1, "Tie Points and Interpolation Zones"]] ==== Tie Points and Interpolation Zones -Reconstitution of the uncompressed coordinate and auxiliary coordinate variables is based on interpolation. To accomplish this, the target domain is segmented into smaller __interpolation zones__, for each of which the interpolation method is applied independently. For one dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone; for two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes; etc. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables within an interpolation zone, the interpolation method is permitted to access the coordinates of the defining tie points, but not the coordinates of any other tie points. - -Although the coordinate and auxiliary coordinate variables are stored in orthogonal multidimensional array representation, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates, or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. In such cases the location of the discontinuities in the coordinate values can be based either on knowledge of how the data set was created, e.g. by a remote sensing instrument, or alternatively by inspection of the actual coordinates. - -As the interpolation methods rely on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in <>. +Reconstitution of the uncompressed coordinate and auxiliary coordinate +variables is based on interpolation. To accomplish this, the target +domain is segmented into smaller __interpolation zones__, for each of +which the interpolation method is applied independently. For +one-dimensional interpolation, an interpolation zone is defined by two +tie points, one at each end of the interpolation zone; for +two-dimensional interpolation, an interpolation zone is defined by +four tie points, one at each corner of a rectangular area aligned with +the domain axes; etc. For the reconstitution of the uncompressed +coordinate and auxiliary coordinate variables within an interpolation +zone, the interpolation method is permitted to access its defining tie +points, but not the tie points of any other interpolation zone. + +As an interpolation method relies on the regularity and continuity of +the coordinate values within each interpolation zone, special +attention must be given to the case when uncompressed coordinates +contain discontinuities. A discontinuity could be an overlap or a gap +in the coordinates' coverage, or a change in cell size or cell +alignment. As an example, such discontinuities are common in remote +sensing data and may be caused by combinations of the instrument scan +motion, the motion of the sensor platform and changes in the +instrument scan mode. When discontinuities are present, the domain is +first divided into multiple __interpolation areas__, each of which is +free of discontinuities. When no discontinuities are present, the +whole domain is a single interpolation area. Following this step, each +interpolation area is segmented into interpolation zones. The +processes of generating interpolation zones for a domain without +discontinuities and for a domain with discontinuities is illustrated +in <>. Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. From 4f9491a71ed761652b0b8752418915e7442f4e9a Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 14 Dec 2020 16:01:46 +0100 Subject: [PATCH 075/249] Add **`coordinates`** attribute in table J.2 --- appj.adoc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/appj.adoc b/appj.adoc index 51ed8d1c..1f227327 100644 --- a/appj.adoc +++ b/appj.adoc @@ -57,16 +57,16 @@ [[compression-by-coordinate-sampling-reconstitution-of-coordinates]] .Reconstitution of Coordinate and Auxillary Coordinate Variables -[options="header",cols="1,16,6",caption="Table J.1. "] +[options="header",cols="1,16,6",caption="Table J.2. "] |=============== | Step | Description | Link | 1 -| From the **`tie_points`** attribute of the data variable, identify the coordinate and auxillary coordinate variable subsets for which tie point interpolation is required. +| From the **`tie_points`** attribute of the data variable, identify the coordinate and auxillary coordinate variable subsets, for which tie point interpolation is required. | <> | 2 -| For each coordinate variable subset, identify the set of dimension. Using the **`tie_point_dimensions`** attribute of the data variable, identify the set of interpolation dimensions and the set of non-interpolation dimensions. +| For each coordinate variable subset, identify the set of dimensions. Using the **`tie_point_dimensions`** attribute of the data variable, identify the set of interpolation dimensions and the set of non-interpolation dimensions. | <> <> @@ -99,6 +99,11 @@ | For each of the tie point coordinate and auxillary coordinate variables having a **`bounds`** attribute, add the **`bounds`** attribute to the target coordinate variable and create the target domain bounds variable. For each interpolation zone, apply the interpolation method to reconstitute the target domain bound values and store these in the target domain bound variables. Repeat this step for each combination of indices of the non-interpolation dimensions. | <> +| 10 +| Add a **`coordinates`** attribute to the data variable and set the value to the list of the names of auxiliary coordinate variables. +| <> + + |=============== From fa47a7dd6e463f3fbd28012ca6d86ca098f1989a Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 14 Dec 2020 15:03:02 +0000 Subject: [PATCH 076/249] zone/area rewording --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 369fccfd..f896b6fa 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -97,7 +97,7 @@ four tie points, one at each corner of a rectangular area aligned with the domain axes; etc. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables within an interpolation zone, the interpolation method is permitted to access its defining tie -points, but not the tie points of any other interpolation zone. +points, and no others. As an interpolation method relies on the regularity and continuity of the coordinate values within each interpolation zone, special From 669d72c8134595274a76c5ac9e650d3316a018bf Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 14 Dec 2020 16:10:54 +0100 Subject: [PATCH 077/249] Update table J.2 step 10 --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 1f227327..ce66d8a5 100644 --- a/appj.adoc +++ b/appj.adoc @@ -100,7 +100,7 @@ | <> | 10 -| Add a **`coordinates`** attribute to the data variable and set the value to the list of the names of auxiliary coordinate variables. +| If auxiliary coordinate variables have been reconstituted, then add a **`coordinates`** attribute to the data variable, if not already present, and add to the attribute the list of the names of the reconstituted auxiliary coordinate variables. | <> From 5aa8752ea1b5fa94a72015cc86d57c24171bc104 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 14 Dec 2020 16:30:39 +0100 Subject: [PATCH 078/249] Redefined interpolation area boundary to refelext no tie point offset. --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index f6858741..1be3dae5 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -135,7 +135,7 @@ image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices where the value of the second is the equal to the value of the first incremented by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. From 97834662498e8867f8aa6300ae401e03bf5666e4 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 14 Dec 2020 16:36:29 +0100 Subject: [PATCH 079/249] Remove dimesion relationships from Tie Point Indices, now in Tie Point Dimensions Attribute --- ch08.adoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 1be3dae5..4695c115 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -145,8 +145,6 @@ For instance, in example <> the tie poi To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. -The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point index variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point index variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. - [[Two-dimensional-tie-point-interpolation]] [caption="Example 8.3. "] .Two-dimensional tie point interpolation From cab69d7ebc2cb587d3e10405a9c850e9e8cdd0a5 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 14 Dec 2020 17:12:44 +0000 Subject: [PATCH 080/249] Anders subsampled (#7) * more text following 2020-11-27 discussions * bounds * tidy * tidy * tidy * tidy * reproducability * offset * indices * indices * indices * super * tie_point_dimension (1) * tie_point_dimension (2) * tie_point_dimension (3) * tie_point_dimension (4) * tie point * tie_point_dimension (5) * corrected interpolation_configuration description * zone/area rewording * zone/area rewording --- ch08.adoc | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 4695c115..4fe63a0c 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -77,7 +77,7 @@ For some applications the coordinates of a data variable can require considerabl The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. -In addition to the tie point variables themselves, metadata definging the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. +In addition to the tie point variables themselves, metadata defining the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. The metadata that define the interpolation formula and its inputs are complete, so that the results of the coordinate reconstitution process are well defined and of a predictable accuracy. @@ -86,11 +86,35 @@ The data variable coordinate interpolation attributes may also be used on a doma [[compression-by-coordinate-sampling-tie-points, Section 8.3.1, "Tie Points and Interpolation Zones"]] ==== Tie Points and Interpolation Zones -Reconstitution of the uncompressed coordinate and auxiliary coordinate variables is based on interpolation. To accomplish this, the target domain is segmented into smaller __interpolation zones__, for each of which the interpolation method is applied independently. For one dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone; for two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes; etc. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables within an interpolation zone, the interpolation method is permitted to access the coordinates of the defining tie points, but not the coordinates of any other tie points. - -Although the coordinate and auxiliary coordinate variables are stored in orthogonal multidimensional array representation, the actual coordinate values may contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates, or a change in cell size or cell alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. In such cases the location of the discontinuities in the coordinate values can be based either on knowledge of how the data set was created, e.g. by a remote sensing instrument, or alternatively by inspection of the actual coordinates. - -As the interpolation methods rely on a certain regularity and continuity of the coordinate values within each interpolation zone, special attention must be given to the discontinuities in the process of defining the interpolation zones. When discontinuities are present, the grid is first divided into multiple __interpolation areas__, each of which is free of grid discontinuities. When no discontinuities are present, the whole grid is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a grid without discontinuities and for a grid with discontinuities is illustrated in <>. +Reconstitution of the uncompressed coordinate and auxiliary coordinate +variables is based on interpolation. To accomplish this, the target +domain is segmented into smaller __interpolation zones__, for each of +which the interpolation method is applied independently. For +one-dimensional interpolation, an interpolation zone is defined by two +tie points, one at each end of the interpolation zone; for +two-dimensional interpolation, an interpolation zone is defined by +four tie points, one at each corner of a rectangular area aligned with +the domain axes; etc. For the reconstitution of the uncompressed +coordinate and auxiliary coordinate variables within an interpolation +zone, the interpolation method is permitted to access its defining tie +points, and no others. + +As an interpolation method relies on the regularity and continuity of +the coordinate values within each interpolation zone, special +attention must be given to the case when uncompressed coordinates +contain discontinuities. A discontinuity could be an overlap or a gap +in the coordinates' coverage, or a change in cell size or cell +alignment. As an example, such discontinuities are common in remote +sensing data and may be caused by combinations of the instrument scan +motion, the motion of the sensor platform and changes in the +instrument scan mode. When discontinuities are present, the domain is +first divided into multiple __interpolation areas__, each of which is +free of discontinuities. When no discontinuities are present, the +whole domain is a single interpolation area. Following this step, each +interpolation area is segmented into interpolation zones. The +processes of generating interpolation zones for a domain without +discontinuities and for a domain with discontinuities is illustrated +in <>. Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. From 457e2c02d1029c0716a6d9ee1af3c33da9b7b279 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 15 Dec 2020 13:56:31 +0100 Subject: [PATCH 081/249] Add figure and Linear method to Appendix J --- appj.adoc | 52 +++++++++++++++++++++---------------- images/ci_interpolation.svg | 1 + 2 files changed, 30 insertions(+), 23 deletions(-) create mode 100644 images/ci_interpolation.svg diff --git a/appj.adoc b/appj.adoc index ce66d8a5..780a038e 100644 --- a/appj.adoc +++ b/appj.adoc @@ -3,6 +3,8 @@ [appendix] == Coordinate Sampling +=== Steps for Generation of Tie Points + [[compression-by-coordinate-sampling-generation-of-tie-points]] .Generation of Tie Point Variables and Interpolation Variables @@ -54,6 +56,8 @@ |=============== +=== Steps for Reconstitution of Coordinate and Auxillary Coordinate Variables + [[compression-by-coordinate-sampling-reconstitution-of-coordinates]] .Reconstitution of Coordinate and Auxillary Coordinate Variables @@ -100,37 +104,39 @@ | <> | 10 -| If auxiliary coordinate variables have been reconstituted, then add a **`coordinates`** attribute to the data variable, if not already present, and add to the attribute the list of the names of the reconstituted auxiliary coordinate variables. +| If auxiliary coordinate variables have been reconstituted, then, if not already present, add a **`coordinates`** attribute to the data variable and add to the attribute the list of the names of the reconstituted auxiliary coordinate variables. | <> - |=============== -Each recognized coordinate interpolation is described in one of the sections below. -Each section contains: the valid name that is used with the -**`tie_point`** attribute; +=== Interpolation Methods + +==== General definitions + +[[interpolation, figure J.1]] +[.text-center] +.Interpolation indices and interpolation parameter s +image::images/ci_interpolation.svg[,100%,pdfwidth=50vw,align="center"] +Two Tie Points, A and B, and a reconstituted point P, are shown in In he Figure J.1. The indices of A nd B in the tie point interpolation dimension are n and n+1 respectively. The corresponding indices in the interpolation dimension, i~A~ and i~B~, are stored in the tie point index variable, index(n) and index(n+1). -a list of the specific attributes -that may be used to assign values to the mapping's parameters; the -standard names used to identify the coordinate variables that contain -the mapping's independent variables; and references to the mapping's -definition or other information that may help in using the mapping. -Since the attributes used to set a mapping's parameters may be shared -among several mappings, their definitions are contained in a table in -the final section. -The attributes which describe the ellipsoid and prime meridian may be included, when applicable, with any grid mapping. -These are: +A real number interpolation parameter s, running from 0.0 to 1.0 between tie point A and B, is introduced for the purpose of teh interpolation calculations. For the point P to be reconstituted, the interpolation parameter is -- `earth_radius` -- `inverse_flattening` -- `longitude_of_prime_meridian` -- `prime_meridian_name` -- `reference_ellipsoid_name` -- `semi_major_axis` -- `semi_minor_axis` +s~P~ = (i~P~ - i~A~)/(i~B~ - i~A~) + +The coordinate values at the tie points A and B are c~A~ and c~B~ and are stored in the tie point coordinate variables. For the point P, the coordinate value can be reconstituted as c~P~ applying the selected interpolation method. + +==== Linear + +[cols="6,15"] +|=============== +| Name | **`interpolation_name = "linear"`** +| Description/Features | General purpose one dimensional linear interpolation +| Definition | c~P~ = (1 - s~P~) c~A~ + s~P~ c~B~ +| Interpolation Coefficients | None +| Interpolation Configuration | None +|=============== -We have used the FGDC "Content Standard for Digital Geospatial Metadata" <> as a guide in choosing the values for **`grid_mapping_name`** and the attribute names for the parameters describing map projections. diff --git a/images/ci_interpolation.svg b/images/ci_interpolation.svg new file mode 100644 index 00000000..8598b5a0 --- /dev/null +++ b/images/ci_interpolation.svg @@ -0,0 +1 @@ +n+1TiePoint Interpolation DimensionnInterpolation DimensioniB= index(n+1)ReconstitutedPoint (Interpolation Dimension)ABiA= index(n)iP0.0……1.0sPcPcAcBCoordinateValuesInterpolation ParameterTiePoints and ReconstitutedPointP \ No newline at end of file From 1f0e1bc5aab7d9aff98b872617302ca8255d9c92 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 15 Dec 2020 18:09:06 +0100 Subject: [PATCH 082/249] Updat example 8.5 VIIRS to refelect multiple mapping for same dimension in tie_point_dimensions and tie_point_indices --- ch08.adoc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 4fe63a0c..8c92ae81 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -319,28 +319,28 @@ dimensions : zone_scan= 200 ; // scan interpolation zone // Time, stored at scan-start and scan-end of each scan - time_scan = 2; + tp_time_scan = 2; variables: // VIIRS M-Band float m_radiance(m_track, m_scan, m_channel) ; m_radiance:tie_points = "m_lat: m_lon: m_sen_azi_ang: m_sen_zen_ang: m_sol_azi_ang: m_sol_zen_ang: tp_interpolation t: time_interpolation" ; - m_radiance:tie_point_dimensions = "m_track: tp_track zone_track m_scan: tp_scan zone_scan" ; - m_radiance:tie_point_indices = "m_track: m_track_indices m_scan: m_scan_indices time_scan: m_time_scan_indices" ; + m_radiance:tie_point_dimensions = "m_track: tp_track zone_track m_scan: tp_scan zone_scan m_scan: tp_time_scan" ; + m_radiance:tie_point_indices = "m_track: m_track_indices m_scan: m_scan_indices m_scan: m_time_scan_indices" ; // VIIRS I-Band float i_radiance(i_track, i_scan, i_channel) ; i_radiance:tie_points = "i_lat: i_lon: i_sen_azi_ang: i_sen_zen_ang: i_sol_azi_ang: i_sol_zen_ang: tp_interpolation t: time_interpolation" ; - m_radiance:tie_point_dimensions = "i_track: tp_track zone_track i_scan: tp_scan zone_scan" ; - i_radiance:tie_point_indices = "i_track: zone_track: i_track_indices i_scan: zone_scan: i_scan_indices time_scan: i_time_scan_indices" ; + i_radiance:tie_point_dimensions = "i_track: tp_track zone_track i_scan: tp_scan zone_scan i_scan: tp_time_scan" ; + i_radiance:tie_point_indices = "i_track: zone_track: i_track_indices i_scan: zone_scan: i_scan_indices i_scan: i_time_scan_indices" ; // Tie point index variables int m_track_indices(tp_track) ; // shared by tp_interpolation and time_interpolation int m_scan_indices(tp_scan) ; - int m_time_scan_indices(time_scan) + int m_time_scan_indices(tp_time_scan) int i_track_indices(tp_track) ; // shared by tp_interpolation and time_interpolation int i_scan_indices(tp_scan) ; - int i_time_scan_indices(time_scan) + int i_time_scan_indices(tp_time_scan) // Tie points float m_lat(tp_track, tp_scan) ; @@ -398,11 +398,11 @@ variables: interpolation_zone_flags : flag_meanings = "location_use_cartesian sensor_direction_use_cartesian solar_direction_use_cartesian" ; // Time tie points - double t(tp_track, time_scan) ; + double t(tp_track, tp_time_scan) ; t : long_name = "time" ; t : units = "days since 1990-1-1 0:0:0" ; - // Time interploation variable + // Time interpolation variable char time_interpolation ; time_interpolation : interpolation_name = "bi_linear" ; ---- From a0b41ae8c9d8d47e16dc206d8cc1016120f7c767 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 15 Dec 2020 17:14:57 +0000 Subject: [PATCH 083/249] multiple mappings --- ch08.adoc | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index f896b6fa..d841b569 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -114,7 +114,8 @@ whole domain is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a domain without discontinuities and for a domain with discontinuities is illustrated -in <>. +in <>, and described in more detail in +<>. Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. @@ -156,6 +157,29 @@ Note that an interpolation zone dimension has, by definition, the same size as t .Overview of the different dimensions for coordinate interpolation. image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] +A single interpolation dimension may be associated with multiple tie +point interpolation dimensions by repeating the interpolation +dimension in the **`tie_point_dimensions`** attribute. For instance, +interpolation dimension `dimension1` could be mapped to two different +tie point interpolation dimensions with `dimension1: tp_dimension1 +dimension1: tp_dimension2`. This is necssary when different tie point +variables for a particular interpolation dimension do not contain the +same number of tie points, and therefore have different numbers of +interpolation zones, as is the case in <>. A tie point +variable must span at most one of the tie point interpolation +dimensions associated with a given interpolation dimension. Since all +tie point variables for a given interpolation variable must span the +same set of dimensions (see +<>), the tie point +variables corresponding to a particular interpolation dimension +spanning must be separately associated with the corresponding +interpolation variable, even if that interpolation variable is the +same in each case. For instance, if tie point variables `lat` and +`lon` span dimension `tp_dimension1` and `time` spans dimension +`tp_dimension2`, and all three are to interpolated according to +interpolation variable `linear`, then the **`tie_points`** attribute +could be `lat: lon: linear time: linear`. + [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices From 4a821d23c90a1d6459135c4414583ccdf51378fe Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 15 Dec 2020 17:18:19 +0000 Subject: [PATCH 084/249] multiple mappings --- ch08.adoc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index d841b569..f427aae0 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -164,21 +164,22 @@ interpolation dimension `dimension1` could be mapped to two different tie point interpolation dimensions with `dimension1: tp_dimension1 dimension1: tp_dimension2`. This is necssary when different tie point variables for a particular interpolation dimension do not contain the -same number of tie points, and therefore have different numbers of +same number of tie points, and therefore define different numbers of interpolation zones, as is the case in <>. A tie point variable must span at most one of the tie point interpolation dimensions associated with a given interpolation dimension. Since all tie point variables for a given interpolation variable must span the same set of dimensions (see <>), the tie point -variables corresponding to a particular interpolation dimension -spanning must be separately associated with the corresponding -interpolation variable, even if that interpolation variable is the -same in each case. For instance, if tie point variables `lat` and -`lon` span dimension `tp_dimension1` and `time` spans dimension -`tp_dimension2`, and all three are to interpolated according to -interpolation variable `linear`, then the **`tie_points`** attribute -could be `lat: lon: linear time: linear`. +variables corresponding to a particular interpolation dimension must +be separately associated with the corresponding interpolation variable +according to which corresponding tie interpolation dimension they +span, even if that interpolation variable is the same in each +case. For instance, if tie point variables `lat` and `lon` span +dimension `tp_dimension1` and `time` spans dimension `tp_dimension2`, +and all three are to interpolated according to interpolation variable +`linear`, then the **`tie_points`** attribute could be `lat: lon: +linear time: linear`. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices From f54b352b8963537dce9df48931994b3a82453a9a Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 15 Dec 2020 17:19:46 +0000 Subject: [PATCH 085/249] multiple mappings --- ch08.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index f427aae0..42d71ff0 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -172,9 +172,9 @@ tie point variables for a given interpolation variable must span the same set of dimensions (see <>), the tie point variables corresponding to a particular interpolation dimension must -be separately associated with the corresponding interpolation variable -according to which corresponding tie interpolation dimension they -span, even if that interpolation variable is the same in each +be separately associated with their corresponding interpolation +variables according to which corresponding tie interpolation dimension +they span, even if those interpolation variable are the same in each case. For instance, if tie point variables `lat` and `lon` span dimension `tp_dimension1` and `time` spans dimension `tp_dimension2`, and all three are to interpolated according to interpolation variable From c8d3d679d96e9d3224178972bd31a5a68b4cd258 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 11 Jan 2021 11:41:17 +0000 Subject: [PATCH 086/249] Multiply mapped dinterpolation dimensions (#8) * more text following 2020-11-27 discussions * bounds * tidy * tidy * tidy * tidy * reproducability * offset * indices * indices * indices * super * tie_point_dimension (1) * tie_point_dimension (2) * tie_point_dimension (3) * tie_point_dimension (4) * tie point * tie_point_dimension (5) * corrected interpolation_configuration description * zone/area rewording * zone/area rewording * multiple mappings * multiple mappings * multiple mappings Co-authored-by: AndersMS <63056394+AndersMS@users.noreply.github.com> --- ch08.adoc | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 8c92ae81..81d60da6 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -114,7 +114,8 @@ whole domain is a single interpolation area. Following this step, each interpolation area is segmented into interpolation zones. The processes of generating interpolation zones for a domain without discontinuities and for a domain with discontinuities is illustrated -in <>. +in <>, and described in more detail in +<>. Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. @@ -156,6 +157,30 @@ Note that an interpolation zone dimension has, by definition, the same size as t .Overview of the different dimensions for coordinate interpolation. image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] +A single interpolation dimension may be associated with multiple tie +point interpolation dimensions by repeating the interpolation +dimension in the **`tie_point_dimensions`** attribute. For instance, +interpolation dimension `dimension1` could be mapped to two different +tie point interpolation dimensions with `dimension1: tp_dimension1 +dimension1: tp_dimension2`. This is necssary when different tie point +variables for a particular interpolation dimension do not contain the +same number of tie points, and therefore define different numbers of +interpolation zones, as is the case in <>. A tie point +variable must span at most one of the tie point interpolation +dimensions associated with a given interpolation dimension. Since all +tie point variables for a given interpolation variable must span the +same set of dimensions (see +<>), the tie point +variables corresponding to a particular interpolation dimension must +be separately associated with their corresponding interpolation +variables according to which corresponding tie interpolation dimension +they span, even if those interpolation variable are the same in each +case. For instance, if tie point variables `lat` and `lon` span +dimension `tp_dimension1` and `time` spans dimension `tp_dimension2`, +and all three are to interpolated according to interpolation variable +`linear`, then the **`tie_points`** attribute could be `lat: lon: +linear time: linear`. + [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices From fb398a6e48ae36d69b844d9f1e9ce16560b06ef6 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 12 Jan 2021 11:07:51 +0000 Subject: [PATCH 087/249] typos and some minor rewording suggestions --- ch08.adoc | 59 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 42d71ff0..fcb410b0 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -73,7 +73,7 @@ This information implies that the salinity field should be uncompressed to an ar [[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Sampling"]] === Lossy Compression by Coordinate Sampling -For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to user of the uncompressed dataset. +For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. @@ -174,7 +174,7 @@ same set of dimensions (see variables corresponding to a particular interpolation dimension must be separately associated with their corresponding interpolation variables according to which corresponding tie interpolation dimension -they span, even if those interpolation variable are the same in each +they span, even if those interpolation variables are the same in each case. For instance, if tie point variables `lat` and `lon` span dimension `tp_dimension1` and `time` spans dimension `tp_dimension2`, and all three are to interpolated according to interpolation variable @@ -184,14 +184,25 @@ linear time: linear`. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices that are equal, or differ by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). +The relationship between a tie point interpolation dimension and its +corresponding interpolation dimension is defined with a __tie point +index variable__. This contains zero-based indices that relate each +element of a tie point interpolation dimension to its related location +in the corresponding interpolation dimension. The tie point index +variable is a one-dimensional integer variable that must span the tie +point interpolation dimension specified by the +**`tie_point_dimensions`** attribute. The values must be strictly +monotonically increasing within interpolation areas. When two adjacent +values are equal, or differ by one, it indicates the location (in +index space) of an interpolation area boundary relating to an grid +discontinuity (<>). When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. -Conversely, when tie point variables represent a superset of the uncompressed coordinates, each value of the tie point index variable is the index of the tie point interpolation dimension that corresponds to the corresponding interpolation dimension. This situation could occur when a hierarchy of different resolution representations of data are stored in different data variables. Space can be saved by storing the highest resolution coordinates, and using tie point indices with an interpolation variable to derive the lower resolution coordinates. Such a superset is identifiable by there being a unique interpolation area and the size of the tie point interpolation dimension being strictly greater than than the size of interpolation dimension. - For instance, in example <> the tie point variables represent a subset of the target domain and tie point index variable **`int x_indices(tp_xc)`** contains the indices **`x_indices = 0, 9, 19, 29`** that identify location of the interpolation dimension **`xc`** of size 30. However, in example < the tie point index variables represent a superset of the target domain and so in this case the same indices are identifying locations of the tie point interpolation dimension. +Conversely, when tie point variables represent a superset of the uncompressed coordinates, each value of the tie point index variable is the index of the tie point interpolation dimension that corresponds to the corresponding interpolation dimension. This situation could occur when a hierarchy of different resolution representations of data are stored in different data variables. Space can be saved by storing the highest resolution coordinates, and using tie point indices with an interpolation variable to derive the lower resolution coordinates. Such a superset is identifiable by there being a unique interpolation area and the size of the tie point interpolation dimension being strictly greater than than the size of interpolation dimension. + To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. The **`tie_point_indices`** attribute also serves to identify the corresponding tie point interpolation dimensions, as each tie point index variable spans a unique tie point interpolation dimension. In the example, interpolation dimension **`xc`** references tie point index variable **`x_indices`**, which in turn identifies tie point interpolation dimension **`tp_xc`**. @@ -285,13 +296,25 @@ The method used to uncompress the tie point variables is described by an interpo The interpolation method must be identified in one of two ways. Either by the **`interpolation_name`** attribute, which takes a string value that contains the method's name, or else by the **`interpolation_description`** attribute, which takes a string value that contains a non-standardized description of the method. These attributes must not be both set. -The valid values of **`interpolation_name`** are given in Appendix . This appendix also describes the interpolation technique and optional interpolation variable attributes for configuring the interpolation process. +The valid values of **`interpolation_name`** are given in Appendix . This appendix describes the interpolation technique for each method, and optional interpolation variable attributes for configuring the interpolation process. If a standardized interpolation name is not given, the interpolation variable must have a **`interpolation_description`** attribute defined instead, containing a description of the non-standardised interpolation (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including a URI, for example). Whilst it is recommended that a standardised interpolation is provided, the alternative is provided to promote interoperability in cases where a well defined user community needs to use sophisticated interpolation techniques that may also be under development. The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). -An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie points. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation equations, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. +An interpolation method may require __interpolation coefficient +variables__ that provide values for interpolation equation terms that +are not satisfied by the tie points. Such terms in the interpolation +equations are associated with interpolation coefficient variables by +the **`interpolation_coefficients`** attribute that takes a string +value, the string being comprised of blank-separated elements of the +form `"term: variable"`, where `term` is a case-insensitive keyword +that defines one of the terms in the interpolation method's +definition, and `variable` is the name of the interpolation +coefficient variable that contains the values for that term. The order +of elements is not significant. A term that is omitted from the +**`interpolation_coefficients`** attribute should be assumed to be +zero. The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"item: variable"`, where `item` is a case-insensitive keyword that identies a configuration item defined in the interpolations method's definition, and `variable` is the name of the interpolation configuration variable that contains the values for that item. The order of elements is not significant. @@ -318,9 +341,25 @@ image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="cente [[compression-by-coordinate-sampling-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds -If a tie point variable has cell boundaries bounds then it must have the attribute **`bounds`** that names the variable that contains the vertices of the cell boundaries. The bounds should be the same as the bounds of the corresponding target grid cells. It is thereforefore likely that tie point cells will be non-contiguous. - -The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the indentifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensionsal tie point variable with four-sided cells then the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. +If reconstituted coordinates have cell boundaries, then the +corresponding tie point variable must also have cell boundaries, +specified by the **`bounds`** attribute that names the variable that +contains the vertices of the cell boundaries. The bounds of a tie +point must be the same as the bounds of the corresponding target grid +cells. It is thereforefore likely that tie point cells will be +non-contiguous. + +The target domain cell bounds are calculated by interpolating each +cell bound position independently of the others, using the same +interpolation method and tie point index variables as used for the +cell coordinates. In this case, though, the tie point index variables +are the indentifying target domain cells to which the bounds apply, +rather than bounds values themselves. For instance, in the case of a +two-dimensionsal tie point variable with four-sided cells, the target +domain cell bounds would be calculated with four separate +interpolations, one for each of the bounds positions (following the +notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, +`(j+1,i+1)`, `(j+1,i-1)`. Note that an implementation of the interpolation method is free to calculate the uncompressed bounds locations in the manner of its choosing, as a long as the result is formally equivalent to each bounds position being treated independently. From 03b1fe18103fb3bf2c79bce51df99326fc1cb56b Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 12 Jan 2021 11:16:01 +0000 Subject: [PATCH 088/249] format --- ch08.adoc | 49 +++++-------------------------------------------- 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 80fb7ee7..a8e0faf6 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -184,18 +184,7 @@ linear time: linear`. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its -corresponding interpolation dimension is defined with a __tie point -index variable__. This contains zero-based indices that relate each -element of a tie point interpolation dimension to its related location -in the corresponding interpolation dimension. The tie point index -variable is a one-dimensional integer variable that must span the tie -point interpolation dimension specified by the -**`tie_point_dimensions`** attribute. The values must be strictly -monotonically increasing within interpolation areas. When two adjacent -values are equal, or differ by one, it indicates the location (in -index space) of an interpolation area boundary relating to an grid -discontinuity (<>). +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas. When two adjacent values are equal, or differ by one, it indicates the location (in index space) of an interpolation area boundary relating to an grid discontinuity (<>). When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. @@ -300,19 +289,7 @@ If a standardized interpolation name is not given, the interpolation variable mu The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). -An interpolation method may require __interpolation coefficient -variables__ that provide values for interpolation equation terms that -are not satisfied by the tie points. Such terms in the interpolation -equations are associated with interpolation coefficient variables by -the **`interpolation_coefficients`** attribute that takes a string -value, the string being comprised of blank-separated elements of the -form `"term: variable"`, where `term` is a case-insensitive keyword -that defines one of the terms in the interpolation method's -definition, and `variable` is the name of the interpolation -coefficient variable that contains the values for that term. The order -of elements is not significant. A term that is omitted from the -**`interpolation_coefficients`** attribute should be assumed to be -zero. +An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie points. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that defines one of the terms in the interpolation method's definition, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"item: variable"`, where `item` is a case-insensitive keyword that identies a configuration item defined in the interpolations method's definition, and `variable` is the name of the interpolation configuration variable that contains the values for that item. The order of elements is not significant. @@ -339,25 +316,9 @@ image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="cente [[compression-by-coordinate-sampling-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds -If reconstituted coordinates have cell boundaries, then the -corresponding tie point variable must also have cell boundaries, -specified by the **`bounds`** attribute that names the variable that -contains the vertices of the cell boundaries. The bounds of a tie -point must be the same as the bounds of the corresponding target grid -cells. It is thereforefore likely that tie point cells will be -non-contiguous. - -The target domain cell bounds are calculated by interpolating each -cell bound position independently of the others, using the same -interpolation method and tie point index variables as used for the -cell coordinates. In this case, though, the tie point index variables -are the indentifying target domain cells to which the bounds apply, -rather than bounds values themselves. For instance, in the case of a -two-dimensionsal tie point variable with four-sided cells, the target -domain cell bounds would be calculated with four separate -interpolations, one for each of the bounds positions (following the -notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, -`(j+1,i+1)`, `(j+1,i-1)`. +If reconstituted coordinates have cell boundaries, then the corresponding tie point variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. The bounds of a tie point must be the same as the bounds of the corresponding target grid cells. It is thereforefore likely that tie point cells will be non-contiguous. + +The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the indentifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensionsal tie point variable with four-sided cells, the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. Note that an implementation of the interpolation method is free to calculate the uncompressed bounds locations in the manner of its choosing, as a long as the result is formally equivalent to each bounds position being treated independently. From cf377b270f84e567598a4b5fb172fbd3406b434e Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 12 Jan 2021 12:14:04 +0000 Subject: [PATCH 089/249] Typos and some minor rewording suggestions (#9) * more text following 2020-11-27 discussions * bounds * tidy * tidy * tidy * tidy * reproducability * offset * indices * indices * indices * super * tie_point_dimension (1) * tie_point_dimension (2) * tie_point_dimension (3) * tie_point_dimension (4) * tie point * tie_point_dimension (5) * corrected interpolation_configuration description * zone/area rewording * zone/area rewording * multiple mappings * multiple mappings * multiple mappings * typos and some minor rewording suggestions * format Co-authored-by: AndersMS <63056394+AndersMS@users.noreply.github.com> --- ch08.adoc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 81d60da6..a8e0faf6 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -73,7 +73,7 @@ This information implies that the salinity field should be uncompressed to an ar [[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Sampling"]] === Lossy Compression by Coordinate Sampling -For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to user of the uncompressed dataset. +For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. @@ -174,7 +174,7 @@ same set of dimensions (see variables corresponding to a particular interpolation dimension must be separately associated with their corresponding interpolation variables according to which corresponding tie interpolation dimension -they span, even if those interpolation variable are the same in each +they span, even if those interpolation variables are the same in each case. For instance, if tie point variables `lat` and `lon` span dimension `tp_dimension1` and `time` spans dimension `tp_dimension2`, and all three are to interpolated according to interpolation variable @@ -184,14 +184,14 @@ linear time: linear`. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas, and two adjacent indices where the value of the second is the equal to the value of the first incremented by one, indicates the location of an interpolation area boundary relating to an grid discontinuity (<>). +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas. When two adjacent values are equal, or differ by one, it indicates the location (in index space) of an interpolation area boundary relating to an grid discontinuity (<>). When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. -Conversely, when tie point variables represent a superset of the uncompressed coordinates, each value of the tie point index variable is the index of the tie point interpolation dimension that corresponds to the corresponding interpolation dimension. This situation could occur when a hierarchy of different resolution representations of data are stored in different data variables. Space can be saved by storing the highest resolution coordinates, and using tie point indices with an interpolation variable to derive the lower resolution coordinates. Such a superset is identifiable by there being a unique interpolation area and the size of the tie point interpolation dimension being strictly greater than than the size of interpolation dimension. - For instance, in example <> the tie point variables represent a subset of the target domain and tie point index variable **`int x_indices(tp_xc)`** contains the indices **`x_indices = 0, 9, 19, 29`** that identify location of the interpolation dimension **`xc`** of size 30. However, in example < the tie point index variables represent a superset of the target domain and so in this case the same indices are identifying locations of the tie point interpolation dimension. +Conversely, when tie point variables represent a superset of the uncompressed coordinates, each value of the tie point index variable is the index of the tie point interpolation dimension that corresponds to the corresponding interpolation dimension. This situation could occur when a hierarchy of different resolution representations of data are stored in different data variables. Space can be saved by storing the highest resolution coordinates, and using tie point indices with an interpolation variable to derive the lower resolution coordinates. Such a superset is identifiable by there being a unique interpolation area and the size of the tie point interpolation dimension being strictly greater than than the size of interpolation dimension. + To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. [[Two-dimensional-tie-point-interpolation]] @@ -283,13 +283,13 @@ The method used to uncompress the tie point variables is described by an interpo The interpolation method must be identified in one of two ways. Either by the **`interpolation_name`** attribute, which takes a string value that contains the method's name, or else by the **`interpolation_description`** attribute, which takes a string value that contains a non-standardized description of the method. These attributes must not be both set. -The valid values of **`interpolation_name`** are given in Appendix . This appendix also describes the interpolation technique and optional interpolation variable attributes for configuring the interpolation process. +The valid values of **`interpolation_name`** are given in Appendix . This appendix describes the interpolation technique for each method, and optional interpolation variable attributes for configuring the interpolation process. If a standardized interpolation name is not given, the interpolation variable must have a **`interpolation_description`** attribute defined instead, containing a description of the non-standardised interpolation (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including a URI, for example). Whilst it is recommended that a standardised interpolation is provided, the alternative is provided to promote interoperability in cases where a well defined user community needs to use sophisticated interpolation techniques that may also be under development. The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). -An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie points. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that represents one of the terms in the interpolation equations, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. +An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie points. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that defines one of the terms in the interpolation method's definition, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"item: variable"`, where `item` is a case-insensitive keyword that identies a configuration item defined in the interpolations method's definition, and `variable` is the name of the interpolation configuration variable that contains the values for that item. The order of elements is not significant. @@ -316,9 +316,9 @@ image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="cente [[compression-by-coordinate-sampling-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds -If a tie point variable has cell boundaries bounds then it must have the attribute **`bounds`** that names the variable that contains the vertices of the cell boundaries. The bounds should be the same as the bounds of the corresponding target grid cells. It is thereforefore likely that tie point cells will be non-contiguous. +If reconstituted coordinates have cell boundaries, then the corresponding tie point variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. The bounds of a tie point must be the same as the bounds of the corresponding target grid cells. It is thereforefore likely that tie point cells will be non-contiguous. -The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the indentifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensionsal tie point variable with four-sided cells then the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. +The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the indentifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensionsal tie point variable with four-sided cells, the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. Note that an implementation of the interpolation method is free to calculate the uncompressed bounds locations in the manner of its choosing, as a long as the result is formally equivalent to each bounds position being treated independently. From 94611db2edf57c169be32dfb1e36211a238b80b7 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 12 Jan 2021 14:55:48 +0100 Subject: [PATCH 090/249] Size of a tie point interpolation dimension --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index a8e0faf6..052faed1 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -136,7 +136,7 @@ To indicate that coordinate interpolation is required, a **`tie_points`** attrib [[compression-by-coordinate-sampling-dimensions,Section 8.3.3, "Interpolation and Non-Interpolation Dimensions"]] ==== Interpolation and Non-Interpolation Dimensions -For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required; and may additionally contain one or more __non-interpolation dimensions__, i.e. those of the target domain for which no coordinate interpolation is required. +For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required; and may additionally contain one or more __non-interpolation dimensions__, i.e. those of the target domain for which no coordinate interpolation is required. The size of a tie point interpolation dimension must be less than or equal to the size of its corresponding interpolation dimension. An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point interpolation dimension related to the interpolation dimension **`xc`**, and **`tp_yc`** is the tie point interpolation dimension related to the interpolation dimension **`yc`**. From ae052e7c0bc1c16bfa88e640ff7d2810be4955a2 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 12 Jan 2021 15:07:54 +0100 Subject: [PATCH 091/249] The creator of the compressed data --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 052faed1..de4e2893 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -73,7 +73,7 @@ This information implies that the salinity field should be uncompressed to an ar [[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Sampling"]] === Lossy Compression by Coordinate Sampling -For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. +For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed data set can control the accuracy of the reconstituted coordinates through the degree of subsambling and the choice of interploation method, see appendix XX. The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. From 83f9ab9b4cdcea938f54f85e7c791259f8d4ed28 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 12 Jan 2021 18:26:07 +0100 Subject: [PATCH 092/249] Typos and proposed rewordings (#11) Typos and proposed rewordings. @davidhassell: let m know if you agree. --- ch08.adoc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index de4e2893..dca99742 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -145,9 +145,9 @@ The presence of non-interpolation dimensions in the tie point variable impacts t [[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.4, "Tie Point Dimensions Attribute"]] ==== Tie Point Dimensions Attribute -Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficient or configuation variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. +Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficients or configuation variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. -An overview of the different dimensions for coordinate interpolation is shown in figure <>. +An overview of the different dimensions for coordinate interpolation is shown in <>. Note that an interpolation zone dimension has, by definition, the same size as the corresponding tie point interpolation dimension, minus the number of interpolation areas. @@ -157,6 +157,7 @@ Note that an interpolation zone dimension has, by definition, the same size as t .Overview of the different dimensions for coordinate interpolation. image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] + A single interpolation dimension may be associated with multiple tie point interpolation dimensions by repeating the interpolation dimension in the **`tie_point_dimensions`** attribute. For instance, @@ -171,9 +172,9 @@ dimensions associated with a given interpolation dimension. Since all tie point variables for a given interpolation variable must span the same set of dimensions (see <>), the tie point -variables corresponding to a particular interpolation dimension must +variables corresponding to a particular set of interpolation dimensions must be separately associated with their corresponding interpolation -variables according to which corresponding tie interpolation dimension +variables according to which corresponding tie point interpolation dimension they span, even if those interpolation variables are the same in each case. For instance, if tie point variables `lat` and `lon` span dimension `tp_dimension1` and `time` spans dimension `tp_dimension2`, @@ -184,7 +185,7 @@ linear time: linear`. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas. When two adjacent values are equal, or differ by one, it indicates the location (in index space) of an interpolation area boundary relating to an grid discontinuity (<>). +The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas. When two adjacent values are equal, or differ by one, it indicates the location (in index space) of an interpolation area boundary relating to a grid discontinuity (<>). When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. From 6c14101af9b0d75c380663ec9c92e7f9686b4012 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 12 Jan 2021 18:32:00 +0100 Subject: [PATCH 093/249] The same interpolation variable may --- ch08.adoc | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index dca99742..f88d0e6d 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -168,19 +168,16 @@ variables for a particular interpolation dimension do not contain the same number of tie points, and therefore define different numbers of interpolation zones, as is the case in <>. A tie point variable must span at most one of the tie point interpolation -dimensions associated with a given interpolation dimension. Since all -tie point variables for a given interpolation variable must span the -same set of dimensions (see -<>), the tie point -variables corresponding to a particular set of interpolation dimensions must -be separately associated with their corresponding interpolation -variables according to which corresponding tie point interpolation dimension -they span, even if those interpolation variables are the same in each -case. For instance, if tie point variables `lat` and `lon` span -dimension `tp_dimension1` and `time` spans dimension `tp_dimension2`, -and all three are to interpolated according to interpolation variable -`linear`, then the **`tie_points`** attribute could be `lat: lon: -linear time: linear`. +dimensions associated with a given interpolation dimension. + +The same interpolation variable may be multiply mapped from the +different sets of tie point variables. For instance, if tie point +variables lat and lon span dimension tp_dimension1 and time spans +dimension tp_dimension2, and all three are to interpolated according +to interpolation variable linear, then the tie_points attribute could +be lat: lon: linear time: linear. In this case is not possible to +simultaneously map all three tie point variables to the linear +interpolation variable because they do not all span the same axes. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices From 57e342cdd0969ec533117ecb2151a06901c0b399 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 12 Jan 2021 18:40:00 +0100 Subject: [PATCH 094/249] Remove supersampling --- ch08.adoc | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index f88d0e6d..6dc57b4a 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -182,15 +182,40 @@ interpolation variable because they do not all span the same axes. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. This contains zero-based indices that relate each element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the **`tie_point_dimensions`** attribute. The values must be strictly monotonically increasing within interpolation areas. When two adjacent values are equal, or differ by one, it indicates the location (in index space) of an interpolation area boundary relating to a grid discontinuity (<>). - -When tie point variables represent a subset of the uncompressed coordinates, each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. - -For instance, in example <> the tie point variables represent a subset of the target domain and tie point index variable **`int x_indices(tp_xc)`** contains the indices **`x_indices = 0, 9, 19, 29`** that identify location of the interpolation dimension **`xc`** of size 30. However, in example < the tie point index variables represent a superset of the target domain and so in this case the same indices are identifying locations of the tie point interpolation dimension. - -Conversely, when tie point variables represent a superset of the uncompressed coordinates, each value of the tie point index variable is the index of the tie point interpolation dimension that corresponds to the corresponding interpolation dimension. This situation could occur when a hierarchy of different resolution representations of data are stored in different data variables. Space can be saved by storing the highest resolution coordinates, and using tie point indices with an interpolation variable to derive the lower resolution coordinates. Such a superset is identifiable by there being a unique interpolation area and the size of the tie point interpolation dimension being strictly greater than than the size of interpolation dimension. - -To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be defined for the data variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable [interpolation_dimension: tie_point_index_variable ...]__". Continuing the above example, specifying that the target dimension **`xc`** and **`yc`** are associated with the tie point index variables **`x_indices`** and **`y_indices`** respectively, could be indicated with **`xc: x_indices yc: y_indices`**. +The relationship between a tie point interpolation dimension and its +corresponding interpolation dimension is defined with a __tie point +index variable__. This contains zero-based indices that relate each +element of a tie point interpolation dimension to its related +location in the corresponding interpolation dimension. The tie point +index variable is a one-dimensional integer variable that must span +the tie point interpolation dimension specified by the +**`tie_point_dimensions`** attribute. The values must be strictly +monotonically increasing within interpolation areas. When two adjacent +values are equal, or differ by one, it indicates the location +(in index space) of an interpolation area boundary relating to a +grid discontinuity (<>). + +Each value of the tie point index variable is the index of the +interpolation dimension that corresponds to the corresponding +tie point interpolation dimension. + +For instance, in example <> +the tie point variables represent a subset of the target domain +and tie point index variable **`int x_indices(tp_xc)`** contains +the indices **`x_indices = 0, 9, 19, 29`** that identify location +of the interpolation dimension **`xc`** of size 30. + +To indicate which tie point index variable applies to each +interpolation dimension, a **`tie_point_indices`** attribute must +be defined for the data variable. This is a string attribute that +maps the interpolation dimensions to the corresponding tie point +index variables. It is a blank-separated list of words of the form +"__interpolation_dimension: tie_point_index_variable +[interpolation_dimension: tie_point_index_variable ...]__". +Continuing the above example, specifying that the target dimension +**`xc`** and **`yc`** are associated with the tie point index +variables **`x_indices`** and **`y_indices`** respectively, could +be indicated with **`xc: x_indices yc: y_indices`**. [[Two-dimensional-tie-point-interpolation]] [caption="Example 8.3. "] From ba3eb6a8dfbcaff1f5384228d9d4a8b8754f8e05 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 12 Jan 2021 18:42:31 +0100 Subject: [PATCH 095/249] Add Appendix J references --- ch08.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 6dc57b4a..47cb8550 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -73,7 +73,7 @@ This information implies that the salinity field should be uncompressed to an ar [[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Sampling"]] === Lossy Compression by Coordinate Sampling -For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed data set can control the accuracy of the reconstituted coordinates through the degree of subsambling and the choice of interploation method, see appendix XX. +For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed data set can control the accuracy of the reconstituted coordinates through the degree of subsambling and the choice of interploation method, see <>. The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. @@ -306,7 +306,7 @@ The method used to uncompress the tie point variables is described by an interpo The interpolation method must be identified in one of two ways. Either by the **`interpolation_name`** attribute, which takes a string value that contains the method's name, or else by the **`interpolation_description`** attribute, which takes a string value that contains a non-standardized description of the method. These attributes must not be both set. -The valid values of **`interpolation_name`** are given in Appendix . This appendix describes the interpolation technique for each method, and optional interpolation variable attributes for configuring the interpolation process. +The valid values of **`interpolation_name`** are given in <>. This appendix describes the interpolation technique for each method, and optional interpolation variable attributes for configuring the interpolation process. If a standardized interpolation name is not given, the interpolation variable must have a **`interpolation_description`** attribute defined instead, containing a description of the non-standardised interpolation (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including a URI, for example). Whilst it is recommended that a standardised interpolation is provided, the alternative is provided to promote interoperability in cases where a well defined user community needs to use sophisticated interpolation techniques that may also be under development. From 210628143eb27548c0da7562195dd336eeec7068 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 12 Jan 2021 19:03:43 +0100 Subject: [PATCH 096/249] Updated --- images/ci_interpolation_coefficients.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/ci_interpolation_coefficients.svg b/images/ci_interpolation_coefficients.svg index 9d663102..1861539f 100644 --- a/images/ci_interpolation_coefficients.svg +++ b/images/ci_interpolation_coefficients.svg @@ -1 +1 @@ -xyDimension (y_interpolation_zone, x_tie_point_interpolation)Example (1, 2) Dimension (y_tie_point_interpolation, x_interpolation_zone,)Example (2, 0) Dimension (y_interpolation_zone, x_interpolation_zone)Example (0, 1) Dimension (x_interpolation_zone,)Example (1) \ No newline at end of file +xyDimension (y_interpolation_zone, x_tie_point_interpolation)Example (1, 2) Dimension (y_tie_point_interpolation, x_interpolation_zone)Example (2, 0) Dimension (y_interpolation_zone, x_interpolation_zone)Example (0, 1) Dimension (x_interpolation_zone)Example (1) \ No newline at end of file From fb2c7b4c10df42fd50df8d17dbe05b249b1c9c07 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 12 Jan 2021 19:09:35 +0100 Subject: [PATCH 097/249] Minor corrections --- ch08.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 47cb8550..28d12a9e 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -332,7 +332,7 @@ Note that the interpolation method is always applied on a per interpolation zone [[ci_interpolation_coefficients, figure 3]] [.text-center] -.Through combination of dimensions, interpolation coefficients and configuration variables may provide values for each interpolation zone, for couples of neighboring interpolation zones or for multiple interpolation zones sharing a boundary. +.Through combination of dimensions, interpolation coefficient and interpolation configuration variables may provide values for each interpolation zone, for couples of neighboring interpolation zones or for multiple interpolation zones sharing a boundary. image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] @@ -346,7 +346,7 @@ The target domain cell bounds are calculated by interpolating each cell bound po Note that an implementation of the interpolation method is free to calculate the uncompressed bounds locations in the manner of its choosing, as a long as the result is formally equivalent to each bounds position being treated independently. [caption="Example 8.5. "] -.Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation flags attributes. +.Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation configuration attributes. ==== ---- dimensions : From 8ef779265507199ef0e16869bca2d3d2bd6101a3 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 13 Jan 2021 14:10:27 +0100 Subject: [PATCH 098/249] Update ch08.adoc --- ch08.adoc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 28d12a9e..1d38002b 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -172,10 +172,10 @@ dimensions associated with a given interpolation dimension. The same interpolation variable may be multiply mapped from the different sets of tie point variables. For instance, if tie point -variables lat and lon span dimension tp_dimension1 and time spans -dimension tp_dimension2, and all three are to interpolated according -to interpolation variable linear, then the tie_points attribute could -be lat: lon: linear time: linear. In this case is not possible to +variables lat and lon span dimension **`tp_dimension1`** and time spans +dimension **`tp_dimension2`**, and all three are to interpolated according +to interpolation variable linear, then the **`tie_points`** attribute could +be **`lat: lon: linear time: linear`**. In this case is not possible to simultaneously map all three tie point variables to the linear interpolation variable because they do not all span the same axes. @@ -201,9 +201,9 @@ tie point interpolation dimension. For instance, in example <> the tie point variables represent a subset of the target domain -and tie point index variable **`int x_indices(tp_xc)`** contains -the indices **`x_indices = 0, 9, 19, 29`** that identify location -of the interpolation dimension **`xc`** of size 30. +and the tie point index variable **`int x_indices(tp_xc)`** contains +the indices **`x_indices = 0, 9, 19, 29`** that identify the location +in the interpolation dimension **`xc`** of size 30. To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must From e9b0c55992b36cd6ed3fbd36537edf4b35eea22c Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 13 Jan 2021 13:50:52 +0000 Subject: [PATCH 099/249] spell check --- ch08.adoc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 1d38002b..f151a18a 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -73,7 +73,7 @@ This information implies that the salinity field should be uncompressed to an ar [[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Sampling"]] === Lossy Compression by Coordinate Sampling -For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed data set can control the accuracy of the reconstituted coordinates through the degree of subsambling and the choice of interploation method, see <>. +For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed dataset can control the accuracy of the reconstituted coordinates through the degree of subsambling and the choice of interpolation method, see <>. The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. @@ -145,7 +145,7 @@ The presence of non-interpolation dimensions in the tie point variable impacts t [[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.4, "Tie Point Dimensions Attribute"]] ==== Tie Point Dimensions Attribute -Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficients or configuation variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. +Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficients or configuration variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. An overview of the different dimensions for coordinate interpolation is shown in <>. @@ -163,7 +163,7 @@ point interpolation dimensions by repeating the interpolation dimension in the **`tie_point_dimensions`** attribute. For instance, interpolation dimension `dimension1` could be mapped to two different tie point interpolation dimensions with `dimension1: tp_dimension1 -dimension1: tp_dimension2`. This is necssary when different tie point +dimension1: tp_dimension2`. This is necessary when different tie point variables for a particular interpolation dimension do not contain the same number of tie points, and therefore define different numbers of interpolation zones, as is the case in <>. A tie point @@ -314,34 +314,34 @@ The definition of the interpolation method, however it is specified, may include An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie points. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that defines one of the terms in the interpolation method's definition, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. -The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"item: variable"`, where `item` is a case-insensitive keyword that identies a configuration item defined in the interpolations method's definition, and `variable` is the name of the interpolation configuration variable that contains the values for that item. The order of elements is not significant. +The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"item: variable"`, where `item` is a case-insensitive keyword that identifies a configuration item defined in the interpolations method's definition, and `variable` is the name of the interpolation configuration variable that contains the values for that item. The order of elements is not significant. The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding interpolation zone dimension, but not both, and may include any of the non-interpolation dimensions. -The interpretation of interpolation coefficent and configuration variables depends on the nature of the dimensions that they span: +The interpretation of interpolation coefficient and configuration variables depends on the nature of the dimensions that they span: * If no tie point interpolation dimensions are spanned, then the variable provides a value for every interpolation zone. This case is akin to values being defined at the centre of interpolation zones. * If at least one dimension is a tie point interpolation dimension, then each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). -In both cases, the implementation of the interpolation method should broadcast an interpolation coefficent or configuration variable along any interpolation zone dimensions that it does not span. +In both cases, the implementation of the interpolation method should broadcast an interpolation coefficient or configuration variable along any interpolation zone dimensions that it does not span. Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the uncompressed coordinates may only access the tie point that define the extent of the of the interpolation zone, as well as any interpolation coefficient and configuration variables defined for the interpolation zone, including its boundaries. [[ci_interpolation_coefficients, figure 3]] [.text-center] -.Through combination of dimensions, interpolation coefficient and interpolation configuration variables may provide values for each interpolation zone, for couples of neighboring interpolation zones or for multiple interpolation zones sharing a boundary. +.Through combination of dimensions, interpolation coefficient and interpolation configuration variables may provide values for each interpolation zone, for couples of neighbouring interpolation zones or for multiple interpolation zones sharing a boundary. image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] [[compression-by-coordinate-sampling-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds -If reconstituted coordinates have cell boundaries, then the corresponding tie point variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. The bounds of a tie point must be the same as the bounds of the corresponding target grid cells. It is thereforefore likely that tie point cells will be non-contiguous. +If reconstituted coordinates have cell boundaries, then the corresponding tie point variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. The bounds of a tie point must be the same as the bounds of the corresponding target grid cells. It is therefore likely that tie point cells will be non-contiguous. -The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the indentifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensionsal tie point variable with four-sided cells, the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. +The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the identifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensional tie point variable with four-sided cells, the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. Note that an implementation of the interpolation method is free to calculate the uncompressed bounds locations in the manner of its choosing, as a long as the result is formally equivalent to each bounds position being treated independently. From 65b9604d04d1eca440f001311de4afb269901085 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 13 Jan 2021 13:57:23 +0000 Subject: [PATCH 100/249] markup style --- ch08.adoc | 82 +++++++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index f151a18a..debff293 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -131,16 +131,16 @@ image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,a [[compression-by-coordinate-sampling-tie-points-attribute, Section 8.3.2, "Tie Points Attribute"]] ==== Tie Points Attribute -To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. +To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables `lat` and `lon` are to be interpolated according to the interpolation variable `bi_linear` could be indicated with `lat: lon: bi_linear`. [[compression-by-coordinate-sampling-dimensions,Section 8.3.3, "Interpolation and Non-Interpolation Dimensions"]] ==== Interpolation and Non-Interpolation Dimensions For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required; and may additionally contain one or more __non-interpolation dimensions__, i.e. those of the target domain for which no coordinate interpolation is required. The size of a tie point interpolation dimension must be less than or equal to the size of its corresponding interpolation dimension. -An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point interpolation dimension related to the interpolation dimension **`xc`**, and **`tp_yc`** is the tie point interpolation dimension related to the interpolation dimension **`yc`**. +An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are `xc = 30` and `yc = 10`, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions `tp_xc = 4` and `tp_yc = 2`. Here, `tp_xc` is the tie point interpolation dimension related to the interpolation dimension `xc`, and `tp_yc` is the tie point interpolation dimension related to the interpolation dimension `yc`. -The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. +The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are `xc = 30` and `yc = 10`, interpolation could be applied in the `xc` dimension only, based on tie point variables of the dimensions `tp_xc = 4` and `yc = 10`. The interpolation in the `xc` dimension would then be repeated for each of the 10 indices of the `yc` dimension. [[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.4, "Tie Point Dimensions Attribute"]] ==== Tie Point Dimensions Attribute @@ -168,54 +168,54 @@ variables for a particular interpolation dimension do not contain the same number of tie points, and therefore define different numbers of interpolation zones, as is the case in <>. A tie point variable must span at most one of the tie point interpolation -dimensions associated with a given interpolation dimension. - -The same interpolation variable may be multiply mapped from the -different sets of tie point variables. For instance, if tie point -variables lat and lon span dimension **`tp_dimension1`** and time spans -dimension **`tp_dimension2`**, and all three are to interpolated according -to interpolation variable linear, then the **`tie_points`** attribute could -be **`lat: lon: linear time: linear`**. In this case is not possible to -simultaneously map all three tie point variables to the linear +dimensions associated with a given interpolation dimension. + +The same interpolation variable may be multiply mapped from the +different sets of tie point variables. For instance, if tie point +variables lat and lon span dimension `tp_dimension1` and time spans +dimension `tp_dimension2`, and all three are to interpolated according +to interpolation variable linear, then the **`tie_points`** attribute +could be `lat: lon: linear time: linear`. In this case is not possible +to simultaneously map all three tie point variables to the linear interpolation variable because they do not all span the same axes. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its -corresponding interpolation dimension is defined with a __tie point -index variable__. This contains zero-based indices that relate each -element of a tie point interpolation dimension to its related -location in the corresponding interpolation dimension. The tie point -index variable is a one-dimensional integer variable that must span -the tie point interpolation dimension specified by the -**`tie_point_dimensions`** attribute. The values must be strictly -monotonically increasing within interpolation areas. When two adjacent -values are equal, or differ by one, it indicates the location -(in index space) of an interpolation area boundary relating to a -grid discontinuity (<>). +The relationship between a tie point interpolation dimension and its +corresponding interpolation dimension is defined with a __tie point +index variable__. This contains zero-based indices that relate each +element of a tie point interpolation dimension to its related location +in the corresponding interpolation dimension. The tie point index +variable is a one-dimensional integer variable that must span the tie +point interpolation dimension specified by the +**`tie_point_dimensions`** attribute. The values must be strictly +monotonically increasing within interpolation areas. When two adjacent +values are equal, or differ by one, it indicates the location (in +index space) of an interpolation area boundary relating to a grid +discontinuity (<>). Each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. -For instance, in example <> -the tie point variables represent a subset of the target domain -and the tie point index variable **`int x_indices(tp_xc)`** contains -the indices **`x_indices = 0, 9, 19, 29`** that identify the location -in the interpolation dimension **`xc`** of size 30. - -To indicate which tie point index variable applies to each -interpolation dimension, a **`tie_point_indices`** attribute must -be defined for the data variable. This is a string attribute that -maps the interpolation dimensions to the corresponding tie point -index variables. It is a blank-separated list of words of the form -"__interpolation_dimension: tie_point_index_variable -[interpolation_dimension: tie_point_index_variable ...]__". -Continuing the above example, specifying that the target dimension -**`xc`** and **`yc`** are associated with the tie point index -variables **`x_indices`** and **`y_indices`** respectively, could -be indicated with **`xc: x_indices yc: y_indices`**. +For instance, in example <> +the tie point variables represent a subset of the target domain and +the tie point index variable `int x_indices(tp_xc)` contains the +indices `x_indices = 0, 9, 19, 29` that identify the location in the +interpolation dimension `xc` of size 30. + +To indicate which tie point index variable applies to each +interpolation dimension, a **`tie_point_indices`** attribute must be +defined for the data variable. This is a string attribute that maps +the interpolation dimensions to the corresponding tie point index +variables. It is a blank-separated list of words of the form +"__interpolation_dimension: tie_point_index_variable +[interpolation_dimension: tie_point_index_variable ...]__". +Continuing the above example, specifying that the target dimension +`xc` and `yc` are associated with the tie point index variables +`x_indices` and `y_indices` respectively, could be indicated with `xc: +x_indices yc: y_indices`. [[Two-dimensional-tie-point-interpolation]] [caption="Example 8.3. "] From c1680d7a03d2383057706faad0b64f63158e62e0 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 13 Jan 2021 14:07:28 +0000 Subject: [PATCH 101/249] example formatting --- ch08.adoc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index debff293..c22ccff2 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -345,6 +345,7 @@ The target domain cell bounds are calculated by interpolating each cell bound po Note that an implementation of the interpolation method is free to calculate the uncompressed bounds locations in the manner of its choosing, as a long as the result is formally equivalent to each bounds position being treated independently. +[[VIIRS]] [caption="Example 8.5. "] .Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation configuration attributes. ==== @@ -457,7 +458,7 @@ variables: ==== [caption="Example 8.6. "] -.Example demonstrating the combination of grid mapping and coordinate interpolation with time as a non-interpolation dimension. The projection coordinates are 2-D, but are only linearly interpolated in one of their dimensions - the one which is given by the tie_point_indices attribute. +.Combining a grid mapping and coordinate interpolation, with time as a non-interpolation dimension. ==== ---- dimensions: @@ -515,5 +516,14 @@ variables: Temperature:tie_points = "lat: lon: spherical_bilinear y: x: linear" ; Temperature:tie_point_indices = "y: y_indices x: x_indices" ; ---- + +This example demonstrates the use of multiple interpolation variables, +the reusability of the interpolation variable between data variables +of different dimensions and the use of the interpolation coefficients +and interpolation configuration attributes. The projection coordinates +are two-dimensional, but are only linearly interpolated in one of +their dimensions - the one which is given by the +**`tie_point_indices`** attribute. + ==== From f46dea89d7bcd9a9c7bcef0946e96b3e5a733bed Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 13 Jan 2021 14:08:24 +0000 Subject: [PATCH 102/249] example formatting --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index c22ccff2..6b3826a2 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -166,7 +166,7 @@ tie point interpolation dimensions with `dimension1: tp_dimension1 dimension1: tp_dimension2`. This is necessary when different tie point variables for a particular interpolation dimension do not contain the same number of tie points, and therefore define different numbers of -interpolation zones, as is the case in <>. A tie point +interpolation zones, as is the case in <>. A tie point variable must span at most one of the tie point interpolation dimensions associated with a given interpolation dimension. From 53b59829d170c09dfcf988b89a5ba788043b84fe Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 13 Jan 2021 14:12:43 +0000 Subject: [PATCH 103/249] example formatting --- ch08.adoc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 6b3826a2..9e0b3bf8 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -166,7 +166,7 @@ tie point interpolation dimensions with `dimension1: tp_dimension1 dimension1: tp_dimension2`. This is necessary when different tie point variables for a particular interpolation dimension do not contain the same number of tie points, and therefore define different numbers of -interpolation zones, as is the case in <>. A tie point +interpolation zones, as is the case in <>. A tie point variable must span at most one of the tie point interpolation dimensions associated with a given interpolation dimension. @@ -199,7 +199,7 @@ Each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. -For instance, in example <> +For instance, in example <> the tie point variables represent a subset of the target domain and the tie point index variable `int x_indices(tp_xc)` contains the indices `x_indices = 0, 9, 19, 29` that identify the location in the @@ -217,7 +217,7 @@ Continuing the above example, specifying that the target dimension `x_indices` and `y_indices` respectively, could be indicated with `xc: x_indices yc: y_indices`. -[[Two-dimensional-tie-point-interpolation]] +[[example-Two-dimensional-tie-point-interpolation]] [caption="Example 8.3. "] .Two-dimensional tie point interpolation ==== @@ -260,6 +260,7 @@ data: ---- ==== +[[example-1d-interpolation-of-2d-domain]] [caption="Example 8.4. "] .One-dimensional tie point interpolation of two-dimensional domain. ==== @@ -345,7 +346,7 @@ The target domain cell bounds are calculated by interpolating each cell bound po Note that an implementation of the interpolation method is free to calculate the uncompressed bounds locations in the manner of its choosing, as a long as the result is formally equivalent to each bounds position being treated independently. -[[VIIRS]] +[[example-VIIRS]] [caption="Example 8.5. "] .Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation configuration attributes. ==== @@ -457,6 +458,7 @@ variables: ---- ==== +[[example-grid-mapping-and-interpolation-with-time-not-interpolated]] [caption="Example 8.6. "] .Combining a grid mapping and coordinate interpolation, with time as a non-interpolation dimension. ==== From 4a20c40a8c4ce890bb8edf6905d94301c872f6b1 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 13 Jan 2021 14:19:03 +0000 Subject: [PATCH 104/249] example formatting --- ch08.adoc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 9e0b3bf8..03e988a6 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -348,7 +348,8 @@ Note that an implementation of the interpolation method is free to calculate the [[example-VIIRS]] [caption="Example 8.5. "] -.Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation configuration attributes. +.Multiple interpolation variables with interpolation coefficients and +configuration attributes. ==== ---- dimensions : @@ -456,6 +457,12 @@ variables: char time_interpolation ; time_interpolation : interpolation_name = "bi_linear" ; ---- + +This example demonstrates the use of multiple interpolation variables, +the reusability of the interpolation variable between data variables +of different dimensions and the use of the interpolation coefficients +and interpolation configuration attributes. + ==== [[example-grid-mapping-and-interpolation-with-time-not-interpolated]] @@ -519,13 +526,9 @@ variables: Temperature:tie_point_indices = "y: y_indices x: x_indices" ; ---- -This example demonstrates the use of multiple interpolation variables, -the reusability of the interpolation variable between data variables -of different dimensions and the use of the interpolation coefficients -and interpolation configuration attributes. The projection coordinates -are two-dimensional, but are only linearly interpolated in one of -their dimensions - the one which is given by the -**`tie_point_indices`** attribute. +In this the projection coordinates are two-dimensional, but are only +linearly interpolated in one of their dimensions - the one which is +given by the **`tie_point_indices`** attribute. ==== From c323728c6b35edc054d96e7bafb37bc924cc8525 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 13 Jan 2021 15:22:45 +0000 Subject: [PATCH 105/249] example formatting, style, and spelling (#13) * more text following 2020-11-27 discussions * bounds * tidy * tidy * tidy * tidy * reproducability * offset * indices * indices * indices * super * tie_point_dimension (1) * tie_point_dimension (2) * tie_point_dimension (3) * tie_point_dimension (4) * tie point * tie_point_dimension (5) * corrected interpolation_configuration description * zone/area rewording * zone/area rewording * multiple mappings * multiple mappings * multiple mappings * typos and some minor rewording suggestions * format * spell check * markup style * example formatting * example formatting * example formatting * example formatting Co-authored-by: AndersMS <63056394+AndersMS@users.noreply.github.com> --- ch08.adoc | 125 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 55 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 1d38002b..03e988a6 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -73,7 +73,7 @@ This information implies that the salinity field should be uncompressed to an ar [[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Sampling"]] === Lossy Compression by Coordinate Sampling -For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed data set can control the accuracy of the reconstituted coordinates through the degree of subsambling and the choice of interploation method, see <>. +For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed dataset can control the accuracy of the reconstituted coordinates through the degree of subsambling and the choice of interpolation method, see <>. The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. @@ -131,21 +131,21 @@ image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,a [[compression-by-coordinate-sampling-tie-points-attribute, Section 8.3.2, "Tie Points Attribute"]] ==== Tie Points Attribute -To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables **`lat`** and **`lon`** are to be interpolated according to the interpolation variable **`bi_linear`** could be indicated with **`lat: lon: bi_linear`**. +To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables `lat` and `lon` are to be interpolated according to the interpolation variable `bi_linear` could be indicated with `lat: lon: bi_linear`. [[compression-by-coordinate-sampling-dimensions,Section 8.3.3, "Interpolation and Non-Interpolation Dimensions"]] ==== Interpolation and Non-Interpolation Dimensions For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required; and may additionally contain one or more __non-interpolation dimensions__, i.e. those of the target domain for which no coordinate interpolation is required. The size of a tie point interpolation dimension must be less than or equal to the size of its corresponding interpolation dimension. -An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions **`tp_xc = 4`** and **`tp_yc = 2`**. Here, **`tp_xc`** is the tie point interpolation dimension related to the interpolation dimension **`xc`**, and **`tp_yc`** is the tie point interpolation dimension related to the interpolation dimension **`yc`**. +An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are `xc = 30` and `yc = 10`, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions `tp_xc = 4` and `tp_yc = 2`. Here, `tp_xc` is the tie point interpolation dimension related to the interpolation dimension `xc`, and `tp_yc` is the tie point interpolation dimension related to the interpolation dimension `yc`. -The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are **`xc = 30`** and **`yc = 10`**, interpolation could be applied in the **`xc`** dimension only, based on tie point variables of the dimensions **`tp_xc = 4`** and **`yc = 10`**. The interpolation in the **`xc`** dimension would then be repeated for each of the 10 indices of the **`yc`** dimension. +The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are `xc = 30` and `yc = 10`, interpolation could be applied in the `xc` dimension only, based on tie point variables of the dimensions `tp_xc = 4` and `yc = 10`. The interpolation in the `xc` dimension would then be repeated for each of the 10 indices of the `yc` dimension. [[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.4, "Tie Point Dimensions Attribute"]] ==== Tie Point Dimensions Attribute -Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficients or configuation variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. +Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficients or configuration variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. An overview of the different dimensions for coordinate interpolation is shown in <>. @@ -163,61 +163,61 @@ point interpolation dimensions by repeating the interpolation dimension in the **`tie_point_dimensions`** attribute. For instance, interpolation dimension `dimension1` could be mapped to two different tie point interpolation dimensions with `dimension1: tp_dimension1 -dimension1: tp_dimension2`. This is necssary when different tie point +dimension1: tp_dimension2`. This is necessary when different tie point variables for a particular interpolation dimension do not contain the same number of tie points, and therefore define different numbers of -interpolation zones, as is the case in <>. A tie point +interpolation zones, as is the case in <>. A tie point variable must span at most one of the tie point interpolation -dimensions associated with a given interpolation dimension. - -The same interpolation variable may be multiply mapped from the -different sets of tie point variables. For instance, if tie point -variables lat and lon span dimension **`tp_dimension1`** and time spans -dimension **`tp_dimension2`**, and all three are to interpolated according -to interpolation variable linear, then the **`tie_points`** attribute could -be **`lat: lon: linear time: linear`**. In this case is not possible to -simultaneously map all three tie point variables to the linear +dimensions associated with a given interpolation dimension. + +The same interpolation variable may be multiply mapped from the +different sets of tie point variables. For instance, if tie point +variables lat and lon span dimension `tp_dimension1` and time spans +dimension `tp_dimension2`, and all three are to interpolated according +to interpolation variable linear, then the **`tie_points`** attribute +could be `lat: lon: linear time: linear`. In this case is not possible +to simultaneously map all three tie point variables to the linear interpolation variable because they do not all span the same axes. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its -corresponding interpolation dimension is defined with a __tie point -index variable__. This contains zero-based indices that relate each -element of a tie point interpolation dimension to its related -location in the corresponding interpolation dimension. The tie point -index variable is a one-dimensional integer variable that must span -the tie point interpolation dimension specified by the -**`tie_point_dimensions`** attribute. The values must be strictly -monotonically increasing within interpolation areas. When two adjacent -values are equal, or differ by one, it indicates the location -(in index space) of an interpolation area boundary relating to a -grid discontinuity (<>). +The relationship between a tie point interpolation dimension and its +corresponding interpolation dimension is defined with a __tie point +index variable__. This contains zero-based indices that relate each +element of a tie point interpolation dimension to its related location +in the corresponding interpolation dimension. The tie point index +variable is a one-dimensional integer variable that must span the tie +point interpolation dimension specified by the +**`tie_point_dimensions`** attribute. The values must be strictly +monotonically increasing within interpolation areas. When two adjacent +values are equal, or differ by one, it indicates the location (in +index space) of an interpolation area boundary relating to a grid +discontinuity (<>). Each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding tie point interpolation dimension. -For instance, in example <> -the tie point variables represent a subset of the target domain -and the tie point index variable **`int x_indices(tp_xc)`** contains -the indices **`x_indices = 0, 9, 19, 29`** that identify the location -in the interpolation dimension **`xc`** of size 30. - -To indicate which tie point index variable applies to each -interpolation dimension, a **`tie_point_indices`** attribute must -be defined for the data variable. This is a string attribute that -maps the interpolation dimensions to the corresponding tie point -index variables. It is a blank-separated list of words of the form -"__interpolation_dimension: tie_point_index_variable -[interpolation_dimension: tie_point_index_variable ...]__". -Continuing the above example, specifying that the target dimension -**`xc`** and **`yc`** are associated with the tie point index -variables **`x_indices`** and **`y_indices`** respectively, could -be indicated with **`xc: x_indices yc: y_indices`**. - -[[Two-dimensional-tie-point-interpolation]] +For instance, in example <> +the tie point variables represent a subset of the target domain and +the tie point index variable `int x_indices(tp_xc)` contains the +indices `x_indices = 0, 9, 19, 29` that identify the location in the +interpolation dimension `xc` of size 30. + +To indicate which tie point index variable applies to each +interpolation dimension, a **`tie_point_indices`** attribute must be +defined for the data variable. This is a string attribute that maps +the interpolation dimensions to the corresponding tie point index +variables. It is a blank-separated list of words of the form +"__interpolation_dimension: tie_point_index_variable +[interpolation_dimension: tie_point_index_variable ...]__". +Continuing the above example, specifying that the target dimension +`xc` and `yc` are associated with the tie point index variables +`x_indices` and `y_indices` respectively, could be indicated with `xc: +x_indices yc: y_indices`. + +[[example-Two-dimensional-tie-point-interpolation]] [caption="Example 8.3. "] .Two-dimensional tie point interpolation ==== @@ -260,6 +260,7 @@ data: ---- ==== +[[example-1d-interpolation-of-2d-domain]] [caption="Example 8.4. "] .One-dimensional tie point interpolation of two-dimensional domain. ==== @@ -314,39 +315,41 @@ The definition of the interpolation method, however it is specified, may include An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie points. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that defines one of the terms in the interpolation method's definition, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. -The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"item: variable"`, where `item` is a case-insensitive keyword that identies a configuration item defined in the interpolations method's definition, and `variable` is the name of the interpolation configuration variable that contains the values for that item. The order of elements is not significant. +The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"item: variable"`, where `item` is a case-insensitive keyword that identifies a configuration item defined in the interpolations method's definition, and `variable` is the name of the interpolation configuration variable that contains the values for that item. The order of elements is not significant. The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding interpolation zone dimension, but not both, and may include any of the non-interpolation dimensions. -The interpretation of interpolation coefficent and configuration variables depends on the nature of the dimensions that they span: +The interpretation of interpolation coefficient and configuration variables depends on the nature of the dimensions that they span: * If no tie point interpolation dimensions are spanned, then the variable provides a value for every interpolation zone. This case is akin to values being defined at the centre of interpolation zones. * If at least one dimension is a tie point interpolation dimension, then each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). -In both cases, the implementation of the interpolation method should broadcast an interpolation coefficent or configuration variable along any interpolation zone dimensions that it does not span. +In both cases, the implementation of the interpolation method should broadcast an interpolation coefficient or configuration variable along any interpolation zone dimensions that it does not span. Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the uncompressed coordinates may only access the tie point that define the extent of the of the interpolation zone, as well as any interpolation coefficient and configuration variables defined for the interpolation zone, including its boundaries. [[ci_interpolation_coefficients, figure 3]] [.text-center] -.Through combination of dimensions, interpolation coefficient and interpolation configuration variables may provide values for each interpolation zone, for couples of neighboring interpolation zones or for multiple interpolation zones sharing a boundary. +.Through combination of dimensions, interpolation coefficient and interpolation configuration variables may provide values for each interpolation zone, for couples of neighbouring interpolation zones or for multiple interpolation zones sharing a boundary. image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] [[compression-by-coordinate-sampling-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds -If reconstituted coordinates have cell boundaries, then the corresponding tie point variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. The bounds of a tie point must be the same as the bounds of the corresponding target grid cells. It is thereforefore likely that tie point cells will be non-contiguous. +If reconstituted coordinates have cell boundaries, then the corresponding tie point variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. The bounds of a tie point must be the same as the bounds of the corresponding target grid cells. It is therefore likely that tie point cells will be non-contiguous. -The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the indentifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensionsal tie point variable with four-sided cells, the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. +The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the identifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensional tie point variable with four-sided cells, the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. Note that an implementation of the interpolation method is free to calculate the uncompressed bounds locations in the manner of its choosing, as a long as the result is formally equivalent to each bounds position being treated independently. +[[example-VIIRS]] [caption="Example 8.5. "] -.Example demonstrating the use of multiple interpolation variables, the reusability of the interpolation variable between data variables of different dimensions and the use of the interpolation coefficients and interpolation configuration attributes. +.Multiple interpolation variables with interpolation coefficients and +configuration attributes. ==== ---- dimensions : @@ -454,10 +457,17 @@ variables: char time_interpolation ; time_interpolation : interpolation_name = "bi_linear" ; ---- + +This example demonstrates the use of multiple interpolation variables, +the reusability of the interpolation variable between data variables +of different dimensions and the use of the interpolation coefficients +and interpolation configuration attributes. + ==== +[[example-grid-mapping-and-interpolation-with-time-not-interpolated]] [caption="Example 8.6. "] -.Example demonstrating the combination of grid mapping and coordinate interpolation with time as a non-interpolation dimension. The projection coordinates are 2-D, but are only linearly interpolated in one of their dimensions - the one which is given by the tie_point_indices attribute. +.Combining a grid mapping and coordinate interpolation, with time as a non-interpolation dimension. ==== ---- dimensions: @@ -515,5 +525,10 @@ variables: Temperature:tie_points = "lat: lon: spherical_bilinear y: x: linear" ; Temperature:tie_point_indices = "y: y_indices x: x_indices" ; ---- + +In this the projection coordinates are two-dimensional, but are only +linearly interpolated in one of their dimensions - the one which is +given by the **`tie_point_indices`** attribute. + ==== From 51ec3d6c317e0d53d0b640886cdb61f62b8a2d7b Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 13 Jan 2021 18:14:20 +0000 Subject: [PATCH 106/249] minor typesetting --- ch08.adoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 03e988a6..f0b91ba3 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -174,10 +174,11 @@ The same interpolation variable may be multiply mapped from the different sets of tie point variables. For instance, if tie point variables lat and lon span dimension `tp_dimension1` and time spans dimension `tp_dimension2`, and all three are to interpolated according -to interpolation variable linear, then the **`tie_points`** attribute -could be `lat: lon: linear time: linear`. In this case is not possible -to simultaneously map all three tie point variables to the linear -interpolation variable because they do not all span the same axes. +to interpolation variable `linear`, then the **`tie_points`** +attribute could be `lat: lon: linear time: linear`. In this case is +not possible to simultaneously map all three tie point variables to +the linear interpolation variable because they do not all span the +same axes. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices @@ -348,8 +349,7 @@ Note that an implementation of the interpolation method is free to calculate the [[example-VIIRS]] [caption="Example 8.5. "] -.Multiple interpolation variables with interpolation coefficients and -configuration attributes. +.Multiple interpolation variables with interpolation coefficients and configuration attributes. ==== ---- dimensions : From 2af40b9991f3c2d2f6f808bfe5e5bea2bb148d8b Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 14 Jan 2021 11:34:25 +0000 Subject: [PATCH 107/249] Minor typesetting (#14) * more text following 2020-11-27 discussions * bounds * tidy * tidy * tidy * tidy * reproducability * offset * indices * indices * indices * super * tie_point_dimension (1) * tie_point_dimension (2) * tie_point_dimension (3) * tie_point_dimension (4) * tie point * tie_point_dimension (5) * corrected interpolation_configuration description * zone/area rewording * zone/area rewording * multiple mappings * multiple mappings * multiple mappings * typos and some minor rewording suggestions * format * spell check * markup style * example formatting * example formatting * example formatting * example formatting * minor typesetting Co-authored-by: AndersMS <63056394+AndersMS@users.noreply.github.com> --- ch08.adoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 03e988a6..f0b91ba3 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -174,10 +174,11 @@ The same interpolation variable may be multiply mapped from the different sets of tie point variables. For instance, if tie point variables lat and lon span dimension `tp_dimension1` and time spans dimension `tp_dimension2`, and all three are to interpolated according -to interpolation variable linear, then the **`tie_points`** attribute -could be `lat: lon: linear time: linear`. In this case is not possible -to simultaneously map all three tie point variables to the linear -interpolation variable because they do not all span the same axes. +to interpolation variable `linear`, then the **`tie_points`** +attribute could be `lat: lon: linear time: linear`. In this case is +not possible to simultaneously map all three tie point variables to +the linear interpolation variable because they do not all span the +same axes. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] ==== Tie Point Indices @@ -348,8 +349,7 @@ Note that an implementation of the interpolation method is free to calculate the [[example-VIIRS]] [caption="Example 8.5. "] -.Multiple interpolation variables with interpolation coefficients and -configuration attributes. +.Multiple interpolation variables with interpolation coefficients and configuration attributes. ==== ---- dimensions : From 2e9379cf66281b6937d5cf6266eab63062396eb1 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 14 Jan 2021 12:38:15 +0100 Subject: [PATCH 108/249] Change order of sections --- appj.adoc | 64 +++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/appj.adoc b/appj.adoc index 780a038e..9f8d0d55 100644 --- a/appj.adoc +++ b/appj.adoc @@ -3,6 +3,38 @@ [appendix] == Coordinate Sampling + + +=== Interpolation Methods + +==== General definitions + +[[interpolation, figure J.1]] +[.text-center] +.Interpolation indices and interpolation parameter s +image::images/ci_interpolation.svg[,100%,pdfwidth=50vw,align="center"] + +Two Tie Points, A and B, and a reconstituted point P, are shown in In he Figure J.1. The indices of A nd B in the tie point interpolation dimension are n and n+1 respectively. The corresponding indices in the interpolation dimension, i~A~ and i~B~, are stored in the tie point index variable, index(n) and index(n+1). + +A real number interpolation parameter s, running from 0.0 to 1.0 between tie point A and B, is introduced for the purpose of teh interpolation calculations. For the point P to be reconstituted, the interpolation parameter is + +s~P~ = (i~P~ - i~A~)/(i~B~ - i~A~) + +The coordinate values at the tie points A and B are c~A~ and c~B~ and are stored in the tie point coordinate variables. For the point P, the coordinate value can be reconstituted as c~P~ applying the selected interpolation method. + +==== Linear + +[cols="6,15"] +|=============== +| Name | **`interpolation_name = "linear"`** +| Description/Features | General purpose one dimensional linear interpolation +| Definition | c~P~ = (1 - s~P~) c~A~ + s~P~ c~B~ +| Interpolation Coefficients | None +| Interpolation Configuration | None +|=============== + + + === Steps for Generation of Tie Points @@ -108,35 +140,3 @@ | <> |=============== - - - -=== Interpolation Methods - -==== General definitions - -[[interpolation, figure J.1]] -[.text-center] -.Interpolation indices and interpolation parameter s -image::images/ci_interpolation.svg[,100%,pdfwidth=50vw,align="center"] - -Two Tie Points, A and B, and a reconstituted point P, are shown in In he Figure J.1. The indices of A nd B in the tie point interpolation dimension are n and n+1 respectively. The corresponding indices in the interpolation dimension, i~A~ and i~B~, are stored in the tie point index variable, index(n) and index(n+1). - -A real number interpolation parameter s, running from 0.0 to 1.0 between tie point A and B, is introduced for the purpose of teh interpolation calculations. For the point P to be reconstituted, the interpolation parameter is - -s~P~ = (i~P~ - i~A~)/(i~B~ - i~A~) - -The coordinate values at the tie points A and B are c~A~ and c~B~ and are stored in the tie point coordinate variables. For the point P, the coordinate value can be reconstituted as c~P~ applying the selected interpolation method. - -==== Linear - -[cols="6,15"] -|=============== -| Name | **`interpolation_name = "linear"`** -| Description/Features | General purpose one dimensional linear interpolation -| Definition | c~P~ = (1 - s~P~) c~A~ + s~P~ c~B~ -| Interpolation Coefficients | None -| Interpolation Configuration | None -|=============== - - From 112cb8b0c1be55ccf7b2041755f66a2ff1d74d67 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 26 Jan 2021 12:57:23 +0100 Subject: [PATCH 109/249] Large update of Appendix J --- appj.adoc | 177 ++++++++++++++++++++++++++++++++---- images/ci_interpolation.svg | 2 +- 2 files changed, 160 insertions(+), 19 deletions(-) diff --git a/appj.adoc b/appj.adoc index 9f8d0d55..aad691ac 100644 --- a/appj.adoc +++ b/appj.adoc @@ -1,41 +1,182 @@ - [[appendix-coordinate-sampling, Appendix J, Coordinate Sampling]] [appendix] == Coordinate Sampling +The definitions and guidance given here allow an application to compress an existing data set using coordinate sampling, while letting the creator of the compressed dataset control the accuracy of the reconstituted coordinates through the degree of subsambling and the choice of interpolation method. +Futhermore, the definitions given here allow an application to uncompress coordinate and auxiliary coordinate variables that have been compressed using coordinate sampling. The key element of this process is the reconstitution of the full resolution coordinates in the domain of the data by interpolation between the lower resolution coordinates, the tie points, stored in the compressed dataset. -=== Interpolation Methods +=== General Definitions + +The target domain is segmented into smaller interpolation zones as described in <>. -==== General definitions +For one-dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone; for two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes; etc. Examples of one-dimensional and two-dimensional interpolation zones are shown in <>. -[[interpolation, figure J.1]] + +[[interpolation, figure 1]] [.text-center] -.Interpolation indices and interpolation parameter s +.Tie Points A, B, C and D, interpolation indices i, interpolation variables s and coordinate values c for one and two dimensional interpolation. image::images/ci_interpolation.svg[,100%,pdfwidth=50vw,align="center"] -Two Tie Points, A and B, and a reconstituted point P, are shown in In he Figure J.1. The indices of A nd B in the tie point interpolation dimension are n and n+1 respectively. The corresponding indices in the interpolation dimension, i~A~ and i~B~, are stored in the tie point index variable, index(n) and index(n+1). -A real number interpolation parameter s, running from 0.0 to 1.0 between tie point A and B, is introduced for the purpose of teh interpolation calculations. For the point P to be reconstituted, the interpolation parameter is +The coordinate interpolation methods are named to indicate the number of dimensions they interpolate as well as the type of interpolation provided. For example, the interpolation method named `linear` provides linear interpolation in one dimension and the method named `bi_linear` provides linear interpolation in two dimensions. Equivalently, the interpolation method named `quadratic` provides quadratic interpolation in one dimension and the interpolation method named `bi_quadratic` provides quadratic interpolation in two dimensions. + +When an interpolation method is referred to as linear or quadratic, it means that the method is linear or quadratic in the indices of the interpolation dimensions. + +For convenience, an interpolation variable `s` is introduced, calculated as a function of the index in the target domain of the coordinate value to be reconstituted. In the case of one dimensional interpolation the interpolation variable is computed as + +`s = (i - ia)/(ib - ia)` + +where `ia` and `ib` are the indices in the target domain of the tie points `A` and `B` and `i` is the index in the target domain of the coordinate value to be reconstituted. + +Note that the value of `s` varies from `0.0` at the tie point `A` to `1.0` at tie point `B`. For example, if `ia = 100` and `ib = 110` and the index in the target domain of the coordinate value to be reconstituted is `i = 105`, then `s = (105 - 100)/(110 - 100) = 0.5`. + +In the case of two dimensional interpolation, the two interpolation variables are equivalently computed as + +`s1 = (i1 - ia1)/(ib1 - ia1)` + +`s2 = (i2 - ia2)/(id2 - ia2)` -s~P~ = (i~P~ - i~A~)/(i~B~ - i~A~) +where `ia1` and `ib1` are the first dimension indices in the target domain of the tie points `A` and `B`, `ia2` and `id2` are the second dimension indices in the target domain of the tie points `A` and `D` and the indices `i1` and `i2` are the first and second dimension indices in the target domain of the coordinate value to be reconstituted. -The coordinate values at the tie points A and B are c~A~ and c~B~ and are stored in the tie point coordinate variables. For the point P, the coordinate value can be reconstituted as c~P~ applying the selected interpolation method. +For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables the interpolation method can be applied independently for each interpolation zone, making it possible to parallelize the computational process. -==== Linear + +=== Interpolation Methods + +==== Linear Interpolation [cols="6,15"] |=============== | Name | **`interpolation_name = "linear"`** -| Description/Features | General purpose one dimensional linear interpolation -| Definition | c~P~ = (1 - s~P~) c~A~ + s~P~ c~B~ -| Interpolation Coefficients | None -| Interpolation Configuration | None +| Description | General purpose one dimensional linear interpolation method +| Interpolation Coefficient terms | None +| Interpolation Configuration terms | `coordinate_conversion` of dimension (interpolation_zone_1) +| Coordinate Compression Calculations | Calculate `coordinate_conversion`, see <> +| Coordinate Uncompression Calculations | + Calculation of interpolated coordinate `c` at `s` + + `c = (1 - s)*c_a + s*c_b` |=============== +==== Bilinear Interpolation + +[cols="6,15"] +|=============== +| Name | **`interpolation_name = "bi_linear"`** +| Description | General purpose two dimensional linear interpolation method +| Interpolation Coefficient terms | None +| Interpolation Configuration terms | `coordinate_conversion` of dimension (interpolation_zone_1, interpolation_zone_2) +| Coordinate Compression Calculations | Calculate `coordinate_conversion`, see <> +| Coordinate Uncompression Calculations | + Calculation of interpolated coordinate `c` at `(s1, s2)` + + `c_ab = (1 - s1)*c_a + s1*c_b` + + `c_dc = (1 - s1)*c_d + s1*c_c` + + `c = (1 - s2)*c_ab + s2*c_dc` + +|=============== + + +==== Quadratic Interpolation + +[cols="6,15"] +|=============== +| Name | **`interpolation_name = "quadratic"`** +| Description | General purpose one dimensional quadratic interpolation method +| Interpolation Coefficient terms | +`exp1` of dimension (interpolation_zone_1, tie_point_interpolation_1) + +`align1` of dimension (interpolation_zone_1, tie_point_interpolation_1) + +| Interpolation Configuration terms | `coordinate_conversion` of dimension (interpolation_zone_1), see <> +| Coordinate Compression Calculations | Calculate `coordinate_conversion`, see <> + +Calculate `exp1` and `align1` TO BE WRITTEN +| Coordinate Uncompression Calculations | + Calculation of interpolated coordinate `c` at `s` + + `sq = s + s * (1 - s) * exp1` + + `c = (1 - sq) * c_a + sq * c_b` +|=============== + +==== Biquadratic Interpolation + +[cols="6,15"] +|=============== +| Name | **`interpolation_name = "bi_quadratic"`** +| Description | General purpose two dimensional quadratic interpolation method +| Interpolation Coefficient terms | +`exp1` of dimension (interpolation_zone_1, tie_point_interpolation_1) + +`align1` of dimension (interpolation_zone_1, tie_point_interpolation_1) + +`exp2` of dimension (tie_point_interpolation_2, interpolation_zone_2) + +`align2` of dimension (tie_point_interpolation_2, interpolation_zone_2) +| Interpolation Configuration terms | `coordinate_conversion` of dimension (interpolation_zone_1, interpolation_zone_2) +| Coordinate Compression Calculations | Calculate `coordinate_conversion`, see <> + +Calculate `exp1`, `align1`, `exp2` and `align2` TO BE WRITTEN +| Coordinate Uncompression Calculations | + Calculation of interpolated coordinate `c` at `(s1, s2)` + + `sq1 = s1 + s1 * (1 - s1) * exp1 + s2 * (1 - s2) * align2` + + `sq2 = s2 + s2 * (1 - s2) * exp2 + s1 * (1 - s1) * align1` + + `c_ab = (1 - sq1)*c_a + sq1*c_b` + + `c_dc = (1 - sq1)*c_d + sq1*c_c` + + `c = (1 - sq2)*c_ab + sq2*c_dc` +|=============== + + +[[coordinate_conversion]] +=== Coordinate Conversion + + +==== Geographic Coordinates + +[cols="6,15"] +|=============== +| Applicable to Pairs of Coordinates with Standard Names | `(latitude, longitude)` +| Pre-Interpolation Coordinate Conversion | +For `coordinate_conversion = xyz` use + +`x=cos⁡(latitude) * cos⁡(longitude)` + +`y=cos⁡(latitude) * sin⁡(longitude)` + +`z=sin⁡(latitude)` + +For `coordinate_conversion = xy` use + +`x=cos⁡(latitude) * cos⁡(longitude)` + +`y=cos⁡(latitude) * sin⁡(longitude)` + + +| Post-Interpolation Coordinate Conversion | +For `coordinate_conversion = xyz` use + +`longitude = atan2(y, x)` + +`latitude = atan2(z, sqrt(x * x + y * y))` + +For `coordinate_conversion = xy` use + +`longitude = atan2(y, x)` + +`latitude = sign(z) * atan(sqrt(x * x + y * y))` + + +|=============== + +==== Spherical Coordinates + +[cols="6,15"] +|=============== +| Applicable to Pairs of Coordinates with Standard Names | +`(sensor_azimuth_angle, sensor_zenith_angle)` + +`(solar_azimuth_angle, solar_zenith_angle)` + +`(lunar_azimuth_angle, lunar_zenith_angle)` (TO DO: propose as standard name) + +`(platform_azimuth_angle, platform_zenith_angle)` + +| Pre-Interpolation Coordinate Conversion | +For `coordinate_conversion = xyz` use + +`x=sin⁡(zenith) * sin⁡(azimuth)` + +`y=sin⁡(zenith) * cos⁡(azimuth)` + +`z=cos⁡(zenith)` + + +For `coordinate_conversion = xy` use + +`x=sin⁡(zenith) * sin⁡(azimuth)` + +`y=sin⁡(zenith) * cos⁡(azimuth)` + + +| Post-Interpolation Coordinate Conversion | +For `coordinate_conversion = xyz` use + +`azimuth = atan2(y, x)` + +`zenith = atan2(sqrt(x * x + y * y), z)` + +For `coordinate_conversion = xy` use + +`azimuth = atan2(y, x)` + +`zenith = sign(z) * atan(sqrt(x * x + y * y))` + + +|=============== -=== Steps for Generation of Tie Points +=== Coordinate Compression Steps [[compression-by-coordinate-sampling-generation-of-tie-points]] @@ -63,7 +204,7 @@ The coordinate values at the tie points A and B are c~A~ and c~B~ and are stored | 5 | For each set of the interpolation dimensions, identify the interpolation areas and select the interpolation zones and the tie points, taking into account the required coordinate reconstitution accuracy when selecting the density of tie points. -| <> +| <> | 6 | For each of the interpolation dimensions, add the interpolation dimension, the corresponding tie point interpolation dimension and, if required by the selected interpolation method, its corresponding interpolation zone dimension to the **`tie_point_dimensions`** attribute of the data variable. @@ -88,7 +229,7 @@ The coordinate values at the tie points A and B are c~A~ and c~B~ and are stored |=============== -=== Steps for Reconstitution of Coordinate and Auxillary Coordinate Variables +=== Coordinate Uncompression Steps [[compression-by-coordinate-sampling-reconstitution-of-coordinates]] @@ -117,7 +258,7 @@ The coordinate values at the tie points A and B are c~A~ and c~B~ and are stored | 5 | For each of the interpolation dimensions, identify pairs of adjacent indices in the tie point index variable with index values differing by more than one, each index pair defining the extend of an interpolation zone in that dimension. A full interpolation zone is defined by one such index pair per interpolation dimension, with combinations of one index from each pair defining the interpolation zone tie points. -| <> +| <> | 6 | From the **`tie_points`** attribute of the data variable, identify the interpolation variable for the coordinate and auxillary coordinate variable subset. From the **`interpolation_name`** attribute of the interpolation variable, identify the interpolation method. diff --git a/images/ci_interpolation.svg b/images/ci_interpolation.svg index 8598b5a0..f2a97fcd 100644 --- a/images/ci_interpolation.svg +++ b/images/ci_interpolation.svg @@ -1 +1 @@ -n+1TiePoint Interpolation DimensionnInterpolation DimensioniB= index(n+1)ReconstitutedPoint (Interpolation Dimension)ABiA= index(n)iP0.0……1.0sPcPcAcBCoordinateValuesInterpolation ParameterTiePoints and ReconstitutedPointP \ No newline at end of file +c_bc_aAB0.0……1.0sc_ac_bACDB...01.0...s20.0……1.0s1ibiaiccib1ia1i1id2ia2i2c_cc_dc_dcc_ab \ No newline at end of file From 55e18dbb849b3d95cfa350c4dfa6752eed8175e8 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 26 Jan 2021 13:01:30 +0100 Subject: [PATCH 110/249] Changed link name for section 8.3.1 --- ch08.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index f0b91ba3..37cbea36 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -83,7 +83,7 @@ The metadata that define the interpolation formula and its inputs are complete, The data variable coordinate interpolation attributes may also be used on a domain variable (domain-variables) with the same effect. -[[compression-by-coordinate-sampling-tie-points, Section 8.3.1, "Tie Points and Interpolation Zones"]] +[[compression-by-coordinate-sampling-tie-points-and-interpolation-zones, Section 8.3.1, "Tie Points and Interpolation Zones"]] ==== Tie Points and Interpolation Zones Reconstitution of the uncompressed coordinate and auxiliary coordinate @@ -194,7 +194,7 @@ point interpolation dimension specified by the monotonically increasing within interpolation areas. When two adjacent values are equal, or differ by one, it indicates the location (in index space) of an interpolation area boundary relating to a grid -discontinuity (<>). +discontinuity (<>). Each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding From 085caed2350eac9e6a6bbddcc5ec0862ad2392fe Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 8 Feb 2021 23:05:16 +0100 Subject: [PATCH 111/249] First darft for team revciew --- appj.adoc | 270 +++++++++++++++++++++++------------- images/ci_interpolation.svg | 2 +- 2 files changed, 173 insertions(+), 99 deletions(-) diff --git a/appj.adoc b/appj.adoc index aad691ac..e63db255 100644 --- a/appj.adoc +++ b/appj.adoc @@ -6,7 +6,7 @@ The definitions and guidance given here allow an application to compress an exis Futhermore, the definitions given here allow an application to uncompress coordinate and auxiliary coordinate variables that have been compressed using coordinate sampling. The key element of this process is the reconstitution of the full resolution coordinates in the domain of the data by interpolation between the lower resolution coordinates, the tie points, stored in the compressed dataset. -=== General Definitions +=== Common Definitions and Notation The target domain is segmented into smaller interpolation zones as described in <>. @@ -25,7 +25,7 @@ When an interpolation method is referred to as linear or quadratic, it means tha For convenience, an interpolation variable `s` is introduced, calculated as a function of the index in the target domain of the coordinate value to be reconstituted. In the case of one dimensional interpolation the interpolation variable is computed as -`s = (i - ia)/(ib - ia)` +`s = s(i) = (i - ia)/(ib - ia)` where `ia` and `ib` are the indices in the target domain of the tie points `A` and `B` and `i` is the index in the target domain of the coordinate value to be reconstituted. @@ -33,16 +33,68 @@ Note that the value of `s` varies from `0.0` at the tie point `A` to `1.0` at ti In the case of two dimensional interpolation, the two interpolation variables are equivalently computed as -`s1 = (i1 - ia1)/(ib1 - ia1)` + -`s2 = (i2 - ia2)/(id2 - ia2)` +`s1 = s1(i) = (i1 - ia1)/(ib1 - ia1)` + +`s2 = s2(i) = (i2 - ia2)/(id2 - ia2)` -where `ia1` and `ib1` are the first dimension indices in the target domain of the tie points `A` and `B`, `ia2` and `id2` are the second dimension indices in the target domain of the tie points `A` and `D` and the indices `i1` and `i2` are the first and second dimension indices in the target domain of the coordinate value to be reconstituted. +where `ia1` and `ib1` are the first dimension indices in the target domain of the tie points `A` and `B` respectively, `ia2` and `id2` are the second dimension indices in the target domain of the tie points `A` and `D respectively and the indices `i1` and `i2` are the first and second dimension indices respectively in the target domain of the coordinate value to be reconstituted. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables the interpolation method can be applied independently for each interpolation zone, making it possible to parallelize the computational process. +The following notation is used: + +For a vector `v`, `v.x` , `x.y` and `v.z` refer to the three coordinates of that vector. + +For a coordinate pair `ll`, `ll.lat` and `ll.lon` refer to the latitude and longitude coordinates. + +[[coordinate_conversion]] +==== Common conversions and formulas + +[cols="8,12"] +|=============== +| Description | Formula + +| Conversion from geocentric `(latitude, longitude)` to cartesian vector `(x, y, z)` | `(x, y, z) = fll2xyz(ll) = (cos⁡(ll.lat)*cos⁡(ll.lon), cos⁡(ll.lat)*sin⁡(ll.lon), sin⁡(ll.lat))` + +| Conversion from cartesian vector `(x, y, z)` to geocentric `(latitude, longitude)`| `(lat, lon) = fxyz2ll(v) = (atan2(v.y, v.x), atan2(z, sqrt(v.x * v.x + v.y * v.y))` + + +| Conversion from `(azimuth, zenith)` angles to cartesian vector `(x, y, z)` | `(x, y, z) = faz2xyz(az) = (sin⁡(az.zenith) * sin⁡(az.azimuth), sin⁡(az.zenith) * cos⁡(az.azimuth), cos⁡(az.zenith))` + +| Conversion from cartesian vector `(x, y, z)` to `(azimuth, zenith)` angles | `(azimuth, zenith) = fxyz2az(v) = (atan2(y, x), atan2(sqrt(x * x + y * y), z)` + + +| Calculate the interpolation coefficient `c` for quadratic interpolation of one coordinate in one dimension between tie points `a` and `b` from given coordinate value `u` at `s` | `c = fc1(ua, ub, u, s) = ((u - (1 - s)*ua - s*ub)/((1 - s)*s)` + +| Calculate the interpolation coefficients `(c.1, c.2)` for quadratic interpolation of two coordinates in one dimension between tie points `a` and `b` from given coordinate values `(u.1, u.2)` at `s` | `(c.1, c.2) = fc2(ua, ub, u, s) = (fc1(ua.1, ub.1, u.1, s), fc1(ua.2, ub.2, u.2, s))` + +| Calculate the interpolation coefficients `(c.1, c.2, c.3)` for quadratic interpolation of three coordinates in one dimension between tie points `a` and `b` from given coordinate values `(u.1, u.2, u.3)` at `s` | `(c.1, c.2, c.3) = fc3(ua, ub, u, s) = (fc1(ua.1, ub.1, u.1, s), fc1(ua.2, ub.2, u.2, s), fc1(ua.3, ub.3, u.3, s))` + + +| Calculate the linear interpolation value of one coordinate `u` in one dimension between tie points `a` and `b` | `u = fl1(ua, ub, s) = (1 - s)*ua + s*u2`; + + +| Calculate the quadratic interpolation value of one coordinate `u` in one dimension between tie points `a` and `b` with interpolation coefficient `c` | `u = fq1(ua, ub, c, s) = (1 - s)*ua + (1 - s)*s1*c + s*u2`; + + +| Calculate the quadratic interpolation values of two coordinates `(u.1, u.2)` in one dimension between tie points `a` and `b` with interpolation coefficients `(c.1, c.2)` | `(u.1, u.2) = fq2(ua, ub, c, s) = (fq1(ua.1, ua.2, c.1, s), fq1(ua.1, ua.2, c.1, s))``; + + +| Calculate the quadratic interpolation values of three coordinates `(u.1, u.2, u.3)` in one dimension between tie points `a` and `b` with interpolation coefficients `(c.1, c.2, c.3)` | `(u.1, u.2, u.3) = fq3(ua, ub, c, s) = (fq1(ua.1, ub.1, c.1, s), fq1(ua.2, ub.2, c.2, s), fq1(ua.3 ub.3, c.3, s))`; + + +| Vector Sum | `(x, y, z) = va + vb = (va.x + vb.x, va.y + vb.y, va.z + vb.z)` + +| Vector Difference | `(x, y, z) = va - vb = (va.x - vb.x, va.y - vb.y, va.z - vb.z)` + + +| Vector Cross Product | `(x, y, z) = fcross(va, vb) = (va.y*vb.z - va.z*vb.y, va.z*vb.x - vva.zx*b.z, va.x*vb.y - va.y*vb.x)` + + +| Normalised Vector | `(x, y, z) = norm(v) = (v.x, v.y, v.z) / sqrt (v.x*v.x + v.y*v.y + v.z*v.z)` + + +| Vector Dot Product | `d = fdot(va, vb) = va.x*vb.x + va.y*vb.y, va.z*vb.z` + +| Vector from ce, ca | `(x, y, z) = fp(va, vb, ce, ca) = norm(0.5*fplus(va, vb) + ce*fminus(vb, va) + ca*fcross(vb, va))` + +| ce, ca from vector | `(ce, ca) = fceca(va, vb, vp) = (r/(f*f) * fdot(ve, vf), r/(m*m) * fdot(ve, vm))` + +where + +`vn = 0.5*(va + vb); n*n = fdot(n, n)`; + +`ve = vp - vn`; + +`r = 1/(1 + fdot(ve, vn)/(n*n))`; + +`vf = vb - va; f*f = 4*(1- n*n)`; + +`vm = fcross(vb, va); m*m = 8*n*n*(1 - n*n)`; + +|=============== + +[[interpolation_methods]] === Interpolation Methods +In the following `i1` and `i2` are indices in the interpolation dimensions, `tp1` and `tp2` are indices in the tie point interpolation dimensions and `iz1` and `iz2` are indices in the interpolation zone dimensions, see <>. + + + ==== Linear Interpolation [cols="6,15"] @@ -50,11 +102,11 @@ For the reconstitution of the uncompressed coordinate and auxiliary coordinate v | Name | **`interpolation_name = "linear"`** | Description | General purpose one dimensional linear interpolation method | Interpolation Coefficient terms | None -| Interpolation Configuration terms | `coordinate_conversion` of dimension (interpolation_zone_1) -| Coordinate Compression Calculations | Calculate `coordinate_conversion`, see <> +| Interpolation Configuration terms | None +| Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | - Calculation of interpolated coordinate `c` at `s` + - `c = (1 - s)*c_a + s*c_b` + Calculation of interpolated coordinate `u` at `s = s(i)` + + `u = fl1(u(tp1), u(tp1+1), s(i))` |=============== ==== Bilinear Interpolation @@ -62,15 +114,16 @@ For the reconstitution of the uncompressed coordinate and auxiliary coordinate v [cols="6,15"] |=============== | Name | **`interpolation_name = "bi_linear"`** -| Description | General purpose two dimensional linear interpolation method +| Description | General purpose two dimensional linear interpolation method | Interpolation Coefficient terms | None -| Interpolation Configuration terms | `coordinate_conversion` of dimension (interpolation_zone_1, interpolation_zone_2) -| Coordinate Compression Calculations | Calculate `coordinate_conversion`, see <> +| Interpolation Configuration terms | None +| Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | - Calculation of interpolated coordinate `c` at `(s1, s2)` + - `c_ab = (1 - s1)*c_a + s1*c_b` + - `c_dc = (1 - s1)*c_d + s1*c_c` + - `c = (1 - s2)*c_ab + s2*c_dc` + Calculation of interpolated coordinate `u` at `(s1, s2) = (s1(i1), s2(i2))` + +`uab = fl1(u(tp2, tp1), u(tp2, tp1+1), s1(i);` + +`ucd = fl1(u(tp2+1, tp1), u(tp2+1, tp1+1), s1(i));` + +`u = fl1(uab, ucd, s2(i));` + + |=============== @@ -80,105 +133,124 @@ For the reconstitution of the uncompressed coordinate and auxiliary coordinate v [cols="6,15"] |=============== | Name | **`interpolation_name = "quadratic"`** -| Description | General purpose one dimensional quadratic interpolation method -| Interpolation Coefficient terms | -`exp1` of dimension (interpolation_zone_1, tie_point_interpolation_1) + -`align1` of dimension (interpolation_zone_1, tie_point_interpolation_1) + -| Interpolation Configuration terms | `coordinate_conversion` of dimension (interpolation_zone_1), see <> -| Coordinate Compression Calculations | Calculate `coordinate_conversion`, see <> + -Calculate `exp1` and `align1` TO BE WRITTEN +| Description | General purpose one dimensional quadratic interpolation method for one coordinate +| Interpolation Coefficient terms | `c1` of dimension (interpolation_zone_1) +| Interpolation Configuration terms | None +| Coordinate Compression Calculations | Calculate interpolation coefficient `c1` + +TO BE WRITTEN (main element is use of c = fc1(ua, ub, u, s), see <> ) | Coordinate Uncompression Calculations | - Calculation of interpolated coordinate `c` at `s` + - `sq = s + s * (1 - s) * exp1` + - `c = (1 - sq) * c_a + sq * c_b` + Calculation of interpolated coordinate `u` at `s = s(i)`: + +`u = fq2(x(tp1), x(tp1+1), c1(iz1), s(i));` |=============== -==== Biquadratic Interpolation +==== Quadratic Interpolation of geographic coordinates [cols="6,15"] |=============== -| Name | **`interpolation_name = "bi_quadratic"`** -| Description | General purpose two dimensional quadratic interpolation method -| Interpolation Coefficient terms | -`exp1` of dimension (interpolation_zone_1, tie_point_interpolation_1) + -`align1` of dimension (interpolation_zone_1, tie_point_interpolation_1) + -`exp2` of dimension (tie_point_interpolation_2, interpolation_zone_2) + -`align2` of dimension (tie_point_interpolation_2, interpolation_zone_2) -| Interpolation Configuration terms | `coordinate_conversion` of dimension (interpolation_zone_1, interpolation_zone_2) -| Coordinate Compression Calculations | Calculate `coordinate_conversion`, see <> + -Calculate `exp1`, `align1`, `exp2` and `align2` TO BE WRITTEN -| Coordinate Uncompression Calculations | - Calculation of interpolated coordinate `c` at `(s1, s2)` + - `sq1 = s1 + s1 * (1 - s1) * exp1 + s2 * (1 - s2) * align2` + - `sq2 = s2 + s2 * (1 - s2) * exp2 + s1 * (1 - s1) * align1` + - `c_ab = (1 - sq1)*c_a + sq1*c_b` + - `c_dc = (1 - sq1)*c_d + sq1*c_c` + - `c = (1 - sq2)*c_ab + sq2*c_dc` -|=============== +| Name | **`interpolation_name = "quadratic_geo"`** +| Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude. + +Requires a coordinate pair with `standard_name` `latitude` and `longitude`. +Support to be added for coordinate pairs with `standard_name`: + +`(sensor_azimuth_angle, sensor_zenith_angle)` + +`(solar_azimuth_angle, solar_zenith_angle)` + +`(lunar_azimuth_angle, lunar_zenith_angle)` (TO DO: propose as standard name) + +`(platform_azimuth_angle, platform_zenith_angle)` -[[coordinate_conversion]] -=== Coordinate Conversion +Support to be added for coordinate pairs with `standard_name`: + +`(sensor_azimuth_angle, sensor_zenith_angle)` + +`(solar_azimuth_angle, solar_zenith_angle)` + +`(lunar_azimuth_angle, lunar_zenith_angle)` (TO DO: propose as standard name) + +`(platform_azimuth_angle, platform_zenith_angle)` -==== Geographic Coordinates - -[cols="6,15"] -|=============== -| Applicable to Pairs of Coordinates with Standard Names | `(latitude, longitude)` -| Pre-Interpolation Coordinate Conversion | -For `coordinate_conversion = xyz` use + -`x=cos⁡(latitude) * cos⁡(longitude)` + -`y=cos⁡(latitude) * sin⁡(longitude)` + -`z=sin⁡(latitude)` + -For `coordinate_conversion = xy` use + -`x=cos⁡(latitude) * cos⁡(longitude)` + -`y=cos⁡(latitude) * sin⁡(longitude)` + - -| Post-Interpolation Coordinate Conversion | -For `coordinate_conversion = xyz` use + -`longitude = atan2(y, x)` + -`latitude = atan2(z, sqrt(x * x + y * y))` + -For `coordinate_conversion = xy` use + -`longitude = atan2(y, x)` + -`latitude = sign(z) * atan(sqrt(x * x + y * y))` + - -|=============== +| Interpolation Coefficient terms | +`c11, c12` of dimension `(tie_point_interpolation_2, interpolation_zone_1)` TBC + +| Interpolation Configuration terms | `interpolation_zone_flags` of dimension `(tie_point_interpolation_2, interpolation_zone_1)` and `flag_meanings = "location_use_cartesian sensor_direction_use_cartesian solar_direction_use_cartesian lunar_direction_use_cartesian"` +| Coordinate Compression Calculations | +Calculate interpolation coefficients `(c11, c12)` + +TO BE WRITTEN (main element is use of function (ce, ca) = fceca(va, vb, vp), see <> ) + +Calculate `interpolation_zone_flags` + +TO BE WRITTEN (main element is check for proximity to North Pole or South Pole where interpolation must be done in cartesian coordinates) + +| Coordinate Uncompression Calculations | +For each tie point, calculate from the latitude and longitude coordinates `ll` the position vector `vtp`: + +`vtp(tp2, tp1) = fll2xyz(ll(tp2, tp1));` + +For each interpolation coefficient pair `(c11, c12)` with its two neighbouring position vectors, calculate the the vector v1 + +`v1(tp2, iz1) = fp( vtp(tp2, tp1), vtp(tp2, tp1+1), c11(tp2, iz1), c12(tp2, iz1));` + +Convert the vector to latitude, longitude: + +`ll1(tp2, iz1) = fxyz2ll(v1(tp2, iz1));` + +Calculate the interpolation coefficients for use when interpolating directly in (lat, lon): + +`llc1(tp2, iz1) = fc2(ll(tp2, tp1), ll1(tp2, iz1), ll(tp2, tp1+1));` + +Calculate the interpolation coefficients for use when interpolating in (x, y, z): + +`vc1(tp2, iz1) = fc3(vtp(tp2, tp1), x1(tp2, iz1), vtp(tp2, tp1+1));` + +For each point `(s1, s2) = (s1(i1), s2(i2))` in interpolation zone (iz2, iz1) with tie point A at (tp2, tp1), calculate interpolated coordinate value `ll(i2, i1) = (lat(i2, i1), lon(i2, i1)):` + +If `interpolation_zone_flags(tp2, iz1)` is equal to `location_use_cartesian`: + +`v = fq3(vtp(tp2, tp1), vtp(tp2, tp1+1), vc1(tp2, iz1), s1(i);` + +`ll(i2, i1) = fxyz2ll(v(i2, i1));` + +else: + +`ll = fq2(ll(tp2, tp1), ll(tp2, tp1+1), llc1(tp2, iz1), s1(i);` + +|=============== -==== Spherical Coordinates + +==== Biquadratic Interpolation of geographic coordinates [cols="6,15"] |=============== -| Applicable to Pairs of Coordinates with Standard Names | +| Name | **`interpolation_name = "bi_quadratic_geo"`** +| Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude. + +Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + +Support to be added for coordinate pairs with `standard_name`: + `(sensor_azimuth_angle, sensor_zenith_angle)` + `(solar_azimuth_angle, solar_zenith_angle)` + `(lunar_azimuth_angle, lunar_zenith_angle)` (TO DO: propose as standard name) + `(platform_azimuth_angle, platform_zenith_angle)` -| Pre-Interpolation Coordinate Conversion | -For `coordinate_conversion = xyz` use + -`x=sin⁡(zenith) * sin⁡(azimuth)` + -`y=sin⁡(zenith) * cos⁡(azimuth)` + -`z=cos⁡(zenith)` + - -For `coordinate_conversion = xy` use + -`x=sin⁡(zenith) * sin⁡(azimuth)` + -`y=sin⁡(zenith) * cos⁡(azimuth)` + - -| Post-Interpolation Coordinate Conversion | -For `coordinate_conversion = xyz` use + -`azimuth = atan2(y, x)` + -`zenith = atan2(sqrt(x * x + y * y), z)` + -For `coordinate_conversion = xy` use + -`azimuth = atan2(y, x)` + -`zenith = sign(z) * atan(sqrt(x * x + y * y))` + - -|=============== - +| Interpolation Coefficient terms | +`c11, c12` of dimension `(tie_point_interpolation_2, interpolation_zone_1)` + +`c21, c22` of dimension `(interpolation_zone_2, tie_point_interpolation_1)` + +`c31, c32` of dimension `(interpolation_zone_2, interpolation_zone_1)` + +| Interpolation Configuration terms | `interpolation_zone_flags` of dimension `(iz2, iz1)` and `flag_meanings = "location_use_cartesian sensor_direction_use_cartesian solar_direction_use_cartesian lunar_direction_use_cartesian"` +| Coordinate Compression Calculations | +Calculate interpolation coefficients `(c11, c12)`, `(c21, c22)`, `(c31, c32)` + +TO BE WRITTEN (main element is use of function (ce, ca) = fceca(va, vb, vp), see <> ) + +Calculate `interpolation_zone_flags` + +TO BE WRITTEN (main element is check for proximity to North Pole or South Pole where interpolation must be done in cartesian coordinates) + +| Coordinate Uncompression Calculations | +For each tie point, calculate from the latitude and longitude coordinates `ll` the position vector `vtp`: + +`vtp(tp2, tp1) = fll2xyz(ll(tp2, tp1));` + +For each interpolation coefficient pair `(c11, c12)`, `(c21, c22)`, `(c31, c32)` with its two neighbouring position vectors, calculate the the vector v1, v2, v3 respectively + +`v1(tp2, iz1) = fp( vtp(tp2, tp1), vtp(tp2, tp1+1), c11(tp2, iz1), c12(tp2, iz1));` + +`v2(iz2, tp1) = fp( vtp(tp2, tp1), vtp(tp2+1, tp1), c21(iz2, tp1), c22(iz2, tp1));` + +`v3(iz2, iz1) = fp( v2(iz2, tp1), v2(iz2, tp1+1), c31(iz2, iz1), c32(iz2, iz1));` + +Convert the three vectors to latitude, longitude: + +`ll1(tp2, iz1) = fxyz2ll(v1(tp2, iz1));` + +`ll2(iz2, tp1) = fxyz2ll(x2(iz2, tp1));` + +`ll3(iz2, iz1) = fxyz2ll(x3(iz2, iz1));` + +Calculate the interpolation coefficients for use when interpolating directly in (lat, lon): + +`llc1(tp2, iz1) = fc2(ll(tp2, tp1), ll1(tp2, iz1), ll(tp2, tp1+1));` + +`llc2(iz2, tp1) = fc2(ll(tp2, tp1), ll2(iz2, tp1), ll(tp2+1, tp1));` + +`llc3(iz2, iz1) = fc2(ll(tp2, tp1), ll3(iz2, iz1), ll(tp2, tp1+1));` + +Calculate the interpolation coefficients for use when interpolating in (x, y, z): + +`vc1(tp2, iz1) = fc3(vtp(tp2, tp1), x1(tp2, iz1), vtp(tp2, tp1+1));` + +`vc2(iz2, tp1) = fc3(vtp(tp2, tp1), x2(iz2, tp1), vtp(tp2+1, tp1));` + +`vc3(tp2, iz1) = fc3(v2(tp2, tp1), v3(tp2, iz1), v2(tp2, tp1+1));` + +For each point `(s1, s2) = (s1(i1), s2(i2))` in interpolation zone (iz2, iz1) with tie point A at (tp2, tp1), calculate interpolated coordinate value `ll(i2, i1) = (lat(i2, i1), lon(i2, i1)):` + +If `interpolation_zone_flags(iz2, iz1)` is equal to `location_use_cartesian`: + +`vab = fq3(vtp(tp2, tp1), vtp(tp2, tp1+1), vc1(tp2, iz1), s1(i);` + +`vcd = fq3(vtp(tp2+1, tp1), vtp(tp2+1, tp1+1), vc1(tp2+1, iz1), s1(i));` + +`vc = fq3(vc2(iz2, tp1), vc2(iz2, tp1+1), vc3(iz2, iz1), s1(i));` + +`v = fq3(vab, vcd, vc, s2(i));` + +`ll(i2, i1) = fxyz2ll(v(i2, i1));` + +else: + +`llab = fq2(ll(tp2, tp1), ll(tp2, tp1+1), llc1(tp2, iz1), s1(i);` + +`llcd = fq2(ll(tp2+1, tp1), ll(tp2+1, tp1+1), llc1(tp2+1, iz1), s1(i));` + +`llc = fq2(llc2(iz2, tp1), llc2(iz2, tp1+1), llc3(iz2, iz1), s1(i));` + +`ll = fq2(llab, llcd, llc, s2(i));` + +|=============== === Coordinate Compression Steps - [[compression-by-coordinate-sampling-generation-of-tie-points]] .Generation of Tie Point Variables and Interpolation Variables [options="header",cols="1,16,6",caption="Table J.1. "] @@ -223,8 +295,9 @@ For `coordinate_conversion = xy` use + | <> | 10 -| Finally, if required by the selected interpolation method, follow the steps defined for the method in Appendix J to create any required interpolation coefficients variables and interpolation configuration variables. As relevant, create the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes and populate them with the interpolation coefficients variables and interpolation configuration variables respectively. -| <> +| Finally, if required by the selected interpolation method, follow the steps defined for the method in <> to create any required interpolation coefficients variables and interpolation configuration variables. As relevant, create the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes and populate them with the interpolation coefficients variables and interpolation configuration variables respectively. +| <> + +<> |=============== @@ -269,13 +342,14 @@ For `coordinate_conversion = xy` use + | <> | 8 -| For each of the tie point coordinate and auxillary coordinate variables, create the corresponding target coordinate variable. For each interpolation zone, apply the interpolation method to reconstitute the target domain coordinate values and store these in the target domain coordinate variables. Repeat this step for each combination of indices of the non-interpolation dimensions. -| <> +| For each of the tie point coordinate and auxillary coordinate variables, create the corresponding target coordinate variable. For each interpolation zone, apply the interpolation method, as described in <>, to reconstitute the target domain coordinate values and store these in the target domain coordinate variables. Repeat this step for each combination of indices of the non-interpolation dimensions. +| <> + +<> | 9 | For each of the tie point coordinate and auxillary coordinate variables having a **`bounds`** attribute, add the **`bounds`** attribute to the target coordinate variable and create the target domain bounds variable. For each interpolation zone, apply the interpolation method to reconstitute the target domain bound values and store these in the target domain bound variables. Repeat this step for each combination of indices of the non-interpolation dimensions. | <> - + | 10 | If auxiliary coordinate variables have been reconstituted, then, if not already present, add a **`coordinates`** attribute to the data variable and add to the attribute the list of the names of the reconstituted auxiliary coordinate variables. | <> diff --git a/images/ci_interpolation.svg b/images/ci_interpolation.svg index f2a97fcd..3eb4dc19 100644 --- a/images/ci_interpolation.svg +++ b/images/ci_interpolation.svg @@ -1 +1 @@ -c_bc_aAB0.0……1.0sc_ac_bACDB...01.0...s20.0……1.0s1ibiaiccib1ia1i1id2ia2i2c_cc_dc_dcc_ab \ No newline at end of file +ubuaAB0.0……1.0suaubACDB...01.0...s20.0……1.0s1ibiaiuuib1ia1i1id2ia2i2ucududcuabtp1+1tp1tp2+1tp2tp1+1tp1 \ No newline at end of file From 93c3182d1743358695489500ee40dcd79de8be4c Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 10 Feb 2021 15:26:25 +0000 Subject: [PATCH 112/249] interpolation_parameters --- ch08.adoc | 65 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 37cbea36..9d6e2bc7 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -314,23 +314,56 @@ If a standardized interpolation name is not given, the interpolation variable mu The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). -An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie points. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that defines one of the terms in the interpolation method's definition, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. - -The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"item: variable"`, where `item` is a case-insensitive keyword that identifies a configuration item defined in the interpolations method's definition, and `variable` is the name of the interpolation configuration variable that contains the values for that item. The order of elements is not significant. - -The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. - -The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding interpolation zone dimension, but not both, and may include any of the non-interpolation dimensions. - -The interpretation of interpolation coefficient and configuration variables depends on the nature of the dimensions that they span: - -* If no tie point interpolation dimensions are spanned, then the variable provides a value for every interpolation zone. This case is akin to values being defined at the centre of interpolation zones. +The interpolation variable attribute **`interpolation_parameters`** +may be used to provide extra information to the interpolation +process. This attribute names __interpolation parameter variables__ +that provide values for coefficent terms in the interpolation +equation, or for non-equation terms that configure the interpolation +process. The **`interpolation_parameters`** attribute takes a string +value, the string being comprised of blank-separated elements of the +form `"term: variable"`, where `term` is a case-insensitive keyword +that defines one of the terms in the interpolation method's definition +given in <>, and `variable` is the name of the +interpolation parameter variable that contains the values for that +term. The order of elements is not significant. A numerical term that +is omitted from the **`interpolation_parameters`** attribute should be +assumed to be zero. + +The **`interpolation_parameters`** attribute may only be provided if +allowed by the definition of the interpolation method. + +The variables named by the **`interpolation_parameters`** attribute +must either be scalar, or else their dimensions may include, for each +interpolation dimension, either the corresponding tie point +interpolation dimension or the corresponding interpolation zone +dimension, but not both, and may include any of the non-interpolation +dimensions. + +The interpretation of interpolation coefficient and configuration +variables depends on the nature of the dimensions that they span: + +* If no tie point interpolation dimensions are spanned, then the + variable provides values for every interpolation zone. This case is + akin to values being defined at the centre of interpolation zones. -* If at least one dimension is a tie point interpolation dimension, then each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). - -In both cases, the implementation of the interpolation method should broadcast an interpolation coefficient or configuration variable along any interpolation zone dimensions that it does not span. - -Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the uncompressed coordinates may only access the tie point that define the extent of the of the interpolation zone, as well as any interpolation coefficient and configuration variables defined for the interpolation zone, including its boundaries. +* If at least one dimension is a tie point interpolation dimension, + then the variable's values are to be shared by the interpolation + zones that are adjacent along each of the specified tie point + interpolation dimensions. This case is akin to the values being + defined at interpolation zone boundaries, and therefore equally + applicable to the interpolation zones that share that boundary + (<>). + +In both cases, the implementation of the interpolation method should +broadcast an interpolation coefficient or configuration variable along +any interpolation zone dimensions that it does not span. + +Note that the interpolation method is always applied on a per +interpolation zone basis, for which the construction of the +uncompressed coordinates may only access the tie point that define the +extent of the of the interpolation zone, as well as any interpolation +coefficient and configuration variables defined for the interpolation +zone, including its boundaries. [[ci_interpolation_coefficients, figure 3]] [.text-center] From 33835009a0ff9fac78a9817101d2f3434888666b Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 10 Feb 2021 15:36:29 +0000 Subject: [PATCH 113/249] interpolation parameters variable dimensions --- ch08.adoc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 9d6e2bc7..b2aadcac 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -320,7 +320,7 @@ process. This attribute names __interpolation parameter variables__ that provide values for coefficent terms in the interpolation equation, or for non-equation terms that configure the interpolation process. The **`interpolation_parameters`** attribute takes a string -value, the string being comprised of blank-separated elements of the +value, the string being comprising blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that defines one of the terms in the interpolation method's definition given in <>, and `variable` is the name of the @@ -339,8 +339,23 @@ interpolation dimension or the corresponding interpolation zone dimension, but not both, and may include any of the non-interpolation dimensions. -The interpretation of interpolation coefficient and configuration -variables depends on the nature of the dimensions that they span: +The dimensions spanned by an interpolation parameter variable are +constrained by the interpolation method's definition, which will which if the dimensions + +The variables named by the **`interpolation_parameters`** attribute +may be scalar, or else their dimensions must correspond to those of +the tie point variablesmay include, for each interpolation dimension, +either the corresponding tie point interpolation dimension or the +corresponding interpolation zone dimension, but not both, and may +include any of the non-interpolation dimensions. + +The dimensions of an interpolation parameter variable must be a subset +of zero or more the tie point variable dimensions, with the +possibility of a tie point interpolation dimension being replaced with +the corresponding interpolation zone dimension. The interpretation of +an interpolation parameter variable depends on which of its dimensions +are tie point interpolation dimensions, and which are interpolation +zone dimensions: * If no tie point interpolation dimensions are spanned, then the variable provides values for every interpolation zone. This case is From 56e265c0d313dbfde982f588ca5fba4eac43bc66 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 10 Feb 2021 15:48:08 +0000 Subject: [PATCH 114/249] interpolation parameters variable dimensions --- ch08.adoc | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index b2aadcac..bd3c1acf 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -314,6 +314,11 @@ If a standardized interpolation name is not given, the interpolation variable mu The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). +Note that the interpolation method is always applied on a per +interpolation zone basis, for which the construction of the +uncompressed coordinates may only access those tie points that define +the extent of the of the interpolation zone. + The interpolation variable attribute **`interpolation_parameters`** may be used to provide extra information to the interpolation process. This attribute names __interpolation parameter variables__ @@ -339,23 +344,13 @@ interpolation dimension or the corresponding interpolation zone dimension, but not both, and may include any of the non-interpolation dimensions. -The dimensions spanned by an interpolation parameter variable are -constrained by the interpolation method's definition, which will which if the dimensions - -The variables named by the **`interpolation_parameters`** attribute -may be scalar, or else their dimensions must correspond to those of -the tie point variablesmay include, for each interpolation dimension, -either the corresponding tie point interpolation dimension or the -corresponding interpolation zone dimension, but not both, and may -include any of the non-interpolation dimensions. - The dimensions of an interpolation parameter variable must be a subset of zero or more the tie point variable dimensions, with the possibility of a tie point interpolation dimension being replaced with the corresponding interpolation zone dimension. The interpretation of -an interpolation parameter variable depends on which of its dimensions -are tie point interpolation dimensions, and which are interpolation -zone dimensions: +an interpolation parameter variable depends on which, if any, of its +dimensions are tie point interpolation dimensions, and which are +interpolation zone dimensions: * If no tie point interpolation dimensions are spanned, then the variable provides values for every interpolation zone. This case is @@ -365,20 +360,13 @@ zone dimensions: then the variable's values are to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being - defined at interpolation zone boundaries, and therefore equally + defined at the interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). In both cases, the implementation of the interpolation method should -broadcast an interpolation coefficient or configuration variable along -any interpolation zone dimensions that it does not span. - -Note that the interpolation method is always applied on a per -interpolation zone basis, for which the construction of the -uncompressed coordinates may only access the tie point that define the -extent of the of the interpolation zone, as well as any interpolation -coefficient and configuration variables defined for the interpolation -zone, including its boundaries. +assume that an interpolation parameter variable is broadcast to any +interpolation zones that it does not span. [[ci_interpolation_coefficients, figure 3]] [.text-center] From 74e10de59c8d73ad8242628d154c4135d00d4097 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 10 Feb 2021 15:53:46 +0000 Subject: [PATCH 115/249] non-standard provision --- ch08.adoc | 56 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index bd3c1acf..d4c68301 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -304,15 +304,43 @@ data: [[compression-by-coordinate-sampling-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] ==== Interpolation Variable -The method used to uncompress the tie point variables is described by an interpolation variable that acts as a container for the attributes that define the interpolation technique and the parameters that should be used. The variable should be a scalar (i.e. it has no dimensions) of arbitrary type, and the value of its single element is immaterial. - -The interpolation method must be identified in one of two ways. Either by the **`interpolation_name`** attribute, which takes a string value that contains the method's name, or else by the **`interpolation_description`** attribute, which takes a string value that contains a non-standardized description of the method. These attributes must not be both set. - -The valid values of **`interpolation_name`** are given in <>. This appendix describes the interpolation technique for each method, and optional interpolation variable attributes for configuring the interpolation process. - -If a standardized interpolation name is not given, the interpolation variable must have a **`interpolation_description`** attribute defined instead, containing a description of the non-standardised interpolation (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including a URI, for example). Whilst it is recommended that a standardised interpolation is provided, the alternative is provided to promote interoperability in cases where a well defined user community needs to use sophisticated interpolation techniques that may also be under development. - -The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). +The method used to uncompress the tie point variables is described by +an interpolation variable that acts as a container for the attributes +that define the interpolation technique and the parameters that should +be used. The variable should be a scalar (i.e. it has no dimensions) +of arbitrary type, and the value of its single element is immaterial. + +The interpolation method must be identified in one of two ways. Either +by the **`interpolation_name`** attribute, which takes a string value +that contains the method's name, or else by the +**`interpolation_description`** attribute, which takes a string value +that contains a non-standardized description of the method. These +attributes must not be both set. + +The valid values of **`interpolation_name`** are given in <>. This appendix describes the interpolation technique for each +method, and optional interpolation variable attributes for configuring +the interpolation process. + +If a standardized interpolation name is not given, the interpolation +variable must have a **`interpolation_description`** attribute defined +instead, containing a description of the non-standardised +interpolation (in a similar manner to a long name being used instead +of a standard name). This description is free text that can take any +form (including a URI, for example). Whilst it is recommended that a +standardised interpolation is provided, the alternative is provided to +promote interoperability in cases where a well defined user community +needs to use sophisticated interpolation techniques that may also be +under development. + +The definition of the interpolation method, however it is specified, +may include instructions to treat groups of physically related +coordinates simultaneously, if such tie points are present. For +example, there are cases where longitudes cannot be interpolated +without considering the corresponding latitudes. It is up to the +interpolation description to describe how such coordinates are to be +identified (e.g. it may be that such tie point variables require +particular units or standard names). Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the @@ -325,9 +353,9 @@ process. This attribute names __interpolation parameter variables__ that provide values for coefficent terms in the interpolation equation, or for non-equation terms that configure the interpolation process. The **`interpolation_parameters`** attribute takes a string -value, the string being comprising blank-separated elements of the -form `"term: variable"`, where `term` is a case-insensitive keyword -that defines one of the terms in the interpolation method's definition +value, the string comprising blank-separated elements of the form +`"term: variable"`, where `term` is a case-insensitive keyword that +defines one of the terms in the interpolation method's definition given in <>, and `variable` is the name of the interpolation parameter variable that contains the values for that term. The order of elements is not significant. A numerical term that @@ -335,7 +363,9 @@ is omitted from the **`interpolation_parameters`** attribute should be assumed to be zero. The **`interpolation_parameters`** attribute may only be provided if -allowed by the definition of the interpolation method. +allowed by the definition of the interpolation method. Interplation +parameters may always be provided to non-standardized interpolation +methods. The variables named by the **`interpolation_parameters`** attribute must either be scalar, or else their dimensions may include, for each From 85b435c4daa875ddf9f3199fcee7c90639f8f4f0 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 10 Feb 2021 15:54:52 +0000 Subject: [PATCH 116/249] interpolation parameters variable dimensions --- ch08.adoc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index d4c68301..946af797 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -367,13 +367,6 @@ allowed by the definition of the interpolation method. Interplation parameters may always be provided to non-standardized interpolation methods. -The variables named by the **`interpolation_parameters`** attribute -must either be scalar, or else their dimensions may include, for each -interpolation dimension, either the corresponding tie point -interpolation dimension or the corresponding interpolation zone -dimension, but not both, and may include any of the non-interpolation -dimensions. - The dimensions of an interpolation parameter variable must be a subset of zero or more the tie point variable dimensions, with the possibility of a tie point interpolation dimension being replaced with From 41302e9f36d9cbc3e3f64682f463757f55814f9f Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 10 Feb 2021 16:05:28 +0000 Subject: [PATCH 117/249] captions, cdl --- ch08.adoc | 65 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 946af797..a9b3a3b7 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -145,7 +145,21 @@ The presence of non-interpolation dimensions in the tie point variable impacts t [[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.4, "Tie Point Dimensions Attribute"]] ==== Tie Point Dimensions Attribute -Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficients or configuration variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. +Each interpolation dimension must be associated with its corresponding +tie point interpolation dimension and, if required, its corresponding +__interpolation zone dimension__ that defines the number of +interpolation zones which partition the interpolation +dimension. Regardless of its size, an interpolation zone dimension is +only required if it is spanned by an interpolation parameter variable, +as described in +<>. The +association is stored in the data variable's +**`tie_point_dimensions`** attribute that contains a blank-separated +list of words of the form __"interpolation_dimension: +tie_point_interpolation_dimension [interpolation_zone_dimension] +[interpolation_dimension: ...]"__. If an interpolation zone dimension +is provided then it must be the second of the two named dimensions +following the interpolation dimension. An overview of the different dimensions for coordinate interpolation is shown in <>. @@ -385,15 +399,15 @@ interpolation zone dimensions: interpolation dimensions. This case is akin to the values being defined at the interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary - (<>). + (<>). In both cases, the implementation of the interpolation method should assume that an interpolation parameter variable is broadcast to any interpolation zones that it does not span. -[[ci_interpolation_coefficients, figure 3]] +[[ci_interpolation_parameters, figure 3]] [.text-center] -.Through combination of dimensions, interpolation coefficient and interpolation configuration variables may provide values for each interpolation zone, for couples of neighbouring interpolation zones or for multiple interpolation zones sharing a boundary. +.Through combination of dimensions, interpolation parameter variables may provide values for each interpolation zone, for couples of neighbouring interpolation zones or for multiple interpolation zones sharing a boundary. image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] @@ -408,7 +422,7 @@ Note that an implementation of the interpolation method is free to calculate the [[example-VIIRS]] [caption="Example 8.5. "] -.Multiple interpolation variables with interpolation coefficients and configuration attributes. +.Multiple interpolation variables with interpolation parameter attributes. ==== ---- dimensions : @@ -434,15 +448,27 @@ dimensions : variables: // VIIRS M-Band float m_radiance(m_track, m_scan, m_channel) ; - m_radiance:tie_points = "m_lat: m_lon: m_sen_azi_ang: m_sen_zen_ang: m_sol_azi_ang: m_sol_zen_ang: tp_interpolation t: time_interpolation" ; - m_radiance:tie_point_dimensions = "m_track: tp_track zone_track m_scan: tp_scan zone_scan m_scan: tp_time_scan" ; - m_radiance:tie_point_indices = "m_track: m_track_indices m_scan: m_scan_indices m_scan: m_time_scan_indices" ; + m_radiance:tie_points = + "m_lat: m_lon: m_sen_azi_ang: m_sen_zen_ang: m_sol_azi_ang: m_sol_zen_ang: tp_interpolation + t: time_interpolation" ; + m_radiance:tie_point_dimensions = "m_track: tp_track zone_track + m_scan: tp_scan zone_scan + m_scan: tp_time_scan" ; + m_radiance:tie_point_indices = "m_track: m_track_indices + m_scan: m_scan_indices + m_scan: m_time_scan_indices" ; // VIIRS I-Band float i_radiance(i_track, i_scan, i_channel) ; - i_radiance:tie_points = "i_lat: i_lon: i_sen_azi_ang: i_sen_zen_ang: i_sol_azi_ang: i_sol_zen_ang: tp_interpolation t: time_interpolation" ; - i_radiance:tie_point_dimensions = "i_track: tp_track zone_track i_scan: tp_scan zone_scan i_scan: tp_time_scan" ; - i_radiance:tie_point_indices = "i_track: zone_track: i_track_indices i_scan: zone_scan: i_scan_indices i_scan: i_time_scan_indices" ; + i_radiance:tie_points = + "i_lat: i_lon: i_sen_azi_ang: i_sen_zen_ang: i_sol_azi_ang: i_sol_zen_ang: tp_interpolation + t: time_interpolation" ; + i_radiance:tie_point_dimensions = "i_track: tp_track zone_track + i_scan: tp_scan zone_scan + i_scan: tp_time_scan" ; + i_radiance:tie_point_indices = "i_track: i_track_indices zone_track + i_scan: i_scan_indices zone_scan + i_scan: i_time_scan_indices" ; // Tie point index variables int m_track_indices(tp_track) ; // shared by tp_interpolation and time_interpolation @@ -494,8 +520,12 @@ variables: // Interpolation variable char tp_interpolation ; tp_interpolation:interpolation_name = "bi_quadratic_1" ; - tp_interpolation:interpolation_coefficients = "exp1: expansion1 align1: alignment1 exp2: expansion2 align2:alignment2" ; - tp_interpolation:interpolation_configuration = "flags: interpolation_zone_flags" ; + tp_interpolation:interpolation_parameters = + "exp1: expansion1 + align1: alignment1 + exp2: expansion2 + align2:alignment2 + flags: interpolation_zone_flags" ; // Interpolation coefficient and configuration variables short expansion1(zone_track , tp_scan) ; @@ -505,7 +535,10 @@ variables: byte interpolation_zone_flags(zone_track , zone_scan) ; interpolation_zone_flags : valid_range = "1b, 7b" ; interpolation_zone_flags : flag_masks = "1b, 2b, 4b" ; - interpolation_zone_flags : flag_meanings = "location_use_cartesian sensor_direction_use_cartesian solar_direction_use_cartesian" ; + interpolation_zone_flags : flag_meanings = + "location_use_cartesian + sensor_direction_use_cartesian + solar_direction_use_cartesian" ; // Time tie points double t(tp_track, tp_time_scan) ; @@ -519,8 +552,8 @@ variables: This example demonstrates the use of multiple interpolation variables, the reusability of the interpolation variable between data variables -of different dimensions and the use of the interpolation coefficients -and interpolation configuration attributes. +of different dimensions and the use of the interpolation parameter +attribute. ==== From 5b6fff681eb762deab5aefaa987ca315ae97ec94 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 10 Feb 2021 16:09:34 +0000 Subject: [PATCH 118/249] tidy --- ch08.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index a9b3a3b7..51676302 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -365,7 +365,7 @@ The interpolation variable attribute **`interpolation_parameters`** may be used to provide extra information to the interpolation process. This attribute names __interpolation parameter variables__ that provide values for coefficent terms in the interpolation -equation, or for non-equation terms that configure the interpolation +equation, or for any other terms that configure the interpolation process. The **`interpolation_parameters`** attribute takes a string value, the string comprising blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that @@ -385,9 +385,9 @@ The dimensions of an interpolation parameter variable must be a subset of zero or more the tie point variable dimensions, with the possibility of a tie point interpolation dimension being replaced with the corresponding interpolation zone dimension. The interpretation of -an interpolation parameter variable depends on which, if any, of its -dimensions are tie point interpolation dimensions, and which are -interpolation zone dimensions: +an interpolation parameter variable depends on which of its dimensions +are tie point interpolation dimensions, and which are interpolation +zone dimensions: * If no tie point interpolation dimensions are spanned, then the variable provides values for every interpolation zone. This case is From 05237a3d10e34f68f068d636fec13a552bc7c54b Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 22 Feb 2021 19:31:15 +0100 Subject: [PATCH 119/249] Update after discussion on 9 February 2021 --- appj.adoc | 324 +++++++++++++++++++++++++++--------------------------- 1 file changed, 162 insertions(+), 162 deletions(-) diff --git a/appj.adoc b/appj.adoc index e63db255..f122d395 100644 --- a/appj.adoc +++ b/appj.adoc @@ -2,7 +2,7 @@ [appendix] == Coordinate Sampling -The definitions and guidance given here allow an application to compress an existing data set using coordinate sampling, while letting the creator of the compressed dataset control the accuracy of the reconstituted coordinates through the degree of subsambling and the choice of interpolation method. +The definitions and guidance given here allow an application to compress an existing data set using coordinate sampling, while letting the creator of the compressed dataset control the accuracy of the reconstituted coordinates through the degree of subsampling and the choice of interpolation method. Futhermore, the definitions given here allow an application to uncompress coordinate and auxiliary coordinate variables that have been compressed using coordinate sampling. The key element of this process is the reconstitution of the full resolution coordinates in the domain of the data by interpolation between the lower resolution coordinates, the tie points, stored in the compressed dataset. @@ -33,80 +33,36 @@ Note that the value of `s` varies from `0.0` at the tie point `A` to `1.0` at ti In the case of two dimensional interpolation, the two interpolation variables are equivalently computed as -`s1 = s1(i) = (i1 - ia1)/(ib1 - ia1)` + -`s2 = s2(i) = (i2 - ia2)/(id2 - ia2)` +`s1 = s1(i1) = (i1 - ia1)/(ib1 - ia1)` + +`s2 = s2(i2) = (i2 - ia2)/(id2 - ia2)` -where `ia1` and `ib1` are the first dimension indices in the target domain of the tie points `A` and `B` respectively, `ia2` and `id2` are the second dimension indices in the target domain of the tie points `A` and `D respectively and the indices `i1` and `i2` are the first and second dimension indices respectively in the target domain of the coordinate value to be reconstituted. +where `ia1` and `ib1` are the first dimension indices in the target domain of the tie points `A` and `B` respectively, `ia2` and `id2` are the second dimension indices in the target domain of the tie points `A` and `D` respectively and the indices `i1` and `i2` are the first and second dimension indices respectively in the target domain of the coordinate value to be reconstituted. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables the interpolation method can be applied independently for each interpolation zone, making it possible to parallelize the computational process. The following notation is used: + -For a vector `v`, `v.x` , `x.y` and `v.z` refer to the three coordinates of that vector. + -For a coordinate pair `ll`, `ll.lat` and `ll.lon` refer to the latitude and longitude coordinates. + +A variable staring with `v` denotes a vector and `v.x` , `x.y` and `v.z` refer to the three coordinates of that vector. + +A variable staring with `ll` denotes a latitude-longitude coordinate pair and `ll.lat` and `ll.lon` refer to the latitude and longitude coordinates. + +For one dimensional interpolation, `i` is an index in the interpolation dimension, `tp` is an index in the tie point interpolation dimension and `iz` is an index in the interpolation zone dimensions. +For two dimensional interpolation, `i1` and `i2` are indices in the interpolation dimensions, `tp1` and `tp2` are indices in the tie point interpolation dimensions and `iz1` and `iz2` are indices in the interpolation zone dimensions. + -[[coordinate_conversion]] -==== Common conversions and formulas - -[cols="8,12"] -|=============== -| Description | Formula - -| Conversion from geocentric `(latitude, longitude)` to cartesian vector `(x, y, z)` | `(x, y, z) = fll2xyz(ll) = (cos⁡(ll.lat)*cos⁡(ll.lon), cos⁡(ll.lat)*sin⁡(ll.lon), sin⁡(ll.lat))` + -| Conversion from cartesian vector `(x, y, z)` to geocentric `(latitude, longitude)`| `(lat, lon) = fxyz2ll(v) = (atan2(v.y, v.x), atan2(z, sqrt(v.x * v.x + v.y * v.y))` + - -| Conversion from `(azimuth, zenith)` angles to cartesian vector `(x, y, z)` | `(x, y, z) = faz2xyz(az) = (sin⁡(az.zenith) * sin⁡(az.azimuth), sin⁡(az.zenith) * cos⁡(az.azimuth), cos⁡(az.zenith))` + -| Conversion from cartesian vector `(x, y, z)` to `(azimuth, zenith)` angles | `(azimuth, zenith) = fxyz2az(v) = (atan2(y, x), atan2(sqrt(x * x + y * y), z)` + - -| Calculate the interpolation coefficient `c` for quadratic interpolation of one coordinate in one dimension between tie points `a` and `b` from given coordinate value `u` at `s` | `c = fc1(ua, ub, u, s) = ((u - (1 - s)*ua - s*ub)/((1 - s)*s)` + -| Calculate the interpolation coefficients `(c.1, c.2)` for quadratic interpolation of two coordinates in one dimension between tie points `a` and `b` from given coordinate values `(u.1, u.2)` at `s` | `(c.1, c.2) = fc2(ua, ub, u, s) = (fc1(ua.1, ub.1, u.1, s), fc1(ua.2, ub.2, u.2, s))` + -| Calculate the interpolation coefficients `(c.1, c.2, c.3)` for quadratic interpolation of three coordinates in one dimension between tie points `a` and `b` from given coordinate values `(u.1, u.2, u.3)` at `s` | `(c.1, c.2, c.3) = fc3(ua, ub, u, s) = (fc1(ua.1, ub.1, u.1, s), fc1(ua.2, ub.2, u.2, s), fc1(ua.3, ub.3, u.3, s))` + - -| Calculate the linear interpolation value of one coordinate `u` in one dimension between tie points `a` and `b` | `u = fl1(ua, ub, s) = (1 - s)*ua + s*u2`; + - -| Calculate the quadratic interpolation value of one coordinate `u` in one dimension between tie points `a` and `b` with interpolation coefficient `c` | `u = fq1(ua, ub, c, s) = (1 - s)*ua + (1 - s)*s1*c + s*u2`; + +Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refers to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. If, in the two dimensional case, `a = tp(tp2, tp1)` then `b = tp(tp2, tp1+1)`, `c = tp(tp2+1, tp1)` and `d = tp(tp2+1, tp1+1)`, reflecting the way the tie point data would be stored in the data set, see also <>. -| Calculate the quadratic interpolation values of two coordinates `(u.1, u.2)` in one dimension between tie points `a` and `b` with interpolation coefficients `(c.1, c.2)` | `(u.1, u.2) = fq2(ua, ub, c, s) = (fq1(ua.1, ua.2, c.1, s), fq1(ua.1, ua.2, c.1, s))``; + - -| Calculate the quadratic interpolation values of three coordinates `(u.1, u.2, u.3)` in one dimension between tie points `a` and `b` with interpolation coefficients `(c.1, c.2, c.3)` | `(u.1, u.2, u.3) = fq3(ua, ub, c, s) = (fq1(ua.1, ub.1, c.1, s), fq1(ua.2, ub.2, c.2, s), fq1(ua.3 ub.3, c.3, s))`; + - -| Vector Sum | `(x, y, z) = va + vb = (va.x + vb.x, va.y + vb.y, va.z + vb.z)` + -| Vector Difference | `(x, y, z) = va - vb = (va.x - vb.x, va.y - vb.y, va.z - vb.z)` + - -| Vector Cross Product | `(x, y, z) = fcross(va, vb) = (va.y*vb.z - va.z*vb.y, va.z*vb.x - vva.zx*b.z, va.x*vb.y - va.y*vb.x)` + - -| Normalised Vector | `(x, y, z) = norm(v) = (v.x, v.y, v.z) / sqrt (v.x*v.x + v.y*v.y + v.z*v.z)` + - -| Vector Dot Product | `d = fdot(va, vb) = va.x*vb.x + va.y*vb.y, va.z*vb.z` - -| Vector from ce, ca | `(x, y, z) = fp(va, vb, ce, ca) = norm(0.5*fplus(va, vb) + ce*fminus(vb, va) + ca*fcross(vb, va))` - -| ce, ca from vector | `(ce, ca) = fceca(va, vb, vp) = (r/(f*f) * fdot(ve, vf), r/(m*m) * fdot(ve, vm))` + -where + -`vn = 0.5*(va + vb); n*n = fdot(n, n)`; + -`ve = vp - vn`; + -`r = 1/(1 + fdot(ve, vn)/(n*n))`; + -`vf = vb - va; f*f = 4*(1- n*n)`; + -`vm = fcross(vb, va); m*m = 8*n*n*(1 - n*n)`; + -|=============== - -[[interpolation_methods]] === Interpolation Methods -In the following `i1` and `i2` are indices in the interpolation dimensions, `tp1` and `tp2` are indices in the tie point interpolation dimensions and `iz1` and `iz2` are indices in the interpolation zone dimensions, see <>. + - - ==== Linear Interpolation [cols="6,15"] |=============== | Name | **`interpolation_name = "linear"`** -| Description | General purpose one dimensional linear interpolation method -| Interpolation Coefficient terms | None -| Interpolation Configuration terms | None +| Description | General purpose one dimensional linear interpolation method for one or more coordinates +| Interpolation Parameter terms | None | Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | - Calculation of interpolated coordinate `u` at `s = s(i)` + - `u = fl1(u(tp1), u(tp1+1), s(i))` + The coordinate value `u(i)` at index `i` between tie points `a` and `b` is calculated from: + + `u(i) = fl(ua, ub, s(i)) = (1 - s)*ua + s*ub`; + +where `ua` and `ub` are the coordinate values at tie points `a` and `b` respectively. + + |=============== ==== Bilinear Interpolation @@ -114,141 +70,185 @@ In the following `i1` and `i2` are indices in the interpolation dimensions, `tp1 [cols="6,15"] |=============== | Name | **`interpolation_name = "bi_linear"`** -| Description | General purpose two dimensional linear interpolation method -| Interpolation Coefficient terms | None -| Interpolation Configuration terms | None +| Description | General purpose two dimensional linear interpolation method for one or more coordinates +| Interpolation Parameter terms | None | Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | - Calculation of interpolated coordinate `u` at `(s1, s2) = (s1(i1), s2(i2))` + -`uab = fl1(u(tp2, tp1), u(tp2, tp1+1), s1(i);` + -`ucd = fl1(u(tp2+1, tp1), u(tp2+1, tp1+1), s1(i));` + -`u = fl1(uab, ucd, s2(i));` + +The interpolation function fl() defined for linear interpolation above is first applied twice in the interpolation dimension 1, once between between tie points `a` and `b` and once between tie point `c` and `d`. It is then applied once in the interpolation dimension 2, between the two resulting coordinate points, yielding the interpolated coordinate value `u(i1, i2)`: + +`uab = fl(ua, ub, s1(i1))`; + +`ucd = fl(uc, ud, s1(i1))`; + +`u(i1, i2) = fl(uab, ucd, s2(i2))`; + |=============== - +[[quadratic]] ==== Quadratic Interpolation [cols="6,15"] |=============== | Name | **`interpolation_name = "quadratic"`** -| Description | General purpose one dimensional quadratic interpolation method for one coordinate -| Interpolation Coefficient terms | `c1` of dimension (interpolation_zone_1) -| Interpolation Configuration terms | None -| Coordinate Compression Calculations | Calculate interpolation coefficient `c1` + -TO BE WRITTEN (main element is use of c = fc1(ua, ub, u, s), see <> ) +| Description | General purpose one dimensional quadratic interpolation method for one coordinate. + +| Interpolation Parameter terms | Optionally interpolation coefficient `c`, which must span the interpolation_zone dimension. + +| Coordinate Compression Calculations | +The expression + +`c = fc(ua, ub, u(i), s(i)) = ((u - (1 - s) * ua - s * ub)/( 4 * (1 - s) * s)` + +enables the creator of the dataset to calculate `c` from the coordinate values `ua` and `ub` at tie points `a` and `b` respectively, and the coordinate value `u(i)` at index `i` between the tie points `a` and `b`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib - ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib - ia - 1)/2` shall be selected. + | Coordinate Uncompression Calculations | - Calculation of interpolated coordinate `u` at `s = s(i)`: + -`u = fq2(x(tp1), x(tp1+1), c1(iz1), s(i));` +The coordinate value `u(i)` at index `i` between tie points `a` and `b` is calculated from: + + `u(i) = fq(ua, ub, c, s(i)) = (1 - s) * ua + 4 * (1 - s) * s * c + s * ub`; + +where `ua` and `ub` are the coordinate values at tie points `a` and `b` respectively and the coefficient `c` is available as a term in the `interpolation_parameters`, or otherwise defaults to `0.0`. + |=============== -==== Quadratic Interpolation of geographic coordinates +[[quadratic_geo]] +==== Quadratic Interpolation of geographic coordinates latitude and longitude [cols="6,15"] |=============== | Name | **`interpolation_name = "quadratic_geo"`** -| Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude. + -Requires a coordinate pair with `standard_name` `latitude` and `longitude`. +| Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + + + +By default, interpolation is performed directly in the latitude and longitude coordinates, but may be performed in cartesian coordinates where required for achieving the desired accuracy. This must be indicated by setting the `location_use_cartesian` flag within the interpolation parameter `interpolation_zone_flags` for each interpolation zone where interpolation in cartesian coordinates is required. + +The coefficients of the quadratic interpolation term express the offset of the interpolated point at `s=0.5` relative to a geometric midpoint between the tie points `a` and `b`. The coefficients may be represented in three different ways: + +For storage in the dataset as the coefficients `(ce, ca)`, referred to as the dimensional representation. The component `ce` is the offset projected on the line from tie point `b` to tie point `a`. The component `ca` is the offset projected on the line perpendicular to the line from tie point `b` to tie point `a` and perpendicular to the plane spanned `va` and `vb`, the vector representations of the two tie points. + -Support to be added for coordinate pairs with `standard_name`: + -`(sensor_azimuth_angle, sensor_zenith_angle)` + -`(solar_azimuth_angle, solar_zenith_angle)` + -`(lunar_azimuth_angle, lunar_zenith_angle)` (TO DO: propose as standard name) + -`(platform_azimuth_angle, platform_zenith_angle)` +For interpolation in cartesian coordinates as the coefficients `vcxyz = (cx, cy, cz)`, expressing the offset components along the cartesian axes x, y and z respectively. +For interpolation in geographic coordinates latitude and longitude as the coefficients `vcll = (clat, clon)`, expressing the offset components along the longitude and latitude directions respectively. -Support to be added for coordinate pairs with `standard_name`: + -`(sensor_azimuth_angle, sensor_zenith_angle)` + -`(solar_azimuth_angle, solar_zenith_angle)` + -`(lunar_azimuth_angle, lunar_zenith_angle)` (TO DO: propose as standard name) + -`(platform_azimuth_angle, platform_zenith_angle)` +The functions fq() and fc() referenced in the following are defined in <>. + +Note that in the following, conversions between the latitude-longitude representation of a point, `p = (p.lat, p.lon)`, and its cartesian representation, `vp = (vp.x, vp.y, vp.z)`, are not explicitly stated. Where required they shall be performed using `fll2xyz()` and `fxyz2ll()` defined in <>. -| Interpolation Coefficient terms | -`c11, c12` of dimension `(tie_point_interpolation_2, interpolation_zone_1)` TBC + -| Interpolation Configuration terms | `interpolation_zone_flags` of dimension `(tie_point_interpolation_2, interpolation_zone_1)` and `flag_meanings = "location_use_cartesian sensor_direction_use_cartesian solar_direction_use_cartesian lunar_direction_use_cartesian"` +| Interpolation Parameter terms | Any subset of interpolation coefficients `ce, ca`, which must each span the interpolation_zone dimension. + +Optionally the flag variable `interpolation_zone_flags`, which must span the interpolation_zone dimension and must include `location_use_cartesian` in the `flag_meanings` attribute. + | Coordinate Compression Calculations | -Calculate interpolation coefficients `(c11, c12)` + -TO BE WRITTEN (main element is use of function (ce, ca) = fceca(va, vb, vp), see <> ) + -Calculate `interpolation_zone_flags` + -TO BE WRITTEN (main element is check for proximity to North Pole or South Pole where interpolation must be done in cartesian coordinates) + -| Coordinate Uncompression Calculations | -For each tie point, calculate from the latitude and longitude coordinates `ll` the position vector `vtp`: + -`vtp(tp2, tp1) = fll2xyz(ll(tp2, tp1));` + -For each interpolation coefficient pair `(c11, c12)` with its two neighbouring position vectors, calculate the the vector v1 + -`v1(tp2, iz1) = fp( vtp(tp2, tp1), vtp(tp2, tp1+1), c11(tp2, iz1), c12(tp2, iz1));` + -Convert the vector to latitude, longitude: + -`ll1(tp2, iz1) = fxyz2ll(v1(tp2, iz1));` + -Calculate the interpolation coefficients for use when interpolating directly in (lat, lon): + -`llc1(tp2, iz1) = fc2(ll(tp2, tp1), ll1(tp2, iz1), ll(tp2, tp1+1));` + -Calculate the interpolation coefficients for use when interpolating in (x, y, z): + -`vc1(tp2, iz1) = fc3(vtp(tp2, tp1), x1(tp2, iz1), vtp(tp2, tp1+1));` + -For each point `(s1, s2) = (s1(i1), s2(i2))` in interpolation zone (iz2, iz1) with tie point A at (tp2, tp1), calculate interpolated coordinate value `ll(i2, i1) = (lat(i2, i1), lon(i2, i1)):` + -If `interpolation_zone_flags(tp2, iz1)` is equal to `location_use_cartesian`: + -`v = fq3(vtp(tp2, tp1), vtp(tp2, tp1+1), vc1(tp2, iz1), s1(i);` + -`ll(i2, i1) = fxyz2ll(v(i2, i1));` + -else: + -`ll = fq2(ll(tp2, tp1), ll(tp2, tp1+1), llc1(tp2, iz1), s1(i);` + +First calculate the cartesian representation of the interpolation coefficients from the tie points `a` and `b` as well as the point `p(i)` at index `i` between the tie points `a` and `b`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib - ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib - ia - 1)/2` shall be selected. + +The cartesian interpolation coefficients are found from + +`vcxyz = fcxyz(va, vb, vp(i), s(i)) = (fc(va.x, vb.x, vp(i).x, s(i)), fc(va.y, vb.y, vp(i).y, s(i)), fc(va.z, vb.z, vp(i).z, s(i)))` + +Finally, for storage in the dataset, convert the coefficients to the dimensional representation + +`(ce(iz), ca(iz)) = fcxyz2cea(va, vb, vcxyz) = (fdot(vcxyz, fminus(va, vb))/ (4*(1-rsqr)), fdot(vcxyz, fcross(va, vb))/(2*rsqr*(1-rsqr))` + +where `vr = fmultiply(0.5, fplus(va, vb))` and `rsqr = fdot(vr, vr)`. + +`vf = fminus(va, vb)`; + +`vn = fcross(va, vb)`; + +The interpolation parameter term `interpolation_zone_flags(iz)` shall have the flag `location_use_cartesian` set if the interpolation zone intersects the `longitude = 180.0` or if the interpolation zone extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. +| Coordinate Uncompression Calculations | +First calculate the cartesian representation of the interpolation coefficients from the dimensional representation stored in the dataset using + +`vcxyz = fcea2cxyz(va, vb, ce(iz), ca(iz)) = fplus(fmultiply(ce, fminus(va, vb)), fmultiply(ca, fcross(va, vb)), fmultiply(cr, vr))` + +where + +`vr = fmultiply(0.5, fplus(va, vb))`; + +`rsqr = fdot(vr, vr)`. + +`cr = fsqrt(1 - ce(iz)*ce(iz) - ca(iz)*ca(iz)) - fsqrt(rsqr)`; + +If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_zone_flags(iz2, iz1)` is set, use the following expression to reconstitute any point `p(i)` between the tie points `a` and `b` using interpolation in cartesian coordinates + +`vp(i) = fqxyz(va, vb, vcxyz, s(i)) = (fq(va.x, vb.x, vcxyz.x, s(i)), fq(va.y, vb.y, vcxyz.y, s(i)), fq(va.z, vb.z, vcxyz.z, s(i)))` + +Otherwise, first calculate latitude-longitude representation of the interpolation coefficients + +`vcll = fcxyz2cll(va, vb, vcea) = (fc(a.lat, b.lat, pll.lat, 0.5), fc(a.lon, b.lon, pll.lon, 0.5))` + +where `pll = fxyz2ll(fqxyz(va, vb, vcxyz, 0.5))`. + +Then use the following expression to reconstitute any point `p(i)` between the tie points `a` and `b` using interpolation in latitude-longitude coordinates + +`p(i) = (p(i).lat, p(i).lon) = fqll(va, vb, vcll, s(i)) = ((fq(a.lat, b.lat, vcll.lat, s(i)), fq(a.lon, b.lon, .vcll.lon, s(i))`. + |=============== - + +[[bi_quadratic_geo]] ==== Biquadratic Interpolation of geographic coordinates [cols="6,15"] |=============== | Name | **`interpolation_name = "bi_quadratic_geo"`** -| Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude. + -Requires a coordinate pair with `standard_name` `latitude` and `longitude`. - -Support to be added for coordinate pairs with `standard_name`: + -`(sensor_azimuth_angle, sensor_zenith_angle)` + -`(solar_azimuth_angle, solar_zenith_angle)` + -`(lunar_azimuth_angle, lunar_zenith_angle)` (TO DO: propose as standard name) + -`(platform_azimuth_angle, platform_zenith_angle)` - -| Interpolation Coefficient terms | -`c11, c12` of dimension `(tie_point_interpolation_2, interpolation_zone_1)` + -`c21, c22` of dimension `(interpolation_zone_2, tie_point_interpolation_1)` + -`c31, c32` of dimension `(interpolation_zone_2, interpolation_zone_1)` + -| Interpolation Configuration terms | `interpolation_zone_flags` of dimension `(iz2, iz1)` and `flag_meanings = "location_use_cartesian sensor_direction_use_cartesian solar_direction_use_cartesian lunar_direction_use_cartesian"` +| Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + + +The functions fcxyz(), fcxyz2cea(), fcea2cxyz(), fcxyz2cll(), fqxyz() and fqll() referenced in the following are defined in <>. As for this method interpolation is performed directly in the latitude and longitude coordinates or in cartesian coordinates, where required for achieving the desired accuracy. Similarly, it shares the three different representations of the quadratic interpolation coefficients, the dimensional representation `(ce, ca)` for storage in the dataset, `vcll = (clat, clon)` for interpolation in geographic coordinates latitude and longitude and `vcxyz = (cx, cy, cz)` for cartesian interpolation. + +Note that in the following, conversions between the latitude-longitude representation of a point, `p = (p.lat, p.lon)`, and its cartesian representation, `vp = (vp.x, vp.y, vp.z)`, are not explicitly stated. Where required they shall be performed using `fll2xyz()` and `fxyz2ll()` defined in <>. + +| Interpolation Parameter terms | +Any subset of interpolation coefficients `ce1, ca1`, which must each span the `tie_point_interpolation_2` and `interpolation_zone_1` dimensions; + +Any subset of interpolation coefficients `ce2, ca2`, which must each span the `interpolation_zone_2` and `tie_point_interpolation_1` dimensions; + +Any subset of interpolation coefficients `ce3, ca3`, which must each span the `interpolation_zone_2` and `interpolation_zone_1` dimensions; + + +Optionally the flag variable `interpolation_zone_flags`, which must span the `interpolation_zone_2` and `interpolation_zone_1` dimensions and must include `location_use_cartesian` in the `flag_meanings` attribute. + | Coordinate Compression Calculations | -Calculate interpolation coefficients `(c11, c12)`, `(c21, c22)`, `(c31, c32)` + -TO BE WRITTEN (main element is use of function (ce, ca) = fceca(va, vb, vp), see <> ) + -Calculate `interpolation_zone_flags` + -TO BE WRITTEN (main element is check for proximity to North Pole or South Pole where interpolation must be done in cartesian coordinates) + + +First calculate the cartesian representation of the interpolation coefficients sets from the tie points as well as a point `p(i2, i1)` between the tie points. If the size of the interpolation zone in the first dimension `(ib1 - ia1)` is an even number, then the index `i1 = (ib1 - ia1)/2` shall be selected for this calculation, otherwise the index `i1 = (ib1 - ia1 - 1)/2` shall be selected. If the size of the interpolation zone in the second dimension `(ib2 - ic2)` is an even number, then the index `i2 = (ib2 - ic2)/2` shall be selected for this calculation, otherwise the index `i2 = (ib2 - ic2 - 1)/2` shall be selected. + +Using the selected `(i2, i1)`, the cartesian interpolation coefficients are found from + +`vcxyz_ab = fcxyz( va, vb, vp(ia2, i1), s(i1));` `vcxyz_cd = fcxyz( vc, vd, vp(ic2, i1), s(i1));` + +`vcxyz_ac = fcxyz( va, vc, vp(i2, ia1), s(i2));` `vcxyz_bd = fcxyz( vb, vd, vp(i2, ib1), s(i2));` + +`vcxyz_z = fcxyz( fqxyz(va, vc, vcxyz_ac, 0.5), fqxyz(vb, vd, vcxyz_bd, 0.5), vp(i2, i1), s(i1));` + +Finally, for storage in the interpolation parameter datasets, convert the coefficients to the dimensional representation + +`(ce1(tp2, iz1), ca1(tp2, iz1)) = fcxyz2cea( va, vb, vcxyz_ab);` + +`(ce1(tp2+1, iz1), ca1(tp2+1, iz1)) = fcxyz2cea( vc, vd, vcxyz_cd);` + +`(ce2(iz2, tp1), ca2(iz2, tp1)) = fcxyz2cea( va, vc, vcxyz_ac);` + +`(ce2(iz2, tp1+1), ca2(iz2, tp1+1)) = fcxyz2cea( vb, vd, vcxyz_bd);` + +`(ce3(iz2, iz1), ca3(iz2, iz1)) = fcxyz2cea( fqxyz(va, vc, vcxyz_ac, 0.5), fqxyz(vb, vd, vcxyz_bd, 0.5), vcxyz_z);` + +The interpolation parameter term `interpolation_zone_flags(iz2, iz1)` shall have the flag `location_use_cartesian` set if the interpolation zone intersects the `longitude = 180.0` or if the interpolation zone extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | -For each tie point, calculate from the latitude and longitude coordinates `ll` the position vector `vtp`: + -`vtp(tp2, tp1) = fll2xyz(ll(tp2, tp1));` + -For each interpolation coefficient pair `(c11, c12)`, `(c21, c22)`, `(c31, c32)` with its two neighbouring position vectors, calculate the the vector v1, v2, v3 respectively + -`v1(tp2, iz1) = fp( vtp(tp2, tp1), vtp(tp2, tp1+1), c11(tp2, iz1), c12(tp2, iz1));` + -`v2(iz2, tp1) = fp( vtp(tp2, tp1), vtp(tp2+1, tp1), c21(iz2, tp1), c22(iz2, tp1));` + -`v3(iz2, iz1) = fp( v2(iz2, tp1), v2(iz2, tp1+1), c31(iz2, iz1), c32(iz2, iz1));` + -Convert the three vectors to latitude, longitude: + -`ll1(tp2, iz1) = fxyz2ll(v1(tp2, iz1));` + -`ll2(iz2, tp1) = fxyz2ll(x2(iz2, tp1));` + -`ll3(iz2, iz1) = fxyz2ll(x3(iz2, iz1));` + -Calculate the interpolation coefficients for use when interpolating directly in (lat, lon): + -`llc1(tp2, iz1) = fc2(ll(tp2, tp1), ll1(tp2, iz1), ll(tp2, tp1+1));` + -`llc2(iz2, tp1) = fc2(ll(tp2, tp1), ll2(iz2, tp1), ll(tp2+1, tp1));` + -`llc3(iz2, iz1) = fc2(ll(tp2, tp1), ll3(iz2, iz1), ll(tp2, tp1+1));` + -Calculate the interpolation coefficients for use when interpolating in (x, y, z): + -`vc1(tp2, iz1) = fc3(vtp(tp2, tp1), x1(tp2, iz1), vtp(tp2, tp1+1));` + -`vc2(iz2, tp1) = fc3(vtp(tp2, tp1), x2(iz2, tp1), vtp(tp2+1, tp1));` + -`vc3(tp2, iz1) = fc3(v2(tp2, tp1), v3(tp2, iz1), v2(tp2, tp1+1));` + -For each point `(s1, s2) = (s1(i1), s2(i2))` in interpolation zone (iz2, iz1) with tie point A at (tp2, tp1), calculate interpolated coordinate value `ll(i2, i1) = (lat(i2, i1), lon(i2, i1)):` + -If `interpolation_zone_flags(iz2, iz1)` is equal to `location_use_cartesian`: + -`vab = fq3(vtp(tp2, tp1), vtp(tp2, tp1+1), vc1(tp2, iz1), s1(i);` + -`vcd = fq3(vtp(tp2+1, tp1), vtp(tp2+1, tp1+1), vc1(tp2+1, iz1), s1(i));` + -`vc = fq3(vc2(iz2, tp1), vc2(iz2, tp1+1), vc3(iz2, iz1), s1(i));` + -`v = fq3(vab, vcd, vc, s2(i));` + -`ll(i2, i1) = fxyz2ll(v(i2, i1));` + -else: + -`llab = fq2(ll(tp2, tp1), ll(tp2, tp1+1), llc1(tp2, iz1), s1(i);` + -`llcd = fq2(ll(tp2+1, tp1), ll(tp2+1, tp1+1), llc1(tp2+1, iz1), s1(i));` + -`llc = fq2(llc2(iz2, tp1), llc2(iz2, tp1+1), llc3(iz2, iz1), s1(i));` + -`ll = fq2(llab, llcd, llc, s2(i));` + +First calculate the cartesian representation of the interpolation coefficient sets from the dimensional representation stored in the dataset + +`vcxyz_ab = fcea2cxyz( va, vb, ce1(tp2, iz1), ca1(tp2, iz1));` + +`vcxyz_cd = fcea2cxyz( vc, vd, ce1(tp2+1, iz1), ca1(tp2+1, iz1));` + +`vcxyz_ac = fcea2cxyz( va, vc, ce2(iz2, tp1), ca2(iz2, tp1));` + +`vcxyz_bd = fcea2cxyz( vb, vd, ce2(iz2, tp1+1), ca2(iz2, tp1+1));` + +`vcxyz_z = fcea2cxyz( fqxyz(va, vc, vcxyz_ac, 0.5), fqxyz(vb, vd, vcxyz_bd, 0.5), ce3(iz2, iz1), ca3(iz2, iz1));` + +If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_zone_flags` is set, use the following expression to reconstitute any point `p(i2, i1)` between the tie points `a` and `b` using interpolation in cartesian coordinates + +`vp(i2, i1) = fqxyz(vab, vcd, vz, s2(i2));` + +where + +`vab = fqxyz(va, vb, vcxyz_ab, s1(i1))`; + +`vcd = fqxyz(vc, vd, vcxyz_cd, s1(i1))`; + +`vz = fqxyz(vcxyz_ac, vcxyz_bd, vcxyz_z, s1(i1))`. + +Otherwise, first calculate latitude-longitude representation of the interpolation coefficients + +`vcll_ab = fcxyz2cll( va, vb, vcxyz_ab);` `vcll_cd = fcxyz2cll( vc, vd, vcxyz_cd);` + +`vcll_ac = fcxyz2cll( va, vc, vcxyz_ac);` `vcll_bd = fcxyz2cll( vb, vd, vcxyz_bd);` + +`vcll_z = fcxyz2cll( fqxyz(va, vc, vcxyz_ac, 0.5), fqxyz(vb, vd, vcxyz_bd, 0.5), vcxyz_z);` + +Then use the following expression to reconstitute any point `p(i2, i1)` in the tie point zone using interpolation in latitude-longitude coordinates + + `p(i2, i1) = fqll(ab, cd, z, s2(i2));` + +where + +`ab = fqll(a, b, vcll_ab, s1(i1))`; + +`cd = fqll(c, d, vcll_cd, s1(i1))`; + +`z = fqll(vcll_ac, vcll_bd, vcll_z, s1(i1))`. |=============== + +[[coordinate_conversion]] +==== Common conversions and formulas + +[cols="1, 8, 8"] +|=============== +| |Description | Formula + +| fll2xyz | Conversion from geocentric `(latitude, longitude)` to cartesian vector `(x, y, z)` | `(x, y, z) = fll2xyz(ll) = (cos⁡(ll.lat)*cos⁡(ll.lon), cos⁡(ll.lat)*sin⁡(ll.lon), sin⁡(ll.lat))` + + +| fxyz2ll | Conversion from cartesian vector `(x, y, z)` to geocentric `(latitude, longitude)`| `(lat, lon) = fxyz2ll(v) = (atan2(v.y, v.x), atan2(z, sqrt(v.x * v.x + v.y * v.y))` + + +| faz2xyz | Conversion from `(azimuth, zenith)` angles to cartesian vector `(x, y, z)` | `(x, y, z) = faz2xyz(az) = (sin⁡(az.zenith) * sin⁡(az.azimuth), sin⁡(az.zenith) * cos⁡(az.azimuth), cos⁡(az.zenith))` + + +| fxyz2az | Conversion from cartesian vector `(x, y, z)` to `(azimuth, zenith)` angles | `(azimuth, zenith) = fxyz2az(v) = (atan2(y, x), atan2(sqrt(x * x + y * y), z)` + + +| fsqrt | Square Root | `s = fsqrt(t)` + +| fplus | Vector Sum | `(x, y, z) = fplus(va , vb) = (va.x + vb.x, va.y + vb.y, va.z + vb.z)` + +`(x, y, z) = fplus(va , vb, vc) = (va.x + vb.x + vc.x, va.y + vb.y + vc.y, va.z + vb.z + vc.z)` + +| fminus | Vector Difference | `(x, y, z) = fminus(va, vb) = (va.x - vb.x, va.y - vb.y, va.z - vb.z)` + + +| fmultiply | Vector multiplied by Scalar | `(x, y, z) = fmultiply(r, v) = (r * va.x, vr * va.y, r * va.z)` + + +| fcross | Vector Cross Product | `(x, y, z) = fcross(va, vb) = (va.y*vb.z - va.z*vb.y, va.z*vb.x - vva.zx*b.z, va.x*vb.y - va.y*vb.x)` + + +| norm | Normalised Vector | `(x, y, z) = norm(v) = (v.x, v.y, v.z) / sqrt (v.x*v.x + v.y*v.y + v.z*v.z)` + + +| fdot | Vector Dot Product | `d = fdot(va, vb) = va.x*vb.x + va.y*vb.y, va.z*vb.z` + +|=============== + +[[interpolation_methods]] + + === Coordinate Compression Steps [[compression-by-coordinate-sampling-generation-of-tie-points]] @@ -295,7 +295,7 @@ else: + | <> | 10 -| Finally, if required by the selected interpolation method, follow the steps defined for the method in <> to create any required interpolation coefficients variables and interpolation configuration variables. As relevant, create the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes and populate them with the interpolation coefficients variables and interpolation configuration variables respectively. +| Finally, if required by the selected interpolation method, follow the steps defined for the method in <> to create any required interpolation parameter variables. As relevant, create the **`interpolation_parameters`** attribute and populate it with the interpolation parameter variables. | <> + <> @@ -338,7 +338,7 @@ else: + | <> | 7 -| As required by the selected interpolation method, identify the interpolation coefficients variables and interpolation configuration variables from the interpolation variable **`interpolation_coefficients`** and **`interpolation_configuration`** attributes respectively. +| As required by the selected interpolation method, identify the interpolation parameter variables from the interpolation variable attribute **`interpolation_parameters`** . | <> | 8 From bc17dc68bb5a4e30cbd7502fe92d5e883237baf7 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 23 Feb 2021 11:41:29 +0000 Subject: [PATCH 120/249] minumum size of interpolation zones --- ch08.adoc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 51676302..5dffde19 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -204,11 +204,15 @@ element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the -**`tie_point_dimensions`** attribute. The values must be strictly -monotonically increasing within interpolation areas. When two adjacent -values are equal, or differ by one, it indicates the location (in -index space) of an interpolation area boundary relating to a grid -discontinuity (<>). +**`tie_point_dimensions`** attribute. The tie point index values must +be strictly monotonically increasing within interpolation areas. An +interpolation zone must span at least two points of each of its +corresponding interpolation dimensions, therefore the tie point +indices that define an interpolation zone must all be different. When +two adjacent values are equal, or differ by one, it indicates the +location (in index space) of an interpolation area boundary relating +to a grid discontinuity +(<>). Each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding From 750144bccf1ca2cbac2700828a0267c3f77d84b9 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 23 Feb 2021 14:22:58 +0000 Subject: [PATCH 121/249] Appendix A attributes --- appa.adoc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/appa.adoc b/appa.adoc index ee404d74..f9c358ff 100644 --- a/appa.adoc +++ b/appa.adoc @@ -294,6 +294,24 @@ formula in the definition. | <> | A standard name that references a description of a variable"s content in the standard name table. +| **`tie_point_dimensions`** +| S +| D, Do +| <> and <> +| When coordinates have been compressed by interpolation, provides a mapping of interpolation dimensions to tie point index variables. + +| **`tie_point_indices`** +| S +| D, Do +| <> and <> +| When coordinates have been compressed by interpolation, provides a mapping of interpolation dimensions to tie point interpolation dimensions and interpolation zone dimensions. + +| **`tie_points`** +| S +| D, Do +| <> and <> +| Indicates that coordinates have been compressed by interpolation and identifies the tie point variables and their associated interpolation variables. + | **`title`** | S | G, Gr From 13066bbaadcf9ba093641e467a3e11f66fc40d0b Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 23 Feb 2021 14:27:14 +0000 Subject: [PATCH 122/249] interpolation -> sampling --- appa.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/appa.adoc b/appa.adoc index f9c358ff..32eefb4f 100644 --- a/appa.adoc +++ b/appa.adoc @@ -298,19 +298,19 @@ formula in the definition. | S | D, Do | <> and <> -| When coordinates have been compressed by interpolation, provides a mapping of interpolation dimensions to tie point index variables. +| When coordinates have been compressed by sampling, provides a mapping of interpolation dimensions to tie point index variables. | **`tie_point_indices`** | S | D, Do | <> and <> -| When coordinates have been compressed by interpolation, provides a mapping of interpolation dimensions to tie point interpolation dimensions and interpolation zone dimensions. +| When coordinates have been compressed by sampling, provides a mapping of interpolation dimensions to tie point interpolation dimensions and interpolation zone dimensions. | **`tie_points`** | S | D, Do | <> and <> -| Indicates that coordinates have been compressed by interpolation and identifies the tie point variables and their associated interpolation variables. +| Indicates that coordinates have been compressed by sampling and identifies the tie point variables and their associated interpolation variables. | **`title`** | S From e3569618539e2e35e4c28dcf4ea27cb5751fa4ef Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 23 Feb 2021 16:22:35 +0000 Subject: [PATCH 123/249] Conformance - first draft --- conformance.adoc | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/conformance.adoc b/conformance.adoc index a7c18cdf..e9a4ec34 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -632,4 +632,95 @@ in the file. starting with 0 and going up to the product of the compressed dimension sizes minus 1 (CDL index conventions). +[[compression-by-gathering]] +=== 8.2 Lossless Compression by Gathering + +*Requirements:* + +* The **`compress`** attribute may only be attached to a coordinate variable +with an integer data type. +* The type of the **`compress`** attribute is a string whose value is a blank +separated list of dimension names. The specified dimensions must exist +in the file. +* The values of the associated coordinate variable must be in the range +starting with 0 and going up to the product of the compressed dimension +sizes minus 1 (CDL index conventions). + +[[compression-by-coordinate-sampling]] +=== 8.3 Lossy Compression by Coordinate Sampling + +*Requirements:* + +* When attached to a data or domain variable, the type of the + **`tie_point_dimensions`** attribute is a string whose value is list + of blank separated word groups of the following form, in which + brackets indicate optional text: **`interpolation_dimension: + tie_point_interpolation_dimension [interpolation_zone_dimension]`**. + Each **`interpolation_dimension** token specifies a unique + interpolation dimension of the parent data or domain variable, each + **`tie_point_interpolation_dimension`** token specifies the tie + point interpolation dimension of a unique tie point index variable, + and each **`interpolation_zone_dimension`** token specifies a unique + interpolation zone dimension. + +* When attached to a data or domain variable, the type of the + `tie_point_indices`** attribute is a string whose value is list of + blank separated word groups of the following form: + **`interpolation_dimension: tie_point_index_variable`**. The + **`interpolation_dimension** tokens specify the interpolation + dimensions of the parent data or domain variable and must match the + same tokens in the **`tie_point_dimensions`** attribute, and each + **`tie_point_index_variable`** token specifies a tie point index + variable that must exist in the file. + +* A tie point index variable must be a one-dimensional variable with + an integer data type. The dimension of the tie point index variable + must be a tie point interpolation dimension identified by the + **`tie_point_dimensions`** attribute. + +* The values of a tie point index variable must be non-negative + integers. The first value must be zero, and each subsequent value + must be greater than or equal to the previous value. If a value + differs by zero or one from its previous value, then it must differ + by two or more from the subsequent value. + +* When attached to a data or domain variable, the type of the + **`tie_points`** attribute is a string whose value is list of blank + separated word groups of the following form, in which brackets + indicate optional text: **`tie_point_variable: [tie_point_variable: + ...] interpolation_variable`**. Each **`interpolation_variable`** + token specifies an interpolation variable that must exist in the + file, and each **`tie_point_variable** token specifies a tie point + variable that must exist in the file. + +* The tie point variables associated with each + **`interpolation_variable`** token must all span the same dimensions, + which comprise a subset of zero or more dimensions of the parent + data or domain variable with at least one tie point interpolation + dimension. A tie point variable must not span both a tie point + interpolation dimension and its corresponding interpolation + dimension as defined by the **`tie_point_dimensions`** mapping. + +* An interpolation variable must have one of the string-valued + attributes **`interpolation_name`** or + **`interpolation_description`**, but not both. The legal values for + the **`interpolation_name`** attribute are contained in Appendix J. + +* When attached to an interpolation variable, the type of the + **`interpolation_parameters`** attribute is a string whose value is + list of blank separated word pairs in the form **`term: var`**. The + legal values **`term`** are contained in Appendix J for each valid + **`interpolation_name`**. The values of **`var`** must be + interpolation parameter variables that exist in the file. + +* Each dimension of an interpolation parameter variable must either be + a non-interpolation dimension of the parent data or domain variable, + or else a tie point interpolation dimension or interpolation zone + dimension corresponding to an interpolation dimension. In the latter + case, the corresponding interpolation dimension must also be spanned + by all of the tie point variables that use this interpolation + variable. + + +   From dffcb7115a360dd145706ceadab5663e2636348c Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 24 Feb 2021 09:27:44 +0000 Subject: [PATCH 124/249] 2nd draft: better descriptions of allowed dimensions --- conformance.adoc | 69 ++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/conformance.adoc b/conformance.adoc index e9a4ec34..871ca1c9 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -651,55 +651,59 @@ sizes minus 1 (CDL index conventions). *Requirements:* -* When attached to a data or domain variable, the type of the +* When attached to a data variable, the type of the **`tie_point_dimensions`** attribute is a string whose value is list of blank separated word groups of the following form, in which brackets indicate optional text: **`interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension]`**. Each **`interpolation_dimension** token specifies a unique - interpolation dimension of the parent data or domain variable, each + interpolation dimension of the parent data variable, each **`tie_point_interpolation_dimension`** token specifies the tie point interpolation dimension of a unique tie point index variable, and each **`interpolation_zone_dimension`** token specifies a unique - interpolation zone dimension. + interpolation zone dimension. The tie point interpolation dimensions + and interpolation zone dimensions must not be dimensions of the + parent data variable. -* When attached to a data or domain variable, the type of the - `tie_point_indices`** attribute is a string whose value is list of - blank separated word groups of the following form: +* When attached to a data variable, the type of the + **`tie_point_indices`** attribute is a string whose value is list of + blank separated word pairs of the following form: **`interpolation_dimension: tie_point_index_variable`**. The - **`interpolation_dimension** tokens specify the interpolation - dimensions of the parent data or domain variable and must match the - same tokens in the **`tie_point_dimensions`** attribute, and each + **`interpolation_dimension** tokens specify the same interpolation + dimensions as the **`tie_point_dimensions`**, and each **`tie_point_index_variable`** token specifies a tie point index variable that must exist in the file. * A tie point index variable must be a one-dimensional variable with - an integer data type. The dimension of the tie point index variable - must be a tie point interpolation dimension identified by the - **`tie_point_dimensions`** attribute. + an integer data type. + +* The dimension of a tie point index variable must be a tie point + interpolation dimension identified by the **`tie_point_dimensions`** + attribute. * The values of a tie point index variable must be non-negative integers. The first value must be zero, and each subsequent value must be greater than or equal to the previous value. If a value differs by zero or one from its previous value, then it must differ - by two or more from the subsequent value. - -* When attached to a data or domain variable, the type of the - **`tie_points`** attribute is a string whose value is list of blank - separated word groups of the following form, in which brackets - indicate optional text: **`tie_point_variable: [tie_point_variable: - ...] interpolation_variable`**. Each **`interpolation_variable`** - token specifies an interpolation variable that must exist in the - file, and each **`tie_point_variable** token specifies a tie point + by two or more from its subsequent value. + +* When attached to a data variable, the type of the **`tie_points`** + attribute is a string whose value is list of blank separated word + groups of the following form, in which brackets indicate optional + text: **`tie_point_variable: [tie_point_variable: ...] + interpolation_variable`**. Each **`tie_point_variable** token + specifies a tie point variable that must exist in the file, and each + **`interpolation_variable`** token specifies an interpolation variable that must exist in the file. * The tie point variables associated with each **`interpolation_variable`** token must all span the same dimensions, which comprise a subset of zero or more dimensions of the parent - data or domain variable with at least one tie point interpolation - dimension. A tie point variable must not span both a tie point - interpolation dimension and its corresponding interpolation - dimension as defined by the **`tie_point_dimensions`** mapping. + data variable with at least one tie point interpolation dimension + identified by the **`tie_point_dimensions`** attribute. A tie point + variable must not span both a tie point interpolation dimension and + its corresponding interpolation dimension defined by the + **`tie_point_dimensions`** mapping. * An interpolation variable must have one of the string-valued attributes **`interpolation_name`** or @@ -713,14 +717,15 @@ sizes minus 1 (CDL index conventions). **`interpolation_name`**. The values of **`var`** must be interpolation parameter variables that exist in the file. -* Each dimension of an interpolation parameter variable must either be - a non-interpolation dimension of the parent data or domain variable, - or else a tie point interpolation dimension or interpolation zone - dimension corresponding to an interpolation dimension. In the latter - case, the corresponding interpolation dimension must also be spanned - by all of the tie point variables that use this interpolation - variable. +* The dimensions of an interpolation parameter variable must either be + a subset of zero or more of the dimensions of the corresponding tie + point variables, with the exception that a tie point interpolation + dimension may be replaced with its corresponding interpolation zone + dimension. + +*Recommendations:* +* An interpolation variable should have 0 dimensions.   From 641dfee087fa5dc4673337dc195432dde60e7305 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 25 Feb 2021 10:05:20 +0000 Subject: [PATCH 125/249] typos --- conformance.adoc | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/conformance.adoc b/conformance.adoc index 871ca1c9..6b43f46a 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -656,7 +656,7 @@ sizes minus 1 (CDL index conventions). of blank separated word groups of the following form, in which brackets indicate optional text: **`interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension]`**. - Each **`interpolation_dimension** token specifies a unique + Each **`interpolation_dimension`** token specifies a unique interpolation dimension of the parent data variable, each **`tie_point_interpolation_dimension`** token specifies the tie point interpolation dimension of a unique tie point index variable, @@ -669,7 +669,7 @@ sizes minus 1 (CDL index conventions). **`tie_point_indices`** attribute is a string whose value is list of blank separated word pairs of the following form: **`interpolation_dimension: tie_point_index_variable`**. The - **`interpolation_dimension** tokens specify the same interpolation + **`interpolation_dimension`** tokens specify the same interpolation dimensions as the **`tie_point_dimensions`**, and each **`tie_point_index_variable`** token specifies a tie point index variable that must exist in the file. @@ -691,19 +691,19 @@ sizes minus 1 (CDL index conventions). attribute is a string whose value is list of blank separated word groups of the following form, in which brackets indicate optional text: **`tie_point_variable: [tie_point_variable: ...] - interpolation_variable`**. Each **`tie_point_variable** token + interpolation_variable`**. Each **`tie_point_variable`** token specifies a tie point variable that must exist in the file, and each **`interpolation_variable`** token specifies an interpolation variable that must exist in the file. * The tie point variables associated with each - **`interpolation_variable`** token must all span the same dimensions, - which comprise a subset of zero or more dimensions of the parent - data variable with at least one tie point interpolation dimension - identified by the **`tie_point_dimensions`** attribute. A tie point - variable must not span both a tie point interpolation dimension and - its corresponding interpolation dimension defined by the - **`tie_point_dimensions`** mapping. + **`interpolation_variable`** token must all span the same + dimensions, which comprise a subset of zero or more dimensions of + the parent data variable with the addition of at least one tie point + interpolation dimension identified by the **`tie_point_dimensions`** + attribute. A tie point variable must not span both a tie point + interpolation dimension and its corresponding interpolation + dimension, as defined by the **`tie_point_dimensions`** mapping. * An interpolation variable must have one of the string-valued attributes **`interpolation_name`** or @@ -717,11 +717,12 @@ sizes minus 1 (CDL index conventions). **`interpolation_name`**. The values of **`var`** must be interpolation parameter variables that exist in the file. -* The dimensions of an interpolation parameter variable must either be - a subset of zero or more of the dimensions of the corresponding tie +* The dimensions of an interpolation parameter variable must be a + subset of zero or more of the dimensions of the corresponding tie point variables, with the exception that a tie point interpolation dimension may be replaced with its corresponding interpolation zone - dimension. + dimension, as defined by the **`tie_point_dimensions`** mapping. + *Recommendations:* From 9d762e99f43d30a13bb84f4f2348e75debbeb75c Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 1 Mar 2021 17:20:59 +0100 Subject: [PATCH 126/249] Correct 'is list' to 'is a list' --- conformance.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conformance.adoc b/conformance.adoc index 6b43f46a..c38b1bce 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -652,7 +652,7 @@ sizes minus 1 (CDL index conventions). *Requirements:* * When attached to a data variable, the type of the - **`tie_point_dimensions`** attribute is a string whose value is list + **`tie_point_dimensions`** attribute is a string whose value is a list of blank separated word groups of the following form, in which brackets indicate optional text: **`interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension]`**. @@ -666,7 +666,7 @@ sizes minus 1 (CDL index conventions). parent data variable. * When attached to a data variable, the type of the - **`tie_point_indices`** attribute is a string whose value is list of + **`tie_point_indices`** attribute is a string whose value is a list of blank separated word pairs of the following form: **`interpolation_dimension: tie_point_index_variable`**. The **`interpolation_dimension`** tokens specify the same interpolation @@ -688,7 +688,7 @@ sizes minus 1 (CDL index conventions). by two or more from its subsequent value. * When attached to a data variable, the type of the **`tie_points`** - attribute is a string whose value is list of blank separated word + attribute is a string whose value is a list of blank separated word groups of the following form, in which brackets indicate optional text: **`tie_point_variable: [tie_point_variable: ...] interpolation_variable`**. Each **`tie_point_variable`** token From 382631a9dd6ad6d5ce3b5f355247b970684103d2 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 1 Mar 2021 16:25:57 +0000 Subject: [PATCH 127/249] Interpolation parameters (#15) * more text following 2020-11-27 discussions * bounds * tidy * tidy * tidy * tidy * reproducability * offset * indices * indices * indices * super * tie_point_dimension (1) * tie_point_dimension (2) * tie_point_dimension (3) * tie_point_dimension (4) * tie point * tie_point_dimension (5) * corrected interpolation_configuration description * zone/area rewording * zone/area rewording * multiple mappings * multiple mappings * multiple mappings * typos and some minor rewording suggestions * format * spell check * markup style * example formatting * example formatting * example formatting * example formatting * minor typesetting * interpolation_parameters * interpolation parameters variable dimensions * interpolation parameters variable dimensions * non-standard provision * interpolation parameters variable dimensions * captions, cdl * tidy * minumum size of interpolation zones * Appendix A attributes * interpolation -> sampling * Conformance - first draft * 2nd draft: better descriptions of allowed dimensions * typos * Correct 'is list' to 'is a list' Co-authored-by: AndersMS <63056394+AndersMS@users.noreply.github.com> --- appa.adoc | 18 +++++ ch08.adoc | 190 +++++++++++++++++++++++++++++++++++------------ conformance.adoc | 97 ++++++++++++++++++++++++ 3 files changed, 258 insertions(+), 47 deletions(-) diff --git a/appa.adoc b/appa.adoc index ee404d74..32eefb4f 100644 --- a/appa.adoc +++ b/appa.adoc @@ -294,6 +294,24 @@ formula in the definition. | <> | A standard name that references a description of a variable"s content in the standard name table. +| **`tie_point_dimensions`** +| S +| D, Do +| <> and <> +| When coordinates have been compressed by sampling, provides a mapping of interpolation dimensions to tie point index variables. + +| **`tie_point_indices`** +| S +| D, Do +| <> and <> +| When coordinates have been compressed by sampling, provides a mapping of interpolation dimensions to tie point interpolation dimensions and interpolation zone dimensions. + +| **`tie_points`** +| S +| D, Do +| <> and <> +| Indicates that coordinates have been compressed by sampling and identifies the tie point variables and their associated interpolation variables. + | **`title`** | S | G, Gr diff --git a/ch08.adoc b/ch08.adoc index 37cbea36..5dffde19 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -145,7 +145,21 @@ The presence of non-interpolation dimensions in the tie point variable impacts t [[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.4, "Tie Point Dimensions Attribute"]] ==== Tie Point Dimensions Attribute -Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by one or more interpolation coefficients or configuration variables, as described in <>. The association is stored in the data variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. +Each interpolation dimension must be associated with its corresponding +tie point interpolation dimension and, if required, its corresponding +__interpolation zone dimension__ that defines the number of +interpolation zones which partition the interpolation +dimension. Regardless of its size, an interpolation zone dimension is +only required if it is spanned by an interpolation parameter variable, +as described in +<>. The +association is stored in the data variable's +**`tie_point_dimensions`** attribute that contains a blank-separated +list of words of the form __"interpolation_dimension: +tie_point_interpolation_dimension [interpolation_zone_dimension] +[interpolation_dimension: ...]"__. If an interpolation zone dimension +is provided then it must be the second of the two named dimensions +following the interpolation dimension. An overview of the different dimensions for coordinate interpolation is shown in <>. @@ -190,11 +204,15 @@ element of a tie point interpolation dimension to its related location in the corresponding interpolation dimension. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension specified by the -**`tie_point_dimensions`** attribute. The values must be strictly -monotonically increasing within interpolation areas. When two adjacent -values are equal, or differ by one, it indicates the location (in -index space) of an interpolation area boundary relating to a grid -discontinuity (<>). +**`tie_point_dimensions`** attribute. The tie point index values must +be strictly monotonically increasing within interpolation areas. An +interpolation zone must span at least two points of each of its +corresponding interpolation dimensions, therefore the tie point +indices that define an interpolation zone must all be different. When +two adjacent values are equal, or differ by one, it indicates the +location (in index space) of an interpolation area boundary relating +to a grid discontinuity +(<>). Each value of the tie point index variable is the index of the interpolation dimension that corresponds to the corresponding @@ -304,37 +322,96 @@ data: [[compression-by-coordinate-sampling-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] ==== Interpolation Variable -The method used to uncompress the tie point variables is described by an interpolation variable that acts as a container for the attributes that define the interpolation technique and the parameters that should be used. The variable should be a scalar (i.e. it has no dimensions) of arbitrary type, and the value of its single element is immaterial. - -The interpolation method must be identified in one of two ways. Either by the **`interpolation_name`** attribute, which takes a string value that contains the method's name, or else by the **`interpolation_description`** attribute, which takes a string value that contains a non-standardized description of the method. These attributes must not be both set. - -The valid values of **`interpolation_name`** are given in <>. This appendix describes the interpolation technique for each method, and optional interpolation variable attributes for configuring the interpolation process. - -If a standardized interpolation name is not given, the interpolation variable must have a **`interpolation_description`** attribute defined instead, containing a description of the non-standardised interpolation (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including a URI, for example). Whilst it is recommended that a standardised interpolation is provided, the alternative is provided to promote interoperability in cases where a well defined user community needs to use sophisticated interpolation techniques that may also be under development. - -The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be identified (e.g. it may be that such tie point variables require particular units or standard names). - -An interpolation method may require __interpolation coefficient variables__ that provide values for interpolation equation terms that are not satisfied by the tie points. Such terms in the interpolation equations are associated with interpolation coefficient variables by the **`interpolation_coefficients`** attribute that takes a string value, the string being comprised of blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that defines one of the terms in the interpolation method's definition, and `variable` is the name of the interpolation coefficient variable that contains the values for that term. The order of elements is not significant. A term that is omitted from the **`interpolation_coefficients`** attribute should be assumed to be zero. - -The interpolation variable attribute **`interpolation_configuration`** may be used to configure the interpolation process. This attribute names other __interpolation configuration variables__ that contain parameters needed to correctly configure the interpolation process. The **`interpolation_configuration`** attribute takes a string value, the string being comprised of blank-separated elements of the form `"item: variable"`, where `item` is a case-insensitive keyword that identifies a configuration item defined in the interpolations method's definition, and `variable` is the name of the interpolation configuration variable that contains the values for that item. The order of elements is not significant. - -The **`interpolation_coefficient`** and **`interpolation_configuration`** attributes may only be provided if allowed by the definition of the interpolation method. - -The variables named by the **`interpolation_coefficients`** and **`interpolation_configuration`** attributes must either be scalar, or else their dimensions may include, for each interpolation dimension, either the corresponding tie point interpolation dimension or the corresponding interpolation zone dimension, but not both, and may include any of the non-interpolation dimensions. - -The interpretation of interpolation coefficient and configuration variables depends on the nature of the dimensions that they span: - -* If no tie point interpolation dimensions are spanned, then the variable provides a value for every interpolation zone. This case is akin to values being defined at the centre of interpolation zones. +The method used to uncompress the tie point variables is described by +an interpolation variable that acts as a container for the attributes +that define the interpolation technique and the parameters that should +be used. The variable should be a scalar (i.e. it has no dimensions) +of arbitrary type, and the value of its single element is immaterial. + +The interpolation method must be identified in one of two ways. Either +by the **`interpolation_name`** attribute, which takes a string value +that contains the method's name, or else by the +**`interpolation_description`** attribute, which takes a string value +that contains a non-standardized description of the method. These +attributes must not be both set. + +The valid values of **`interpolation_name`** are given in <>. This appendix describes the interpolation technique for each +method, and optional interpolation variable attributes for configuring +the interpolation process. + +If a standardized interpolation name is not given, the interpolation +variable must have a **`interpolation_description`** attribute defined +instead, containing a description of the non-standardised +interpolation (in a similar manner to a long name being used instead +of a standard name). This description is free text that can take any +form (including a URI, for example). Whilst it is recommended that a +standardised interpolation is provided, the alternative is provided to +promote interoperability in cases where a well defined user community +needs to use sophisticated interpolation techniques that may also be +under development. + +The definition of the interpolation method, however it is specified, +may include instructions to treat groups of physically related +coordinates simultaneously, if such tie points are present. For +example, there are cases where longitudes cannot be interpolated +without considering the corresponding latitudes. It is up to the +interpolation description to describe how such coordinates are to be +identified (e.g. it may be that such tie point variables require +particular units or standard names). + +Note that the interpolation method is always applied on a per +interpolation zone basis, for which the construction of the +uncompressed coordinates may only access those tie points that define +the extent of the of the interpolation zone. + +The interpolation variable attribute **`interpolation_parameters`** +may be used to provide extra information to the interpolation +process. This attribute names __interpolation parameter variables__ +that provide values for coefficent terms in the interpolation +equation, or for any other terms that configure the interpolation +process. The **`interpolation_parameters`** attribute takes a string +value, the string comprising blank-separated elements of the form +`"term: variable"`, where `term` is a case-insensitive keyword that +defines one of the terms in the interpolation method's definition +given in <>, and `variable` is the name of the +interpolation parameter variable that contains the values for that +term. The order of elements is not significant. A numerical term that +is omitted from the **`interpolation_parameters`** attribute should be +assumed to be zero. + +The **`interpolation_parameters`** attribute may only be provided if +allowed by the definition of the interpolation method. Interplation +parameters may always be provided to non-standardized interpolation +methods. + +The dimensions of an interpolation parameter variable must be a subset +of zero or more the tie point variable dimensions, with the +possibility of a tie point interpolation dimension being replaced with +the corresponding interpolation zone dimension. The interpretation of +an interpolation parameter variable depends on which of its dimensions +are tie point interpolation dimensions, and which are interpolation +zone dimensions: + +* If no tie point interpolation dimensions are spanned, then the + variable provides values for every interpolation zone. This case is + akin to values being defined at the centre of interpolation zones. -* If at least one dimension is a tie point interpolation dimension, then each of the variable's values is to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary (<>). - -In both cases, the implementation of the interpolation method should broadcast an interpolation coefficient or configuration variable along any interpolation zone dimensions that it does not span. - -Note that the interpolation method is always applied on a per interpolation zone basis, for which the construction of the uncompressed coordinates may only access the tie point that define the extent of the of the interpolation zone, as well as any interpolation coefficient and configuration variables defined for the interpolation zone, including its boundaries. - -[[ci_interpolation_coefficients, figure 3]] +* If at least one dimension is a tie point interpolation dimension, + then the variable's values are to be shared by the interpolation + zones that are adjacent along each of the specified tie point + interpolation dimensions. This case is akin to the values being + defined at the interpolation zone boundaries, and therefore equally + applicable to the interpolation zones that share that boundary + (<>). + +In both cases, the implementation of the interpolation method should +assume that an interpolation parameter variable is broadcast to any +interpolation zones that it does not span. + +[[ci_interpolation_parameters, figure 3]] [.text-center] -.Through combination of dimensions, interpolation coefficient and interpolation configuration variables may provide values for each interpolation zone, for couples of neighbouring interpolation zones or for multiple interpolation zones sharing a boundary. +.Through combination of dimensions, interpolation parameter variables may provide values for each interpolation zone, for couples of neighbouring interpolation zones or for multiple interpolation zones sharing a boundary. image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] @@ -349,7 +426,7 @@ Note that an implementation of the interpolation method is free to calculate the [[example-VIIRS]] [caption="Example 8.5. "] -.Multiple interpolation variables with interpolation coefficients and configuration attributes. +.Multiple interpolation variables with interpolation parameter attributes. ==== ---- dimensions : @@ -375,15 +452,27 @@ dimensions : variables: // VIIRS M-Band float m_radiance(m_track, m_scan, m_channel) ; - m_radiance:tie_points = "m_lat: m_lon: m_sen_azi_ang: m_sen_zen_ang: m_sol_azi_ang: m_sol_zen_ang: tp_interpolation t: time_interpolation" ; - m_radiance:tie_point_dimensions = "m_track: tp_track zone_track m_scan: tp_scan zone_scan m_scan: tp_time_scan" ; - m_radiance:tie_point_indices = "m_track: m_track_indices m_scan: m_scan_indices m_scan: m_time_scan_indices" ; + m_radiance:tie_points = + "m_lat: m_lon: m_sen_azi_ang: m_sen_zen_ang: m_sol_azi_ang: m_sol_zen_ang: tp_interpolation + t: time_interpolation" ; + m_radiance:tie_point_dimensions = "m_track: tp_track zone_track + m_scan: tp_scan zone_scan + m_scan: tp_time_scan" ; + m_radiance:tie_point_indices = "m_track: m_track_indices + m_scan: m_scan_indices + m_scan: m_time_scan_indices" ; // VIIRS I-Band float i_radiance(i_track, i_scan, i_channel) ; - i_radiance:tie_points = "i_lat: i_lon: i_sen_azi_ang: i_sen_zen_ang: i_sol_azi_ang: i_sol_zen_ang: tp_interpolation t: time_interpolation" ; - i_radiance:tie_point_dimensions = "i_track: tp_track zone_track i_scan: tp_scan zone_scan i_scan: tp_time_scan" ; - i_radiance:tie_point_indices = "i_track: zone_track: i_track_indices i_scan: zone_scan: i_scan_indices i_scan: i_time_scan_indices" ; + i_radiance:tie_points = + "i_lat: i_lon: i_sen_azi_ang: i_sen_zen_ang: i_sol_azi_ang: i_sol_zen_ang: tp_interpolation + t: time_interpolation" ; + i_radiance:tie_point_dimensions = "i_track: tp_track zone_track + i_scan: tp_scan zone_scan + i_scan: tp_time_scan" ; + i_radiance:tie_point_indices = "i_track: i_track_indices zone_track + i_scan: i_scan_indices zone_scan + i_scan: i_time_scan_indices" ; // Tie point index variables int m_track_indices(tp_track) ; // shared by tp_interpolation and time_interpolation @@ -435,8 +524,12 @@ variables: // Interpolation variable char tp_interpolation ; tp_interpolation:interpolation_name = "bi_quadratic_1" ; - tp_interpolation:interpolation_coefficients = "exp1: expansion1 align1: alignment1 exp2: expansion2 align2:alignment2" ; - tp_interpolation:interpolation_configuration = "flags: interpolation_zone_flags" ; + tp_interpolation:interpolation_parameters = + "exp1: expansion1 + align1: alignment1 + exp2: expansion2 + align2:alignment2 + flags: interpolation_zone_flags" ; // Interpolation coefficient and configuration variables short expansion1(zone_track , tp_scan) ; @@ -446,7 +539,10 @@ variables: byte interpolation_zone_flags(zone_track , zone_scan) ; interpolation_zone_flags : valid_range = "1b, 7b" ; interpolation_zone_flags : flag_masks = "1b, 2b, 4b" ; - interpolation_zone_flags : flag_meanings = "location_use_cartesian sensor_direction_use_cartesian solar_direction_use_cartesian" ; + interpolation_zone_flags : flag_meanings = + "location_use_cartesian + sensor_direction_use_cartesian + solar_direction_use_cartesian" ; // Time tie points double t(tp_track, tp_time_scan) ; @@ -460,8 +556,8 @@ variables: This example demonstrates the use of multiple interpolation variables, the reusability of the interpolation variable between data variables -of different dimensions and the use of the interpolation coefficients -and interpolation configuration attributes. +of different dimensions and the use of the interpolation parameter +attribute. ==== diff --git a/conformance.adoc b/conformance.adoc index a7c18cdf..c38b1bce 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -632,4 +632,101 @@ in the file. starting with 0 and going up to the product of the compressed dimension sizes minus 1 (CDL index conventions). +[[compression-by-gathering]] +=== 8.2 Lossless Compression by Gathering + +*Requirements:* + +* The **`compress`** attribute may only be attached to a coordinate variable +with an integer data type. +* The type of the **`compress`** attribute is a string whose value is a blank +separated list of dimension names. The specified dimensions must exist +in the file. +* The values of the associated coordinate variable must be in the range +starting with 0 and going up to the product of the compressed dimension +sizes minus 1 (CDL index conventions). + +[[compression-by-coordinate-sampling]] +=== 8.3 Lossy Compression by Coordinate Sampling + +*Requirements:* + +* When attached to a data variable, the type of the + **`tie_point_dimensions`** attribute is a string whose value is a list + of blank separated word groups of the following form, in which + brackets indicate optional text: **`interpolation_dimension: + tie_point_interpolation_dimension [interpolation_zone_dimension]`**. + Each **`interpolation_dimension`** token specifies a unique + interpolation dimension of the parent data variable, each + **`tie_point_interpolation_dimension`** token specifies the tie + point interpolation dimension of a unique tie point index variable, + and each **`interpolation_zone_dimension`** token specifies a unique + interpolation zone dimension. The tie point interpolation dimensions + and interpolation zone dimensions must not be dimensions of the + parent data variable. + +* When attached to a data variable, the type of the + **`tie_point_indices`** attribute is a string whose value is a list of + blank separated word pairs of the following form: + **`interpolation_dimension: tie_point_index_variable`**. The + **`interpolation_dimension`** tokens specify the same interpolation + dimensions as the **`tie_point_dimensions`**, and each + **`tie_point_index_variable`** token specifies a tie point index + variable that must exist in the file. + +* A tie point index variable must be a one-dimensional variable with + an integer data type. + +* The dimension of a tie point index variable must be a tie point + interpolation dimension identified by the **`tie_point_dimensions`** + attribute. + +* The values of a tie point index variable must be non-negative + integers. The first value must be zero, and each subsequent value + must be greater than or equal to the previous value. If a value + differs by zero or one from its previous value, then it must differ + by two or more from its subsequent value. + +* When attached to a data variable, the type of the **`tie_points`** + attribute is a string whose value is a list of blank separated word + groups of the following form, in which brackets indicate optional + text: **`tie_point_variable: [tie_point_variable: ...] + interpolation_variable`**. Each **`tie_point_variable`** token + specifies a tie point variable that must exist in the file, and each + **`interpolation_variable`** token specifies an interpolation + variable that must exist in the file. + +* The tie point variables associated with each + **`interpolation_variable`** token must all span the same + dimensions, which comprise a subset of zero or more dimensions of + the parent data variable with the addition of at least one tie point + interpolation dimension identified by the **`tie_point_dimensions`** + attribute. A tie point variable must not span both a tie point + interpolation dimension and its corresponding interpolation + dimension, as defined by the **`tie_point_dimensions`** mapping. + +* An interpolation variable must have one of the string-valued + attributes **`interpolation_name`** or + **`interpolation_description`**, but not both. The legal values for + the **`interpolation_name`** attribute are contained in Appendix J. + +* When attached to an interpolation variable, the type of the + **`interpolation_parameters`** attribute is a string whose value is + list of blank separated word pairs in the form **`term: var`**. The + legal values **`term`** are contained in Appendix J for each valid + **`interpolation_name`**. The values of **`var`** must be + interpolation parameter variables that exist in the file. + +* The dimensions of an interpolation parameter variable must be a + subset of zero or more of the dimensions of the corresponding tie + point variables, with the exception that a tie point interpolation + dimension may be replaced with its corresponding interpolation zone + dimension, as defined by the **`tie_point_dimensions`** mapping. + + +*Recommendations:* + +* An interpolation variable should have 0 dimensions. + +   From a5c6e3b19ccd2d1f52057025978f5a4510f6500d Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 8 Mar 2021 19:01:41 +0100 Subject: [PATCH 128/249] Updated decriptions of quadratic and biquadratic geo methods --- appj.adoc | 65 +++++++++++++++++++++++++++++----------- images/ci_quadratic1.svg | 1 + images/ci_quadratic2.svg | 1 + images/ci_quadratic3.svg | 1 + 4 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 images/ci_quadratic1.svg create mode 100644 images/ci_quadratic2.svg create mode 100644 images/ci_quadratic3.svg diff --git a/appj.adoc b/appj.adoc index f122d395..6bd2f56f 100644 --- a/appj.adoc +++ b/appj.adoc @@ -1,11 +1,16 @@ [[appendix-coordinate-sampling, Appendix J, Coordinate Sampling]] [appendix] -== Coordinate Sampling +== Coordinate Sampling Methods + +The general description of of the compression by coordinate sampling is given in section <>. This appendix provides details on the available methods for compression by coordinate sampling. The definitions and guidance given here allow an application to compress an existing data set using coordinate sampling, while letting the creator of the compressed dataset control the accuracy of the reconstituted coordinates through the degree of subsampling and the choice of interpolation method. Futhermore, the definitions given here allow an application to uncompress coordinate and auxiliary coordinate variables that have been compressed using coordinate sampling. The key element of this process is the reconstitution of the full resolution coordinates in the domain of the data by interpolation between the lower resolution coordinates, the tie points, stored in the compressed dataset. +The appendix is organised in a sections on <>, <>, <> and finally two sections with step procedures <> and <>. + +[[common_definitions_and_notation]] === Common Definitions and Notation The target domain is segmented into smaller interpolation zones as described in <>. @@ -48,6 +53,7 @@ For two dimensional interpolation, `i1` and `i2` are indices in the interpolatio Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refers to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. If, in the two dimensional case, `a = tp(tp2, tp1)` then `b = tp(tp2, tp1+1)`, `c = tp(tp2+1, tp1)` and `d = tp(tp2+1, tp1+1)`, reflecting the way the tie point data would be stored in the data set, see also <>. +[[interpolation_methods]] === Interpolation Methods ==== Linear Interpolation @@ -106,40 +112,55 @@ where `ua` and `ub` are the coordinate values at tie points `a` and `b` respecti [[quadratic_geo]] ==== Quadratic Interpolation of geographic coordinates latitude and longitude +[[quadratic1, figure 2]] +[.text-center] +.With the expansion coefficient ce = 0 and the alignment coefficient ca = 0, the method reconstitutes the points at regular intervals along a great circle between tie points A and B. +image::images/ci_quadratic1.svg[,100%,pdfwidth=50vw,align="center"] + +[[quadratic2, figure 3]] +[.text-center] +.With the expansion coefficient ce > 0 and the alignment coefficient ca > 0, the method reconstitutes the points at intervals of expanding size (ce) along an arc with an alignment offset (ca) from the great circle between tie points A and B. +image::images/ci_quadratic2.svg[,100%,pdfwidth=50vw,align="center"] + + [cols="6,15"] |=============== | Name | **`interpolation_name = "quadratic_geo"`** -| Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + +| Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + + By default, interpolation is performed directly in the latitude and longitude coordinates, but may be performed in cartesian coordinates where required for achieving the desired accuracy. This must be indicated by setting the `location_use_cartesian` flag within the interpolation parameter `interpolation_zone_flags` for each interpolation zone where interpolation in cartesian coordinates is required. -The coefficients of the quadratic interpolation term express the offset of the interpolated point at `s=0.5` relative to a geometric midpoint between the tie points `a` and `b`. The coefficients may be represented in three different ways: +The quadratic interpolation coefficients `ce` and `ca`, stored as interpolation parameters in the product, describes a point `P` between the tie points `A` and `B`, which is equivalent of an additional tie point in the sense that the method will accurately reconstitute the point `P` in the same way as it accurately reconstitutes the tie points `A` and `B`. See <> and <>. -For storage in the dataset as the coefficients `(ce, ca)`, referred to as the dimensional representation. The component `ce` is the offset projected on the line from tie point `b` to tie point `a`. The component `ca` is the offset projected on the line perpendicular to the line from tie point `b` to tie point `a` and perpendicular to the plane spanned `va` and `vb`, the vector representations of the two tie points. + +Although equivalent to a tie point, the coefficients `ce` and `ca` have two advantages over tie points. Firstly, they can often be stored as a lower precision floating point number compared to the tie points, as `ce` and `ca` only describes the position of P relative to the midpoint `M` between the tie points `A` and `B`. Secondly, if any of `ce` and `ca` do not contribute significantly to the accuracy of the reconstituted points, it can be left out of the data set and its value will default to zero during uncompression. -For interpolation in cartesian coordinates as the coefficients `vcxyz = (cx, cy, cz)`, expressing the offset components along the cartesian axes x, y and z respectively. +The coefficients may be represented in three different ways: + +For storage in the dataset as the non-dimensional coefficients `(ce, ca)`, referred to as the parametric representation. The component `ce` is the offset projected on the line from tie point `b` to tie point `a` and expressed as a fraction of the distance between `A` and `B`. The component `ca` is the offset projected on the line perpendicular to the line from tie point `b` to tie point `a` and perpendicular to the plane spanned `va` and `vb`, the vector representations of the two tie points, and expressed as a fraction of the distance between `A` an `B`. + + +For interpolation in cartesian coordinates as the coefficients `vcxyz = (cx, cy, cz)`, expressing the offset components along the cartesian axes X, Y and Z respectively. For interpolation in geographic coordinates latitude and longitude as the coefficients `vcll = (clat, clon)`, expressing the offset components along the longitude and latitude directions respectively. -The functions fq() and fc() referenced in the following are defined in <>. +The functions `fq() `and `fc()` referenced in the following are defined in <>. -Note that in the following, conversions between the latitude-longitude representation of a point, `p = (p.lat, p.lon)`, and its cartesian representation, `vp = (vp.x, vp.y, vp.z)`, are not explicitly stated. Where required they shall be performed using `fll2xyz()` and `fxyz2ll()` defined in <>. +Note that in the following, conversions between the latitude-longitude representation of a point, `p = (p.lat, p.lon)`, and its cartesian representation, `vp = (vp.x, vp.y, vp.z)`, are not explicitly stated. Where required they shall be performed using `fll2xyz()` and `fxyz2ll()` defined in <>. | Interpolation Parameter terms | Any subset of interpolation coefficients `ce, ca`, which must each span the interpolation_zone dimension. + -Optionally the flag variable `interpolation_zone_flags`, which must span the interpolation_zone dimension and must include `location_use_cartesian` in the `flag_meanings` attribute. +Optionally the flag variable `interpolation_zone_flags`, which must span the `interpolation_zone` dimension and must include `location_use_cartesian` in the `flag_meanings` attribute. | Coordinate Compression Calculations | First calculate the cartesian representation of the interpolation coefficients from the tie points `a` and `b` as well as the point `p(i)` at index `i` between the tie points `a` and `b`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib - ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib - ia - 1)/2` shall be selected. + The cartesian interpolation coefficients are found from + `vcxyz = fcxyz(va, vb, vp(i), s(i)) = (fc(va.x, vb.x, vp(i).x, s(i)), fc(va.y, vb.y, vp(i).y, s(i)), fc(va.z, vb.z, vp(i).z, s(i)))` + -Finally, for storage in the dataset, convert the coefficients to the dimensional representation + +Finally, for storage in the dataset, convert the coefficients to the parametric representation + `(ce(iz), ca(iz)) = fcxyz2cea(va, vb, vcxyz) = (fdot(vcxyz, fminus(va, vb))/ (4*(1-rsqr)), fdot(vcxyz, fcross(va, vb))/(2*rsqr*(1-rsqr))` + where `vr = fmultiply(0.5, fplus(va, vb))` and `rsqr = fdot(vr, vr)`. + `vf = fminus(va, vb)`; + `vn = fcross(va, vb)`; + The interpolation parameter term `interpolation_zone_flags(iz)` shall have the flag `location_use_cartesian` set if the interpolation zone intersects the `longitude = 180.0` or if the interpolation zone extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | -First calculate the cartesian representation of the interpolation coefficients from the dimensional representation stored in the dataset using + +First calculate the cartesian representation of the interpolation coefficients from the parametric representation stored in the dataset using + `vcxyz = fcea2cxyz(va, vb, ce(iz), ca(iz)) = fplus(fmultiply(ce, fminus(va, vb)), fmultiply(ca, fcross(va, vb)), fmultiply(cr, vr))` + where + `vr = fmultiply(0.5, fplus(va, vb))`; + @@ -158,14 +179,22 @@ Then use the following expression to reconstitute any point `p(i)` between the t [[bi_quadratic_geo]] ==== Biquadratic Interpolation of geographic coordinates +[[quadratic3, figure 4]] +[.text-center] +.With the expansion coefficient ce = 0 and the alignment coefficient ca = 0, the method reconstitutes the points at regular intervals along a great circle between tie points A and B. +image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] + + [cols="6,15"] |=============== | Name | **`interpolation_name = "bi_quadratic_geo"`** -| Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + +| Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used fro remote sensing products with geographic coordinates on the reference ellipsoid. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + + +The functions `fcxyz()`, `fcxyz2cea()`, `fcea2cxyz()`, `fcxyz2cll()`, `fqxyz()` and `fqll()` referenced in the following are defined in <>. As for that method, interpolation is performed directly in the latitude and longitude coordinates or in cartesian coordinates, where required for achieving the desired accuracy. Similarly, it shares the three different representations of the quadratic interpolation coefficients, the parametric representation `(ce, ca)` for storage in the dataset, `vcll = (clat, clon)` for interpolation in geographic coordinates latitude and longitude and `vcxyz = (cx, cy, cz)` for cartesian interpolation. -The functions fcxyz(), fcxyz2cea(), fcea2cxyz(), fcxyz2cll(), fqxyz() and fqll() referenced in the following are defined in <>. As for this method interpolation is performed directly in the latitude and longitude coordinates or in cartesian coordinates, where required for achieving the desired accuracy. Similarly, it shares the three different representations of the quadratic interpolation coefficients, the dimensional representation `(ce, ca)` for storage in the dataset, `vcll = (clat, clon)` for interpolation in geographic coordinates latitude and longitude and `vcxyz = (cx, cy, cz)` for cartesian interpolation. +The the parametric representation of the interpolation coefficients are store in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3` equivalent to five additional tie points for the interpolation zone as shown in <>, which also shows the orientation and indices of the parameters. -Note that in the following, conversions between the latitude-longitude representation of a point, `p = (p.lat, p.lon)`, and its cartesian representation, `vp = (vp.x, vp.y, vp.z)`, are not explicitly stated. Where required they shall be performed using `fll2xyz()` and `fxyz2ll()` defined in <>. +Note that in the following, conversions between the latitude-longitude representation of a point, `p = (p.lat, p.lon)`, and its cartesian representation, `vp = (vp.x, vp.y, vp.z)`, are not explicitly stated. Where required they shall be performed using `fll2xyz()` and `fxyz2ll()` defined in <>. | Interpolation Parameter terms | Any subset of interpolation coefficients `ce1, ca1`, which must each span the `tie_point_interpolation_2` and `interpolation_zone_1` dimensions; + @@ -181,7 +210,7 @@ Using the selected `(i2, i1)`, the cartesian interpolation coefficients are foun `vcxyz_ab = fcxyz( va, vb, vp(ia2, i1), s(i1));` `vcxyz_cd = fcxyz( vc, vd, vp(ic2, i1), s(i1));` + `vcxyz_ac = fcxyz( va, vc, vp(i2, ia1), s(i2));` `vcxyz_bd = fcxyz( vb, vd, vp(i2, ib1), s(i2));` + `vcxyz_z = fcxyz( fqxyz(va, vc, vcxyz_ac, 0.5), fqxyz(vb, vd, vcxyz_bd, 0.5), vp(i2, i1), s(i1));` + -Finally, for storage in the interpolation parameter datasets, convert the coefficients to the dimensional representation + +Finally, for storage in the interpolation parameter datasets, convert the coefficients to the parametric representation + `(ce1(tp2, iz1), ca1(tp2, iz1)) = fcxyz2cea( va, vb, vcxyz_ab);` + `(ce1(tp2+1, iz1), ca1(tp2+1, iz1)) = fcxyz2cea( vc, vd, vcxyz_cd);` + `(ce2(iz2, tp1), ca2(iz2, tp1)) = fcxyz2cea( va, vc, vcxyz_ac);` + @@ -189,7 +218,7 @@ Finally, for storage in the interpolation parameter datasets, convert the coeffi `(ce3(iz2, iz1), ca3(iz2, iz1)) = fcxyz2cea( fqxyz(va, vc, vcxyz_ac, 0.5), fqxyz(vb, vd, vcxyz_bd, 0.5), vcxyz_z);` + The interpolation parameter term `interpolation_zone_flags(iz2, iz1)` shall have the flag `location_use_cartesian` set if the interpolation zone intersects the `longitude = 180.0` or if the interpolation zone extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | -First calculate the cartesian representation of the interpolation coefficient sets from the dimensional representation stored in the dataset + +First calculate the cartesian representation of the interpolation coefficient sets from the parametric representation stored in the dataset + `vcxyz_ab = fcea2cxyz( va, vb, ce1(tp2, iz1), ca1(tp2, iz1));` + `vcxyz_cd = fcea2cxyz( vc, vd, ce1(tp2+1, iz1), ca1(tp2+1, iz1));` + `vcxyz_ac = fcea2cxyz( va, vc, ce2(iz2, tp1), ca2(iz2, tp1));` + @@ -214,7 +243,7 @@ where + |=============== -[[coordinate_conversion]] +[[common_conversions_and_formulas]] ==== Common conversions and formulas [cols="1, 8, 8"] @@ -246,9 +275,9 @@ where + |=============== -[[interpolation_methods]] +[[coordinate_compression_steps]] === Coordinate Compression Steps [[compression-by-coordinate-sampling-generation-of-tie-points]] @@ -301,7 +330,7 @@ where + |=============== - +[[coordinate_uncompression_steps]] === Coordinate Uncompression Steps diff --git a/images/ci_quadratic1.svg b/images/ci_quadratic1.svg new file mode 100644 index 00000000..a6275a43 --- /dev/null +++ b/images/ci_quadratic1.svg @@ -0,0 +1 @@ +-0.2-0.100.10.2-0.200.20.40.60.811.2YXca(iz)= 0ABM, Pce(iz)= 0 \ No newline at end of file diff --git a/images/ci_quadratic2.svg b/images/ci_quadratic2.svg new file mode 100644 index 00000000..e2c3fd6c --- /dev/null +++ b/images/ci_quadratic2.svg @@ -0,0 +1 @@ +-0.2-0.100.10.2-0.200.20.40.60.811.2YXABMca(iz)= 0.1ce(iz)=0.07P \ No newline at end of file diff --git a/images/ci_quadratic3.svg b/images/ci_quadratic3.svg new file mode 100644 index 00000000..49eb9320 --- /dev/null +++ b/images/ci_quadratic3.svg @@ -0,0 +1 @@ +ABCDca1(tp2+1, iz1)ca1(tp2, iz1)ce1(tp2, iz1)ca1(tp2+1, iz1)ca3(iz2, iz1)ce3(iz2, iz1)ca2(iz2, tp1)ce2(iz2, tp1)ca2(iz2, tp1+1)ce2(iz2, tp1+1) \ No newline at end of file From ba48116dcdb804cd3826f710ca28689a726a1329 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 8 Mar 2021 19:10:08 +0100 Subject: [PATCH 129/249] Updated text of figure 4 --- appj.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 6bd2f56f..08c019c7 100644 --- a/appj.adoc +++ b/appj.adoc @@ -181,7 +181,8 @@ Then use the following expression to reconstitute any point `p(i)` between the t [[quadratic3, figure 4]] [.text-center] -.With the expansion coefficient ce = 0 and the alignment coefficient ca = 0, the method reconstitutes the points at regular intervals along a great circle between tie points A and B. +.The the parametric representation of the interpolation coefficients `(ce, ca)`, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, are equivalent to five additional tie points for the interpolation zone. Shown with parameter orientation and indices. + image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] From 837e8939b979701464cce4f90aaed7b34ec1d93d Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 9 Mar 2021 12:58:33 +0000 Subject: [PATCH 130/249] check on interpolation zone dimension size --- conformance.adoc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/conformance.adoc b/conformance.adoc index c38b1bce..a7db3d9a 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -687,6 +687,13 @@ sizes minus 1 (CDL index conventions). differs by zero or one from its previous value, then it must differ by two or more from its subsequent value. +* The size of an interpolation zone dimension must be equal to the + size of the corresponding tie point interpolation dimension minus + the number of interpolation areas for that tie point interpolation + dimension. The number of interpolation areas is equal one plus the + number of occurences of adjacent values differing by zero or one in + the corresponding tie point index variable. + * When attached to a data variable, the type of the **`tie_points`** attribute is a string whose value is a list of blank separated word groups of the following form, in which brackets indicate optional From a02d099dc7dda5ddd91e6fdb900ae7bee8d45e1a Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 11 Mar 2021 17:19:01 +0100 Subject: [PATCH 131/249] Update appj.adoc Co-authored-by: OceanDataLab --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 08c019c7..63eba0f2 100644 --- a/appj.adoc +++ b/appj.adoc @@ -80,7 +80,7 @@ where `ua` and `ub` are the coordinate values at tie points `a` and `b` respecti | Interpolation Parameter terms | None | Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | -The interpolation function fl() defined for linear interpolation above is first applied twice in the interpolation dimension 1, once between between tie points `a` and `b` and once between tie point `c` and `d`. It is then applied once in the interpolation dimension 2, between the two resulting coordinate points, yielding the interpolated coordinate value `u(i1, i2)`: + +The interpolation function fl() defined for linear interpolation above is first applied twice in the interpolation dimension 1, once between tie points `a` and `b` and once between tie points `c` and `d`. It is then applied once in the interpolation dimension 2, between the two resulting coordinate points, yielding the interpolated coordinate value `u(i1, i2)`: + `uab = fl(ua, ub, s1(i1))`; + `ucd = fl(uc, ud, s1(i1))`; + `u(i1, i2) = fl(uab, ucd, s2(i2))`; + From abe1cbf8a2197ca6aaf9f0e770579cbc204576ae Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 11 Mar 2021 17:19:15 +0100 Subject: [PATCH 132/249] Update appj.adoc Co-authored-by: OceanDataLab --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 63eba0f2..6bfbb116 100644 --- a/appj.adoc +++ b/appj.adoc @@ -130,7 +130,7 @@ image::images/ci_quadratic2.svg[,100%,pdfwidth=50vw,align="center"] + By default, interpolation is performed directly in the latitude and longitude coordinates, but may be performed in cartesian coordinates where required for achieving the desired accuracy. This must be indicated by setting the `location_use_cartesian` flag within the interpolation parameter `interpolation_zone_flags` for each interpolation zone where interpolation in cartesian coordinates is required. -The quadratic interpolation coefficients `ce` and `ca`, stored as interpolation parameters in the product, describes a point `P` between the tie points `A` and `B`, which is equivalent of an additional tie point in the sense that the method will accurately reconstitute the point `P` in the same way as it accurately reconstitutes the tie points `A` and `B`. See <> and <>. +The quadratic interpolation coefficients `ce` and `ca`, stored as interpolation parameters in the product, describe a point `P` between the tie points `A` and `B`, which is equivalent of an additional tie point in the sense that the method will accurately reconstitute the point `P` in the same way as it accurately reconstitutes the tie points `A` and `B`. See <> and <>. Although equivalent to a tie point, the coefficients `ce` and `ca` have two advantages over tie points. Firstly, they can often be stored as a lower precision floating point number compared to the tie points, as `ce` and `ca` only describes the position of P relative to the midpoint `M` between the tie points `A` and `B`. Secondly, if any of `ce` and `ca` do not contribute significantly to the accuracy of the reconstituted points, it can be left out of the data set and its value will default to zero during uncompression. From 5e5a03d8e886c45d2e45c52fb081461ea73bcd77 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 11 Mar 2021 17:19:35 +0100 Subject: [PATCH 133/249] Update appj.adoc Co-authored-by: OceanDataLab --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 6bfbb116..f1d48925 100644 --- a/appj.adoc +++ b/appj.adoc @@ -136,7 +136,7 @@ Although equivalent to a tie point, the coefficients `ce` and `ca` have two adva The coefficients may be represented in three different ways: -For storage in the dataset as the non-dimensional coefficients `(ce, ca)`, referred to as the parametric representation. The component `ce` is the offset projected on the line from tie point `b` to tie point `a` and expressed as a fraction of the distance between `A` and `B`. The component `ca` is the offset projected on the line perpendicular to the line from tie point `b` to tie point `a` and perpendicular to the plane spanned `va` and `vb`, the vector representations of the two tie points, and expressed as a fraction of the distance between `A` an `B`. + +For storage in the dataset as the non-dimensional coefficients `(ce, ca)`, referred to as the parametric representation. The component `ce` is the offset projected on the line from tie point `b` to tie point `a` and expressed as a fraction of the distance between `A` and `B`. The component `ca` is the offset projected on the line perpendicular to the line from tie point `b` to tie point `a` and perpendicular to the plane spanned by `va` and `vb`, the vector representations of the two tie points, and expressed as a fraction of the distance between `A` and `B`. + For interpolation in cartesian coordinates as the coefficients `vcxyz = (cx, cy, cz)`, expressing the offset components along the cartesian axes X, Y and Z respectively. From dba592281eec18a4c1b623350b27d4223522fc79 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 11 Mar 2021 17:19:55 +0100 Subject: [PATCH 134/249] Update appj.adoc Co-authored-by: OceanDataLab --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index f1d48925..d8041550 100644 --- a/appj.adoc +++ b/appj.adoc @@ -181,7 +181,7 @@ Then use the following expression to reconstitute any point `p(i)` between the t [[quadratic3, figure 4]] [.text-center] -.The the parametric representation of the interpolation coefficients `(ce, ca)`, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, are equivalent to five additional tie points for the interpolation zone. Shown with parameter orientation and indices. +.The parametric representation of the interpolation coefficients `(ce, ca)`, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation zone. Shown with parameter orientation and indices. image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] From 1f733338c072b049571a601ac3dbe4a5df78f63b Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 11 Mar 2021 17:20:06 +0100 Subject: [PATCH 135/249] Update appj.adoc Co-authored-by: OceanDataLab --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index d8041550..62a1925b 100644 --- a/appj.adoc +++ b/appj.adoc @@ -189,7 +189,7 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] [cols="6,15"] |=============== | Name | **`interpolation_name = "bi_quadratic_geo"`** -| Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used fro remote sensing products with geographic coordinates on the reference ellipsoid. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + +| Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + The functions `fcxyz()`, `fcxyz2cea()`, `fcea2cxyz()`, `fcxyz2cll()`, `fqxyz()` and `fqll()` referenced in the following are defined in <>. As for that method, interpolation is performed directly in the latitude and longitude coordinates or in cartesian coordinates, where required for achieving the desired accuracy. Similarly, it shares the three different representations of the quadratic interpolation coefficients, the parametric representation `(ce, ca)` for storage in the dataset, `vcll = (clat, clon)` for interpolation in geographic coordinates latitude and longitude and `vcxyz = (cx, cy, cz)` for cartesian interpolation. From 6f62026f8aba6bd54dbb01a629ac36e8ef512735 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 11 Mar 2021 17:20:40 +0100 Subject: [PATCH 136/249] Update appj.adoc Co-authored-by: OceanDataLab --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 62a1925b..d6eb06ac 100644 --- a/appj.adoc +++ b/appj.adoc @@ -193,7 +193,7 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] The functions `fcxyz()`, `fcxyz2cea()`, `fcea2cxyz()`, `fcxyz2cll()`, `fqxyz()` and `fqll()` referenced in the following are defined in <>. As for that method, interpolation is performed directly in the latitude and longitude coordinates or in cartesian coordinates, where required for achieving the desired accuracy. Similarly, it shares the three different representations of the quadratic interpolation coefficients, the parametric representation `(ce, ca)` for storage in the dataset, `vcll = (clat, clon)` for interpolation in geographic coordinates latitude and longitude and `vcxyz = (cx, cy, cz)` for cartesian interpolation. -The the parametric representation of the interpolation coefficients are store in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3` equivalent to five additional tie points for the interpolation zone as shown in <>, which also shows the orientation and indices of the parameters. +The parametric representation of the interpolation coefficients, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation zone as shown in <>, which also shows the orientation and indices of the parameters. Note that in the following, conversions between the latitude-longitude representation of a point, `p = (p.lat, p.lon)`, and its cartesian representation, `vp = (vp.x, vp.y, vp.z)`, are not explicitly stated. Where required they shall be performed using `fll2xyz()` and `fxyz2ll()` defined in <>. From 33197f50b50017da58a71d93e652e308eb691752 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 11 Mar 2021 17:21:01 +0100 Subject: [PATCH 137/249] Update appj.adoc Co-authored-by: OceanDataLab --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index d6eb06ac..c6682e4a 100644 --- a/appj.adoc +++ b/appj.adoc @@ -211,7 +211,7 @@ Using the selected `(i2, i1)`, the cartesian interpolation coefficients are foun `vcxyz_ab = fcxyz( va, vb, vp(ia2, i1), s(i1));` `vcxyz_cd = fcxyz( vc, vd, vp(ic2, i1), s(i1));` + `vcxyz_ac = fcxyz( va, vc, vp(i2, ia1), s(i2));` `vcxyz_bd = fcxyz( vb, vd, vp(i2, ib1), s(i2));` + `vcxyz_z = fcxyz( fqxyz(va, vc, vcxyz_ac, 0.5), fqxyz(vb, vd, vcxyz_bd, 0.5), vp(i2, i1), s(i1));` + -Finally, for storage in the interpolation parameter datasets, convert the coefficients to the parametric representation + +Finally, before storing them in the dataset's interpolation parameters, convert the coefficients to the parametric representation + `(ce1(tp2, iz1), ca1(tp2, iz1)) = fcxyz2cea( va, vb, vcxyz_ab);` + `(ce1(tp2+1, iz1), ca1(tp2+1, iz1)) = fcxyz2cea( vc, vd, vcxyz_cd);` + `(ce2(iz2, tp1), ca2(iz2, tp1)) = fcxyz2cea( va, vc, vcxyz_ac);` + From c72c31b5fed3dd88b2145a30b2124f7367bb1f3b Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 11 Mar 2021 17:21:11 +0100 Subject: [PATCH 138/249] Update ch08.adoc Co-authored-by: OceanDataLab --- ch08.adoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 5dffde19..3783a267 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -381,7 +381,7 @@ is omitted from the **`interpolation_parameters`** attribute should be assumed to be zero. The **`interpolation_parameters`** attribute may only be provided if -allowed by the definition of the interpolation method. Interplation +allowed by the definition of the interpolation method. Interpolation parameters may always be provided to non-standardized interpolation methods. @@ -627,4 +627,3 @@ linearly interpolated in one of their dimensions - the one which is given by the **`tie_point_indices`** attribute. ==== - From bd0162b3db05ad9e06955f196973343dd24a3c83 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 11 Mar 2021 17:36:14 +0100 Subject: [PATCH 139/249] Minor updates --- appj.adoc | 16 ++++++++++++---- ch08.adoc | 6 +++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/appj.adoc b/appj.adoc index 08c019c7..21c3071d 100644 --- a/appj.adoc +++ b/appj.adoc @@ -181,7 +181,7 @@ Then use the following expression to reconstitute any point `p(i)` between the t [[quadratic3, figure 4]] [.text-center] -.The the parametric representation of the interpolation coefficients `(ce, ca)`, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, are equivalent to five additional tie points for the interpolation zone. Shown with parameter orientation and indices. +.The the parametric representation of the interpolation coefficients `(ce, ca)`, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation zone. Shown with parameter orientation and indices. image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] @@ -226,11 +226,14 @@ First calculate the cartesian representation of the interpolation coefficient se `vcxyz_bd = fcea2cxyz( vb, vd, ce2(iz2, tp1+1), ca2(iz2, tp1+1));` + `vcxyz_z = fcea2cxyz( fqxyz(va, vc, vcxyz_ac, 0.5), fqxyz(vb, vd, vcxyz_bd, 0.5), ce3(iz2, iz1), ca3(iz2, iz1));` + If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_zone_flags` is set, use the following expression to reconstitute any point `p(i2, i1)` between the tie points `a` and `b` using interpolation in cartesian coordinates + -`vp(i2, i1) = fqxyz(vab, vcd, vz, s2(i2));` + +`vp(i2, i1) = fqxyz(vab, vcd, vcz, s2(i2));` + where + `vab = fqxyz(va, vb, vcxyz_ab, s1(i1))`; + `vcd = fqxyz(vc, vd, vcxyz_cd, s1(i1))`; + -`vz = fqxyz(vcxyz_ac, vcxyz_bd, vcxyz_z, s1(i1))`. + +`vac = fqxyz(va, vc, vcxyz_ac, 0.5)`; + +`vbd = fqxyz(vb, vd, vcxyz_bd, 0.5)`; + +`vz = fqxyz(vac, vbd, vcxyz_z, s1(i1))`. + +`vcz = fcxyz( vab, vcd, vz, 0.5)` + Otherwise, first calculate latitude-longitude representation of the interpolation coefficients + `vcll_ab = fcxyz2cll( va, vb, vcxyz_ab);` `vcll_cd = fcxyz2cll( vc, vd, vcxyz_cd);` + `vcll_ac = fcxyz2cll( va, vc, vcxyz_ac);` `vcll_bd = fcxyz2cll( vb, vd, vcxyz_bd);` + @@ -240,7 +243,12 @@ Then use the following expression to reconstitute any point `p(i2, i1)` in the t where + `ab = fqll(a, b, vcll_ab, s1(i1))`; + `cd = fqll(c, d, vcll_cd, s1(i1))`; + -`z = fqll(vcll_ac, vcll_bd, vcll_z, s1(i1))`. +`ac = fqll(a, c, vcll_ac, 0.5`; + +`bd = fqll(b, d, vcll_bd, 0.5`; + + + +`z = fqll(vcll_ac, vcll_bd, vcll_z, s1(i1))` +. |=============== diff --git a/ch08.adoc b/ch08.adoc index 5dffde19..0eb358ea 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -73,7 +73,7 @@ This information implies that the salinity field should be uncompressed to an ar [[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Sampling"]] === Lossy Compression by Coordinate Sampling -For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by the storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed dataset can control the accuracy of the reconstituted coordinates through the degree of subsambling and the choice of interpolation method, see <>. +For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed dataset can control the accuracy of the reconstituted coordinates through the degree of subsambling and the choice of interpolation method, see <>. The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. @@ -121,7 +121,7 @@ Within an interpolation area, interpolation zones must share tie points with nei For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__, which also indicates the location of the interpolation areas (<>). -For each interpolation dimension, the number interpolation zones is equal to the number of tie points minus the number of interpolation areas. +For each interpolation dimension, the number of interpolation zones is equal to the number of tie points minus the number of interpolation areas. [[interpolation_zone_generation, figure 1]] [.text-center] @@ -189,7 +189,7 @@ different sets of tie point variables. For instance, if tie point variables lat and lon span dimension `tp_dimension1` and time spans dimension `tp_dimension2`, and all three are to interpolated according to interpolation variable `linear`, then the **`tie_points`** -attribute could be `lat: lon: linear time: linear`. In this case is +attribute could be `lat: lon: linear time: linear`. In this case it is not possible to simultaneously map all three tie point variables to the linear interpolation variable because they do not all span the same axes. From 42c909769c637d0516d9f4df50a95ce2a6bd9c13 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Sun, 21 Mar 2021 22:07:37 +0100 Subject: [PATCH 140/249] Formula improvements --- appj.adoc | 188 +++++++++++++++++++++++++++--------------------------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/appj.adoc b/appj.adoc index dad61f42..6726077d 100644 --- a/appj.adoc +++ b/appj.adoc @@ -46,12 +46,12 @@ where `ia1` and `ib1` are the first dimension indices in the target domain of th For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables the interpolation method can be applied independently for each interpolation zone, making it possible to parallelize the computational process. The following notation is used: + -A variable staring with `v` denotes a vector and `v.x` , `x.y` and `v.z` refer to the three coordinates of that vector. + +A variable staring with `v` denotes a vector and `v.x` , `v.y` and `v.z` refer to the three coordinates of that vector. + A variable staring with `ll` denotes a latitude-longitude coordinate pair and `ll.lat` and `ll.lon` refer to the latitude and longitude coordinates. + For one dimensional interpolation, `i` is an index in the interpolation dimension, `tp` is an index in the tie point interpolation dimension and `iz` is an index in the interpolation zone dimensions. For two dimensional interpolation, `i1` and `i2` are indices in the interpolation dimensions, `tp1` and `tp2` are indices in the tie point interpolation dimensions and `iz1` and `iz2` are indices in the interpolation zone dimensions. + -Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refers to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. If, in the two dimensional case, `a = tp(tp2, tp1)` then `b = tp(tp2, tp1+1)`, `c = tp(tp2+1, tp1)` and `d = tp(tp2+1, tp1+1)`, reflecting the way the tie point data would be stored in the data set, see also <>. +Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refers to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. In the two dimensional case, `a = tp(tp2, tp1)` then `b = tp(tp2, tp1+1)`, `c = tp(tp2+1, tp1)` and `d = tp(tp2+1, tp1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. [[interpolation_methods]] === Interpolation Methods @@ -65,9 +65,9 @@ Note that, for simplicity of notation, the descriptions of the interpolation met | Interpolation Parameter terms | None | Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | - The coordinate value `u(i)` at index `i` between tie points `a` and `b` is calculated from: + + The coordinate value `u(i)` at index `i` between tie points `A` and `B` is calculated from: + `u(i) = fl(ua, ub, s(i)) = (1 - s)*ua + s*ub`; + -where `ua` and `ub` are the coordinate values at tie points `a` and `b` respectively. + +where `ua` and `ub` are the coordinate values at tie points `A` and `B` respectively. + |=============== @@ -80,7 +80,7 @@ where `ua` and `ub` are the coordinate values at tie points `a` and `b` respecti | Interpolation Parameter terms | None | Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | -The interpolation function fl() defined for linear interpolation above is first applied twice in the interpolation dimension 1, once between tie points `a` and `b` and once between tie points `c` and `d`. It is then applied once in the interpolation dimension 2, between the two resulting coordinate points, yielding the interpolated coordinate value `u(i1, i2)`: + +The interpolation function fl() defined for linear interpolation above is first applied twice in the interpolation dimension 1, once between tie points `A` and `B` and once between tie points `C` and `D`. It is then applied once in the interpolation dimension 2, between the two resulting coordinate points, yielding the interpolated coordinate value `u(i1, i2)`: + `uab = fl(ua, ub, s1(i1))`; + `ucd = fl(uc, ud, s1(i1))`; + `u(i1, i2) = fl(uab, ucd, s2(i2))`; + @@ -101,102 +101,93 @@ The interpolation function fl() defined for linear interpolation above is first | Coordinate Compression Calculations | The expression + `c = fc(ua, ub, u(i), s(i)) = ((u - (1 - s) * ua - s * ub)/( 4 * (1 - s) * s)` + -enables the creator of the dataset to calculate `c` from the coordinate values `ua` and `ub` at tie points `a` and `b` respectively, and the coordinate value `u(i)` at index `i` between the tie points `a` and `b`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib - ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib - ia - 1)/2` shall be selected. +enables the creator of the dataset to calculate `c` from the coordinate values `ua` and `ub` at tie points `A` and `B` respectively, and the coordinate value `u(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib - ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib - ia - 1)/2` shall be selected. | Coordinate Uncompression Calculations | -The coordinate value `u(i)` at index `i` between tie points `a` and `b` is calculated from: + +The coordinate value `u(i)` at index `i` between tie points `A` and `B` is calculated from: + `u(i) = fq(ua, ub, c, s(i)) = (1 - s) * ua + 4 * (1 - s) * s * c + s * ub`; + -where `ua` and `ub` are the coordinate values at tie points `a` and `b` respectively and the coefficient `c` is available as a term in the `interpolation_parameters`, or otherwise defaults to `0.0`. + +where `ua` and `ub` are the coordinate values at tie points `A` and `B` respectively and the coefficient `c` is available as a term in the `interpolation_parameters`, or otherwise defaults to `0.0`. + |=============== [[quadratic_geo]] ==== Quadratic Interpolation of geographic coordinates latitude and longitude -[[quadratic1, figure 2]] -[.text-center] -.With the expansion coefficient ce = 0 and the alignment coefficient ca = 0, the method reconstitutes the points at regular intervals along a great circle between tie points A and B. -image::images/ci_quadratic1.svg[,100%,pdfwidth=50vw,align="center"] - -[[quadratic2, figure 3]] -[.text-center] -.With the expansion coefficient ce > 0 and the alignment coefficient ca > 0, the method reconstitutes the points at intervals of expanding size (ce) along an arc with an alignment offset (ca) from the great circle between tie points A and B. -image::images/ci_quadratic2.svg[,100%,pdfwidth=50vw,align="center"] - - [cols="6,15"] |=============== -| Name | **`interpolation_name = "quadratic_geo"`** +| Name | **`interpolation_name = "quadratic_remote_sensing"`** | Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + + By default, interpolation is performed directly in the latitude and longitude coordinates, but may be performed in cartesian coordinates where required for achieving the desired accuracy. This must be indicated by setting the `location_use_cartesian` flag within the interpolation parameter `interpolation_zone_flags` for each interpolation zone where interpolation in cartesian coordinates is required. The quadratic interpolation coefficients `ce` and `ca`, stored as interpolation parameters in the product, describe a point `P` between the tie points `A` and `B`, which is equivalent of an additional tie point in the sense that the method will accurately reconstitute the point `P` in the same way as it accurately reconstitutes the tie points `A` and `B`. See <> and <>. -Although equivalent to a tie point, the coefficients `ce` and `ca` have two advantages over tie points. Firstly, they can often be stored as a lower precision floating point number compared to the tie points, as `ce` and `ca` only describes the position of P relative to the midpoint `M` between the tie points `A` and `B`. Secondly, if any of `ce` and `ca` do not contribute significantly to the accuracy of the reconstituted points, it can be left out of the data set and its value will default to zero during uncompression. +Although equivalent to a tie point, the coefficients `ce` and `ca` have two advantages over tie points. Firstly, they can often be stored as a lower precision floating point number compared to the tie points, as `ce` and `ca` only describes the position of `P` relative to the midpoint `M` between the tie points `A` and `B`. Secondly, if any of `ce` and `ca` do not contribute significantly to the accuracy of the reconstituted points, it can be left out of the data set and its value will default to zero during uncompression. The coefficients may be represented in three different ways: -For storage in the dataset as the non-dimensional coefficients `(ce, ca)`, referred to as the parametric representation. The component `ce` is the offset projected on the line from tie point `b` to tie point `a` and expressed as a fraction of the distance between `A` and `B`. The component `ca` is the offset projected on the line perpendicular to the line from tie point `b` to tie point `a` and perpendicular to the plane spanned by `va` and `vb`, the vector representations of the two tie points, and expressed as a fraction of the distance between `A` and `B`. + - -For interpolation in cartesian coordinates as the coefficients `vcxyz = (cx, cy, cz)`, expressing the offset components along the cartesian axes X, Y and Z respectively. +For storage in the dataset as the non-dimensional coefficients `(ce, ca)`, referred to as the parametric representation. The component `ce` is the offset projected on the line from tie point `B` to tie point `A` and expressed as a fraction of the distance between `A` and `B`. The component `ca` is the offset projected on the line perpendicular to the line from tie point `B` to tie point `A` and perpendicular to the plane spanned by `va` and `vb`, the vector representations of the two tie points, and expressed as a fraction of the distance between `A` and `B`. + -For interpolation in geographic coordinates latitude and longitude as the coefficients `vcll = (clat, clon)`, expressing the offset components along the longitude and latitude directions respectively. +For interpolation in cartesian coordinates as the coefficients `cv = (cv.x, cv.y, cv.z)`, expressing the offset components along the cartesian axes X, Y and Z respectively. -The functions `fq() `and `fc()` referenced in the following are defined in <>. +For interpolation in geographic coordinates latitude and longitude as the coefficients `cll = (cll.lat, cll.lon)`, expressing the offset components along the longitude and latitude directions respectively. -Note that in the following, conversions between the latitude-longitude representation of a point, `p = (p.lat, p.lon)`, and its cartesian representation, `vp = (vp.x, vp.y, vp.z)`, are not explicitly stated. Where required they shall be performed using `fll2xyz()` and `fxyz2ll()` defined in <>. +The functions `fq()` and `fc()` referenced in the following are defined in <>. | Interpolation Parameter terms | Any subset of interpolation coefficients `ce, ca`, which must each span the interpolation_zone dimension. + Optionally the flag variable `interpolation_zone_flags`, which must span the `interpolation_zone` dimension and must include `location_use_cartesian` in the `flag_meanings` attribute. | Coordinate Compression Calculations | -First calculate the cartesian representation of the interpolation coefficients from the tie points `a` and `b` as well as the point `p(i)` at index `i` between the tie points `a` and `b`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib - ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib - ia - 1)/2` shall be selected. + +First calculate the tie point vector representations from the tie point latitude-longitude representations + +`va = fll2v(lla); vb = fll2v(llb);` + +Then calculate the cartesian representation of the interpolation coefficients from the tie points `va` and `vb` as well as the point `vp(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib - ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib - ia - 1)/2` shall be selected. + The cartesian interpolation coefficients are found from + -`vcxyz = fcxyz(va, vb, vp(i), s(i)) = (fc(va.x, vb.x, vp(i).x, s(i)), fc(va.y, vb.y, vp(i).y, s(i)), fc(va.z, vb.z, vp(i).z, s(i)))` + +`cv = fcv(va, vb, vp(i), s(i)) = (fc(va.x, vb.x, vp(i).x, s(i)), fc(va.y, vb.y, vp(i).y, s(i)), fc(va.z, vb.z, vp(i).z, s(i))).` + Finally, for storage in the dataset, convert the coefficients to the parametric representation + -`(ce(iz), ca(iz)) = fcxyz2cea(va, vb, vcxyz) = (fdot(vcxyz, fminus(va, vb))/ (4*(1-rsqr)), fdot(vcxyz, fcross(va, vb))/(2*rsqr*(1-rsqr))` + -where `vr = fmultiply(0.5, fplus(va, vb))` and `rsqr = fdot(vr, vr)`. + -`vf = fminus(va, vb)`; + -`vn = fcross(va, vb)`; + +`(ce(iz), ca(iz)) = fcv2cea(va, vb, cv) = (fdot(cv, fminus(va, vb))/ gsqr), fdot(cv, fcross(va, vb))/(rsqr*gsqr);` + +where `vr = fmultiply(0.5, fplus(va, vb))`, `rsqr = fdot(vr, vr)` and `gsqr = 4*(1-rsqr).` + The interpolation parameter term `interpolation_zone_flags(iz)` shall have the flag `location_use_cartesian` set if the interpolation zone intersects the `longitude = 180.0` or if the interpolation zone extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | -First calculate the cartesian representation of the interpolation coefficients from the parametric representation stored in the dataset using + -`vcxyz = fcea2cxyz(va, vb, ce(iz), ca(iz)) = fplus(fmultiply(ce, fminus(va, vb)), fmultiply(ca, fcross(va, vb)), fmultiply(cr, vr))` + +First calculate the tie point vector representations from the tie point latitude-longitude representations + +`va = fll2v(lla); vb = fll2v(llb);` + +Then calculate the cartesian representation of the interpolation coefficients from the parametric representation stored in the dataset using + +`cv = fcea2cv(va, vb, ce(iz), ca(iz)) = fplus(fmultiply(ce, fminus(va, vb)), fmultiply(ca, fcross(va, vb)), fmultiply(cr, vr));` + where + `vr = fmultiply(0.5, fplus(va, vb))`; + -`rsqr = fdot(vr, vr)`. + -`cr = fsqrt(1 - ce(iz)*ce(iz) - ca(iz)*ca(iz)) - fsqrt(rsqr)`; + -If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_zone_flags(iz2, iz1)` is set, use the following expression to reconstitute any point `p(i)` between the tie points `a` and `b` using interpolation in cartesian coordinates + -`vp(i) = fqxyz(va, vb, vcxyz, s(i)) = (fq(va.x, vb.x, vcxyz.x, s(i)), fq(va.y, vb.y, vcxyz.y, s(i)), fq(va.z, vb.z, vcxyz.z, s(i)))` + +`rsqr = fdot(vr, vr);` + +`cr = fsqrt(1 - ce(iz)*ce(iz) - ca(iz)*ca(iz)) - fsqrt(rsqr).` + +If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_zone_flags(iz2, iz1)` is set, use the following expression to reconstitute any point `llp(i)` between the tie points `A` and `B` using interpolation in cartesian coordinates + +`vp(i) = fqv(va, vb, cv, s(i)) = (fq(va.x, vb.x, cv.x, s(i)), fq(va.y, vb.y, cv.y, s(i)), fq(va.z, vb.z, cv.z, s(i)));` + +`llp(i) = fv2ll(vp(i)).` + Otherwise, first calculate latitude-longitude representation of the interpolation coefficients + -`vcll = fcxyz2cll(va, vb, vcea) = (fc(a.lat, b.lat, pll.lat, 0.5), fc(a.lon, b.lon, pll.lon, 0.5))` + -where `pll = fxyz2ll(fqxyz(va, vb, vcxyz, 0.5))`. + -Then use the following expression to reconstitute any point `p(i)` between the tie points `a` and `b` using interpolation in latitude-longitude coordinates + -`p(i) = (p(i).lat, p(i).lon) = fqll(va, vb, vcll, s(i)) = ((fq(a.lat, b.lat, vcll.lat, s(i)), fq(a.lon, b.lon, .vcll.lon, s(i))`. + +`cll = fcll(lla, llb, llab) = (fc(lla.lat, llb.lat, llab.lat, 0.5), fc(lla.lon, llb.lon, llab.lon, 0.5));` + +where `llab = fv2ll(fqv(va, vb, cv, 0.5))`. + +Then use the following expression to reconstitute any point `llp(i)` between the tie points `A` and `B` using interpolation in latitude-longitude coordinates + +`llp(i) = (llp(i).lat, llp(i).lon) = fqll(lla, llb, cll, s(i)) = (fq(lla.lat, llb.lat, cll.lat, s(i)), fq(lla.lon, llb.lon, cll.lon, s(i)))`. + |=============== +[[quadratic1, figure 2]] +[.text-center] +.With the expansion coefficient ce = 0 and the alignment coefficient ca = 0, the method reconstitutes the points at regular intervals along a great circle between tie points A and B. +image::images/ci_quadratic1.svg[,100%,pdfwidth=50vw,align="center"] -[[bi_quadratic_geo]] -==== Biquadratic Interpolation of geographic coordinates - -[[quadratic3, figure 4]] +[[quadratic2, figure 3]] [.text-center] -.The parametric representation of the interpolation coefficients `(ce, ca)`, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation zone. Shown with parameter orientation and indices. +.With the expansion coefficient ce > 0 and the alignment coefficient ca > 0, the method reconstitutes the points at intervals of expanding size (ce) along an arc with an alignment offset (ca) from the great circle between tie points A and B. +image::images/ci_quadratic2.svg[,100%,pdfwidth=50vw,align="center"] -image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] +[[bi_quadratic_geo]] +==== Biquadratic Interpolation of geographic coordinates [cols="6,15"] |=============== -| Name | **`interpolation_name = "bi_quadratic_geo"`** +| Name | **`interpolation_name = "bi_quadratic_remote_sensing"`** | Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + -The functions `fcxyz()`, `fcxyz2cea()`, `fcea2cxyz()`, `fcxyz2cll()`, `fqxyz()` and `fqll()` referenced in the following are defined in <>. As for that method, interpolation is performed directly in the latitude and longitude coordinates or in cartesian coordinates, where required for achieving the desired accuracy. Similarly, it shares the three different representations of the quadratic interpolation coefficients, the parametric representation `(ce, ca)` for storage in the dataset, `vcll = (clat, clon)` for interpolation in geographic coordinates latitude and longitude and `vcxyz = (cx, cy, cz)` for cartesian interpolation. +The functions `fcv()`, `fcv2cea()`, `fcea2cv()`, `fcll()`, `fqv()` and `fqll()` referenced in the following are defined in <>. As for that method, interpolation is performed directly in the latitude and longitude coordinates or in cartesian coordinates, where required for achieving the desired accuracy. Similarly, it shares the three different representations of the quadratic interpolation coefficients, the parametric representation `(ce, ca)` for storage in the dataset, `cll = (cll.lat, cll.lon)` for interpolation in geographic coordinates latitude and longitude and `cv = (cv.x, cv.y, cv.z)` for cartesian interpolation. The parametric representation of the interpolation coefficients, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation zone as shown in <>, which also shows the orientation and indices of the parameters. -Note that in the following, conversions between the latitude-longitude representation of a point, `p = (p.lat, p.lon)`, and its cartesian representation, `vp = (vp.x, vp.y, vp.z)`, are not explicitly stated. Where required they shall be performed using `fll2xyz()` and `fxyz2ll()` defined in <>. - | Interpolation Parameter terms | Any subset of interpolation coefficients `ce1, ca1`, which must each span the `tie_point_interpolation_2` and `interpolation_zone_1` dimensions; + Any subset of interpolation coefficients `ce2, ca2`, which must each span the `interpolation_zone_2` and `tie_point_interpolation_1` dimensions; + @@ -205,52 +196,61 @@ Any subset of interpolation coefficients `ce3, ca3`, which must each span the `i Optionally the flag variable `interpolation_zone_flags`, which must span the `interpolation_zone_2` and `interpolation_zone_1` dimensions and must include `location_use_cartesian` in the `flag_meanings` attribute. | Coordinate Compression Calculations | - -First calculate the cartesian representation of the interpolation coefficients sets from the tie points as well as a point `p(i2, i1)` between the tie points. If the size of the interpolation zone in the first dimension `(ib1 - ia1)` is an even number, then the index `i1 = (ib1 - ia1)/2` shall be selected for this calculation, otherwise the index `i1 = (ib1 - ia1 - 1)/2` shall be selected. If the size of the interpolation zone in the second dimension `(ib2 - ic2)` is an even number, then the index `i2 = (ib2 - ic2)/2` shall be selected for this calculation, otherwise the index `i2 = (ib2 - ic2 - 1)/2` shall be selected. + +First calculate the tie point vector representations from the tie point latitude-longitude representations + +`va = fll2v(lla); vb = fll2v(llb); vc = fll2v(llc); vd = fll2v(lld).` + +Then calculate the cartesian representation of the interpolation coefficients sets from the tie points as well as a point `vp(i2, i1)` between the tie points. If the size of the interpolation zone in the first dimension `(ib1 - ia1)` is an even number, then the index `i1 = (ib1 - ia1)/2` shall be selected for this calculation, otherwise the index `i1 = (ib1 - ia1 - 1)/2` shall be selected. If the size of the interpolation zone in the second dimension `(ib2 - ic2)` is an even number, then the index `i2 = (ib2 - ic2)/2` shall be selected for this calculation, otherwise the index `i2 = (ib2 - ic2 - 1)/2` shall be selected. + Using the selected `(i2, i1)`, the cartesian interpolation coefficients are found from + -`vcxyz_ab = fcxyz( va, vb, vp(ia2, i1), s(i1));` `vcxyz_cd = fcxyz( vc, vd, vp(ic2, i1), s(i1));` + -`vcxyz_ac = fcxyz( va, vc, vp(i2, ia1), s(i2));` `vcxyz_bd = fcxyz( vb, vd, vp(i2, ib1), s(i2));` + -`vcxyz_z = fcxyz( fqxyz(va, vc, vcxyz_ac, 0.5), fqxyz(vb, vd, vcxyz_bd, 0.5), vp(i2, i1), s(i1));` + +`cv_ab = fcv( va, vb, vp(ia2, i1), s(i1));` + +`cv_cd = fcv( vc, vd, vp(ic2, i1), s(i1));` + +`cv_ac = fcv( va, vc, vp(i2, ia1), s(i2));` + +`cv_bd = fcv( vb, vd, vp(i2, ib1), s(i2));` + +`vab = fqv(va, vb, cv_ab, s1(i1))`; + +`vcd = fqv(vc, vd, cv_cd, s1(i1))`; + +`cv_zz = fcv( vab, vcd, vp(i2, i1), s(i2));` + +`vac = fqv(va, vc, cv_ac, 0.5);` + +`vbd = fqv(vb, vd, cv_bd, 0.5);` + +`vz = fqv( vab, vcd, cv_zz, 0.5);` + +`cv_z = fcv( vac, vbd, vz, 0.5).` + Finally, before storing them in the dataset's interpolation parameters, convert the coefficients to the parametric representation + -`(ce1(tp2, iz1), ca1(tp2, iz1)) = fcxyz2cea( va, vb, vcxyz_ab);` + -`(ce1(tp2+1, iz1), ca1(tp2+1, iz1)) = fcxyz2cea( vc, vd, vcxyz_cd);` + -`(ce2(iz2, tp1), ca2(iz2, tp1)) = fcxyz2cea( va, vc, vcxyz_ac);` + -`(ce2(iz2, tp1+1), ca2(iz2, tp1+1)) = fcxyz2cea( vb, vd, vcxyz_bd);` + -`(ce3(iz2, iz1), ca3(iz2, iz1)) = fcxyz2cea( fqxyz(va, vc, vcxyz_ac, 0.5), fqxyz(vb, vd, vcxyz_bd, 0.5), vcxyz_z);` + +`(ce1(tp2, iz1), ca1(tp2, iz1)) = fcv2cea( va, vb, cv_ab);` + +`(ce1(tp2+1, iz1), ca1(tp2+1, iz1)) = fcv2cea( vc, vd, cv_cd);` + +`(ce2(iz2, tp1), ca2(iz2, tp1)) = fcv2cea( va, vc, cv_ac);` + +`(ce2(iz2, tp1+1), ca2(iz2, tp1+1)) = fcv2cea( vb, vd, cv_bd);` + +`(ce3(iz2, iz1), ca3(iz2, iz1)) = fcv2cea( vac, vbd, cv_z).` + The interpolation parameter term `interpolation_zone_flags(iz2, iz1)` shall have the flag `location_use_cartesian` set if the interpolation zone intersects the `longitude = 180.0` or if the interpolation zone extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | -First calculate the cartesian representation of the interpolation coefficient sets from the parametric representation stored in the dataset + -`vcxyz_ab = fcea2cxyz( va, vb, ce1(tp2, iz1), ca1(tp2, iz1));` + -`vcxyz_cd = fcea2cxyz( vc, vd, ce1(tp2+1, iz1), ca1(tp2+1, iz1));` + -`vcxyz_ac = fcea2cxyz( va, vc, ce2(iz2, tp1), ca2(iz2, tp1));` + -`vcxyz_bd = fcea2cxyz( vb, vd, ce2(iz2, tp1+1), ca2(iz2, tp1+1));` + -`vcxyz_z = fcea2cxyz( fqxyz(va, vc, vcxyz_ac, 0.5), fqxyz(vb, vd, vcxyz_bd, 0.5), ce3(iz2, iz1), ca3(iz2, iz1));` + -If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_zone_flags` is set, use the following expression to reconstitute any point `p(i2, i1)` between the tie points `a` and `b` using interpolation in cartesian coordinates + -`vp(i2, i1) = fqxyz(vab, vcd, vcz, s2(i2));` + +First calculate the tie point vector representations from the tie point latitude-longitude representations + +`va = fll2v(lla); vb = fll2v(llb); vc = fll2v(llc); vd = fll2v(lld).` + +Then calculate the cartesian representation of the interpolation coefficient sets from the parametric representation stored in the dataset + +`cv_ab = fcea2cv( va, vb, ce1(tp2, iz1), ca1(tp2, iz1));` + +`cv_cd = fcea2cv( vc, vd, ce1(tp2+1, iz1), ca1(tp2+1, iz1));` + +`vac = fqv(va, vc, fcea2cv( va, vc, ce2(iz2, tp1), ca2(iz2, tp1)), 0.5);` + +`vbd = fqv(vb, vd, fcea2cv( vb, vd, ce2(iz2, tp1+1), ca2(iz2, tp1+1)), 0.5);` + +`cv_z = fcea2cv( vac, vbd, ce3(iz2, iz1), ca3(iz2, iz1)).` + +If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_zone_flags` is set, use the following expression to reconstitute any point `llp(i2, i1)` between the tie points `A` and `B` using interpolation in cartesian coordinates + +`llp(i2, i1) = fv2ll(fqv(vab, vcd, fcv( vab, vcd, vz, 0.5), s2(i2)));` + where + -`vab = fqxyz(va, vb, vcxyz_ab, s1(i1))`; + -`vcd = fqxyz(vc, vd, vcxyz_cd, s1(i1))`; + -`vac = fqxyz(va, vc, vcxyz_ac, 0.5)`; + -`vbd = fqxyz(vb, vd, vcxyz_bd, 0.5)`; + -`vz = fqxyz(vac, vbd, vcxyz_z, s1(i1))`. + -`vcz = fcxyz( vab, vcd, vz, 0.5)` + +`vab = fqv(va, vb, cv_ab, s1(i1));` + +`vcd = fqv(vc, vd, cv_cd, s1(i1));` + +`vz = fqv(vac, vbd, cv_z, s1(i1)).` + Otherwise, first calculate latitude-longitude representation of the interpolation coefficients + -`vcll_ab = fcxyz2cll( va, vb, vcxyz_ab);` `vcll_cd = fcxyz2cll( vc, vd, vcxyz_cd);` + -`vcll_ac = fcxyz2cll( va, vc, vcxyz_ac);` `vcll_bd = fcxyz2cll( vb, vd, vcxyz_bd);` + -`vcll_z = fcxyz2cll( fqxyz(va, vc, vcxyz_ac, 0.5), fqxyz(vb, vd, vcxyz_bd, 0.5), vcxyz_z);` + -Then use the following expression to reconstitute any point `p(i2, i1)` in the tie point zone using interpolation in latitude-longitude coordinates + - `p(i2, i1) = fqll(ab, cd, z, s2(i2));` + +`llc_ab = fcll( a, b, fv2ll(fqv(va, vb, cv_ab, 0.5)));` + +`llc_cd = fcll( c, d, fv2ll(fqv(vc, vd, cv_cd, 0.5)));` + +`llac = fv2ll(vac); llbd = fv2ll(vbd);` + +`llc_z = fcll( a, b, fv2ll(fqv(vac, vbd, cv_ab, 0.5))).` + +Then use the following expression to reconstitute any point `llp(i2, i1)` in the tie point zone using interpolation in latitude-longitude coordinates + + `llp(i2, i1) = fqll(llab, llcd, fcll(llab, llcd, llz, 0.5), s2(i2));` + where + -`ab = fqll(a, b, vcll_ab, s1(i1))`; + -`cd = fqll(c, d, vcll_cd, s1(i1))`; + -`ac = fqll(a, c, vcll_ac, 0.5`; + -`bd = fqll(b, d, vcll_bd, 0.5`; + - - -`z = fqll(vcll_ac, vcll_bd, vcll_z, s1(i1))` -. +`llab = fqll(a, b, llc_ab, s1(i1));` + +`llcd = fqll(c, d, llc_cd, s1(i1));` + +`llz = fqll(llac, llbd, llc_z, s1(i1)).` + |=============== +[[quadratic3, figure 4]] +[.text-center] +.The parametric representation of the interpolation coefficients `(ce, ca)`, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation zone. Shown with parameter orientation and indices. +image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] + [[common_conversions_and_formulas]] ==== Common conversions and formulas @@ -259,13 +259,13 @@ where + |=============== | |Description | Formula -| fll2xyz | Conversion from geocentric `(latitude, longitude)` to cartesian vector `(x, y, z)` | `(x, y, z) = fll2xyz(ll) = (cos⁡(ll.lat)*cos⁡(ll.lon), cos⁡(ll.lat)*sin⁡(ll.lon), sin⁡(ll.lat))` + +| fll2v | Conversion from geocentric `(latitude, longitude)` to cartesian vector `(x, y, z)` | `(x, y, z) = fll2v(ll) = (cos⁡(ll.lat)*cos⁡(ll.lon), cos⁡(ll.lat)*sin⁡(ll.lon), sin⁡(ll.lat))` + -| fxyz2ll | Conversion from cartesian vector `(x, y, z)` to geocentric `(latitude, longitude)`| `(lat, lon) = fxyz2ll(v) = (atan2(v.y, v.x), atan2(z, sqrt(v.x * v.x + v.y * v.y))` + +| fv2ll | Conversion from cartesian vector `(x, y, z)` to geocentric `(latitude, longitude)`| `(lat, lon) = fv2ll(v) = (atan2(v.y, v.x), atan2(z, sqrt(v.x * v.x + v.y * v.y))` + -| faz2xyz | Conversion from `(azimuth, zenith)` angles to cartesian vector `(x, y, z)` | `(x, y, z) = faz2xyz(az) = (sin⁡(az.zenith) * sin⁡(az.azimuth), sin⁡(az.zenith) * cos⁡(az.azimuth), cos⁡(az.zenith))` + +| faz2v | Conversion from `(azimuth, zenith)` angles to cartesian vector `(x, y, z)` | `(x, y, z) = faz2v(az) = (sin⁡(az.zenith) * sin⁡(az.azimuth), sin⁡(az.zenith) * cos⁡(az.azimuth), cos⁡(az.zenith))` + -| fxyz2az | Conversion from cartesian vector `(x, y, z)` to `(azimuth, zenith)` angles | `(azimuth, zenith) = fxyz2az(v) = (atan2(y, x), atan2(sqrt(x * x + y * y), z)` + +| fv2az | Conversion from cartesian vector `(x, y, z)` to `(azimuth, zenith)` angles | `(azimuth, zenith) = fv2az(v) = (atan2(y, x), atan2(sqrt(x * x + y * y), z)` + | fsqrt | Square Root | `s = fsqrt(t)` From ab53e2e667827d952fa4340032f7e77127bb68f5 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 22 Mar 2021 17:19:55 +0100 Subject: [PATCH 141/249] Update appj.adoc Co-authored-by: OceanDataLab --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 6726077d..9b57947d 100644 --- a/appj.adoc +++ b/appj.adoc @@ -51,7 +51,7 @@ A variable staring with `ll` denotes a latitude-longitude coordinate pair and `l For one dimensional interpolation, `i` is an index in the interpolation dimension, `tp` is an index in the tie point interpolation dimension and `iz` is an index in the interpolation zone dimensions. For two dimensional interpolation, `i1` and `i2` are indices in the interpolation dimensions, `tp1` and `tp2` are indices in the tie point interpolation dimensions and `iz1` and `iz2` are indices in the interpolation zone dimensions. + -Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refers to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. In the two dimensional case, `a = tp(tp2, tp1)` then `b = tp(tp2, tp1+1)`, `c = tp(tp2+1, tp1)` and `d = tp(tp2+1, tp1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. +Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refer to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. In the two dimensional case, `a = tp(tp2, tp1)` then `b = tp(tp2, tp1+1)`, `c = tp(tp2+1, tp1)` and `d = tp(tp2+1, tp1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. [[interpolation_methods]] === Interpolation Methods From 11428f4120fd1763111f6d344d25482048f73585 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 22 Mar 2021 17:25:19 +0100 Subject: [PATCH 142/249] Minor editorial correction --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 9b57947d..149374c7 100644 --- a/appj.adoc +++ b/appj.adoc @@ -51,7 +51,7 @@ A variable staring with `ll` denotes a latitude-longitude coordinate pair and `l For one dimensional interpolation, `i` is an index in the interpolation dimension, `tp` is an index in the tie point interpolation dimension and `iz` is an index in the interpolation zone dimensions. For two dimensional interpolation, `i1` and `i2` are indices in the interpolation dimensions, `tp1` and `tp2` are indices in the tie point interpolation dimensions and `iz1` and `iz2` are indices in the interpolation zone dimensions. + -Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refer to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. In the two dimensional case, `a = tp(tp2, tp1)` then `b = tp(tp2, tp1+1)`, `c = tp(tp2+1, tp1)` and `d = tp(tp2+1, tp1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. +Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refer to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. In the two dimensional case, `a = tp(tp2, tp1)`, `b = tp(tp2, tp1+1)`, `c = tp(tp2+1, tp1)` and `d = tp(tp2+1, tp1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. [[interpolation_methods]] === Interpolation Methods From 7855a0b0bf295a1c9912f00ce070136a8048f873 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 20 Apr 2021 10:03:43 +0100 Subject: [PATCH 143/249] conformance changes for new interpolation variable --- conformance.adoc | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/conformance.adoc b/conformance.adoc index a7db3d9a..ac9a1550 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -651,6 +651,95 @@ sizes minus 1 (CDL index conventions). *Requirements:* +* When attached to a data variable, the type of the **`tie_points`** + attribute is a string whose value is a list of blank separated word + groups of the following form, in which brackets indicate optional + text: **`tie_point_variable: [tie_point_variable: ...] + interpolation_variable`**. Each **`tie_point_variable`** token + specifies a tie point variable that must exist in the file, and each + **`interpolation_variable`** token specifies an interpolation + variable that must exist in the file. + +* An interpolation variable must have one of the string-valued + attributes **`interpolation_name`** or + **`interpolation_description`**, but not both. The legal values for + the **`interpolation_name`** attribute are contained in Appendix J. + +* An interpolation variable must have a **`tie_point_dimensions`** + attribute that is a string whose value is a list of blank separated + word groups of the following form, in which brackets indicate + optional text: **`interpolation_dimension: + tie_point_interpolation_dimension [interpolation_zone_dimension]`**. + Each **`interpolation_dimension`** token specifies a unique + interpolation dimension of the parent data variable, each + **`tie_point_interpolation_dimension`** token specifies the tie + point interpolation dimension of a unique tie point index variable, + and each **`interpolation_zone_dimension`** token specifies a unique + interpolation zone dimension. The tie point interpolation dimensions + and interpolation zone dimensions must not be dimensions of the + parent data variable. + +* The tie point variables associated with each + `interpolation_variable`** token must all span the same dimensions, + which comprise a subset of zero or more dimensions of the parent + data variable with the addition of at least one tie point + interpolation dimension identified by the **`tie_point_dimensions`** + attribute of the interpolation variable. A tie point variable must + not span both a tie point interpolation dimension and its + corresponding interpolation dimension, as defined by the + **`tie_point_dimensions`** mapping. + +* An interpolation variable must have a **`tie_point_indices`** + attribute that is a string whose value is a list of blank separated + word pairs of the following form: **`interpolation_dimension: + tie_point_index_variable`**. The **`interpolation_dimension`** + tokens specify the same interpolation dimensions as the + **`tie_point_dimensions`** attribute, and each + **`tie_point_index_variable`** token specifies a tie point index + variable that must exist in the file. + +* A tie point index variable must be a one-dimensional variable with + an integer data type. + +* The dimension of a tie point index variable must be a tie point + interpolation dimension identified by the **`tie_point_dimensions`** + attribute. + +* The values of a tie point index variable must be non-negative + integers. The first value must be zero, and each subsequent value + must be greater than or equal to the previous value. If a value + differs by zero or one from its previous value, then it must differ + by two or more from its subsequent value. + +* When attached to an interpolation variable, the type of the + **`interpolation_parameters`** attribute is a string whose value is + list of blank separated word pairs in the form **`term: var`**. The + legal values **`term`** are contained in Appendix J for each valid + **`interpolation_name`**. The values of **`var`** must be + interpolation parameter variables that exist in the file. + +* The size of an interpolation zone dimension must be equal to the + size of the corresponding tie point interpolation dimension minus + the number of interpolation areas for that tie point interpolation + dimension. The number of interpolation areas is equal one plus the + number of occurences of adjacent values differing by zero or one in + the corresponding tie point index variable. + +* The dimensions of an interpolation parameter variable must be a + subset of zero or more of the dimensions of the corresponding tie + point variables, with the exception that a tie point interpolation + dimension may be replaced with its corresponding interpolation zone + dimension, as defined by the **`tie_point_dimensions`** mapping. + +*Recommendations:* + +* An interpolation variable should have 0 dimensions. + + +  + +*Requirements:* + * When attached to a data variable, the type of the **`tie_point_dimensions`** attribute is a string whose value is a list of blank separated word groups of the following form, in which From 361ee0e8d08a1e55ff9a1871506a6d718337ac65 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 20 Apr 2021 10:09:47 +0100 Subject: [PATCH 144/249] conformance changes for new interpolation variable --- conformance.adoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/conformance.adoc b/conformance.adoc index ac9a1550..18942de7 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -680,7 +680,7 @@ sizes minus 1 (CDL index conventions). parent data variable. * The tie point variables associated with each - `interpolation_variable`** token must all span the same dimensions, + **`interpolation_variable`** token must all span the same dimensions, which comprise a subset of zero or more dimensions of the parent data variable with the addition of at least one tie point interpolation dimension identified by the **`tie_point_dimensions`** @@ -711,13 +711,6 @@ sizes minus 1 (CDL index conventions). differs by zero or one from its previous value, then it must differ by two or more from its subsequent value. -* When attached to an interpolation variable, the type of the - **`interpolation_parameters`** attribute is a string whose value is - list of blank separated word pairs in the form **`term: var`**. The - legal values **`term`** are contained in Appendix J for each valid - **`interpolation_name`**. The values of **`var`** must be - interpolation parameter variables that exist in the file. - * The size of an interpolation zone dimension must be equal to the size of the corresponding tie point interpolation dimension minus the number of interpolation areas for that tie point interpolation @@ -725,6 +718,13 @@ sizes minus 1 (CDL index conventions). number of occurences of adjacent values differing by zero or one in the corresponding tie point index variable. +* When attached to an interpolation variable, the type of the + **`interpolation_parameters`** attribute is a string whose value is + list of blank separated word pairs in the form **`term: var`**. The + legal values **`term`** are contained in Appendix J for each valid + **`interpolation_name`**. The values of **`var`** must be + interpolation parameter variables that exist in the file. + * The dimensions of an interpolation parameter variable must be a subset of zero or more of the dimensions of the corresponding tie point variables, with the exception that a tie point interpolation From 24fea49c592304628f4dd5b2080f01f4def28438 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 20 Apr 2021 10:12:10 +0100 Subject: [PATCH 145/249] conformance changes for new interpolation variable --- conformance.adoc | 90 ------------------------------------------------ 1 file changed, 90 deletions(-) diff --git a/conformance.adoc b/conformance.adoc index 18942de7..069faf04 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -735,94 +735,4 @@ sizes minus 1 (CDL index conventions). * An interpolation variable should have 0 dimensions. - -  - -*Requirements:* - -* When attached to a data variable, the type of the - **`tie_point_dimensions`** attribute is a string whose value is a list - of blank separated word groups of the following form, in which - brackets indicate optional text: **`interpolation_dimension: - tie_point_interpolation_dimension [interpolation_zone_dimension]`**. - Each **`interpolation_dimension`** token specifies a unique - interpolation dimension of the parent data variable, each - **`tie_point_interpolation_dimension`** token specifies the tie - point interpolation dimension of a unique tie point index variable, - and each **`interpolation_zone_dimension`** token specifies a unique - interpolation zone dimension. The tie point interpolation dimensions - and interpolation zone dimensions must not be dimensions of the - parent data variable. - -* When attached to a data variable, the type of the - **`tie_point_indices`** attribute is a string whose value is a list of - blank separated word pairs of the following form: - **`interpolation_dimension: tie_point_index_variable`**. The - **`interpolation_dimension`** tokens specify the same interpolation - dimensions as the **`tie_point_dimensions`**, and each - **`tie_point_index_variable`** token specifies a tie point index - variable that must exist in the file. - -* A tie point index variable must be a one-dimensional variable with - an integer data type. - -* The dimension of a tie point index variable must be a tie point - interpolation dimension identified by the **`tie_point_dimensions`** - attribute. - -* The values of a tie point index variable must be non-negative - integers. The first value must be zero, and each subsequent value - must be greater than or equal to the previous value. If a value - differs by zero or one from its previous value, then it must differ - by two or more from its subsequent value. - -* The size of an interpolation zone dimension must be equal to the - size of the corresponding tie point interpolation dimension minus - the number of interpolation areas for that tie point interpolation - dimension. The number of interpolation areas is equal one plus the - number of occurences of adjacent values differing by zero or one in - the corresponding tie point index variable. - -* When attached to a data variable, the type of the **`tie_points`** - attribute is a string whose value is a list of blank separated word - groups of the following form, in which brackets indicate optional - text: **`tie_point_variable: [tie_point_variable: ...] - interpolation_variable`**. Each **`tie_point_variable`** token - specifies a tie point variable that must exist in the file, and each - **`interpolation_variable`** token specifies an interpolation - variable that must exist in the file. - -* The tie point variables associated with each - **`interpolation_variable`** token must all span the same - dimensions, which comprise a subset of zero or more dimensions of - the parent data variable with the addition of at least one tie point - interpolation dimension identified by the **`tie_point_dimensions`** - attribute. A tie point variable must not span both a tie point - interpolation dimension and its corresponding interpolation - dimension, as defined by the **`tie_point_dimensions`** mapping. - -* An interpolation variable must have one of the string-valued - attributes **`interpolation_name`** or - **`interpolation_description`**, but not both. The legal values for - the **`interpolation_name`** attribute are contained in Appendix J. - -* When attached to an interpolation variable, the type of the - **`interpolation_parameters`** attribute is a string whose value is - list of blank separated word pairs in the form **`term: var`**. The - legal values **`term`** are contained in Appendix J for each valid - **`interpolation_name`**. The values of **`var`** must be - interpolation parameter variables that exist in the file. - -* The dimensions of an interpolation parameter variable must be a - subset of zero or more of the dimensions of the corresponding tie - point variables, with the exception that a tie point interpolation - dimension may be replaced with its corresponding interpolation zone - dimension, as defined by the **`tie_point_dimensions`** mapping. - - -*Recommendations:* - -* An interpolation variable should have 0 dimensions. - -   From 9660fe41ddb5bba4dfccde0c10aa265825b9c36f Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 20 Apr 2021 10:15:37 +0100 Subject: [PATCH 146/249] conformance changes for new interpolation variable --- conformance.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conformance.adoc b/conformance.adoc index 069faf04..251dbc70 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -682,8 +682,8 @@ sizes minus 1 (CDL index conventions). * The tie point variables associated with each **`interpolation_variable`** token must all span the same dimensions, which comprise a subset of zero or more dimensions of the parent - data variable with the addition of at least one tie point - interpolation dimension identified by the **`tie_point_dimensions`** + data variable with the addition of all of the tie point + interpolation dimensions identified by the **`tie_point_dimensions`** attribute of the interpolation variable. A tie point variable must not span both a tie point interpolation dimension and its corresponding interpolation dimension, as defined by the From 3f648b9da52c6a96a92d18813963c5c2e13bd968 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 20 Apr 2021 10:16:21 +0100 Subject: [PATCH 147/249] appendix A changes for new interpolation variable --- appa.adoc | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/appa.adoc b/appa.adoc index 32eefb4f..4c5a9735 100644 --- a/appa.adoc +++ b/appa.adoc @@ -294,18 +294,6 @@ formula in the definition. | <> | A standard name that references a description of a variable"s content in the standard name table. -| **`tie_point_dimensions`** -| S -| D, Do -| <> and <> -| When coordinates have been compressed by sampling, provides a mapping of interpolation dimensions to tie point index variables. - -| **`tie_point_indices`** -| S -| D, Do -| <> and <> -| When coordinates have been compressed by sampling, provides a mapping of interpolation dimensions to tie point interpolation dimensions and interpolation zone dimensions. - | **`tie_points`** | S | D, Do From c84ef46c34206d1efca1db6be01685ca7c449ea9 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 20 Apr 2021 10:18:03 +0100 Subject: [PATCH 148/249] appendix A changes for new interpolation variable --- appa.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appa.adoc b/appa.adoc index 4c5a9735..9783bfdd 100644 --- a/appa.adoc +++ b/appa.adoc @@ -297,7 +297,7 @@ formula in the definition. | **`tie_points`** | S | D, Do -| <> and <> +| <> | Indicates that coordinates have been compressed by sampling and identifies the tie point variables and their associated interpolation variables. | **`title`** From 9ccc3e11a4aa164ed07978f4ea6a85e1c07cc23f Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 20 Apr 2021 12:49:59 +0200 Subject: [PATCH 149/249] Updates for new Interpolation Variable --- appj.adoc | 83 +++++++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/appj.adoc b/appj.adoc index 149374c7..79859dac 100644 --- a/appj.adoc +++ b/appj.adoc @@ -30,7 +30,7 @@ When an interpolation method is referred to as linear or quadratic, it means tha For convenience, an interpolation variable `s` is introduced, calculated as a function of the index in the target domain of the coordinate value to be reconstituted. In the case of one dimensional interpolation the interpolation variable is computed as -`s = s(i) = (i - ia)/(ib - ia)` +`s = s(ia, ib, i) = (i - ia)/(ib - ia)` where `ia` and `ib` are the indices in the target domain of the tie points `A` and `B` and `i` is the index in the target domain of the coordinate value to be reconstituted. @@ -38,8 +38,8 @@ Note that the value of `s` varies from `0.0` at the tie point `A` to `1.0` at ti In the case of two dimensional interpolation, the two interpolation variables are equivalently computed as -`s1 = s1(i1) = (i1 - ia1)/(ib1 - ia1)` + -`s2 = s2(i2) = (i2 - ia2)/(id2 - ia2)` +`s1 = s(ia1, ib1, i1) = (i1 - ia1)/(ib1 - ia1)` + +`s2 = s(ia2, ic2, i2) = (i2 - ia2)/(ic2 - ia2)` where `ia1` and `ib1` are the first dimension indices in the target domain of the tie points `A` and `B` respectively, `ia2` and `id2` are the second dimension indices in the target domain of the tie points `A` and `D` respectively and the indices `i1` and `i2` are the first and second dimension indices respectively in the target domain of the coordinate value to be reconstituted. @@ -81,9 +81,9 @@ where `ua` and `ub` are the coordinate values at tie points `A` and `B` respecti | Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | The interpolation function fl() defined for linear interpolation above is first applied twice in the interpolation dimension 1, once between tie points `A` and `B` and once between tie points `C` and `D`. It is then applied once in the interpolation dimension 2, between the two resulting coordinate points, yielding the interpolated coordinate value `u(i1, i2)`: + -`uab = fl(ua, ub, s1(i1))`; + -`ucd = fl(uc, ud, s1(i1))`; + -`u(i1, i2) = fl(uab, ucd, s2(i2))`; + +`uab = fl(ua, ub, s(ia1, ib1, i1))`; + +`ucd = fl(uc, ud, s(ia1, ib1, i1))`; + +`u(i1, i2) = fl(uab, ucd, s(ia2, ic2, i2))`; + |=============== @@ -143,7 +143,7 @@ Then calculate the cartesian representation of the interpolation coefficients fr The cartesian interpolation coefficients are found from + `cv = fcv(va, vb, vp(i), s(i)) = (fc(va.x, vb.x, vp(i).x, s(i)), fc(va.y, vb.y, vp(i).y, s(i)), fc(va.z, vb.z, vp(i).z, s(i))).` + Finally, for storage in the dataset, convert the coefficients to the parametric representation + -`(ce(iz), ca(iz)) = fcv2cea(va, vb, cv) = (fdot(cv, fminus(va, vb))/ gsqr), fdot(cv, fcross(va, vb))/(rsqr*gsqr);` + +`(ce(iz), ca(iz)) = fcv2cea(va, vb, cv) = (fdot(cv, fminus(va, vb))/ gsqr), fdot(cv, fcross(va, vb))/(rsqr*gsqr));` + where `vr = fmultiply(0.5, fplus(va, vb))`, `rsqr = fdot(vr, vr)` and `gsqr = 4*(1-rsqr).` + The interpolation parameter term `interpolation_zone_flags(iz)` shall have the flag `location_use_cartesian` set if the interpolation zone intersects the `longitude = 180.0` or if the interpolation zone extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | @@ -198,15 +198,15 @@ Optionally the flag variable `interpolation_zone_flags`, which must span the `in | Coordinate Compression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb); vc = fll2v(llc); vd = fll2v(lld).` + -Then calculate the cartesian representation of the interpolation coefficients sets from the tie points as well as a point `vp(i2, i1)` between the tie points. If the size of the interpolation zone in the first dimension `(ib1 - ia1)` is an even number, then the index `i1 = (ib1 - ia1)/2` shall be selected for this calculation, otherwise the index `i1 = (ib1 - ia1 - 1)/2` shall be selected. If the size of the interpolation zone in the second dimension `(ib2 - ic2)` is an even number, then the index `i2 = (ib2 - ic2)/2` shall be selected for this calculation, otherwise the index `i2 = (ib2 - ic2 - 1)/2` shall be selected. + +Then calculate the cartesian representation of the interpolation coefficients sets from the tie points as well as a point `vp(i2, i1)` between the tie points. If the size of the interpolation zone in the first dimension `(ib1 - ia1)` is an even number, then the index `i1 = (ib1 + ia1)/2` shall be selected for this calculation, otherwise the index `i1 = (ib1 + ia1 - 1)/2` shall be selected. If the size of the interpolation zone in the second dimension `(ib2 - ic2)` is an even number, then the index `i2 = (ib2 + ic2)/2` shall be selected for this calculation, otherwise the index `i2 = (ib2 + ic2 - 1)/2` shall be selected. + Using the selected `(i2, i1)`, the cartesian interpolation coefficients are found from + -`cv_ab = fcv( va, vb, vp(ia2, i1), s(i1));` + -`cv_cd = fcv( vc, vd, vp(ic2, i1), s(i1));` + -`cv_ac = fcv( va, vc, vp(i2, ia1), s(i2));` + -`cv_bd = fcv( vb, vd, vp(i2, ib1), s(i2));` + -`vab = fqv(va, vb, cv_ab, s1(i1))`; + -`vcd = fqv(vc, vd, cv_cd, s1(i1))`; + -`cv_zz = fcv( vab, vcd, vp(i2, i1), s(i2));` + +`cv_ab = fcv( va, vb, fll2v(ll(ia2, i1)), s(ia1, ib1, i1));` + +`cv_cd = fcv( vc, vd, fll2v(ll(ic2, i1)), s(ia1, ib1, i1));` + +`cv_ac = fcv( va, vc, fll2v(ll(i2, ia1)), s(ia2, ic2, i2));` + +`cv_bd = fcv( vb, vd, fll2v(ll(i2, ib1)), s(ia2, ic2, i2));` + +`vab = fqv(va, vb, cv_ab, s(ia1, ib1, i1))`; + +`vcd = fqv(vc, vd, cv_cd, s(ia1, ib1, i1))`; + +`cv_zz = fcv( vab, vcd, fll2v(ll(i2, i1)), s(ia2, ic2, i2));` + `vac = fqv(va, vc, cv_ac, 0.5);` + `vbd = fqv(vb, vd, cv_bd, 0.5);` + `vz = fqv( vab, vcd, cv_zz, 0.5);` + @@ -228,22 +228,22 @@ Then calculate the cartesian representation of the interpolation coefficient set `vbd = fqv(vb, vd, fcea2cv( vb, vd, ce2(iz2, tp1+1), ca2(iz2, tp1+1)), 0.5);` + `cv_z = fcea2cv( vac, vbd, ce3(iz2, iz1), ca3(iz2, iz1)).` + If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_zone_flags` is set, use the following expression to reconstitute any point `llp(i2, i1)` between the tie points `A` and `B` using interpolation in cartesian coordinates + -`llp(i2, i1) = fv2ll(fqv(vab, vcd, fcv( vab, vcd, vz, 0.5), s2(i2)));` + +`llp(i2, i1) = fv2ll(fqv(vab, vcd, fcv( vab, vcd, vz, 0.5), s(ia2, ic2, i2)));` + where + -`vab = fqv(va, vb, cv_ab, s1(i1));` + -`vcd = fqv(vc, vd, cv_cd, s1(i1));` + -`vz = fqv(vac, vbd, cv_z, s1(i1)).` + +`vab = fqv(va, vb, cv_ab, s(ia1, ib1, i1));` + +`vcd = fqv(vc, vd, cv_cd, s(ia1, ib1, i1));` + +`vz = fqv(vac, vbd, cv_z, s(ia1, ib1, i1)).` + Otherwise, first calculate latitude-longitude representation of the interpolation coefficients + `llc_ab = fcll( a, b, fv2ll(fqv(va, vb, cv_ab, 0.5)));` + `llc_cd = fcll( c, d, fv2ll(fqv(vc, vd, cv_cd, 0.5)));` + `llac = fv2ll(vac); llbd = fv2ll(vbd);` + `llc_z = fcll( a, b, fv2ll(fqv(vac, vbd, cv_ab, 0.5))).` + Then use the following expression to reconstitute any point `llp(i2, i1)` in the tie point zone using interpolation in latitude-longitude coordinates + - `llp(i2, i1) = fqll(llab, llcd, fcll(llab, llcd, llz, 0.5), s2(i2));` + + `llp(i2, i1) = fqll(llab, llcd, fcll(llab, llcd, llz, 0.5), s(ia2, ic2, i2));` + where + -`llab = fqll(a, b, llc_ab, s1(i1));` + -`llcd = fqll(c, d, llc_cd, s1(i1));` + -`llz = fqll(llac, llbd, llc_z, s1(i1)).` + +`llab = fqll(a, b, llc_ab, s(ia1, ib1, i1));` + +`llcd = fqll(c, d, llc_cd, s(ia1, ib1, i1));` + +`llz = fqll(llac, llbd, llc_z, s(ia1, ib1, i1)).` + |=============== [[quadratic3, figure 4]] @@ -274,13 +274,13 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] | fminus | Vector Difference | `(x, y, z) = fminus(va, vb) = (va.x - vb.x, va.y - vb.y, va.z - vb.z)` + -| fmultiply | Vector multiplied by Scalar | `(x, y, z) = fmultiply(r, v) = (r * va.x, vr * va.y, r * va.z)` + +| fmultiply | Vector multiplied by Scalar | `(x, y, z) = fmultiply(r, v) = (r * v.x, r * v.y, r * v.z)` + -| fcross | Vector Cross Product | `(x, y, z) = fcross(va, vb) = (va.y*vb.z - va.z*vb.y, va.z*vb.x - vva.zx*b.z, va.x*vb.y - va.y*vb.x)` + +| fcross | Vector Cross Product | `(x, y, z) = fcross(va, vb) = (va.y*vb.z - va.z*vb.y, va.z*vb.x - va.x*vb.z, va.x*vb.y - va.y*vb.x)` + | norm | Normalised Vector | `(x, y, z) = norm(v) = (v.x, v.y, v.z) / sqrt (v.x*v.x + v.y*v.y + v.z*v.z)` + -| fdot | Vector Dot Product | `d = fdot(va, vb) = va.x*vb.x + va.y*vb.y, va.z*vb.z` +| fdot | Vector Dot Product | `d = fdot(va, vb) = va.x*vb.x + va.y*vb.y + va.z*vb.z` |=============== @@ -317,11 +317,11 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] | <> | 6 -| For each of the interpolation dimensions, add the interpolation dimension, the corresponding tie point interpolation dimension and, if required by the selected interpolation method, its corresponding interpolation zone dimension to the **`tie_point_dimensions`** attribute of the data variable. +| For each of the interpolation dimensions, add the interpolation dimension, the corresponding tie point interpolation dimension and, if required by the selected interpolation method, its corresponding interpolation zone dimension to the **`tie_point_dimensions`** attribute of the interpolation variable. | <> | 7 -| For each of the interpolation dimensions, record the location of each identified tie point in a tie point index variable. For each interpolation dimension, add the interpolation dimension and its tie point index variable to the **`tie_point_indices`** attribute of the data variable. +| For each of the interpolation dimensions, record the location of each identified tie point in a tie point index variable. For each interpolation dimension, add the interpolation dimension and its tie point index variable to the **`tie_point_indices`** attribute of the interpolation variable. | <> | 8 @@ -350,33 +350,32 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] | Step | Description | Link | 1 -| From the **`tie_points`** attribute of the data variable, identify the coordinate and auxillary coordinate variable subsets, for which tie point interpolation is required. +| From the **`tie_points`** attribute of the data variable, identify the coordinate and auxillary coordinate variable subsets, for which tie point interpolation is required, and the interpolation variable corresponding to each subset. | <> | 2 -| For each coordinate variable subset, identify the set of dimensions. Using the **`tie_point_dimensions`** attribute of the data variable, identify the set of interpolation dimensions and the set of non-interpolation dimensions. -| <> - -<> +| For each coordinate variable subset, identify the interpolation method from the +**`interpolation_name`** attribute of the interpolation variable. +| <> | 3 -| From the **`tie_point_dimensions`** attribute of the data variable, identify for each of the interpolation dimensions the corresponding tie point interpolation dimension and, if defined, the corresponding interpolation zone dimension. -| <> +| For each coordinate variable subset, identify the set of interpolation dimensions and the set of non-interpolation dimensions from the **`tie_point_dimensions`** attribute of the interpolation variable. +| <> <> | 4 -| From the tie point index variables referenced in the **`tie_point_indices`** attribute of the data variable, identify the location of the tie points in the corresponding interpolation dimension. -| <> +| From the **`tie_point_dimensions`** attribute of the interpolation variable, identify for each of the interpolation dimensions the corresponding tie point interpolation dimension and, if defined, the corresponding interpolation zone dimension. +| <> | 5 -| For each of the interpolation dimensions, identify pairs of adjacent indices in the tie point index variable with index values differing by more than one, each index pair defining the extend of an interpolation zone in that dimension. A full interpolation zone is defined by one such index pair per interpolation dimension, with combinations of one index from each pair defining the interpolation zone tie points. -| <> +| From the tie point index variables referenced in the **`tie_point_indices`** attribute of the interpolation variable, identify the location of the tie points in the corresponding interpolation dimension. +| <> | 6 -| From the **`tie_points`** attribute of the data variable, identify the interpolation variable for the coordinate and auxillary coordinate variable subset. From the **`interpolation_name`** attribute of the interpolation variable, identify the interpolation method. -| <> +| For each of the interpolation dimensions, identify pairs of adjacent indices in the tie point index variable with index values differing by more than one, each index pair defining the extend of an interpolation zone in that dimension. A full interpolation zone is defined by one such index pair per interpolation dimension, with combinations of one index from each pair defining the interpolation zone tie points. +| <> | 7 -| As required by the selected interpolation method, identify the interpolation parameter variables from the interpolation variable attribute **`interpolation_parameters`** . +| As required by the selected interpolation method, identify the interpolation parameter variables from the interpolation variable attribute **`interpolation_parameters`**. | <> | 8 From e3b4905c57a57b54f779b40dc5a0caaba5a67926 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 20 Apr 2021 12:05:23 +0100 Subject: [PATCH 150/249] New conformace check (#16) * more text following 2020-11-27 discussions * bounds * tidy * tidy * tidy * tidy * reproducability * offset * indices * indices * indices * super * tie_point_dimension (1) * tie_point_dimension (2) * tie_point_dimension (3) * tie_point_dimension (4) * tie point * tie_point_dimension (5) * corrected interpolation_configuration description * zone/area rewording * zone/area rewording * multiple mappings * multiple mappings * multiple mappings * typos and some minor rewording suggestions * format * spell check * markup style * example formatting * example formatting * example formatting * example formatting * minor typesetting * interpolation_parameters * interpolation parameters variable dimensions * interpolation parameters variable dimensions * non-standard provision * interpolation parameters variable dimensions * captions, cdl * tidy * minumum size of interpolation zones * Appendix A attributes * interpolation -> sampling * Conformance - first draft * 2nd draft: better descriptions of allowed dimensions * typos * Correct 'is list' to 'is a list' * check on interpolation zone dimension size * conformance changes for new interpolation variable * conformance changes for new interpolation variable * conformance changes for new interpolation variable * conformance changes for new interpolation variable * appendix A changes for new interpolation variable * appendix A changes for new interpolation variable Co-authored-by: AndersMS <63056394+AndersMS@users.noreply.github.com> --- appa.adoc | 14 +-------- conformance.adoc | 74 ++++++++++++++++++++++++++---------------------- 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/appa.adoc b/appa.adoc index 32eefb4f..9783bfdd 100644 --- a/appa.adoc +++ b/appa.adoc @@ -294,22 +294,10 @@ formula in the definition. | <> | A standard name that references a description of a variable"s content in the standard name table. -| **`tie_point_dimensions`** -| S -| D, Do -| <> and <> -| When coordinates have been compressed by sampling, provides a mapping of interpolation dimensions to tie point index variables. - -| **`tie_point_indices`** -| S -| D, Do -| <> and <> -| When coordinates have been compressed by sampling, provides a mapping of interpolation dimensions to tie point interpolation dimensions and interpolation zone dimensions. - | **`tie_points`** | S | D, Do -| <> and <> +| <> | Indicates that coordinates have been compressed by sampling and identifies the tie point variables and their associated interpolation variables. | **`title`** diff --git a/conformance.adoc b/conformance.adoc index c38b1bce..251dbc70 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -651,10 +651,24 @@ sizes minus 1 (CDL index conventions). *Requirements:* -* When attached to a data variable, the type of the - **`tie_point_dimensions`** attribute is a string whose value is a list - of blank separated word groups of the following form, in which - brackets indicate optional text: **`interpolation_dimension: +* When attached to a data variable, the type of the **`tie_points`** + attribute is a string whose value is a list of blank separated word + groups of the following form, in which brackets indicate optional + text: **`tie_point_variable: [tie_point_variable: ...] + interpolation_variable`**. Each **`tie_point_variable`** token + specifies a tie point variable that must exist in the file, and each + **`interpolation_variable`** token specifies an interpolation + variable that must exist in the file. + +* An interpolation variable must have one of the string-valued + attributes **`interpolation_name`** or + **`interpolation_description`**, but not both. The legal values for + the **`interpolation_name`** attribute are contained in Appendix J. + +* An interpolation variable must have a **`tie_point_dimensions`** + attribute that is a string whose value is a list of blank separated + word groups of the following form, in which brackets indicate + optional text: **`interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension]`**. Each **`interpolation_dimension`** token specifies a unique interpolation dimension of the parent data variable, each @@ -665,12 +679,22 @@ sizes minus 1 (CDL index conventions). and interpolation zone dimensions must not be dimensions of the parent data variable. -* When attached to a data variable, the type of the - **`tie_point_indices`** attribute is a string whose value is a list of - blank separated word pairs of the following form: - **`interpolation_dimension: tie_point_index_variable`**. The - **`interpolation_dimension`** tokens specify the same interpolation - dimensions as the **`tie_point_dimensions`**, and each +* The tie point variables associated with each + **`interpolation_variable`** token must all span the same dimensions, + which comprise a subset of zero or more dimensions of the parent + data variable with the addition of all of the tie point + interpolation dimensions identified by the **`tie_point_dimensions`** + attribute of the interpolation variable. A tie point variable must + not span both a tie point interpolation dimension and its + corresponding interpolation dimension, as defined by the + **`tie_point_dimensions`** mapping. + +* An interpolation variable must have a **`tie_point_indices`** + attribute that is a string whose value is a list of blank separated + word pairs of the following form: **`interpolation_dimension: + tie_point_index_variable`**. The **`interpolation_dimension`** + tokens specify the same interpolation dimensions as the + **`tie_point_dimensions`** attribute, and each **`tie_point_index_variable`** token specifies a tie point index variable that must exist in the file. @@ -687,28 +711,12 @@ sizes minus 1 (CDL index conventions). differs by zero or one from its previous value, then it must differ by two or more from its subsequent value. -* When attached to a data variable, the type of the **`tie_points`** - attribute is a string whose value is a list of blank separated word - groups of the following form, in which brackets indicate optional - text: **`tie_point_variable: [tie_point_variable: ...] - interpolation_variable`**. Each **`tie_point_variable`** token - specifies a tie point variable that must exist in the file, and each - **`interpolation_variable`** token specifies an interpolation - variable that must exist in the file. - -* The tie point variables associated with each - **`interpolation_variable`** token must all span the same - dimensions, which comprise a subset of zero or more dimensions of - the parent data variable with the addition of at least one tie point - interpolation dimension identified by the **`tie_point_dimensions`** - attribute. A tie point variable must not span both a tie point - interpolation dimension and its corresponding interpolation - dimension, as defined by the **`tie_point_dimensions`** mapping. - -* An interpolation variable must have one of the string-valued - attributes **`interpolation_name`** or - **`interpolation_description`**, but not both. The legal values for - the **`interpolation_name`** attribute are contained in Appendix J. +* The size of an interpolation zone dimension must be equal to the + size of the corresponding tie point interpolation dimension minus + the number of interpolation areas for that tie point interpolation + dimension. The number of interpolation areas is equal one plus the + number of occurences of adjacent values differing by zero or one in + the corresponding tie point index variable. * When attached to an interpolation variable, the type of the **`interpolation_parameters`** attribute is a string whose value is @@ -723,10 +731,8 @@ sizes minus 1 (CDL index conventions). dimension may be replaced with its corresponding interpolation zone dimension, as defined by the **`tie_point_dimensions`** mapping. - *Recommendations:* * An interpolation variable should have 0 dimensions. -   From 7b0e9790c00ebb61be82ba43e46c9b294a495c73 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 22 Apr 2021 10:37:28 +0200 Subject: [PATCH 151/249] Test --- ch08.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ch08.adoc b/ch08.adoc index 99890a79..061e9260 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -83,6 +83,8 @@ The metadata that define the interpolation formula and its inputs are complete, The data variable coordinate interpolation attributes may also be used on a domain variable (domain-variables) with the same effect. +Test........... + [[compression-by-coordinate-sampling-tie-points-and-interpolation-zones, Section 8.3.1, "Tie Points and Interpolation Zones"]] ==== Tie Points and Interpolation Zones From eb7bf2883dc40d8e6cb71dafbec6843067c789f8 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 22 Apr 2021 15:52:09 +0200 Subject: [PATCH 152/249] Updated for new Interpolation Variable --- appj.adoc | 2 +- images/ci_interpolation_coefficients.svg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/appj.adoc b/appj.adoc index 79859dac..6a065ca4 100644 --- a/appj.adoc +++ b/appj.adoc @@ -210,7 +210,7 @@ Using the selected `(i2, i1)`, the cartesian interpolation coefficients are foun `vac = fqv(va, vc, cv_ac, 0.5);` + `vbd = fqv(vb, vd, cv_bd, 0.5);` + `vz = fqv( vab, vcd, cv_zz, 0.5);` + -`cv_z = fcv( vac, vbd, vz, 0.5).` + +`cv_z = fcv(vac, vbd, vz, s(ia1, ib1, i1)).` + Finally, before storing them in the dataset's interpolation parameters, convert the coefficients to the parametric representation + `(ce1(tp2, iz1), ca1(tp2, iz1)) = fcv2cea( va, vb, cv_ab);` + `(ce1(tp2+1, iz1), ca1(tp2+1, iz1)) = fcv2cea( vc, vd, cv_cd);` + diff --git a/images/ci_interpolation_coefficients.svg b/images/ci_interpolation_coefficients.svg index 1861539f..1d6ace6b 100644 --- a/images/ci_interpolation_coefficients.svg +++ b/images/ci_interpolation_coefficients.svg @@ -1 +1 @@ -xyDimension (y_interpolation_zone, x_tie_point_interpolation)Example (1, 2) Dimension (y_tie_point_interpolation, x_interpolation_zone)Example (2, 0) Dimension (y_interpolation_zone, x_interpolation_zone)Example (0, 1) Dimension (x_interpolation_zone)Example (1) \ No newline at end of file +xyDimension (y_interpolation_zone, x_tie_point_interpolation)Example (1, 2) Dimension (y_tie_point_interpolation, x_interpolation_zone)Example (2, 0) Dimension (y_interpolation_zone, x_interpolation_zone)Example (0, 1) Dimension (x_interpolation_zone)Example (1) Dimension (y_ tie_point_interpolation, x_tie_point_interpolation)Example (0, 0) \ No newline at end of file From 5b0461f563bf8bd1e564940ec742c28aa05e0f85 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 27 Apr 2021 14:51:13 +0100 Subject: [PATCH 153/249] lat lon tie point definition --- appj.adoc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/appj.adoc b/appj.adoc index 6a065ca4..28600e7d 100644 --- a/appj.adoc +++ b/appj.adoc @@ -115,8 +115,10 @@ where `ua` and `ub` are the coordinate values at tie points `A` and `B` respecti [cols="6,15"] |=============== | Name | **`interpolation_name = "quadratic_remote_sensing"`** -| Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + - + +| Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. + + +Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. + By default, interpolation is performed directly in the latitude and longitude coordinates, but may be performed in cartesian coordinates where required for achieving the desired accuracy. This must be indicated by setting the `location_use_cartesian` flag within the interpolation parameter `interpolation_zone_flags` for each interpolation zone where interpolation in cartesian coordinates is required. The quadratic interpolation coefficients `ce` and `ca`, stored as interpolation parameters in the product, describe a point `P` between the tie points `A` and `B`, which is equivalent of an additional tie point in the sense that the method will accurately reconstitute the point `P` in the same way as it accurately reconstitutes the tie points `A` and `B`. See <> and <>. From b14646db79031e5553b20466e7db46d7a642eef0 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Wed, 28 Apr 2021 09:21:23 +0100 Subject: [PATCH 154/249] lat/lon tie point definition in appendix J (#18) * more text following 2020-11-27 discussions * bounds * tidy * tidy * tidy * tidy * reproducability * offset * indices * indices * indices * super * tie_point_dimension (1) * tie_point_dimension (2) * tie_point_dimension (3) * tie_point_dimension (4) * tie point * tie_point_dimension (5) * corrected interpolation_configuration description * zone/area rewording * zone/area rewording * multiple mappings * multiple mappings * multiple mappings * typos and some minor rewording suggestions * format * spell check * markup style * example formatting * example formatting * example formatting * example formatting * minor typesetting * interpolation_parameters * interpolation parameters variable dimensions * interpolation parameters variable dimensions * non-standard provision * interpolation parameters variable dimensions * captions, cdl * tidy * minumum size of interpolation zones * Appendix A attributes * interpolation -> sampling * Conformance - first draft * 2nd draft: better descriptions of allowed dimensions * typos * Correct 'is list' to 'is a list' * check on interpolation zone dimension size * conformance changes for new interpolation variable * conformance changes for new interpolation variable * conformance changes for new interpolation variable * conformance changes for new interpolation variable * appendix A changes for new interpolation variable * appendix A changes for new interpolation variable * lat lon tie point definition Co-authored-by: AndersMS <63056394+AndersMS@users.noreply.github.com> --- appj.adoc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/appj.adoc b/appj.adoc index 6a065ca4..28600e7d 100644 --- a/appj.adoc +++ b/appj.adoc @@ -115,8 +115,10 @@ where `ua` and `ub` are the coordinate values at tie points `A` and `B` respecti [cols="6,15"] |=============== | Name | **`interpolation_name = "quadratic_remote_sensing"`** -| Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + - + +| Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. + + +Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. + By default, interpolation is performed directly in the latitude and longitude coordinates, but may be performed in cartesian coordinates where required for achieving the desired accuracy. This must be indicated by setting the `location_use_cartesian` flag within the interpolation parameter `interpolation_zone_flags` for each interpolation zone where interpolation in cartesian coordinates is required. The quadratic interpolation coefficients `ce` and `ca`, stored as interpolation parameters in the product, describe a point `P` between the tie points `A` and `B`, which is equivalent of an additional tie point in the sense that the method will accurately reconstitute the point `P` in the same way as it accurately reconstitutes the tie points `A` and `B`. See <> and <>. From 7106321f4b0b7c2e7733dbb87dfba63f8186fdc6 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 28 Apr 2021 14:59:19 +0200 Subject: [PATCH 155/249] Delete ci_interpolation_coefficients.svg --- images/ci_interpolation_coefficients.svg | 1 - 1 file changed, 1 deletion(-) delete mode 100644 images/ci_interpolation_coefficients.svg diff --git a/images/ci_interpolation_coefficients.svg b/images/ci_interpolation_coefficients.svg deleted file mode 100644 index 1d6ace6b..00000000 --- a/images/ci_interpolation_coefficients.svg +++ /dev/null @@ -1 +0,0 @@ -xyDimension (y_interpolation_zone, x_tie_point_interpolation)Example (1, 2) Dimension (y_tie_point_interpolation, x_interpolation_zone)Example (2, 0) Dimension (y_interpolation_zone, x_interpolation_zone)Example (0, 1) Dimension (x_interpolation_zone)Example (1) Dimension (y_ tie_point_interpolation, x_tie_point_interpolation)Example (0, 0) \ No newline at end of file From 65040daeac6ade330e6d48ded84087198f87837f Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 28 Apr 2021 15:00:01 +0200 Subject: [PATCH 156/249] Add new Figure --- images/ci_interpolation_coefficients.svg | 734 +++++++++++++++++++++++ 1 file changed, 734 insertions(+) create mode 100644 images/ci_interpolation_coefficients.svg diff --git a/images/ci_interpolation_coefficients.svg b/images/ci_interpolation_coefficients.svg new file mode 100644 index 00000000..d4e0a87e --- /dev/null +++ b/images/ci_interpolation_coefficients.svg @@ -0,0 +1,734 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + xy + Dimension (x_interpolation_zone)Example (1) + + + + + + + + Dimension (y_tie_point_interpolation,x_tie_point_interpolation)Example(0, 0) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dimension (y_tie_point_interpolation , x_interpolation_zone )Example (2, 0) + + Dimension (y_interpolation_zone , x_tie_point_interpolation )Example (1, 2) + + Dimension (y_interpolation_zone , x_interpolation_zone ) +Example (0, 1) + + + + + + + From 947a869dde5efa0e2b5446087f2696533d5fdec8 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 28 Apr 2021 19:06:32 +0200 Subject: [PATCH 157/249] Updates to chapter 8 for new interpolation variable (#17) * Update for new IUnterpolation Variable * Add files via upload * New figure * New figure * Add files via upload * Rename ci_interpolation_coefficeints.svg to ci_interpolation_coefficients.svg * Update ch08.adoc Co-authored-by: OceanDataLab * Update ch08.adoc Co-authored-by: OceanDataLab * Update ch08.adoc Co-authored-by: OceanDataLab * Update ch08.adoc Co-authored-by: OceanDataLab Co-authored-by: OceanDataLab --- ch08.adoc | 334 +++++----- images/ci_interpolation_coefficients.svg | 735 +---------------------- images/interpolation coefficeints.svg | 1 + 3 files changed, 151 insertions(+), 919 deletions(-) create mode 100644 images/interpolation coefficeints.svg diff --git a/ch08.adoc b/ch08.adoc index 061e9260..88c3838b 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -81,9 +81,7 @@ In addition to the tie point variables themselves, metadata defining the coordin The metadata that define the interpolation formula and its inputs are complete, so that the results of the coordinate reconstitution process are well defined and of a predictable accuracy. -The data variable coordinate interpolation attributes may also be used on a domain variable (domain-variables) with the same effect. - -Test........... +The data variable coordinate interpolation attribute may also be used on a domain variable (domain-variables) with the same effect. [[compression-by-coordinate-sampling-tie-points-and-interpolation-zones, Section 8.3.1, "Tie Points and Interpolation Zones"]] ==== Tie Points and Interpolation Zones @@ -135,7 +133,55 @@ image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,a To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables `lat` and `lon` are to be interpolated according to the interpolation variable `bi_linear` could be indicated with `lat: lon: bi_linear`. -[[compression-by-coordinate-sampling-dimensions,Section 8.3.3, "Interpolation and Non-Interpolation Dimensions"]] +[[compression-by-coordinate-sampling-interpolation-variable, Section 8.3.3, "Interpolation Variable"]] +==== Interpolation Variable + +The method used to uncompress the tie point variables is described by +an interpolation variable that acts as a container for the attributes +that define the interpolation technique and the parameters that should +be used. The variable should be a scalar (i.e. it has no dimensions) +of arbitrary type, and the value of its single element is immaterial. + +The interpolation method must be identified in one of two ways. Either +by the **`interpolation_name`** attribute, which takes a string value +that contains the method's name, or else by the +**`interpolation_description`** attribute, which takes a string value +that contains a non-standardized description of the method. These +attributes must not be both set. + +The valid values of **`interpolation_name`** are given in <>. This appendix describes the interpolation technique for each +method, and optional interpolation variable attributes for configuring +the interpolation process. + +If a standardized interpolation name is not given, the interpolation +variable must have a **`interpolation_description`** attribute defined +instead, containing a description of the non-standardised +interpolation (in a similar manner to a long name being used instead +of a standard name). This description is free text that can take any +form (including a URI, for example). Whilst it is recommended that a +standardised interpolation is provided, the alternative is provided to +promote interoperability in cases where a well defined user community +needs to use sophisticated interpolation techniques that may also be +under development. + +The definition of the interpolation method, however it is specified, +may include instructions to treat groups of physically related +coordinates simultaneously, if such tie points are present. For +example, there are cases where longitudes cannot be interpolated +without considering the corresponding latitudes. It is up to the +interpolation description to describe how such coordinates are to be +identified (e.g. it may be that such tie point variables require +particular units or standard names). + +Note that the interpolation method is always applied on a per +interpolation zone basis, for which the construction of the +uncompressed coordinates may only access those tie points that define +the extent of the of the interpolation zone. + +In addition to the **`interpolation_name`** and **`interpolation_description`** attributes described in this section, further attributes of the interpolation variable are described in <>, <> and <>. + +[[compression-by-coordinate-sampling-dimensions,Section 8.3.4, "Interpolation and Non-Interpolation Dimensions"]] ==== Interpolation and Non-Interpolation Dimensions For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required; and may additionally contain one or more __non-interpolation dimensions__, i.e. those of the target domain for which no coordinate interpolation is required. The size of a tie point interpolation dimension must be less than or equal to the size of its corresponding interpolation dimension. @@ -144,7 +190,7 @@ An interpolation dimension typically differs in size from the corresponding tie The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are `xc = 30` and `yc = 10`, interpolation could be applied in the `xc` dimension only, based on tie point variables of the dimensions `tp_xc = 4` and `yc = 10`. The interpolation in the `xc` dimension would then be repeated for each of the 10 indices of the `yc` dimension. -[[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.4, "Tie Point Dimensions Attribute"]] +[[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.5, "Tie Point Dimensions Attribute"]] ==== Tie Point Dimensions Attribute Each interpolation dimension must be associated with its corresponding @@ -155,7 +201,7 @@ dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by an interpolation parameter variable, as described in <>. The -association is stored in the data variable's +association is stored in the interpolation variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] @@ -196,7 +242,7 @@ not possible to simultaneously map all three tie point variables to the linear interpolation variable because they do not all span the same axes. -[[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.5, "Tie Point Indices"]] +[[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.6, "Tie Point Indices"]] ==== Tie Point Indices The relationship between a tie point interpolation dimension and its @@ -228,7 +274,7 @@ interpolation dimension `xc` of size 30. To indicate which tie point index variable applies to each interpolation dimension, a **`tie_point_indices`** attribute must be -defined for the data variable. This is a string attribute that maps +defined for the interpolation variable. This is a string attribute that maps the interpolation dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form "__interpolation_dimension: tie_point_index_variable @@ -250,9 +296,17 @@ dimensions: tp_yc = 2 ; variables: - // Interpolation variables - char bi_linear ; - interpolation:interpolation_name = "bi_linear" ; + // Data variable + float Temperature(yc, xc) ; + Temperature:standard_name = "air_temperature" ; + Temperature:units = "K" ; + Temperature:tie_points = "lat: lon: bl_interpolation" ; + + // Interpolation variable + char bl_interpolation ; + bl_interpolation:interpolation_name = "bi_linear" ; + bl_interpolation:tie_point_dimensions = "xc: tp_xc yc: tp_y" ; + bl_interpolation:tie_point_indices = "yc: y_indices xc: x_indices" ; // Tie point variables double lat(tp_yc, tp_xc) ; @@ -266,14 +320,6 @@ variables: int y_indices(tp_yc) ; int x_indices(tp_xc) ; - // Data variable - float Temperature(yc, xc) ; - Temperature:standard_name = "air_temperature" ; - Temperature:units = "K" ; - Temperature:tie_points = "lat: lon: bi_linear" ; - Temperature:tie_point_dimensions = "xc: tp_xc yc: tp_y" ; - Temperature:tie_point_indices = "yc: y_indices xc: x_indices" ; - data: x_indices = 0, 9, 19, 29 ; y_indices = 0, 9 ; @@ -292,9 +338,17 @@ dimensions: tp_xc = 4 ; variables: + // Data variable + float Temperature(yc, xc) ; + Temperature:standard_name = "air_temperature" ; + Temperature:units = "K" ; + Temperature:tie_points = "lat: lon: l_interpolation" ; + // Interpolation variables - char linear ; - interpolation:interpolation_name = "linear" ; + char l_interpolation ; + l_interpolation:interpolation_name = "linear" ; + l_interpolation:tie_point_dimensions = "xc: tp_xc" ; + l_interpolation:tie_point_indices = "xc: x_indices" ; // Tie point variables double lat(yc, tp_xc) ; @@ -307,65 +361,14 @@ variables: // Tie point index variables int x_indices(tp_xc) ; - // Data variable - float Temperature(yc, xc) ; - Temperature:standard_name = "air_temperature" ; - Temperature:units = "K" ; - Temperature:tie_points = "lat: lon: linear" ; - Temperature:tie_point_dimensions = "xc: tp_xc" ; - Temperature:tie_point_indices = "xc: x_indices" ; - data: x_indices = 0, 9, 19, 29 ; ... ---- ==== -[[compression-by-coordinate-sampling-interpolation-variable, Section 8.3.6, "Interpolation Variable"]] -==== Interpolation Variable - -The method used to uncompress the tie point variables is described by -an interpolation variable that acts as a container for the attributes -that define the interpolation technique and the parameters that should -be used. The variable should be a scalar (i.e. it has no dimensions) -of arbitrary type, and the value of its single element is immaterial. - -The interpolation method must be identified in one of two ways. Either -by the **`interpolation_name`** attribute, which takes a string value -that contains the method's name, or else by the -**`interpolation_description`** attribute, which takes a string value -that contains a non-standardized description of the method. These -attributes must not be both set. - -The valid values of **`interpolation_name`** are given in <>. This appendix describes the interpolation technique for each -method, and optional interpolation variable attributes for configuring -the interpolation process. - -If a standardized interpolation name is not given, the interpolation -variable must have a **`interpolation_description`** attribute defined -instead, containing a description of the non-standardised -interpolation (in a similar manner to a long name being used instead -of a standard name). This description is free text that can take any -form (including a URI, for example). Whilst it is recommended that a -standardised interpolation is provided, the alternative is provided to -promote interoperability in cases where a well defined user community -needs to use sophisticated interpolation techniques that may also be -under development. - -The definition of the interpolation method, however it is specified, -may include instructions to treat groups of physically related -coordinates simultaneously, if such tie points are present. For -example, there are cases where longitudes cannot be interpolated -without considering the corresponding latitudes. It is up to the -interpolation description to describe how such coordinates are to be -identified (e.g. it may be that such tie point variables require -particular units or standard names). - -Note that the interpolation method is always applied on a per -interpolation zone basis, for which the construction of the -uncompressed coordinates may only access those tie points that define -the extent of the of the interpolation zone. +[[compression-by-coordinate-sampling-interpolation-parameters, Section 8.3.7, "Interpolation Parameters"]] +==== Interpolation Parameters The interpolation variable attribute **`interpolation_parameters`** may be used to provide extra information to the interpolation @@ -417,7 +420,7 @@ interpolation zones that it does not span. image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] -[[compression-by-coordinate-sampling-bounds, Section 8.3.6, "Interpolation of Tie Point Bounds"]] +[[compression-by-coordinate-sampling-bounds, Section 8.3.8, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds If reconstituted coordinates have cell boundaries, then the corresponding tie point variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. The bounds of a tie point must be the same as the bounds of the corresponding target grid cells. It is therefore likely that tie point cells will be non-contiguous. @@ -432,112 +435,52 @@ Note that an implementation of the interpolation method is free to calculate the ==== ---- dimensions : - // VIIRS M-Band (750 m resolution imaging) - m_track = 768 ; - m_scan = 3200 ; - m_channel = 16 ; - // VIIRS I-Band (375 m resolution imaging) - i_track = 1536 ; - i_scan = 6400 ; - i_channel = 5 ; - - // Tie points and interpolation zones (shared between VIIRS M-Band and I-Band) + track = 1536 ; + scan = 6400 ; + // Tie points and interpolation zones tp_track = 96 ; // 48 VIIRS scans tp_scan = 205 ; zone_track = 48 ; // track interpolation zone zone_scan= 200 ; // scan interpolation zone - // Time, stored at scan-start and scan-end of each scan tp_time_scan = 2; variables: - // VIIRS M-Band - float m_radiance(m_track, m_scan, m_channel) ; - m_radiance:tie_points = - "m_lat: m_lon: m_sen_azi_ang: m_sen_zen_ang: m_sol_azi_ang: m_sol_zen_ang: tp_interpolation - t: time_interpolation" ; - m_radiance:tie_point_dimensions = "m_track: tp_track zone_track - m_scan: tp_scan zone_scan - m_scan: tp_time_scan" ; - m_radiance:tie_point_indices = "m_track: m_track_indices - m_scan: m_scan_indices - m_scan: m_time_scan_indices" ; - - // VIIRS I-Band - float i_radiance(i_track, i_scan, i_channel) ; - i_radiance:tie_points = - "i_lat: i_lon: i_sen_azi_ang: i_sen_zen_ang: i_sol_azi_ang: i_sol_zen_ang: tp_interpolation - t: time_interpolation" ; - i_radiance:tie_point_dimensions = "i_track: tp_track zone_track - i_scan: tp_scan zone_scan - i_scan: tp_time_scan" ; - i_radiance:tie_point_indices = "i_track: i_track_indices zone_track - i_scan: i_scan_indices zone_scan - i_scan: i_time_scan_indices" ; - - // Tie point index variables - int m_track_indices(tp_track) ; // shared by tp_interpolation and time_interpolation - int m_scan_indices(tp_scan) ; - int m_time_scan_indices(tp_time_scan) - int i_track_indices(tp_track) ; // shared by tp_interpolation and time_interpolation - int i_scan_indices(tp_scan) ; - int i_time_scan_indices(tp_time_scan) - - // Tie points - float m_lat(tp_track, tp_scan) ; - m_lat : standard_name = "latitude" ; - m_lat : units = "degrees_north" ; - float m_lon(tp_track, tp_scan) ; - m_lon : standard_name = "longitude" ; - m_lon : units = "degrees_east" ; - float m_sen_azi_ang(tp_track, tp_scan) ; - m_sen_azi_ang : standard_name = "sensor_azimuth_angle" ; - m_sen_azi_ang : units = "degrees" ; - float m_sen_zen_ang(tp_track, tp_scan) ; - m_sen_zen_ang : standard_name = "sensor_zenith_angle" ; - m_sen_zen_ang : units = "degrees" ; - float m_sol_azi_ang(tp_track, tp_scan) ; - m_sol_azi_ang : standard_name = "solar_azimuth_angle" ; - m_sol_azi_ang : units = "degrees" ; - float m_sol_zen_ang(tp_track, tp_scan) ; - m_sol_zen_ang : standard_name = "solar_zenith_angle" ; - m_sol_zen_ang : units = "degrees" ; - - float i_lat(tp_track, tp_scan) ; - i_lat : standard_name = "latitude" ; - i_lat : units = "degrees_north" ; - float i_lon(tp_track, tp_scan) ; - i_lon : standard_name = "longitude" ; - i_lon : units = "degrees_east" ; - float i_sen_azi_ang(tp_track, tp_scan) ; - i_sen_azi_ang : standard_name = "sensor_azimuth_angle" ; - i_sen_azi_ang : units = "degrees" ; - float i_sen_zen_ang(tp_track, tp_scan) ; - i_sen_zen_ang : standard_name = "sensor_zenith_angle" ; - i_sen_zen_ang : units = "degrees" ; - float i_sol_azi_ang(tp_track, tp_scan) ; - i_sol_azi_ang : standard_name = "solar_azimuth_angle" ; - i_sol_azi_ang : units = "degrees" ; - float i_sol_zen_ang(tp_track, tp_scan) ; - i_sol_zen_ang : standard_name = "solar_zenith_angle" ; - i_sol_zen_ang : units = "degrees" ; + // VIIRS I-Band Channel 01 and 04 + float I01_radiance(track, scan) ; + I01_radiance:tie_points = "lat: lon: tp_interpolation t: time_interpolation" ; + I01_radiance:standard_name = "toa_outgoing_radiance_per_unit_wavelength" ; + I01_radiance:units = "W m-2 sr-1 m-1" ; + float I01_reflectance(track, scan) ; + I01_reflectance:tie_points = "lat: lon: tp_interpolation t: time_interpolation" ; + I01_reflectance:long_name = "reflectance" ; + I01_reflectance:units = "1" ; + + float I04_radiance(track, scan) ; + I04_radiance:tie_points = "lat: lon: tp_interpolation t: time_interpolation" ; + I04_radiance:standard_name = "toa_outgoing_radiance_per_unit_wavelength" ; + I04_radiance:units = "W m-2 sr-1 m-1" ; + float I04_brightness_temperature(track, scan) ; + I04_brightness_temperature:tie_points = "lat: lon: tp_interpolation t: time_interpolation" ; + I04_brightness_temperature:standard_name = "brightness_temperature" ; + I04_brightness_temperature:units = "K" ; // Interpolation variable char tp_interpolation ; - tp_interpolation:interpolation_name = "bi_quadratic_1" ; - tp_interpolation:interpolation_parameters = - "exp1: expansion1 - align1: alignment1 - exp2: expansion2 - align2:alignment2 - flags: interpolation_zone_flags" ; - - // Interpolation coefficient and configuration variables - short expansion1(zone_track , tp_scan) ; - short alignment1(zone_track , tp_scan) ; - short expansion2(tp_track, zone_scan) ; - short alignment2(tp_track, zone_scan) ; + tp_interpolation:interpolation_name = "bi_quadratic_remote_sensing" ; + tp_interpolation:tie_point_dimensions = "track: tp_track zone_track + scan: tp_scan zone_scan +; + tp_interpolation:tie_point_indices = "track: track_indices + scan: scan_indices +; + tp_interpolation:interpolation_parameters = "ce1: ce1 ca2: ca2 ce3: ce3 flags: interpolation_zone_flags" ; + + // Interpolation parameters + short ce1(tp_track , zone_scan) ; + short ca2(zone_track , tp_scan) ; + short ce3(zone_track, zone_scan) ; byte interpolation_zone_flags(zone_track , zone_scan) ; interpolation_zone_flags : valid_range = "1b, 7b" ; interpolation_zone_flags : flag_masks = "1b, 2b, 4b" ; @@ -546,14 +489,31 @@ variables: sensor_direction_use_cartesian solar_direction_use_cartesian" ; - // Time tie points - double t(tp_track, tp_time_scan) ; - t : long_name = "time" ; - t : units = "days since 1990-1-1 0:0:0" ; + // Tie point index variables + int track_indices(tp_track) ; // shared by tp_interpolation and time_interpolation + int scan_indices(tp_scan) ; + int time_scan_indices(tp_time_scan) + + // Tie points + float lat(tp_track, tp_scan) ; + lat:standard_name = "latitude" ; + lat:units = "degrees_north" ; + float lon(tp_track, tp_scan) ; + lon:standard_name = "longitude" ; + lon:units = "degrees_east" ; // Time interpolation variable char time_interpolation ; - time_interpolation : interpolation_name = "bi_linear" ; + time_interpolation:interpolation_name = "bi_linear" ; + time_interpolation:tie_point_dimensions = "track: tp_track + scan: tp_time_scan" ; + time_interpolation:tie_point_indices = "track: track_indices + scan: time_scan_indices" ; + + // Time tie points + double t(tp_track, tp_time_scan) ; + t:standard_name = "time" ; ; + t:units = "days since 1990-1-1 0:0:0" ; ---- This example demonstrates the use of multiple interpolation variables, @@ -577,7 +537,14 @@ dimensions: tp_y = 58; tp_x = 52; -variables: +variables: + // Data variable + float Temperature(time, y, x) ; + Temperature:standard_name = "air_temperature" ; + Temperature:units = "K" ; + Temperature:grid_mapping = "lambert_conformal" ; + Temperature:tie_points = "lat: lon: bi_linear y: x: linear" ; + int lambert_conformal ; lambert_conformal:grid_mapping_name = "lambert_conformal_conic" ; lambert_conformal:standard_parallel = 25.0 ; @@ -585,10 +552,15 @@ variables: lambert_conformal:latitude_of_projection_origin = 25.0 ; // Interpolation variables - char spherical_bilinear ; - spherical_bilinear:interpolation_name = "spherical_bilinear" ; + char bi_linear ; + bi_linear:interpolation_name = "bi_linear" ; + bi_linear:tie_point_dimensions = "y: tp_y x: tp_x" ; + bi_linear:tie_point_indices = "y: y_indices x: x_indices" ; + char linear ; linear:interpolation_name = "linear" ; + linear:tie_point_dimensions = "y: tp_y x: tp_x" ; + linear:tie_point_indices = "y: y_indices x: x_indices" ; // Tie point variables double time(time) ; @@ -614,14 +586,6 @@ variables: int x_indices(tp_x) ; x_indices.long_name = "Mapping of x dimension to its ", "corresponding tie point dimension" ; - - // Data variable - float Temperature(time, y, x) ; - Temperature:standard_name = "air_temperature" ; - Temperature:units = "K" ; - Temperature:grid_mapping = "lambert_conformal" ; - Temperature:tie_points = "lat: lon: spherical_bilinear y: x: linear" ; - Temperature:tie_point_indices = "y: y_indices x: x_indices" ; ---- In this the projection coordinates are two-dimensional, but are only diff --git a/images/ci_interpolation_coefficients.svg b/images/ci_interpolation_coefficients.svg index d4e0a87e..990def17 100644 --- a/images/ci_interpolation_coefficients.svg +++ b/images/ci_interpolation_coefficients.svg @@ -1,734 +1 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - xy - Dimension (x_interpolation_zone)Example (1) - - - - - - - - Dimension (y_tie_point_interpolation,x_tie_point_interpolation)Example(0, 0) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Dimension (y_tie_point_interpolation , x_interpolation_zone )Example (2, 0) - - Dimension (y_interpolation_zone , x_tie_point_interpolation )Example (1, 2) - - Dimension (y_interpolation_zone , x_interpolation_zone ) -Example (0, 1) - - - - - - - +xyDimension (y_interpolation_zone, x_tie_point_interpolation)Example (1, 2) Dimension (y_tie_point_interpolation, x_interpolation_zone)Example (2, 0) Dimension (y_interpolation_zone, x_interpolation_zone)Example (0, 1) Dimension (x_interpolation_zone)Example (1) Dimension (y_ tie_point_interpolation, x_tie_point_interpolation)Example (0, 0) \ No newline at end of file diff --git a/images/interpolation coefficeints.svg b/images/interpolation coefficeints.svg new file mode 100644 index 00000000..990def17 --- /dev/null +++ b/images/interpolation coefficeints.svg @@ -0,0 +1 @@ +xyDimension (y_interpolation_zone, x_tie_point_interpolation)Example (1, 2) Dimension (y_tie_point_interpolation, x_interpolation_zone)Example (2, 0) Dimension (y_interpolation_zone, x_interpolation_zone)Example (0, 1) Dimension (x_interpolation_zone)Example (1) Dimension (y_ tie_point_interpolation, x_tie_point_interpolation)Example (0, 0) \ No newline at end of file From 743019c752917512087a623164750c0af64d2249 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 28 Apr 2021 19:08:03 +0200 Subject: [PATCH 158/249] Delete ci_interpolation_coefficients.svg --- images/ci_interpolation_coefficients.svg | 1 - 1 file changed, 1 deletion(-) delete mode 100644 images/ci_interpolation_coefficients.svg diff --git a/images/ci_interpolation_coefficients.svg b/images/ci_interpolation_coefficients.svg deleted file mode 100644 index 990def17..00000000 --- a/images/ci_interpolation_coefficients.svg +++ /dev/null @@ -1 +0,0 @@ -xyDimension (y_interpolation_zone, x_tie_point_interpolation)Example (1, 2) Dimension (y_tie_point_interpolation, x_interpolation_zone)Example (2, 0) Dimension (y_interpolation_zone, x_interpolation_zone)Example (0, 1) Dimension (x_interpolation_zone)Example (1) Dimension (y_ tie_point_interpolation, x_tie_point_interpolation)Example (0, 0) \ No newline at end of file From 9147d3b9179e1131dbc11a5c909ce1b4bcd9d1a1 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 28 Apr 2021 19:13:48 +0200 Subject: [PATCH 159/249] Delete interpolation coefficeints.svg --- images/interpolation coefficeints.svg | 1 - 1 file changed, 1 deletion(-) delete mode 100644 images/interpolation coefficeints.svg diff --git a/images/interpolation coefficeints.svg b/images/interpolation coefficeints.svg deleted file mode 100644 index 990def17..00000000 --- a/images/interpolation coefficeints.svg +++ /dev/null @@ -1 +0,0 @@ -xyDimension (y_interpolation_zone, x_tie_point_interpolation)Example (1, 2) Dimension (y_tie_point_interpolation, x_interpolation_zone)Example (2, 0) Dimension (y_interpolation_zone, x_interpolation_zone)Example (0, 1) Dimension (x_interpolation_zone)Example (1) Dimension (y_ tie_point_interpolation, x_tie_point_interpolation)Example (0, 0) \ No newline at end of file From 36f60572662a54afaee7e97da5e2d01e5e42635c Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 28 Apr 2021 19:14:15 +0200 Subject: [PATCH 160/249] Add files via upload --- images/ci_interpolation_coefficients.svg | 734 +++++++++++++++++++++++ 1 file changed, 734 insertions(+) create mode 100644 images/ci_interpolation_coefficients.svg diff --git a/images/ci_interpolation_coefficients.svg b/images/ci_interpolation_coefficients.svg new file mode 100644 index 00000000..d4e0a87e --- /dev/null +++ b/images/ci_interpolation_coefficients.svg @@ -0,0 +1,734 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + xy + Dimension (x_interpolation_zone)Example (1) + + + + + + + + Dimension (y_tie_point_interpolation,x_tie_point_interpolation)Example(0, 0) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dimension (y_tie_point_interpolation , x_interpolation_zone )Example (2, 0) + + Dimension (y_interpolation_zone , x_tie_point_interpolation )Example (1, 2) + + Dimension (y_interpolation_zone , x_interpolation_zone ) +Example (0, 1) + + + + + + + From ca44ed97e51ae75ffc69ebb99be7bd1b44e6e04d Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 29 Apr 2021 09:04:02 +0100 Subject: [PATCH 161/249] spelling --- ch08.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 88c3838b..f47867c0 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -73,7 +73,7 @@ This information implies that the salinity field should be uncompressed to an ar [[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Sampling"]] === Lossy Compression by Coordinate Sampling -For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed dataset can control the accuracy of the reconstituted coordinates through the degree of subsambling and the choice of interpolation method, see <>. +For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed dataset can control the accuracy of the reconstituted coordinates through the degree of subsampling and the choice of interpolation method, see <>. The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. @@ -373,7 +373,7 @@ data: The interpolation variable attribute **`interpolation_parameters`** may be used to provide extra information to the interpolation process. This attribute names __interpolation parameter variables__ -that provide values for coefficent terms in the interpolation +that provide values for coefficient terms in the interpolation equation, or for any other terms that configure the interpolation process. The **`interpolation_parameters`** attribute takes a string value, the string comprising blank-separated elements of the form From e20ec546f92f4ce5efff6487c03ef70ebaab6ee7 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 29 Apr 2021 09:05:34 +0100 Subject: [PATCH 162/249] URI -> URL --- ch08.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index f47867c0..fcc2482c 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -159,11 +159,11 @@ variable must have a **`interpolation_description`** attribute defined instead, containing a description of the non-standardised interpolation (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any -form (including a URI, for example). Whilst it is recommended that a -standardised interpolation is provided, the alternative is provided to -promote interoperability in cases where a well defined user community -needs to use sophisticated interpolation techniques that may also be -under development. +form (including fully qualified URLs, for example). Whilst it is +recommended that a standardised interpolation is provided, the +alternative is provided to promote interoperability in cases where a +well defined user community needs to use sophisticated interpolation +techniques that may also be under development. The definition of the interpolation method, however it is specified, may include instructions to treat groups of physically related From 887dc579c3938d60c062868131957760547172bb Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 29 Apr 2021 09:10:18 +0100 Subject: [PATCH 163/249] lower resolution -> sampled --- ch08.adoc | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index fcc2482c..007315cd 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -73,9 +73,23 @@ This information implies that the salinity field should be uncompressed to an ar [[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Sampling"]] === Lossy Compression by Coordinate Sampling -For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in the netCDF file by storing coordinates at a lower resolution than the data which they describe. The uncompressed coordinate and auxiliary coordinate variables can be reconstituted by interpolation, from the lower resolution coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding and approximation errors in the interpolation calculations, but it is assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed dataset can control the accuracy of the reconstituted coordinates through the degree of subsampling and the choice of interpolation method, see <>. - -The lower resolution coordinates are called __tie points__ and are stored in __tie point variables__. +For some applications the coordinates of a data variable can require +considerably more storage than the data itself. Space may be saved in +the netCDF file by storing a sample of the coordinates that describe +the data. The uncompressed coordinate and auxiliary coordinate +variables can be reconstituted by interpolation, from the sampled +coordinate values to the domain of the data (i.e. the target +domain). This process will likely result in a loss in accuracy (as +opposed to precision) in the uncompressed variables, due to rounding +and approximation errors in the interpolation calculations, but it is +assumed that these errors will be small enough to not be of concern to +users of the uncompressed dataset. The creator of the compressed +dataset can control the accuracy of the reconstituted coordinates +through the degree of subsampling and the choice of interpolation +method, see <>. + +The sampled coordinates are called __tie points__ and are stored in +__tie point variables__. In addition to the tie point variables themselves, metadata defining the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. From ba02fd2d82383560b185865ebba5dc7c745041cf Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 29 Apr 2021 09:13:27 +0100 Subject: [PATCH 164/249] Use on domain variable --- ch08.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 007315cd..e01a9e52 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -95,7 +95,8 @@ In addition to the tie point variables themselves, metadata defining the coordin The metadata that define the interpolation formula and its inputs are complete, so that the results of the coordinate reconstitution process are well defined and of a predictable accuracy. -The data variable coordinate interpolation attribute may also be used on a domain variable (domain-variables) with the same effect. +This form of compression may also be used on a domain variable +(domain-variables) with the same effect. [[compression-by-coordinate-sampling-tie-points-and-interpolation-zones, Section 8.3.1, "Tie Points and Interpolation Zones"]] ==== Tie Points and Interpolation Zones From 3e91bd530d18a91bbfcdbf228c17eb822db517ab Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 29 Apr 2021 09:14:39 +0100 Subject: [PATCH 165/249] typo --- ch08.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index e01a9e52..f673051b 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -170,8 +170,8 @@ method, and optional interpolation variable attributes for configuring the interpolation process. If a standardized interpolation name is not given, the interpolation -variable must have a **`interpolation_description`** attribute defined -instead, containing a description of the non-standardised +variable must have an **`interpolation_description`** attribute +defined instead, containing a description of the non-standardised interpolation (in a similar manner to a long name being used instead of a standard name). This description is free text that can take any form (including fully qualified URLs, for example). Whilst it is From 1cc229c3273e8b4af163124a618f6509ae896e7a Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 29 Apr 2021 09:18:29 +0100 Subject: [PATCH 166/249] Move 'interpolation dimension' definition to first occurence --- ch08.adoc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index f673051b..a3d73742 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -134,7 +134,11 @@ in <>, and described in more detail in Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. -For each interpolation dimension, the location of the tie points is defined by a corresponding __tie point index variable__, which also indicates the location of the interpolation areas (<>). +For each __interpolation dimension__, i.e. a target domain dimension +for which coordinate interpolation is required, the location of the +tie points is defined by a corresponding __tie point index variable__, +which also indicates the location of the interpolation areas +(<>). For each interpolation dimension, the number of interpolation zones is equal to the number of tie points minus the number of interpolation areas. @@ -199,7 +203,15 @@ In addition to the **`interpolation_name`** and **`interpolation_description`** [[compression-by-coordinate-sampling-dimensions,Section 8.3.4, "Interpolation and Non-Interpolation Dimensions"]] ==== Interpolation and Non-Interpolation Dimensions -For each interpolation variable identified in the **`tie_points`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required; and may additionally contain one or more __non-interpolation dimensions__, i.e. those of the target domain for which no coordinate interpolation is required. The size of a tie point interpolation dimension must be less than or equal to the size of its corresponding interpolation dimension. +For each interpolation variable identified in the **`tie_points`** +attribute, all corresponding tie point variables must share the same +set of one or more dimensions. This set of dimensions must contain at +least one __tie point interpolation dimension__ that corresponds to an +interpolation dimension; and may additionally contain one or more +__non-interpolation dimensions__, i.e. those of the target domain for +which no coordinate interpolation is required. The size of a tie point +interpolation dimension must be less than or equal to the size of its +corresponding interpolation dimension. An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are `xc = 30` and `yc = 10`, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions `tp_xc = 4` and `tp_yc = 2`. Here, `tp_xc` is the tie point interpolation dimension related to the interpolation dimension `xc`, and `tp_yc` is the tie point interpolation dimension related to the interpolation dimension `yc`. From 52f08ead11c8722342d9de0ce5cd95bb6dd377f7 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 29 Apr 2021 09:26:09 +0100 Subject: [PATCH 167/249] Minor re-wording --- ch08.adoc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index a3d73742..cf9ad01b 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -215,7 +215,15 @@ corresponding interpolation dimension. An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are `xc = 30` and `yc = 10`, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions `tp_xc = 4` and `tp_yc = 2`. Here, `tp_xc` is the tie point interpolation dimension related to the interpolation dimension `xc`, and `tp_yc` is the tie point interpolation dimension related to the interpolation dimension `yc`. -The presence of non-interpolation dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolation dimensions. For example, if the target domain dimensions are `xc = 30` and `yc = 10`, interpolation could be applied in the `xc` dimension only, based on tie point variables of the dimensions `tp_xc = 4` and `yc = 10`. The interpolation in the `xc` dimension would then be repeated for each of the 10 indices of the `yc` dimension. +The presence of non-interpolation dimensions in the tie point variable +impacts the interpolation process in that there must be a separate +application of the interpolation method for each combination of +indices of the non-interpolation dimensions. For example, if the +target domain dimensions are `xc = 30` and `yc = 10`, interpolation +could be applied in the `xc` dimension only, based on tie point +variables that have dimensions `tp_xc = 4` and `yc = 10`. The +interpolation in the `xc` dimension would then be repeated for each of +the 10 indices of the `yc` dimension. [[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.5, "Tie Point Dimensions Attribute"]] ==== Tie Point Dimensions Attribute From 56b3a1bc3682083dbf8b5de100f3e5a277e9b1b4 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 29 Apr 2021 09:38:25 +0100 Subject: [PATCH 168/249] Fix cross-reference --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index cf9ad01b..d88c774b 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -235,7 +235,7 @@ interpolation zones which partition the interpolation dimension. Regardless of its size, an interpolation zone dimension is only required if it is spanned by an interpolation parameter variable, as described in -<>. The +<>. The association is stored in the interpolation variable's **`tie_point_dimensions`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: From 87afb2ca4b09e5bf4ad6612ffa5b0120a97f33bb Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 29 Apr 2021 09:45:18 +0100 Subject: [PATCH 169/249] Re-wording --- ch08.adoc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index d88c774b..c3c8b452 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -231,10 +231,11 @@ the 10 indices of the `yc` dimension. Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding __interpolation zone dimension__ that defines the number of -interpolation zones which partition the interpolation -dimension. Regardless of its size, an interpolation zone dimension is -only required if it is spanned by an interpolation parameter variable, -as described in +interpolation zones which partition the interpolation dimension. It is +only required to associate an interpolation zone dimension to an +interpolation dimension in the case that the interpolation zone +dimension is spanned by an interpolation parameter variable, as +described in <>. The association is stored in the interpolation variable's **`tie_point_dimensions`** attribute that contains a blank-separated From ed7509590003ead352a44d7e0fe46c24c9fe0691 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 29 Apr 2021 09:47:40 +0100 Subject: [PATCH 170/249] typesetting --- ch08.adoc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index c3c8b452..228f0e55 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -270,13 +270,13 @@ dimensions associated with a given interpolation dimension. The same interpolation variable may be multiply mapped from the different sets of tie point variables. For instance, if tie point -variables lat and lon span dimension `tp_dimension1` and time spans -dimension `tp_dimension2`, and all three are to interpolated according -to interpolation variable `linear`, then the **`tie_points`** -attribute could be `lat: lon: linear time: linear`. In this case it is -not possible to simultaneously map all three tie point variables to -the linear interpolation variable because they do not all span the -same axes. +variables `lat` and `lon` span dimension `tp_dimension1` and tie point +variable `time` spans dimension `tp_dimension2`, and all three are to +interpolated according to interpolation variable `linear`, then the +**`tie_points`** attribute could be `lat: lon: linear time: +linear`. In this case it is not possible to simultaneously map all +three tie point variables to the linear interpolation variable because +they do not all span the same axes. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.6, "Tie Point Indices"]] ==== Tie Point Indices From 35b0862dfae8dc1815c0e2f236162e7b1976a8e3 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 29 Apr 2021 10:05:03 +0100 Subject: [PATCH 171/249] tie point index re-wording --- ch08.adoc | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 228f0e55..b13dd0f6 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -283,25 +283,21 @@ they do not all span the same axes. The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point -index variable__. This contains zero-based indices that relate each -element of a tie point interpolation dimension to its related location -in the corresponding interpolation dimension. The tie point index -variable is a one-dimensional integer variable that must span the tie -point interpolation dimension specified by the -**`tie_point_dimensions`** attribute. The tie point index values must -be strictly monotonically increasing within interpolation areas. An -interpolation zone must span at least two points of each of its -corresponding interpolation dimensions, therefore the tie point -indices that define an interpolation zone must all be different. When -two adjacent values are equal, or differ by one, it indicates the -location (in index space) of an interpolation area boundary relating -to a grid discontinuity +index variable__. The tie point index variable is a one-dimensional +integer variable that must span the tie point interpolation dimension +specified by the **`tie_point_dimensions`** attribute. Each tie point +index variable value is a zero-based index of the related +interpolation dimension which maps an element of that interpolation +dimension to the corresponding location in the tie point interpolation +dimension. The tie point index values must be strictly monotonically +increasing within interpolation areas. An interpolation zone must span +at least two points of each of its corresponding interpolation +dimensions, therefore the tie point indices that define an +interpolation zone must all be different. When two adjacent values are +equal, or differ by one, it indicates the location (in index space) of +an interpolation area boundary relating to a grid discontinuity (<>). -Each value of the tie point index variable is the index of the -interpolation dimension that corresponds to the corresponding -tie point interpolation dimension. - For instance, in example <> the tie point variables represent a subset of the target domain and the tie point index variable `int x_indices(tp_xc)` contains the From 0104a28c6db62c2b8061425ef28079210149be47 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 5 May 2021 12:04:18 +0200 Subject: [PATCH 172/249] Rotation of interpolation axes for two dimensional methods and mino corrections --- appj.adoc | 109 ++++++++++++++++++++++----------------- images/ci_quadratic3.svg | 2 +- 2 files changed, 62 insertions(+), 49 deletions(-) diff --git a/appj.adoc b/appj.adoc index 28600e7d..64f56a3b 100644 --- a/appj.adoc +++ b/appj.adoc @@ -8,6 +8,8 @@ The definitions and guidance given here allow an application to compress an exis Futhermore, the definitions given here allow an application to uncompress coordinate and auxiliary coordinate variables that have been compressed using coordinate sampling. The key element of this process is the reconstitution of the full resolution coordinates in the domain of the data by interpolation between the lower resolution coordinates, the tie points, stored in the compressed dataset. +All floating point calculations defined in this appendix must be carried out in 64 bit floating point, even if the related coordinates and interpolation parameters are stored in the netCDF files with a lower precision. + The appendix is organised in a sections on <>, <>, <> and finally two sections with step procedures <> and <>. [[common_definitions_and_notation]] @@ -41,7 +43,7 @@ In the case of two dimensional interpolation, the two interpolation variables ar `s1 = s(ia1, ib1, i1) = (i1 - ia1)/(ib1 - ia1)` + `s2 = s(ia2, ic2, i2) = (i2 - ia2)/(ic2 - ia2)` -where `ia1` and `ib1` are the first dimension indices in the target domain of the tie points `A` and `B` respectively, `ia2` and `id2` are the second dimension indices in the target domain of the tie points `A` and `D` respectively and the indices `i1` and `i2` are the first and second dimension indices respectively in the target domain of the coordinate value to be reconstituted. +where `ia1` and `ib1` are the first dimension indices in the target domain of the tie points `A` and `B` respectively, `ia2` and `ic2` are the second dimension indices in the target domain of the tie points `A` and `D` respectively and the indices `i1` and `i2` are the first and second dimension indices respectively in the target domain of the coordinate value to be reconstituted. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables the interpolation method can be applied independently for each interpolation zone, making it possible to parallelize the computational process. @@ -80,10 +82,10 @@ where `ua` and `ub` are the coordinate values at tie points `A` and `B` respecti | Interpolation Parameter terms | None | Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | -The interpolation function fl() defined for linear interpolation above is first applied twice in the interpolation dimension 1, once between tie points `A` and `B` and once between tie points `C` and `D`. It is then applied once in the interpolation dimension 2, between the two resulting coordinate points, yielding the interpolated coordinate value `u(i1, i2)`: + -`uab = fl(ua, ub, s(ia1, ib1, i1))`; + -`ucd = fl(uc, ud, s(ia1, ib1, i1))`; + -`u(i1, i2) = fl(uab, ucd, s(ia2, ic2, i2))`; + +The interpolation function fl() defined for linear interpolation above is first applied twice in the interpolation dimension 2, once between tie points `A` and `C` and once between tie points `B` and `D`. It is then applied once in the interpolation dimension 1, between the two resulting coordinate points, yielding the interpolated coordinate value `u(i2, i1)`: + +`uac = fl(ua, uc, s(ia2, ic2, i2))`; + +`ubd = fl(ub, ud, s(ia2, ic2, i2))`; + +`u(i2, i1) = fl(uac, ubd, s(ia1, ib1, i1))`; + |=============== @@ -101,7 +103,7 @@ The interpolation function fl() defined for linear interpolation above is first | Coordinate Compression Calculations | The expression + `c = fc(ua, ub, u(i), s(i)) = ((u - (1 - s) * ua - s * ub)/( 4 * (1 - s) * s)` + -enables the creator of the dataset to calculate `c` from the coordinate values `ua` and `ub` at tie points `A` and `B` respectively, and the coordinate value `u(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib - ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib - ia - 1)/2` shall be selected. +enables the creator of the dataset to calculate `c` from the coordinate values `ua` and `ub` at tie points `A` and `B` respectively, and the coordinate value `u(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib + ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib + ia - 1)/2` shall be selected. | Coordinate Uncompression Calculations | The coordinate value `u(i)` at index `i` between tie points `A` and `B` is calculated from: + @@ -121,13 +123,13 @@ Requires a pair of latitude and longitude tie point variables, as defined unambi By default, interpolation is performed directly in the latitude and longitude coordinates, but may be performed in cartesian coordinates where required for achieving the desired accuracy. This must be indicated by setting the `location_use_cartesian` flag within the interpolation parameter `interpolation_zone_flags` for each interpolation zone where interpolation in cartesian coordinates is required. -The quadratic interpolation coefficients `ce` and `ca`, stored as interpolation parameters in the product, describe a point `P` between the tie points `A` and `B`, which is equivalent of an additional tie point in the sense that the method will accurately reconstitute the point `P` in the same way as it accurately reconstitutes the tie points `A` and `B`. See <> and <>. +The quadratic interpolation coefficients `cea = (ce, ca)`, stored as interpolation parameters in the product, describe a point `P` between the tie points `A` and `B`, which is equivalent of an additional tie point in the sense that the method will accurately reconstitute the point `P` in the same way as it accurately reconstitutes the tie points `A` and `B`. See <> and <>. Although equivalent to a tie point, the coefficients `ce` and `ca` have two advantages over tie points. Firstly, they can often be stored as a lower precision floating point number compared to the tie points, as `ce` and `ca` only describes the position of `P` relative to the midpoint `M` between the tie points `A` and `B`. Secondly, if any of `ce` and `ca` do not contribute significantly to the accuracy of the reconstituted points, it can be left out of the data set and its value will default to zero during uncompression. The coefficients may be represented in three different ways: -For storage in the dataset as the non-dimensional coefficients `(ce, ca)`, referred to as the parametric representation. The component `ce` is the offset projected on the line from tie point `B` to tie point `A` and expressed as a fraction of the distance between `A` and `B`. The component `ca` is the offset projected on the line perpendicular to the line from tie point `B` to tie point `A` and perpendicular to the plane spanned by `va` and `vb`, the vector representations of the two tie points, and expressed as a fraction of the distance between `A` and `B`. + +For storage in the dataset as the non-dimensional coefficients `cea = (ce, ca)`, referred to as the parametric representation. The component `ce` is the offset projected on the line from tie point `B` to tie point `A` and expressed as a fraction of the distance between `A` and `B`. The component `ca` is the offset projected on the line perpendicular to the line from tie point `B` to tie point `A` and perpendicular to the plane spanned by `va` and `vb`, the vector representations of the two tie points, and expressed as a fraction of the length of `A x B`. + For interpolation in cartesian coordinates as the coefficients `cv = (cv.x, cv.y, cv.z)`, expressing the offset components along the cartesian axes X, Y and Z respectively. @@ -141,18 +143,18 @@ Optionally the flag variable `interpolation_zone_flags`, which must span the `in | Coordinate Compression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb);` + -Then calculate the cartesian representation of the interpolation coefficients from the tie points `va` and `vb` as well as the point `vp(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib - ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib - ia - 1)/2` shall be selected. + +Then calculate the cartesian representation of the interpolation coefficients from the tie points `va` and `vb` as well as the point `vp(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib + ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib + ia - 1)/2` shall be selected. + The cartesian interpolation coefficients are found from + `cv = fcv(va, vb, vp(i), s(i)) = (fc(va.x, vb.x, vp(i).x, s(i)), fc(va.y, vb.y, vp(i).y, s(i)), fc(va.z, vb.z, vp(i).z, s(i))).` + Finally, for storage in the dataset, convert the coefficients to the parametric representation + -`(ce(iz), ca(iz)) = fcv2cea(va, vb, cv) = (fdot(cv, fminus(va, vb))/ gsqr), fdot(cv, fcross(va, vb))/(rsqr*gsqr));` + +`cea(iz) = (ce(iz), ca(iz)) = fcv2cea(va, vb, cv) = (fdot(cv, fminus(va, vb))/ gsqr), fdot(cv, fcross(va, vb))/(rsqr*gsqr));` + where `vr = fmultiply(0.5, fplus(va, vb))`, `rsqr = fdot(vr, vr)` and `gsqr = 4*(1-rsqr).` + The interpolation parameter term `interpolation_zone_flags(iz)` shall have the flag `location_use_cartesian` set if the interpolation zone intersects the `longitude = 180.0` or if the interpolation zone extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb);` + Then calculate the cartesian representation of the interpolation coefficients from the parametric representation stored in the dataset using + -`cv = fcea2cv(va, vb, ce(iz), ca(iz)) = fplus(fmultiply(ce, fminus(va, vb)), fmultiply(ca, fcross(va, vb)), fmultiply(cr, vr));` + +`cv = fcea2cv(va, vb, cea(iz)) = fplus(fmultiply(ce, fminus(va, vb)), fmultiply(ca, fcross(va, vb)), fmultiply(cr, vr));` + where + `vr = fmultiply(0.5, fplus(va, vb))`; + `rsqr = fdot(vr, vr);` + @@ -184,9 +186,11 @@ image::images/ci_quadratic2.svg[,100%,pdfwidth=50vw,align="center"] [cols="6,15"] |=============== | Name | **`interpolation_name = "bi_quadratic_remote_sensing"`** -| Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. Requires a coordinate pair with `standard_name` `latitude` and `longitude`. + +| Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. + +Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. -The functions `fcv()`, `fcv2cea()`, `fcea2cv()`, `fcll()`, `fqv()` and `fqll()` referenced in the following are defined in <>. As for that method, interpolation is performed directly in the latitude and longitude coordinates or in cartesian coordinates, where required for achieving the desired accuracy. Similarly, it shares the three different representations of the quadratic interpolation coefficients, the parametric representation `(ce, ca)` for storage in the dataset, `cll = (cll.lat, cll.lon)` for interpolation in geographic coordinates latitude and longitude and `cv = (cv.x, cv.y, cv.z)` for cartesian interpolation. +The functions `fcv()`, `fcv2cea()`, `fcea2cv()`, `fcll()`, `fqv()` and `fqll()` referenced in the following are defined in <>. As for that method, interpolation is performed directly in the latitude and longitude coordinates or in cartesian coordinates, where required for achieving the desired accuracy. Similarly, it shares the three different representations of the quadratic interpolation coefficients, the parametric representation `cea = (ce, ca)` for storage in the dataset, `cll = (cll.lat, cll.lon)` for interpolation in geographic coordinates latitude and longitude and `cv = (cv.x, cv.y, cv.z)` for interpolation in cartesian coordinates. The parametric representation of the interpolation coefficients, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation zone as shown in <>, which also shows the orientation and indices of the parameters. @@ -200,57 +204,66 @@ Optionally the flag variable `interpolation_zone_flags`, which must span the `in | Coordinate Compression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb); vc = fll2v(llc); vd = fll2v(lld).` + -Then calculate the cartesian representation of the interpolation coefficients sets from the tie points as well as a point `vp(i2, i1)` between the tie points. If the size of the interpolation zone in the first dimension `(ib1 - ia1)` is an even number, then the index `i1 = (ib1 + ia1)/2` shall be selected for this calculation, otherwise the index `i1 = (ib1 + ia1 - 1)/2` shall be selected. If the size of the interpolation zone in the second dimension `(ib2 - ic2)` is an even number, then the index `i2 = (ib2 + ic2)/2` shall be selected for this calculation, otherwise the index `i2 = (ib2 + ic2 - 1)/2` shall be selected. + +Then calculate the cartesian representation of the interpolation coefficients sets from the tie points as well as a point `vp(i2, i1)` between the tie points. If the size of the interpolation zone in the first dimension `(ib1 - ia1)` is an even number, then the index +`i1 = (ib1 + ia1)/2` shall be selected for this calculation, otherwise the index +`i1 = (ib1 + ia1 - 1)/2` shall be selected. If the size of the interpolation zone in the second dimension `(ib2 - ic2)` is an even number, then the index `i2 = (ib2 + ic2)/2` shall be selected for this calculation, otherwise the index `i2 = (ib2 + ic2 - 1)/2` shall be selected. + Using the selected `(i2, i1)`, the cartesian interpolation coefficients are found from + -`cv_ab = fcv( va, vb, fll2v(ll(ia2, i1)), s(ia1, ib1, i1));` + -`cv_cd = fcv( vc, vd, fll2v(ll(ic2, i1)), s(ia1, ib1, i1));` + -`cv_ac = fcv( va, vc, fll2v(ll(i2, ia1)), s(ia2, ic2, i2));` + -`cv_bd = fcv( vb, vd, fll2v(ll(i2, ib1)), s(ia2, ic2, i2));` + -`vab = fqv(va, vb, cv_ab, s(ia1, ib1, i1))`; + -`vcd = fqv(vc, vd, cv_cd, s(ia1, ib1, i1))`; + -`cv_zz = fcv( vab, vcd, fll2v(ll(i2, i1)), s(ia2, ic2, i2));` + -`vac = fqv(va, vc, cv_ac, 0.5);` + -`vbd = fqv(vb, vd, cv_bd, 0.5);` + -`vz = fqv( vab, vcd, cv_zz, 0.5);` + -`cv_z = fcv(vac, vbd, vz, s(ia1, ib1, i1)).` + +`s1 = s(ia1, ib1, i1);` +`s2 = s(ia2, ic2, i2);` + +`vac = fll2v(ll(i2, ia1));` +`vbd = fll2v(ll(i2, ib1));` + +`cv_ac = fcv(va, vc, vac, s2);` + +`cv_bd = fcv(vb, vd, vbd, s2);` + +`cv_ab = fcv(va, vb, fll2v(ll(ia2, i1)), s1);` + +`cv_cd = fcv(vc, vd, fll2v(ll(ic2, i1)), s1);` + +`cv_zz = fcv(vac, vbd, fll2v(ll(i2, i1)), s1);` + +`vz = fqv(vac, vbd, cv_zz, 0.5);` + +`vab = fqv(va, vb, cv_ab, 0.5);` + +`vcd = fqv(vc, vd, cv_cd, 0.5);` + +`cv_z = fcv(vab, vcd, vz, s2);` + Finally, before storing them in the dataset's interpolation parameters, convert the coefficients to the parametric representation + -`(ce1(tp2, iz1), ca1(tp2, iz1)) = fcv2cea( va, vb, cv_ab);` + -`(ce1(tp2+1, iz1), ca1(tp2+1, iz1)) = fcv2cea( vc, vd, cv_cd);` + -`(ce2(iz2, tp1), ca2(iz2, tp1)) = fcv2cea( va, vc, cv_ac);` + -`(ce2(iz2, tp1+1), ca2(iz2, tp1+1)) = fcv2cea( vb, vd, cv_bd);` + -`(ce3(iz2, iz1), ca3(iz2, iz1)) = fcv2cea( vac, vbd, cv_z).` + +`cea1(tp2, iz1) = fcv2cea( va, vb, cv_ab);` + +`cea1(tp2+1, iz1) = fcv2cea( vc, vd, cv_cd);` + +`cea2(iz2, tp1) = fcv2cea( va, vc, cv_ac);` + +`cea2(iz2, tp1+1) = fcv2cea( vb, vd, cv_bd);` + +`cea3(iz2, iz1) = fcv2cea( vab, vcd, cv_z).` + The interpolation parameter term `interpolation_zone_flags(iz2, iz1)` shall have the flag `location_use_cartesian` set if the interpolation zone intersects the `longitude = 180.0` or if the interpolation zone extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb); vc = fll2v(llc); vd = fll2v(lld).` + Then calculate the cartesian representation of the interpolation coefficient sets from the parametric representation stored in the dataset + -`cv_ab = fcea2cv( va, vb, ce1(tp2, iz1), ca1(tp2, iz1));` + -`cv_cd = fcea2cv( vc, vd, ce1(tp2+1, iz1), ca1(tp2+1, iz1));` + -`vac = fqv(va, vc, fcea2cv( va, vc, ce2(iz2, tp1), ca2(iz2, tp1)), 0.5);` + -`vbd = fqv(vb, vd, fcea2cv( vb, vd, ce2(iz2, tp1+1), ca2(iz2, tp1+1)), 0.5);` + -`cv_z = fcea2cv( vac, vbd, ce3(iz2, iz1), ca3(iz2, iz1)).` + +`cv_ac = fcea2cv(va, vc, cea2(iz2, tp1));` + +`cv_bd = fcea2cv(vb, vd, cea2(iz2, tp1 + 1));` + +`vab = fqv(va, vb, fcea2cv(va, vb, cea1(tp2, iz1)), 0.5);` + +`vcd = fqv(vc, vd, fcea2cv(vc, vd, cea1(tp2 + 1, iz1)), 0.5);` + +`cv_z = fcea2cv(vab, vcd, cea3(iz2, iz1));` + If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_zone_flags` is set, use the following expression to reconstitute any point `llp(i2, i1)` between the tie points `A` and `B` using interpolation in cartesian coordinates + -`llp(i2, i1) = fv2ll(fqv(vab, vcd, fcv( vab, vcd, vz, 0.5), s(ia2, ic2, i2)));` + +`llp(i2, i1) = fv2ll(fqv(vac, vbd, cv_zz, s(ia1, ib1, i1)));` + where + -`vab = fqv(va, vb, cv_ab, s(ia1, ib1, i1));` + -`vcd = fqv(vc, vd, cv_cd, s(ia1, ib1, i1));` + -`vz = fqv(vac, vbd, cv_z, s(ia1, ib1, i1)).` + +`s2 = s(ia2, ic2, i2);` + +`vac = fqv(va, vc, cv_ac, s2);` + +`vbd = fqv(vb, vd, cv_bd, s2);` + +`vz = fqv(vab, vcd, cv_z, s2);` + +`cv_zz = fcv(vac, vbd, vz, 0.5);` + Otherwise, first calculate latitude-longitude representation of the interpolation coefficients + -`llc_ab = fcll( a, b, fv2ll(fqv(va, vb, cv_ab, 0.5)));` + -`llc_cd = fcll( c, d, fv2ll(fqv(vc, vd, cv_cd, 0.5)));` + -`llac = fv2ll(vac); llbd = fv2ll(vbd);` + -`llc_z = fcll( a, b, fv2ll(fqv(vac, vbd, cv_ab, 0.5))).` + +`llc_ac = fcll(lla, llc, fv2ll(fqv(va, vc, cv_ac, 0.5)), 0.5);` + +`llc_bd = fcll(llb, lld, fv2ll(fqv(vb, vd, cv_bd, 0.5)), 0.5);` + +`llab = fv2ll(vab);` + +`llcd = fv2ll(vcd);` + +`llc_z = fcll(llab, llcd, fv2ll(fqv(vab, vcd, cv_z, 0.5)), 0.5);` + Then use the following expression to reconstitute any point `llp(i2, i1)` in the tie point zone using interpolation in latitude-longitude coordinates + - `llp(i2, i1) = fqll(llab, llcd, fcll(llab, llcd, llz, 0.5), s(ia2, ic2, i2));` + +`llp(i2, i1) = fqll(llac, llbd, cl_zz, s(ia1, ib1, i1));` + where + -`llab = fqll(a, b, llc_ab, s(ia1, ib1, i1));` + -`llcd = fqll(c, d, llc_cd, s(ia1, ib1, i1));` + -`llz = fqll(llac, llbd, llc_z, s(ia1, ib1, i1)).` + +`s2 = s(ia2, ic2, i2);` + +`llac = fqll(a, c, llc_ac, s2);` + +`llbd = fqll(b, d, llc_bd, s2);` + +`llz = fqll(llab, llcd, llc_z, s2);` + +`cl_zz = fcll(llac, llbd, llz, 0.5);` + |=============== [[quadratic3, figure 4]] [.text-center] -.The parametric representation of the interpolation coefficients `(ce, ca)`, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation zone. Shown with parameter orientation and indices. +.The parametric representation of the interpolation coefficients `cea = (ce, ca)`, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation zone. Shown with parameter orientation and indices. image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] diff --git a/images/ci_quadratic3.svg b/images/ci_quadratic3.svg index 49eb9320..94b42322 100644 --- a/images/ci_quadratic3.svg +++ b/images/ci_quadratic3.svg @@ -1 +1 @@ -ABCDca1(tp2+1, iz1)ca1(tp2, iz1)ce1(tp2, iz1)ca1(tp2+1, iz1)ca3(iz2, iz1)ce3(iz2, iz1)ca2(iz2, tp1)ce2(iz2, tp1)ca2(iz2, tp1+1)ce2(iz2, tp1+1) \ No newline at end of file +ca1(tp2+1, iz1)ca1(tp2, iz1)ce1(tp2, iz1)ca1(tp2+1, iz1)ca3(iz2, iz1)ce3(iz2, iz1)ca2(iz2, tp1)ce2(iz2, tp1)ca2(iz2, tp1+1)ce2(iz2, tp1+1)ABCD \ No newline at end of file From 12d6d2175746b6556a6991e7bbd43c4043a9cc18 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 6 May 2021 09:15:35 +0100 Subject: [PATCH 173/249] terminology: interpolation variable and tie point variable --- ch01.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ch01.adoc b/ch01.adoc index f818f6a4..6599adb2 100644 --- a/ch01.adoc +++ b/ch01.adoc @@ -76,6 +76,8 @@ It is a one-dimensional variable with the same name as its dimension [e.g., **`t grid mapping variable:: A variable used as a container for attributes that define a specific grid mapping. The type of the variable is arbitrary since it contains no data. +interpolation variable:: A variable used as a container for attributes that define a specific interpolation method for uncompressing tie point variables. The type of the variable is arbitrary since it contains no data. + latitude dimension:: A dimension of a netCDF variable that has an associated latitude coordinate variable. local apex group:: The nearest (to a referring group) ancestor group in which a dimension of an out-of-group coordinate is defined. The word "apex" refers to position of this group at the vertex of the tree of groups formed by it, the referring group, and the group where a coordinate is located. @@ -103,6 +105,8 @@ sibling group:: Any group with the same parent group as the referring group spatiotemporal dimension:: A dimension of a netCDF variable that is used to identify a location in time and/or space. +tie point variable:: A netCDF variable that contains coordinates that have been compressed by sampling. There is no relationship between the name of a tie poitnt variable and the name(s) of its dimension(s). + time dimension:: A dimension of a netCDF variable that has an associated time coordinate variable. vertical dimension:: A dimension of a netCDF variable that has an associated vertical coordinate variable. From 2e9fd1651bfdc92a69885a827cbdeab161b3cd9e Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 6 May 2021 09:19:35 +0100 Subject: [PATCH 174/249] typo --- ch01.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch01.adoc b/ch01.adoc index 6599adb2..1b6da72c 100644 --- a/ch01.adoc +++ b/ch01.adoc @@ -105,7 +105,7 @@ sibling group:: Any group with the same parent group as the referring group spatiotemporal dimension:: A dimension of a netCDF variable that is used to identify a location in time and/or space. -tie point variable:: A netCDF variable that contains coordinates that have been compressed by sampling. There is no relationship between the name of a tie poitnt variable and the name(s) of its dimension(s). +tie point variable:: A netCDF variable that contains coordinates that have been compressed by sampling. There is no relationship between the name of a tie point variable and the name(s) of its dimension(s). time dimension:: A dimension of a netCDF variable that has an associated time coordinate variable. From 42c50b33deeaaf418b91cd558bcea5dc86f0a96f Mon Sep 17 00:00:00 2001 From: David Hassell Date: Thu, 6 May 2021 09:34:02 +0100 Subject: [PATCH 175/249] examples in toc --- toc-extra.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/toc-extra.adoc b/toc-extra.adoc index daf76be7..a3854c81 100644 --- a/toc-extra.adoc +++ b/toc-extra.adoc @@ -58,6 +58,10 @@ F.1. <> 7.16. <> 8.1. <> 8.2. <> +8.3. <> +8.4. <> +8.5. <> +8.6. <> B.1. <> H.1. <> H.2. <> From 4088f637e3d76c0046e75255653a40703c4200d3 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Sun, 9 May 2021 15:43:08 +0200 Subject: [PATCH 176/249] Replace expression for gsqr with equivalent, but numerically more accurate version --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 64f56a3b..9ad305a9 100644 --- a/appj.adoc +++ b/appj.adoc @@ -148,7 +148,7 @@ The cartesian interpolation coefficients are found from + `cv = fcv(va, vb, vp(i), s(i)) = (fc(va.x, vb.x, vp(i).x, s(i)), fc(va.y, vb.y, vp(i).y, s(i)), fc(va.z, vb.z, vp(i).z, s(i))).` + Finally, for storage in the dataset, convert the coefficients to the parametric representation + `cea(iz) = (ce(iz), ca(iz)) = fcv2cea(va, vb, cv) = (fdot(cv, fminus(va, vb))/ gsqr), fdot(cv, fcross(va, vb))/(rsqr*gsqr));` + -where `vr = fmultiply(0.5, fplus(va, vb))`, `rsqr = fdot(vr, vr)` and `gsqr = 4*(1-rsqr).` + +where `vr = fmultiply(0.5, fplus(va, vb))`, `rsqr = fdot(vr, vr)`, `vg = fminus(va, vb)` and `gsqr = fdot(vg, vg).` + The interpolation parameter term `interpolation_zone_flags(iz)` shall have the flag `location_use_cartesian` set if the interpolation zone intersects the `longitude = 180.0` or if the interpolation zone extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + From 9483ed9156aec82252f1e05a28d182ae9347c182 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 11 May 2021 14:45:25 +0200 Subject: [PATCH 177/249] Update authors --- cf-conventions.adoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cf-conventions.adoc b/cf-conventions.adoc index 3eb3cca6..5a5f8e0c 100644 --- a/cf-conventions.adoc +++ b/cf-conventions.adoc @@ -39,6 +39,11 @@ include::toc-extra.adoc[] * David Hassell, NCAS and University of Reading * Alan D. Snow, Corteva Agriscience * Tobias Kölling, MPIM +* Aleksandar Jelenak, HDF Group +* Anders Meier Soerensen, EUMETSAT +* Lucile Gaultier, OceanDataLab +* Sylvain Herlédan, OceanDataLab + Many others have contributed to the development of CF through their participation in discussions about proposed changes. From cb6d5afa6e68fdb690c667651e68d8f004af82fd Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 11 May 2021 14:51:35 +0200 Subject: [PATCH 178/249] Update history --- history.adoc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/history.adoc b/history.adoc index d142e870..db8429dd 100644 --- a/history.adoc +++ b/history.adoc @@ -1,6 +1,12 @@ [[revhistory, Revision History]] == Revision History +.Pending +. Added <>. +. Updated definitions in chapter 1 and Appendix A +. Added <>. + + .14 June 2004 . Added <>. . <> : Added **`latitude_of_projection_origin`** map parameter. From ea5268bde8f55073fa626808b3fbfd81136b45f4 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 18 Jun 2021 11:55:46 +0200 Subject: [PATCH 179/249] Rename attribute tie_points to coordinate_interpolation (Change 2) --- ch08.adoc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index b13dd0f6..320b988a 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -147,10 +147,10 @@ For each interpolation dimension, the number of interpolation zones is equal to .Process for generating the interpolation zones for a grid without discontinuities and for a grid with discontinuities. image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,align="center"] -[[compression-by-coordinate-sampling-tie-points-attribute, Section 8.3.2, "Tie Points Attribute"]] -==== Tie Points Attribute +[[compression-by-coordinate-sampling-tie-points-attribute, Section 8.3.2, "Coordinate Interpolation Attribute"]] +==== Coordinate Interpolation Attribute -To indicate that coordinate interpolation is required, a **`tie_points`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables `lat` and `lon` are to be interpolated according to the interpolation variable `bi_linear` could be indicated with `lat: lon: bi_linear`. +To indicate that coordinate interpolation is required, a **`coordinate_interpolation`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables `lat` and `lon` are to be interpolated according to the interpolation variable `bi_linear` could be indicated with `lat: lon: bi_linear`. [[compression-by-coordinate-sampling-interpolation-variable, Section 8.3.3, "Interpolation Variable"]] ==== Interpolation Variable @@ -203,7 +203,7 @@ In addition to the **`interpolation_name`** and **`interpolation_description`** [[compression-by-coordinate-sampling-dimensions,Section 8.3.4, "Interpolation and Non-Interpolation Dimensions"]] ==== Interpolation and Non-Interpolation Dimensions -For each interpolation variable identified in the **`tie_points`** +For each interpolation variable identified in the **`coordinate_interpolation`** attribute, all corresponding tie point variables must share the same set of one or more dimensions. This set of dimensions must contain at least one __tie point interpolation dimension__ that corresponds to an @@ -273,7 +273,7 @@ different sets of tie point variables. For instance, if tie point variables `lat` and `lon` span dimension `tp_dimension1` and tie point variable `time` spans dimension `tp_dimension2`, and all three are to interpolated according to interpolation variable `linear`, then the -**`tie_points`** attribute could be `lat: lon: linear time: +**`coordinate_interpolation`** attribute could be `lat: lon: linear time: linear`. In this case it is not possible to simultaneously map all three tie point variables to the linear interpolation variable because they do not all span the same axes. @@ -332,7 +332,7 @@ variables: float Temperature(yc, xc) ; Temperature:standard_name = "air_temperature" ; Temperature:units = "K" ; - Temperature:tie_points = "lat: lon: bl_interpolation" ; + Temperature:coordinate_interpolation = "lat: lon: bl_interpolation" ; // Interpolation variable char bl_interpolation ; @@ -374,7 +374,7 @@ variables: float Temperature(yc, xc) ; Temperature:standard_name = "air_temperature" ; Temperature:units = "K" ; - Temperature:tie_points = "lat: lon: l_interpolation" ; + Temperature:coordinate_interpolation = "lat: lon: l_interpolation" ; // Interpolation variables char l_interpolation ; @@ -481,20 +481,20 @@ dimensions : variables: // VIIRS I-Band Channel 01 and 04 float I01_radiance(track, scan) ; - I01_radiance:tie_points = "lat: lon: tp_interpolation t: time_interpolation" ; + I01_radiance:coordinate_interpolation = "lat: lon: tp_interpolation t: time_interpolation" ; I01_radiance:standard_name = "toa_outgoing_radiance_per_unit_wavelength" ; I01_radiance:units = "W m-2 sr-1 m-1" ; float I01_reflectance(track, scan) ; - I01_reflectance:tie_points = "lat: lon: tp_interpolation t: time_interpolation" ; + I01_reflectance:coordinate_interpolation = "lat: lon: tp_interpolation t: time_interpolation" ; I01_reflectance:long_name = "reflectance" ; I01_reflectance:units = "1" ; float I04_radiance(track, scan) ; - I04_radiance:tie_points = "lat: lon: tp_interpolation t: time_interpolation" ; + I04_radiance:coordinate_interpolation = "lat: lon: tp_interpolation t: time_interpolation" ; I04_radiance:standard_name = "toa_outgoing_radiance_per_unit_wavelength" ; I04_radiance:units = "W m-2 sr-1 m-1" ; float I04_brightness_temperature(track, scan) ; - I04_brightness_temperature:tie_points = "lat: lon: tp_interpolation t: time_interpolation" ; + I04_brightness_temperature:coordinate_interpolation = "lat: lon: tp_interpolation t: time_interpolation" ; I04_brightness_temperature:standard_name = "brightness_temperature" ; I04_brightness_temperature:units = "K" ; @@ -575,7 +575,7 @@ variables: Temperature:standard_name = "air_temperature" ; Temperature:units = "K" ; Temperature:grid_mapping = "lambert_conformal" ; - Temperature:tie_points = "lat: lon: bi_linear y: x: linear" ; + Temperature:coordinate_interpolation = "lat: lon: bi_linear y: x: linear" ; int lambert_conformal ; lambert_conformal:grid_mapping_name = "lambert_conformal_conic" ; From 190fdffaae6c24c28633cc3e167c68df674a9a1f Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 18 Jun 2021 14:51:49 +0200 Subject: [PATCH 180/249] Reword section Interpolation and Non-Interpolation Dimensions (Cahnge 10) --- ch08.adoc | 51 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 320b988a..7223528b 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -204,24 +204,39 @@ In addition to the **`interpolation_name`** and **`interpolation_description`** ==== Interpolation and Non-Interpolation Dimensions For each interpolation variable identified in the **`coordinate_interpolation`** -attribute, all corresponding tie point variables must share the same -set of one or more dimensions. This set of dimensions must contain at -least one __tie point interpolation dimension__ that corresponds to an -interpolation dimension; and may additionally contain one or more -__non-interpolation dimensions__, i.e. those of the target domain for -which no coordinate interpolation is required. The size of a tie point -interpolation dimension must be less than or equal to the size of its -corresponding interpolation dimension. - -An interpolation dimension typically differs in size from the corresponding tie point interpolation dimension. For example, if the target domain dimensions are `xc = 30` and `yc = 10`, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions `tp_xc = 4` and `tp_yc = 2`. Here, `tp_xc` is the tie point interpolation dimension related to the interpolation dimension `xc`, and `tp_yc` is the tie point interpolation dimension related to the interpolation dimension `yc`. - -The presence of non-interpolation dimensions in the tie point variable +attribute, all of the associated tie point coordinate +variables must share the same set of one or more dimensions. Each of +the dimensions of a tie point coordinate variable must be either a +dimension of the coordinate variable, or a dimension which is to be +interpolated to a dimension of the coordinate variable. Dimensions of the +tie point coordinate variable which are to be interpolated are called +__tie point interpolation dimensions__, and the corresponding coordinate +variable dimensions are called __interpolated dimensions__, while those +for which no interpolation is required, being the same in the coordinate +variable and the tie point coordinate variable, are called +__non-interpolated dimensions__. The dimensions of a tie point +coordinate variable must contain at least one tie point interpolation +dimension, for each of which the corresponding interpolated dimension +cannot be included. + +The size of a tie point interpolation dimension will be less than the +size of the corresponding interpolated dimension. For example, if the +interpolated dimensions are `xc = 30` and `yc = 10`, interpolation +could be applied in both of these dimensions, based on tie point +variables of the dimensions `tp_xc = 4` and `tp_yc = 2`. Here, +`tp_xc` is the tie point interpolation dimension related to the +interpolated dimension `xc`, and `tp_yc` is the tie point +interpolation dimension related to the interpolated dimension `yc`. + +The presence of non-interpolated dimensions in the tie point variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of -indices of the non-interpolation dimensions. For example, if the -target domain dimensions are `xc = 30` and `yc = 10`, interpolation -could be applied in the `xc` dimension only, based on tie point -variables that have dimensions `tp_xc = 4` and `yc = 10`. The +indices of the non-interpolated dimensions. For example, if the +target domain `xc = 30` is an interpolated dimension and `yc = 10` +is a non-interpolated dimension, interpolation +would be applied in the `xc` dimension only, based on tie point +variables that have the interpolation dimension `tp_xc = 4` and the +non-interpolated dimension `yc = 10`. The interpolation in the `xc` dimension would then be repeated for each of the 10 indices of the `yc` dimension. @@ -264,9 +279,7 @@ tie point interpolation dimensions with `dimension1: tp_dimension1 dimension1: tp_dimension2`. This is necessary when different tie point variables for a particular interpolation dimension do not contain the same number of tie points, and therefore define different numbers of -interpolation zones, as is the case in <>. A tie point -variable must span at most one of the tie point interpolation -dimensions associated with a given interpolation dimension. +interpolation zones, as is the case in <>. The same interpolation variable may be multiply mapped from the different sets of tie point variables. For instance, if tie point From f8cd983c76e0a6fb2485144ad5aa699e2e42b30b Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 15:05:44 +0200 Subject: [PATCH 181/249] Rename tie_point_dimensions attribute to tie_point_mapping (Change 2) --- ch08.adoc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 7223528b..9b0d84c3 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -241,7 +241,7 @@ interpolation in the `xc` dimension would then be repeated for each of the 10 indices of the `yc` dimension. [[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.5, "Tie Point Dimensions Attribute"]] -==== Tie Point Dimensions Attribute +==== Tie Point Mapping Attribute Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding @@ -253,7 +253,7 @@ dimension is spanned by an interpolation parameter variable, as described in <>. The association is stored in the interpolation variable's -**`tie_point_dimensions`** attribute that contains a blank-separated +**`tie_point_mapping`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: tie_point_interpolation_dimension [interpolation_zone_dimension] [interpolation_dimension: ...]"__. If an interpolation zone dimension @@ -273,7 +273,7 @@ image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] A single interpolation dimension may be associated with multiple tie point interpolation dimensions by repeating the interpolation -dimension in the **`tie_point_dimensions`** attribute. For instance, +dimension in the **`tie_point_mapping`** attribute. For instance, interpolation dimension `dimension1` could be mapped to two different tie point interpolation dimensions with `dimension1: tp_dimension1 dimension1: tp_dimension2`. This is necessary when different tie point @@ -298,7 +298,7 @@ The relationship between a tie point interpolation dimension and its corresponding interpolation dimension is defined with a __tie point index variable__. The tie point index variable is a one-dimensional integer variable that must span the tie point interpolation dimension -specified by the **`tie_point_dimensions`** attribute. Each tie point +specified by the **`tie_point_mapping`** attribute. Each tie point index variable value is a zero-based index of the related interpolation dimension which maps an element of that interpolation dimension to the corresponding location in the tie point interpolation @@ -350,7 +350,7 @@ variables: // Interpolation variable char bl_interpolation ; bl_interpolation:interpolation_name = "bi_linear" ; - bl_interpolation:tie_point_dimensions = "xc: tp_xc yc: tp_y" ; + bl_interpolation:tie_point_mapping = "xc: tp_xc yc: tp_y" ; bl_interpolation:tie_point_indices = "yc: y_indices xc: x_indices" ; // Tie point variables @@ -392,7 +392,7 @@ variables: // Interpolation variables char l_interpolation ; l_interpolation:interpolation_name = "linear" ; - l_interpolation:tie_point_dimensions = "xc: tp_xc" ; + l_interpolation:tie_point_mapping = "xc: tp_xc" ; l_interpolation:tie_point_indices = "xc: x_indices" ; // Tie point variables @@ -465,7 +465,7 @@ interpolation zones that it does not span. image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] -[[compression-by-coordinate-sampling-bounds, Section 8.3.8, "Interpolation of Tie Point Bounds"]] +[[compression-by-coordinate-sampling-bounds, Section 8.3.9, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds If reconstituted coordinates have cell boundaries, then the corresponding tie point variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. The bounds of a tie point must be the same as the bounds of the corresponding target grid cells. It is therefore likely that tie point cells will be non-contiguous. @@ -514,7 +514,7 @@ variables: // Interpolation variable char tp_interpolation ; tp_interpolation:interpolation_name = "bi_quadratic_remote_sensing" ; - tp_interpolation:tie_point_dimensions = "track: tp_track zone_track + tp_interpolation:tie_point_mapping = "track: tp_track zone_track scan: tp_scan zone_scan ; tp_interpolation:tie_point_indices = "track: track_indices @@ -550,7 +550,7 @@ variables: // Time interpolation variable char time_interpolation ; time_interpolation:interpolation_name = "bi_linear" ; - time_interpolation:tie_point_dimensions = "track: tp_track + time_interpolation:tie_point_mapping = "track: tp_track scan: tp_time_scan" ; time_interpolation:tie_point_indices = "track: track_indices scan: time_scan_indices" ; @@ -599,12 +599,12 @@ variables: // Interpolation variables char bi_linear ; bi_linear:interpolation_name = "bi_linear" ; - bi_linear:tie_point_dimensions = "y: tp_y x: tp_x" ; + bi_linear:tie_point_mapping = "y: tp_y x: tp_x" ; bi_linear:tie_point_indices = "y: y_indices x: x_indices" ; char linear ; linear:interpolation_name = "linear" ; - linear:tie_point_dimensions = "y: tp_y x: tp_x" ; + linear:tie_point_mapping = "y: tp_y x: tp_x" ; linear:tie_point_indices = "y: y_indices x: x_indices" ; // Tie point variables From a6d37b4a9ad545b9e20c22f96f6082aec9dc2f0f Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 16:50:28 +0200 Subject: [PATCH 182/249] Change term 'tie point variable' to 'tie point coordinate variable' (Change 4) --- ch08.adoc | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 9b0d84c3..ccbd99bc 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -89,9 +89,9 @@ through the degree of subsampling and the choice of interpolation method, see <>. The sampled coordinates are called __tie points__ and are stored in -__tie point variables__. +__tie point coordinate variables__. -In addition to the tie point variables themselves, metadata defining the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. +In addition to the tie point coordinate variables themselves, metadata defining the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. The metadata that define the interpolation formula and its inputs are complete, so that the results of the coordinate reconstitution process are well defined and of a predictable accuracy. @@ -150,12 +150,12 @@ image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,a [[compression-by-coordinate-sampling-tie-points-attribute, Section 8.3.2, "Coordinate Interpolation Attribute"]] ==== Coordinate Interpolation Attribute -To indicate that coordinate interpolation is required, a **`coordinate_interpolation`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point variables `lat` and `lon` are to be interpolated according to the interpolation variable `bi_linear` could be indicated with `lat: lon: bi_linear`. +To indicate that coordinate interpolation is required, a **`coordinate_interpolation`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point coordinate variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point coordinate variables `lat` and `lon` are to be interpolated according to the interpolation variable `bi_linear` could be indicated with `lat: lon: bi_linear`. [[compression-by-coordinate-sampling-interpolation-variable, Section 8.3.3, "Interpolation Variable"]] ==== Interpolation Variable -The method used to uncompress the tie point variables is described by +The method used to uncompress the tie point coordinate variables is described by an interpolation variable that acts as a container for the attributes that define the interpolation technique and the parameters that should be used. The variable should be a scalar (i.e. it has no dimensions) @@ -190,7 +190,7 @@ coordinates simultaneously, if such tie points are present. For example, there are cases where longitudes cannot be interpolated without considering the corresponding latitudes. It is up to the interpolation description to describe how such coordinates are to be -identified (e.g. it may be that such tie point variables require +identified (e.g. it may be that such tie point coordinate variables require particular units or standard names). Note that the interpolation method is always applied on a per @@ -228,7 +228,7 @@ variables of the dimensions `tp_xc = 4` and `tp_yc = 2`. Here, interpolated dimension `xc`, and `tp_yc` is the tie point interpolation dimension related to the interpolated dimension `yc`. -The presence of non-interpolated dimensions in the tie point variable +The presence of non-interpolated dimensions in the tie point coordinate variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of indices of the non-interpolated dimensions. For example, if the @@ -282,13 +282,13 @@ same number of tie points, and therefore define different numbers of interpolation zones, as is the case in <>. The same interpolation variable may be multiply mapped from the -different sets of tie point variables. For instance, if tie point +different sets of tie point coordinate variables. For instance, if tie point variables `lat` and `lon` span dimension `tp_dimension1` and tie point variable `time` spans dimension `tp_dimension2`, and all three are to interpolated according to interpolation variable `linear`, then the **`coordinate_interpolation`** attribute could be `lat: lon: linear time: linear`. In this case it is not possible to simultaneously map all -three tie point variables to the linear interpolation variable because +three tie point coordinate variables to the linear interpolation variable because they do not all span the same axes. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.6, "Tie Point Indices"]] @@ -312,7 +312,7 @@ an interpolation area boundary relating to a grid discontinuity (<>). For instance, in example <> -the tie point variables represent a subset of the target domain and +the tie point coordinate variables represent a subset of the target domain and the tie point index variable `int x_indices(tp_xc)` contains the indices `x_indices = 0, 9, 19, 29` that identify the location in the interpolation dimension `xc` of size 30. @@ -353,7 +353,7 @@ variables: bl_interpolation:tie_point_mapping = "xc: tp_xc yc: tp_y" ; bl_interpolation:tie_point_indices = "yc: y_indices xc: x_indices" ; - // Tie point variables + // tie point coordinate variables double lat(tp_yc, tp_xc) ; lat:units = "degrees_north" ; lat:standard_name = "latitude" ; @@ -395,7 +395,7 @@ variables: l_interpolation:tie_point_mapping = "xc: tp_xc" ; l_interpolation:tie_point_indices = "xc: x_indices" ; - // Tie point variables + // tie point coordinate variables double lat(yc, tp_xc) ; lat:units = "degrees_north" ; lat:standard_name = "latitude" ; @@ -436,7 +436,7 @@ parameters may always be provided to non-standardized interpolation methods. The dimensions of an interpolation parameter variable must be a subset -of zero or more the tie point variable dimensions, with the +of zero or more the tie point coordinate variable dimensions, with the possibility of a tie point interpolation dimension being replaced with the corresponding interpolation zone dimension. The interpretation of an interpolation parameter variable depends on which of its dimensions @@ -468,9 +468,9 @@ image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="cente [[compression-by-coordinate-sampling-bounds, Section 8.3.9, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds -If reconstituted coordinates have cell boundaries, then the corresponding tie point variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. The bounds of a tie point must be the same as the bounds of the corresponding target grid cells. It is therefore likely that tie point cells will be non-contiguous. +If reconstituted coordinates have cell boundaries, then the corresponding tie point coordinate variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. The bounds of a tie point must be the same as the bounds of the corresponding target grid cells. It is therefore likely that tie point cells will be non-contiguous. -The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the identifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensional tie point variable with four-sided cells, the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. +The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the identifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensional tie point coordinate variable with four-sided cells, the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. Note that an implementation of the interpolation method is free to calculate the uncompressed bounds locations in the manner of its choosing, as a long as the result is formally equivalent to each bounds position being treated independently. @@ -607,7 +607,7 @@ variables: linear:tie_point_mapping = "y: tp_y x: tp_x" ; linear:tie_point_indices = "y: y_indices x: x_indices" ; - // Tie point variables + // tie point coordinate variables double time(time) ; time:standard_name = "time" ; time:units = "days since 2021-03-01" ; From 27d17334e2348431a2c34326cf487be3201f15b6 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 16:54:34 +0200 Subject: [PATCH 183/249] Reword first paragraph of Section 8 (Change 6) --- ch08.adoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index ccbd99bc..09e38fb1 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -1,7 +1,9 @@ == Reduction of Dataset Size -There are three methods for reducing dataset size: packing, lossless compression, and lossy compression. By packing we mean altering the data in a way that reduces its precision. By lossless compression we mean techniques that store the data more efficiently and result in no precision loss. By lossy compression we mean techniques that store the data more efficiently but result in some loss in accuracy. Lossless compression only works in certain circumstances, e.g., when a variable contains a significant amount of missing or repeated data values. In this case it is possible to make use of standard utilities, e.g., UNIX **`compress`** or GNU **`gzip`** , to compress the entire file after it has been written. In this section we offer an alternative compression method that is applied on a variable by variable basis. This has the advantage that only one variable need be uncompressed at a given time. The disadvantage is that generic utilities that don't recognize the CF conventions will not be able to operate on compressed variables. +There are three methods for reducing dataset size: packing, lossless compression, and lossy compression. By packing we mean altering the data in a way that reduces its precision (but has no other effect on accuracy). By lossless compression we mean techniques that store the data more efficiently and result in no loss of precision or accuracy. By lossy compression we mean techniques that store the data more efficiently and retain its precision but result in some loss in accuracy. + +Lossless compression only works in certain circumstances, e.g., when a variable contains a significant amount of missing or repeated data values. In this case it is possible to make use of standard utilities, e.g., UNIX **`compress`** or GNU **`gzip`** , to compress the entire file after it has been written. In this section we offer an alternative compression method that is applied on a variable by variable basis. This has the advantage that only one variable need be uncompressed at a given time. The disadvantage is that generic utilities that don't recognize the CF conventions will not be able to operate on compressed variables. From 971bfbec0577a2efb7c1a32fc872894e2ee1a86c Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 16:56:51 +0200 Subject: [PATCH 184/249] Remove sentence "This form of compression may also be..." (Change 7) --- ch08.adoc | 3 --- 1 file changed, 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 09e38fb1..461d6318 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -97,9 +97,6 @@ In addition to the tie point coordinate variables themselves, metadata defining The metadata that define the interpolation formula and its inputs are complete, so that the results of the coordinate reconstitution process are well defined and of a predictable accuracy. -This form of compression may also be used on a domain variable -(domain-variables) with the same effect. - [[compression-by-coordinate-sampling-tie-points-and-interpolation-zones, Section 8.3.1, "Tie Points and Interpolation Zones"]] ==== Tie Points and Interpolation Zones From 3d4348f5904bc6a105bf0e853b9cafee9f4ae3e0 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 17:08:40 +0200 Subject: [PATCH 185/249] Update sentence: "A single interpolation dimension may be associated..." (Change 9) --- ch08.adoc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 461d6318..8cea90ea 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -270,15 +270,16 @@ Note that an interpolation zone dimension has, by definition, the same size as t image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] -A single interpolation dimension may be associated with multiple tie -point interpolation dimensions by repeating the interpolation -dimension in the **`tie_point_mapping`** attribute. For instance, -interpolation dimension `dimension1` could be mapped to two different -tie point interpolation dimensions with `dimension1: tp_dimension1 -dimension1: tp_dimension2`. This is necessary when different tie point -variables for a particular interpolation dimension do not contain the -same number of tie points, and therefore define different numbers of -interpolation zones, as is the case in <>. +A single interpolated dimension may be associated with multiple tie point +interpolation dimensions by repeating the interpolated dimension in the +**`tie_point_mapping`** attribute. For instance, interpolated dimension +`dimension1` could be mapped to two different tie point interpolation +dimensions with `dimension1: tp_index_variable1 tp_dimension1 dimension1: +tp_index_variable2 tp_dimension2`. This is necessary when two or more tie +point coordinate variables have different tie point index variables +corresponding to the same interpolated dimension. A tie point coordinate +variable must span at most one of the tie point interpolation dimensions +associated with a given interpolation dimension. The same interpolation variable may be multiply mapped from the different sets of tie point coordinate variables. For instance, if tie point From 7ab0c4f73f4813ebed8dc98779bb6a5d665d2fbf Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 17:35:45 +0200 Subject: [PATCH 186/249] Reword section "Interpolation and non-interpolation dimension" (Change 10) --- ch08.adoc | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 8cea90ea..bfc29ade 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -199,24 +199,26 @@ the extent of the of the interpolation zone. In addition to the **`interpolation_name`** and **`interpolation_description`** attributes described in this section, further attributes of the interpolation variable are described in <>, <> and <>. -[[compression-by-coordinate-sampling-dimensions,Section 8.3.4, "Interpolation and Non-Interpolation Dimensions"]] -==== Interpolation and Non-Interpolation Dimensions - -For each interpolation variable identified in the **`coordinate_interpolation`** -attribute, all of the associated tie point coordinate -variables must share the same set of one or more dimensions. Each of -the dimensions of a tie point coordinate variable must be either a -dimension of the coordinate variable, or a dimension which is to be -interpolated to a dimension of the coordinate variable. Dimensions of the -tie point coordinate variable which are to be interpolated are called -__tie point interpolation dimensions__, and the corresponding coordinate -variable dimensions are called __interpolated dimensions__, while those -for which no interpolation is required, being the same in the coordinate -variable and the tie point coordinate variable, are called -__non-interpolated dimensions__. The dimensions of a tie point -coordinate variable must contain at least one tie point interpolation -dimension, for each of which the corresponding interpolated dimension -cannot be included. +[[compression-by-coordinate-sampling-dimensions,Section 8.3.4, "Interpolation, Interpolated and Non-Interpolated Dimensions"]] +==== Interpolation, Interpolated and Non-Interpolated Dimensions + +For each interpolation variable identified in the +**`coordinate_interpolation`** attribute, all of the associated tie point +coordinate variables must share the same set of one or more dimensions. +This set of dimensions must correspond to the set of dimensions of the +uncompressed coordinate or auxiliary coordinate variables, such that each +of these dimensions must be either the uncompressed dimension itself, or +a dimension that is to be interpolated to the uncompressed dimension. + +Dimensions of the tie point coordinate variable which are to be +interpolated are called __tie point interpolation dimensions__, and +the corresponding data variable dimensions are called __interpolated +dimensions__, while those for which no interpolation is required, +being the same in the data variable and the tie point coordinate +variable, are called __non-interpolated dimensions__. The dimensions +of a tie point coordinate variable must contain at least one tie +point interpolation dimension, for each of which the corresponding +interpolated dimension cannot be included. The size of a tie point interpolation dimension will be less than the size of the corresponding interpolated dimension. For example, if the @@ -230,10 +232,10 @@ interpolation dimension related to the interpolated dimension `yc`. The presence of non-interpolated dimensions in the tie point coordinate variable impacts the interpolation process in that there must be a separate application of the interpolation method for each combination of -indices of the non-interpolated dimensions. For example, if the -target domain `xc = 30` is an interpolated dimension and `yc = 10` +indices of the non-interpolated dimensions. For example, if +`xc = 30` is an interpolated dimension and `yc = 10` is a non-interpolated dimension, interpolation -would be applied in the `xc` dimension only, based on tie point +could be applied in the `xc` dimension only, based on tie point variables that have the interpolation dimension `tp_xc = 4` and the non-interpolated dimension `yc = 10`. The interpolation in the `xc` dimension would then be repeated for each of @@ -277,9 +279,7 @@ interpolation dimensions by repeating the interpolated dimension in the dimensions with `dimension1: tp_index_variable1 tp_dimension1 dimension1: tp_index_variable2 tp_dimension2`. This is necessary when two or more tie point coordinate variables have different tie point index variables -corresponding to the same interpolated dimension. A tie point coordinate -variable must span at most one of the tie point interpolation dimensions -associated with a given interpolation dimension. +corresponding to the same interpolated dimension. The same interpolation variable may be multiply mapped from the different sets of tie point coordinate variables. For instance, if tie point From d715552465cae76bbb912e72f10d2620d7398592 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 17:48:55 +0200 Subject: [PATCH 187/249] Improve sentence "An interpolation zone must span at least two points..." (Change 11) --- ch08.adoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index bfc29ade..ae52603e 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -304,8 +304,9 @@ interpolation dimension which maps an element of that interpolation dimension to the corresponding location in the tie point interpolation dimension. The tie point index values must be strictly monotonically increasing within interpolation areas. An interpolation zone must span -at least two points of each of its corresponding interpolation -dimensions, therefore the tie point indices that define an +at least two points of each of its corresponding interpolated +dimensions in the target domain, therefore the tie point indices that +define an interpolation zone must all be different. When two adjacent values are equal, or differ by one, it indicates the location (in index space) of an interpolation area boundary relating to a grid discontinuity From fdeef671ca195f49965f3d38404f6f4367995178 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 17:52:51 +0200 Subject: [PATCH 188/249] Correct sentence "....must be a subset of zero or more of the ..." (Change 12) --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index ae52603e..4317d813 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -437,7 +437,7 @@ parameters may always be provided to non-standardized interpolation methods. The dimensions of an interpolation parameter variable must be a subset -of zero or more the tie point coordinate variable dimensions, with the +of zero or more of the tie point coordinate variable dimensions, with the possibility of a tie point interpolation dimension being replaced with the corresponding interpolation zone dimension. The interpretation of an interpolation parameter variable depends on which of its dimensions From ba4a65e5fa45c8e11c6ae4b6f4f2551279189af3 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 18:04:11 +0200 Subject: [PATCH 189/249] Reword text about the dimensions of interpolation parameter (Change 13) --- ch08.adoc | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 4317d813..c47290a7 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -436,29 +436,13 @@ allowed by the definition of the interpolation method. Interpolation parameters may always be provided to non-standardized interpolation methods. -The dimensions of an interpolation parameter variable must be a subset -of zero or more of the tie point coordinate variable dimensions, with the -possibility of a tie point interpolation dimension being replaced with -the corresponding interpolation zone dimension. The interpretation of -an interpolation parameter variable depends on which of its dimensions -are tie point interpolation dimensions, and which are interpolation -zone dimensions: - -* If no tie point interpolation dimensions are spanned, then the - variable provides values for every interpolation zone. This case is - akin to values being defined at the centre of interpolation zones. - -* If at least one dimension is a tie point interpolation dimension, - then the variable's values are to be shared by the interpolation - zones that are adjacent along each of the specified tie point - interpolation dimensions. This case is akin to the values being - defined at the interpolation zone boundaries, and therefore equally - applicable to the interpolation zones that share that boundary - (<>). - -In both cases, the implementation of the interpolation method should -assume that an interpolation parameter variable is broadcast to any -interpolation zones that it does not span. +The interpolation parameter variable dimensions must include, for all of the interpolation dimensions, either the associated tie point interpolation dimension or the associated interpolation subarea dimension. Additionally, any subset of zero or more of the non-interpolation dimensions of the tie point coordinate variable are permitted as interpolation parameter variable dimensions. + +The application of an interpolation parameter variable is independent of its non-interpolation dimensions, but depends on its set of tie point interpolation dimensions and interpolation subarea dimensions: + +* If the set only contains tie point interpolation dimensions, then the variable provides values for every tie point and therefore equally applicable to the interpolation zones that share that tie point, see example a) in figure 3; +* If the set only contains interpolation subarea dimensions, then the variable provides values for every interpolation zone and therefore only applicable to that interpolation zone, see example b) in figure 3; +* If the set contains both tie point interpolation dimensions and interpolation zone dimensions, then the variable’s values are to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at the interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary, see example c) and d) in figure 3; [[ci_interpolation_parameters, figure 3]] [.text-center] From aceb9873714a6cf5995c1fe916558bb86de502a3 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 18:25:07 +0200 Subject: [PATCH 190/249] Improve sentence "The bounds of a tie point must be the same..." (Change 14) --- ch08.adoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index c47290a7..69a73347 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -453,7 +453,9 @@ image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="cente [[compression-by-coordinate-sampling-bounds, Section 8.3.9, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds -If reconstituted coordinates have cell boundaries, then the corresponding tie point coordinate variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. The bounds of a tie point must be the same as the bounds of the corresponding target grid cells. It is therefore likely that tie point cells will be non-contiguous. +If reconstituted coordinates have cell boundaries, then the corresponding tie point coordinate variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. +The bounds of a tie point must be the same as the bounds of the target grid cells whose coordinates are specified as the tie point. +It is therefore likely that tie point cells will be non-contiguous. The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the identifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensional tie point coordinate variable with four-sided cells, the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. From f439ee5c9485f5945b00d011162f86b2b1dd4eb9 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 18:29:02 +0200 Subject: [PATCH 191/249] Reduce number of data variables in Example 8.5 (Change 16) --- ch08.adoc | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 69a73347..4f5bb089 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -479,16 +479,7 @@ dimensions : tp_time_scan = 2; variables: - // VIIRS I-Band Channel 01 and 04 - float I01_radiance(track, scan) ; - I01_radiance:coordinate_interpolation = "lat: lon: tp_interpolation t: time_interpolation" ; - I01_radiance:standard_name = "toa_outgoing_radiance_per_unit_wavelength" ; - I01_radiance:units = "W m-2 sr-1 m-1" ; - float I01_reflectance(track, scan) ; - I01_reflectance:coordinate_interpolation = "lat: lon: tp_interpolation t: time_interpolation" ; - I01_reflectance:long_name = "reflectance" ; - I01_reflectance:units = "1" ; - + // VIIRS I-Band Channel 04 float I04_radiance(track, scan) ; I04_radiance:coordinate_interpolation = "lat: lon: tp_interpolation t: time_interpolation" ; I04_radiance:standard_name = "toa_outgoing_radiance_per_unit_wavelength" ; From d6d7ea3d3fffbc05e1479feee36d3780181c912a Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 19:14:25 +0200 Subject: [PATCH 192/249] Rename "terms to continuous area" and "interpolation subarea" (Change 5) --- ch08.adoc | 96 +++++++++++++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 4f5bb089..b103f3ec 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -97,24 +97,24 @@ In addition to the tie point coordinate variables themselves, metadata defining The metadata that define the interpolation formula and its inputs are complete, so that the results of the coordinate reconstitution process are well defined and of a predictable accuracy. -[[compression-by-coordinate-sampling-tie-points-and-interpolation-zones, Section 8.3.1, "Tie Points and Interpolation Zones"]] -==== Tie Points and Interpolation Zones +[[compression-by-coordinate-sampling-tie-points-and-interpolation-subareas, Section 8.3.1, "Tie Points and Interpolation Subareas"]] +==== Tie Points and Interpolation Subareas Reconstitution of the uncompressed coordinate and auxiliary coordinate variables is based on interpolation. To accomplish this, the target -domain is segmented into smaller __interpolation zones__, for each of +domain is segmented into smaller __interpolation subareas__, for each of which the interpolation method is applied independently. For -one-dimensional interpolation, an interpolation zone is defined by two -tie points, one at each end of the interpolation zone; for -two-dimensional interpolation, an interpolation zone is defined by +one-dimensional interpolation, an interpolation subarea is defined by two +tie points, one at each end of the interpolation subarea; for +two-dimensional interpolation, an interpolation subarea is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes; etc. For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables within an interpolation -zone, the interpolation method is permitted to access its defining tie +subarea, the interpolation method is permitted to access its defining tie points, and no others. As an interpolation method relies on the regularity and continuity of -the coordinate values within each interpolation zone, special +the coordinate values within each interpolation subarea, special attention must be given to the case when uncompressed coordinates contain discontinuities. A discontinuity could be an overlap or a gap in the coordinates' coverage, or a change in cell size or cell @@ -122,28 +122,28 @@ alignment. As an example, such discontinuities are common in remote sensing data and may be caused by combinations of the instrument scan motion, the motion of the sensor platform and changes in the instrument scan mode. When discontinuities are present, the domain is -first divided into multiple __interpolation areas__, each of which is +first divided into multiple __continuous areas__, each of which is free of discontinuities. When no discontinuities are present, the -whole domain is a single interpolation area. Following this step, each -interpolation area is segmented into interpolation zones. The -processes of generating interpolation zones for a domain without +whole domain is a single continuous area. Following this step, each +continuous area is segmented into interpolation subareas. The +processes of generating interpolation subareas for a domain without discontinuities and for a domain with discontinuities is illustrated -in <>, and described in more detail in +in <>, and described in more detail in <>. -Within an interpolation area, interpolation zones must share tie points with neighbouring interpolation zones. Between interpolation areas, interpolation zones are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. +Within an continuous area, interpolation subareas must share tie points with neighbouring interpolation subareas. Between continuous areas, interpolation subareas are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. For each __interpolation dimension__, i.e. a target domain dimension for which coordinate interpolation is required, the location of the tie points is defined by a corresponding __tie point index variable__, -which also indicates the location of the interpolation areas +which also indicates the location of the continuous areas (<>). -For each interpolation dimension, the number of interpolation zones is equal to the number of tie points minus the number of interpolation areas. +For each interpolation dimension, the number of interpolation subareas is equal to the number of tie points minus the number of continuous areas. -[[interpolation_zone_generation, figure 1]] +[[interpolation_subarea_generation, figure 1]] [.text-center] -.Process for generating the interpolation zones for a grid without discontinuities and for a grid with discontinuities. +.Process for generating the interpolation subareas for a grid without discontinuities and for a grid with discontinuities. image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,align="center"] [[compression-by-coordinate-sampling-tie-points-attribute, Section 8.3.2, "Coordinate Interpolation Attribute"]] @@ -193,9 +193,9 @@ identified (e.g. it may be that such tie point coordinate variables require particular units or standard names). Note that the interpolation method is always applied on a per -interpolation zone basis, for which the construction of the +interpolation subarea basis, for which the construction of the uncompressed coordinates may only access those tie points that define -the extent of the of the interpolation zone. +the extent of the of the interpolation subarea. In addition to the **`interpolation_name`** and **`interpolation_description`** attributes described in this section, further attributes of the interpolation variable are described in <>, <> and <>. @@ -246,24 +246,24 @@ the 10 indices of the `yc` dimension. Each interpolation dimension must be associated with its corresponding tie point interpolation dimension and, if required, its corresponding -__interpolation zone dimension__ that defines the number of -interpolation zones which partition the interpolation dimension. It is -only required to associate an interpolation zone dimension to an -interpolation dimension in the case that the interpolation zone +__interpolation subarea dimension__ that defines the number of +interpolation subareas which partition the interpolation dimension. It is +only required to associate an interpolation subarea dimension to an +interpolation dimension in the case that the interpolation subarea dimension is spanned by an interpolation parameter variable, as described in <>. The association is stored in the interpolation variable's **`tie_point_mapping`** attribute that contains a blank-separated list of words of the form __"interpolation_dimension: -tie_point_interpolation_dimension [interpolation_zone_dimension] -[interpolation_dimension: ...]"__. If an interpolation zone dimension +tie_point_interpolation_dimension [interpolation_subarea_dimension] +[interpolation_dimension: ...]"__. If an interpolation subarea dimension is provided then it must be the second of the two named dimensions following the interpolation dimension. An overview of the different dimensions for coordinate interpolation is shown in <>. -Note that an interpolation zone dimension has, by definition, the same size as the corresponding tie point interpolation dimension, minus the number of interpolation areas. +Note that an interpolation subarea dimension has, by definition, the same size as the corresponding tie point interpolation dimension, minus the number of continuous areas. [[ci_dimensions_overview, figure 2]] @@ -303,14 +303,14 @@ index variable value is a zero-based index of the related interpolation dimension which maps an element of that interpolation dimension to the corresponding location in the tie point interpolation dimension. The tie point index values must be strictly monotonically -increasing within interpolation areas. An interpolation zone must span +increasing within continuous areas. An interpolation subarea must span at least two points of each of its corresponding interpolated dimensions in the target domain, therefore the tie point indices that define an -interpolation zone must all be different. When two adjacent values are +interpolation subarea must all be different. When two adjacent values are equal, or differ by one, it indicates the location (in index space) of -an interpolation area boundary relating to a grid discontinuity -(<>). +an continuous area boundary relating to a grid discontinuity +(<>). For instance, in example <> the tie point coordinate variables represent a subset of the target domain and @@ -440,13 +440,13 @@ The interpolation parameter variable dimensions must include, for all of the int The application of an interpolation parameter variable is independent of its non-interpolation dimensions, but depends on its set of tie point interpolation dimensions and interpolation subarea dimensions: -* If the set only contains tie point interpolation dimensions, then the variable provides values for every tie point and therefore equally applicable to the interpolation zones that share that tie point, see example a) in figure 3; -* If the set only contains interpolation subarea dimensions, then the variable provides values for every interpolation zone and therefore only applicable to that interpolation zone, see example b) in figure 3; -* If the set contains both tie point interpolation dimensions and interpolation zone dimensions, then the variable’s values are to be shared by the interpolation zones that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at the interpolation zone boundaries, and therefore equally applicable to the interpolation zones that share that boundary, see example c) and d) in figure 3; +* If the set only contains tie point interpolation dimensions, then the variable provides values for every tie point and therefore equally applicable to the interpolation subareas that share that tie point, see example a) in figure 3; +* If the set only contains interpolation subarea dimensions, then the variable provides values for every interpolation subarea and therefore only applicable to that interpolation subarea, see example b) in figure 3; +* If the set contains both tie point interpolation dimensions and interpolation subarea dimensions, then the variable’s values are to be shared by the interpolation subareas that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at the interpolation subarea boundaries, and therefore equally applicable to the interpolation subareas that share that boundary, see example c) and d) in figure 3; [[ci_interpolation_parameters, figure 3]] [.text-center] -.Through combination of dimensions, interpolation parameter variables may provide values for each interpolation zone, for couples of neighbouring interpolation zones or for multiple interpolation zones sharing a boundary. +.Through combination of dimensions, interpolation parameter variables may provide values for each interpolation subarea, for couples of neighbouring interpolation subareas or for multiple interpolation subareas sharing a boundary. image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] @@ -470,11 +470,11 @@ dimensions : // VIIRS I-Band (375 m resolution imaging) track = 1536 ; scan = 6400 ; - // Tie points and interpolation zones + // Tie points and interpolation subareas tp_track = 96 ; // 48 VIIRS scans tp_scan = 205 ; - zone_track = 48 ; // track interpolation zone - zone_scan= 200 ; // scan interpolation zone + subarea_track = 48 ; // track interpolation subarea + subarea_scan= 200 ; // scan interpolation subarea // Time, stored at scan-start and scan-end of each scan tp_time_scan = 2; @@ -492,22 +492,22 @@ variables: // Interpolation variable char tp_interpolation ; tp_interpolation:interpolation_name = "bi_quadratic_remote_sensing" ; - tp_interpolation:tie_point_mapping = "track: tp_track zone_track - scan: tp_scan zone_scan + tp_interpolation:tie_point_mapping = "track: tp_track subarea_track + scan: tp_scan subarea_scan ; tp_interpolation:tie_point_indices = "track: track_indices scan: scan_indices ; - tp_interpolation:interpolation_parameters = "ce1: ce1 ca2: ca2 ce3: ce3 flags: interpolation_zone_flags" ; + tp_interpolation:interpolation_parameters = "ce1: ce1 ca2: ca2 ce3: ce3 flags: interpolation_subarea_flags" ; // Interpolation parameters - short ce1(tp_track , zone_scan) ; - short ca2(zone_track , tp_scan) ; - short ce3(zone_track, zone_scan) ; - byte interpolation_zone_flags(zone_track , zone_scan) ; - interpolation_zone_flags : valid_range = "1b, 7b" ; - interpolation_zone_flags : flag_masks = "1b, 2b, 4b" ; - interpolation_zone_flags : flag_meanings = + short ce1(tp_track , subarea_scan) ; + short ca2(subarea_track , tp_scan) ; + short ce3(subarea_track, subarea_scan) ; + byte interpolation_subarea_flags(subarea_track , subarea_scan) ; + interpolation_subarea_flags : valid_range = "1b, 7b" ; + interpolation_subarea_flags : flag_masks = "1b, 2b, 4b" ; + interpolation_subarea_flags : flag_meanings = "location_use_cartesian sensor_direction_use_cartesian solar_direction_use_cartesian" ; From 5cfae45cdb53b3901e7e2dddeacc4a355c9bfbf2 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 24 Jun 2021 20:08:35 +0200 Subject: [PATCH 193/249] Improve wording of "An interpolation subarea must span..." (Change 11) --- ch08.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index b103f3ec..5e6a0070 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -304,8 +304,8 @@ interpolation dimension which maps an element of that interpolation dimension to the corresponding location in the tie point interpolation dimension. The tie point index values must be strictly monotonically increasing within continuous areas. An interpolation subarea must span -at least two points of each of its corresponding interpolated -dimensions in the target domain, therefore the tie point indices that +at least two points in each of its corresponding interpolated +dimensions, therefore the tie point indices that define an interpolation subarea must all be different. When two adjacent values are equal, or differ by one, it indicates the location (in index space) of From 485d3b8a762d074844611b96fbfd5bbedb228d22 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 25 Jun 2021 11:36:55 +0200 Subject: [PATCH 194/249] Remove paragraph "The same interpolation variable may be multiply mapped ...." no longer relevant --- ch08.adoc | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 5e6a0070..149362ef 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -281,16 +281,6 @@ tp_index_variable2 tp_dimension2`. This is necessary when two or more tie point coordinate variables have different tie point index variables corresponding to the same interpolated dimension. -The same interpolation variable may be multiply mapped from the -different sets of tie point coordinate variables. For instance, if tie point -variables `lat` and `lon` span dimension `tp_dimension1` and tie point -variable `time` spans dimension `tp_dimension2`, and all three are to -interpolated according to interpolation variable `linear`, then the -**`coordinate_interpolation`** attribute could be `lat: lon: linear time: -linear`. In this case it is not possible to simultaneously map all -three tie point coordinate variables to the linear interpolation variable because -they do not all span the same axes. - [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.6, "Tie Point Indices"]] ==== Tie Point Indices From db0eb4e0a75f20d0733996ab8579b26404b148fb Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 1 Jul 2021 12:27:10 +0200 Subject: [PATCH 195/249] Rename terms to: subsampled dimension, interpolated dimension and non-interpolated dimension --- ch08.adoc | 80 +++++++++++++++++++++++++++---------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 149362ef..a471e494 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -133,13 +133,13 @@ in <>, and described in more detail in Within an continuous area, interpolation subareas must share tie points with neighbouring interpolation subareas. Between continuous areas, interpolation subareas are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. -For each __interpolation dimension__, i.e. a target domain dimension +For each __interpolated dimension__, i.e. a target domain dimension for which coordinate interpolation is required, the location of the tie points is defined by a corresponding __tie point index variable__, which also indicates the location of the continuous areas (<>). -For each interpolation dimension, the number of interpolation subareas is equal to the number of tie points minus the number of continuous areas. +For each interpolated dimension, the number of interpolation subareas is equal to the number of tie points minus the number of continuous areas. [[interpolation_subarea_generation, figure 1]] [.text-center] @@ -199,8 +199,8 @@ the extent of the of the interpolation subarea. In addition to the **`interpolation_name`** and **`interpolation_description`** attributes described in this section, further attributes of the interpolation variable are described in <>, <> and <>. -[[compression-by-coordinate-sampling-dimensions,Section 8.3.4, "Interpolation, Interpolated and Non-Interpolated Dimensions"]] -==== Interpolation, Interpolated and Non-Interpolated Dimensions +[[compression-by-coordinate-sampling-dimensions,Section 8.3.4, "Subsampled, Interpolated and Non-Interpolated Dimensions"]] +==== Subsampled, Interpolated and Non-Interpolated Dimensions For each interpolation variable identified in the **`coordinate_interpolation`** attribute, all of the associated tie point @@ -211,23 +211,23 @@ of these dimensions must be either the uncompressed dimension itself, or a dimension that is to be interpolated to the uncompressed dimension. Dimensions of the tie point coordinate variable which are to be -interpolated are called __tie point interpolation dimensions__, and +interpolated are called __subsampled dimensions__, and the corresponding data variable dimensions are called __interpolated dimensions__, while those for which no interpolation is required, being the same in the data variable and the tie point coordinate variable, are called __non-interpolated dimensions__. The dimensions -of a tie point coordinate variable must contain at least one tie -point interpolation dimension, for each of which the corresponding +of a tie point coordinate variable must contain at least one +subsampled dimension, for each of which the corresponding interpolated dimension cannot be included. -The size of a tie point interpolation dimension will be less than the +The size of a subsampled dimension will be less than the size of the corresponding interpolated dimension. For example, if the interpolated dimensions are `xc = 30` and `yc = 10`, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions `tp_xc = 4` and `tp_yc = 2`. Here, -`tp_xc` is the tie point interpolation dimension related to the -interpolated dimension `xc`, and `tp_yc` is the tie point -interpolation dimension related to the interpolated dimension `yc`. +`tp_xc` is the subsampled dimension related to the +interpolated dimension `xc`, and `tp_yc` is the +subsampled dimension related to the interpolated dimension `yc`. The presence of non-interpolated dimensions in the tie point coordinate variable impacts the interpolation process in that there must be a separate @@ -236,34 +236,34 @@ indices of the non-interpolated dimensions. For example, if `xc = 30` is an interpolated dimension and `yc = 10` is a non-interpolated dimension, interpolation could be applied in the `xc` dimension only, based on tie point -variables that have the interpolation dimension `tp_xc = 4` and the +variables that have the subsampled dimension `tp_xc = 4` and the non-interpolated dimension `yc = 10`. The interpolation in the `xc` dimension would then be repeated for each of -the 10 indices of the `yc` dimension. +the 10 indices of the `yc` non-interpolated dimension. [[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.5, "Tie Point Dimensions Attribute"]] ==== Tie Point Mapping Attribute -Each interpolation dimension must be associated with its corresponding -tie point interpolation dimension and, if required, its corresponding +Each interpolated dimension must be associated with its corresponding +subsampled dimension and, if required, its corresponding __interpolation subarea dimension__ that defines the number of -interpolation subareas which partition the interpolation dimension. It is +interpolation subareas which partition the interpolated dimension. It is only required to associate an interpolation subarea dimension to an -interpolation dimension in the case that the interpolation subarea +interpolated dimension in the case that the interpolation subarea dimension is spanned by an interpolation parameter variable, as described in <>. The association is stored in the interpolation variable's **`tie_point_mapping`** attribute that contains a blank-separated -list of words of the form __"interpolation_dimension: -tie_point_interpolation_dimension [interpolation_subarea_dimension] -[interpolation_dimension: ...]"__. If an interpolation subarea dimension +list of words of the form __"interpolated_dimension: +subsampled_dimension [interpolation_subarea_dimension] +[interpolated_dimension: ...]"__. If an interpolation subarea dimension is provided then it must be the second of the two named dimensions -following the interpolation dimension. +following the interpolated dimension. An overview of the different dimensions for coordinate interpolation is shown in <>. -Note that an interpolation subarea dimension has, by definition, the same size as the corresponding tie point interpolation dimension, minus the number of continuous areas. +Note that an interpolation subarea dimension has, by definition, the same size as the corresponding subsampled dimension, minus the number of continuous areas. [[ci_dimensions_overview, figure 2]] @@ -272,10 +272,10 @@ Note that an interpolation subarea dimension has, by definition, the same size a image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] -A single interpolated dimension may be associated with multiple tie point -interpolation dimensions by repeating the interpolated dimension in the +A single interpolated dimension may be associated with multiple +subsampled dimensions by repeating the interpolated dimension in the **`tie_point_mapping`** attribute. For instance, interpolated dimension -`dimension1` could be mapped to two different tie point interpolation +`dimension1` could be mapped to two different subsampled dimensions with `dimension1: tp_index_variable1 tp_dimension1 dimension1: tp_index_variable2 tp_dimension2`. This is necessary when two or more tie point coordinate variables have different tie point index variables @@ -284,14 +284,14 @@ corresponding to the same interpolated dimension. [[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.6, "Tie Point Indices"]] ==== Tie Point Indices -The relationship between a tie point interpolation dimension and its -corresponding interpolation dimension is defined with a __tie point +The relationship between a subsampled dimension and its +corresponding interpolated dimension is defined with a __tie point index variable__. The tie point index variable is a one-dimensional -integer variable that must span the tie point interpolation dimension +integer variable that must span the subsampled dimension specified by the **`tie_point_mapping`** attribute. Each tie point index variable value is a zero-based index of the related -interpolation dimension which maps an element of that interpolation -dimension to the corresponding location in the tie point interpolation +interpolated dimension which maps an element of that interpolated +dimension to the corresponding location in the subsampled dimension. The tie point index values must be strictly monotonically increasing within continuous areas. An interpolation subarea must span at least two points in each of its corresponding interpolated @@ -306,15 +306,15 @@ For instance, in example <> the tie point coordinate variables represent a subset of the target domain and the tie point index variable `int x_indices(tp_xc)` contains the indices `x_indices = 0, 9, 19, 29` that identify the location in the -interpolation dimension `xc` of size 30. +interpolated dimension `xc` of size 30. To indicate which tie point index variable applies to each -interpolation dimension, a **`tie_point_indices`** attribute must be +interpolated dimension, a **`tie_point_indices`** attribute must be defined for the interpolation variable. This is a string attribute that maps -the interpolation dimensions to the corresponding tie point index +the interpolated dimensions to the corresponding tie point index variables. It is a blank-separated list of words of the form -"__interpolation_dimension: tie_point_index_variable -[interpolation_dimension: tie_point_index_variable ...]__". +"__interpolated_dimension: tie_point_index_variable +[interpolated_dimension: tie_point_index_variable ...]__". Continuing the above example, specifying that the target dimension `xc` and `yc` are associated with the tie point index variables `x_indices` and `y_indices` respectively, could be indicated with `xc: @@ -426,13 +426,13 @@ allowed by the definition of the interpolation method. Interpolation parameters may always be provided to non-standardized interpolation methods. -The interpolation parameter variable dimensions must include, for all of the interpolation dimensions, either the associated tie point interpolation dimension or the associated interpolation subarea dimension. Additionally, any subset of zero or more of the non-interpolation dimensions of the tie point coordinate variable are permitted as interpolation parameter variable dimensions. +The interpolation parameter variable dimensions must include, for all of the interpolated dimensions, either the associated subsampled dimension or the associated interpolation subarea dimension. Additionally, any subset of zero or more of the non-interpolated dimensions of the tie point coordinate variable are permitted as interpolation parameter variable dimensions. -The application of an interpolation parameter variable is independent of its non-interpolation dimensions, but depends on its set of tie point interpolation dimensions and interpolation subarea dimensions: +The application of an interpolation parameter variable is independent of its non-interpolated dimensions, but depends on its set of subsampled dimensions and interpolation subarea dimensions: -* If the set only contains tie point interpolation dimensions, then the variable provides values for every tie point and therefore equally applicable to the interpolation subareas that share that tie point, see example a) in figure 3; +* If the set only contains subsampled dimensions, then the variable provides values for every tie point and therefore equally applicable to the interpolation subareas that share that tie point, see example a) in figure 3; * If the set only contains interpolation subarea dimensions, then the variable provides values for every interpolation subarea and therefore only applicable to that interpolation subarea, see example b) in figure 3; -* If the set contains both tie point interpolation dimensions and interpolation subarea dimensions, then the variable’s values are to be shared by the interpolation subareas that are adjacent along each of the specified tie point interpolation dimensions. This case is akin to the values being defined at the interpolation subarea boundaries, and therefore equally applicable to the interpolation subareas that share that boundary, see example c) and d) in figure 3; +* If the set contains both subsampled dimensions and interpolation subarea dimensions, then the variable’s values are to be shared by the interpolation subareas that are adjacent along each of the specified subsampled dimensions. This case is akin to the values being defined at the interpolation subarea boundaries, and therefore equally applicable to the interpolation subareas that share that boundary, see example c) and d) in figure 3; [[ci_interpolation_parameters, figure 3]] [.text-center] @@ -538,7 +538,7 @@ attribute. [[example-grid-mapping-and-interpolation-with-time-not-interpolated]] [caption="Example 8.6. "] -.Combining a grid mapping and coordinate interpolation, with time as a non-interpolation dimension. +.Combining a grid mapping and coordinate interpolation, with time as a non-interpolated dimension. ==== ---- dimensions: From e5feea3947e9958b79ba26da642a2fd1da66921b Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 1 Jul 2021 18:45:25 +0200 Subject: [PATCH 196/249] Combine the tie_point_dimensions and tie_point_indices attributes (Change 1) --- ch08.adoc | 133 ++++++++++++++++++++++++++---------------------------- 1 file changed, 63 insertions(+), 70 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index a471e494..7d94c4c3 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -137,7 +137,7 @@ For each __interpolated dimension__, i.e. a target domain dimension for which coordinate interpolation is required, the location of the tie points is defined by a corresponding __tie point index variable__, which also indicates the location of the continuous areas -(<>). +(<>). For each interpolated dimension, the number of interpolation subareas is equal to the number of tie points minus the number of continuous areas. @@ -197,7 +197,7 @@ interpolation subarea basis, for which the construction of the uncompressed coordinates may only access those tie points that define the extent of the of the interpolation subarea. -In addition to the **`interpolation_name`** and **`interpolation_description`** attributes described in this section, further attributes of the interpolation variable are described in <>, <> and <>. +In addition to the **`interpolation_name`** and **`interpolation_description`** attributes described in this section, further attributes of the interpolation variable are described in <> and <>. [[compression-by-coordinate-sampling-dimensions,Section 8.3.4, "Subsampled, Interpolated and Non-Interpolated Dimensions"]] ==== Subsampled, Interpolated and Non-Interpolated Dimensions @@ -241,36 +241,37 @@ non-interpolated dimension `yc = 10`. The interpolation in the `xc` dimension would then be repeated for each of the 10 indices of the `yc` non-interpolated dimension. -[[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.5, "Tie Point Dimensions Attribute"]] +[[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.5, "Tie Point Mapping Attribute"]] ==== Tie Point Mapping Attribute -Each interpolated dimension must be associated with its corresponding -subsampled dimension and, if required, its corresponding +The **`tie_point_mapping`** attribute provides mapping at two levels. It associates +subsampled dimensions with the corresponding target dimensions, and for each +of these sets of corresponding dimensions, it associates index values +of the subsampled dimension with index values of the target dimension, thereby +uniquely associating the tie points with their corresponding location in the +target domain. + +The mappings are stored in the interpolation variable's +**`tie_point_mapping`** attribute that contains a blank-separated +list of words of the form __"interpolated_dimension: tie_point_index_variable +subsampled_dimension [interpolation_subarea_dimension] +[interpolated_dimension: ...]"__, the details of which are described in the following two sections. + +[[compression-by-coordinate-sampling-tie-point-dimension-mapping, Section 8.3.6, "Tie Point Dimension Mapping"]] +==== Tie Point Dimension Mapping + +The **`tie_point_mapping`** attribute defined above associates +each subsampled dimension and, if required, its corresponding __interpolation subarea dimension__ that defines the number of -interpolation subareas which partition the interpolated dimension. It is +interpolation subareas which partition the interpolated dimension, +with their corresponding interpolated dimension. It is only required to associate an interpolation subarea dimension to an interpolated dimension in the case that the interpolation subarea dimension is spanned by an interpolation parameter variable, as described in -<>. The -association is stored in the interpolation variable's -**`tie_point_mapping`** attribute that contains a blank-separated -list of words of the form __"interpolated_dimension: -subsampled_dimension [interpolation_subarea_dimension] -[interpolated_dimension: ...]"__. If an interpolation subarea dimension -is provided then it must be the second of the two named dimensions -following the interpolated dimension. - -An overview of the different dimensions for coordinate interpolation is shown in <>. - -Note that an interpolation subarea dimension has, by definition, the same size as the corresponding subsampled dimension, minus the number of continuous areas. - - -[[ci_dimensions_overview, figure 2]] -[.text-center] -.Overview of the different dimensions for coordinate interpolation. -image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] - +<>. +If an interpolation subarea dimension is provided then it must be +the second of the two named dimensions following the tie point index variable. A single interpolated dimension may be associated with multiple subsampled dimensions by repeating the interpolated dimension in the @@ -281,24 +282,37 @@ tp_index_variable2 tp_dimension2`. This is necessary when two or more tie point coordinate variables have different tie point index variables corresponding to the same interpolated dimension. -[[compression-by-coordinate-sampling-tie-point-indices, Section 8.3.6, "Tie Point Indices"]] -==== Tie Point Indices +An overview of the different dimensions for coordinate interpolation is shown in <>. -The relationship between a subsampled dimension and its -corresponding interpolated dimension is defined with a __tie point -index variable__. The tie point index variable is a one-dimensional -integer variable that must span the subsampled dimension -specified by the **`tie_point_mapping`** attribute. Each tie point +[[ci_dimensions_overview, figure 2]] +[.text-center] +.Overview of the different dimensions for coordinate interpolation. +image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] + +Note that an interpolation subarea dimension has, by definition, the same size as the corresponding subsampled dimension, minus the number of continuous areas. + +[[compression-by-coordinate-sampling-tie-point-index-mapping, Section 8.3.7, "Tie Point Index Mapping"]] +==== Tie Point Index Mapping + +The **`tie_point_mapping`** attribute defined in +<> +identifies for each subsampled dimension a tie point index variable. The tie +point index variable defines the relationship between the indices of +the subsampled dimension and the indices of its +corresponding interpolated dimension. + +A tie point index variable is a one-dimensional +integer variable that must span the subsampled dimension. Each tie point index variable value is a zero-based index of the related interpolated dimension which maps an element of that interpolated dimension to the corresponding location in the subsampled dimension. The tie point index values must be strictly monotonically -increasing within continuous areas. An interpolation subarea must span +increasing. An interpolation subarea must span at least two points in each of its corresponding interpolated dimensions, therefore the tie point indices that define an -interpolation subarea must all be different. When two adjacent values are -equal, or differ by one, it indicates the location (in index space) of +interpolation subarea must all be different. When two adjacent values differ +by one, it indicates the location (in index space) of an continuous area boundary relating to a grid discontinuity (<>). @@ -306,19 +320,7 @@ For instance, in example <> the tie point coordinate variables represent a subset of the target domain and the tie point index variable `int x_indices(tp_xc)` contains the indices `x_indices = 0, 9, 19, 29` that identify the location in the -interpolated dimension `xc` of size 30. - -To indicate which tie point index variable applies to each -interpolated dimension, a **`tie_point_indices`** attribute must be -defined for the interpolation variable. This is a string attribute that maps -the interpolated dimensions to the corresponding tie point index -variables. It is a blank-separated list of words of the form -"__interpolated_dimension: tie_point_index_variable -[interpolated_dimension: tie_point_index_variable ...]__". -Continuing the above example, specifying that the target dimension -`xc` and `yc` are associated with the tie point index variables -`x_indices` and `y_indices` respectively, could be indicated with `xc: -x_indices yc: y_indices`. +interpolated dimension `xc` of size 30. The corresponding **`tie_point_mapping`** attribute of the interpolation variable is `xc: x_indices tp_xc yc: y_indices tp_yc`. [[example-Two-dimensional-tie-point-interpolation]] [caption="Example 8.3. "] @@ -341,8 +343,7 @@ variables: // Interpolation variable char bl_interpolation ; bl_interpolation:interpolation_name = "bi_linear" ; - bl_interpolation:tie_point_mapping = "xc: tp_xc yc: tp_y" ; - bl_interpolation:tie_point_indices = "yc: y_indices xc: x_indices" ; + bl_interpolation:tie_point_mapping = "xc: x_indices tp_xc yc: y_indices tp_yc" ; // tie point coordinate variables double lat(tp_yc, tp_xc) ; @@ -383,8 +384,7 @@ variables: // Interpolation variables char l_interpolation ; l_interpolation:interpolation_name = "linear" ; - l_interpolation:tie_point_mapping = "xc: tp_xc" ; - l_interpolation:tie_point_indices = "xc: x_indices" ; + l_interpolation:tie_point_mapping = "xc: x_indices tp_xc" ; // tie point coordinate variables double lat(yc, tp_xc) ; @@ -403,7 +403,7 @@ data: ---- ==== -[[compression-by-coordinate-sampling-interpolation-parameters, Section 8.3.7, "Interpolation Parameters"]] +[[compression-by-coordinate-sampling-interpolation-parameters, Section 8.3.8, "Interpolation Parameters"]] ==== Interpolation Parameters The interpolation variable attribute **`interpolation_parameters`** @@ -436,7 +436,7 @@ The application of an interpolation parameter variable is independent of its non [[ci_interpolation_parameters, figure 3]] [.text-center] -.Through combination of dimensions, interpolation parameter variables may provide values for each interpolation subarea, for couples of neighbouring interpolation subareas or for multiple interpolation subareas sharing a boundary. +.Through combination of dimensions, interpolation parameter variables may provide values for a) interpolation subareas sharing a tie point, b) each interpolation subarea, c) and d) interpolation subareas sharing a boundary. image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] @@ -482,12 +482,9 @@ variables: // Interpolation variable char tp_interpolation ; tp_interpolation:interpolation_name = "bi_quadratic_remote_sensing" ; - tp_interpolation:tie_point_mapping = "track: tp_track subarea_track - scan: tp_scan subarea_scan -; - tp_interpolation:tie_point_indices = "track: track_indices - scan: scan_indices -; + tp_interpolation:tie_point_mapping = "track: track_indices tp_track subarea_track + scan: scan_indices tp_scan subarea_scan +;; tp_interpolation:interpolation_parameters = "ce1: ce1 ca2: ca2 ce3: ce3 flags: interpolation_subarea_flags" ; // Interpolation parameters @@ -518,10 +515,8 @@ variables: // Time interpolation variable char time_interpolation ; time_interpolation:interpolation_name = "bi_linear" ; - time_interpolation:tie_point_mapping = "track: tp_track - scan: tp_time_scan" ; - time_interpolation:tie_point_indices = "track: track_indices - scan: time_scan_indices" ; + time_interpolation:tie_point_mapping = "track: track_indices tp_track + scan: time_scan_indices tp_time_scan" ; // Time tie points double t(tp_track, tp_time_scan) ; @@ -567,13 +562,11 @@ variables: // Interpolation variables char bi_linear ; bi_linear:interpolation_name = "bi_linear" ; - bi_linear:tie_point_mapping = "y: tp_y x: tp_x" ; - bi_linear:tie_point_indices = "y: y_indices x: x_indices" ; + bi_linear:tie_point_mapping = "y: y_indices tp_y x: x_indices tp_x" ; char linear ; linear:interpolation_name = "linear" ; - linear:tie_point_mapping = "y: tp_y x: tp_x" ; - linear:tie_point_indices = "y: y_indices x: x_indices" ; + linear:tie_point_mapping = "y: y_indices tp_y x: x_indices tp_x" ; // tie point coordinate variables double time(time) ; @@ -603,6 +596,6 @@ variables: In this the projection coordinates are two-dimensional, but are only linearly interpolated in one of their dimensions - the one which is -given by the **`tie_point_indices`** attribute. +given by the **`tie_point_mapping`** attribute. -==== +==== \ No newline at end of file From 35019927e4218044d09d1cc6a61cf727dc4cf58f Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 1 Jul 2021 18:46:12 +0200 Subject: [PATCH 197/249] Update figures to match new terms --- images/ci_dimensions_overview.svg | 2 +- images/ci_interpolation_coefficients.svg | 735 +----------------- ..._interpolation_zone_generation_process.svg | 2 +- 3 files changed, 3 insertions(+), 736 deletions(-) diff --git a/images/ci_dimensions_overview.svg b/images/ci_dimensions_overview.svg index 84d68a73..907fd835 100644 --- a/images/ci_dimensions_overview.svg +++ b/images/ci_dimensions_overview.svg @@ -1 +1 @@ -901929Interpolation DimensionSize 3010243Tie Point Interpolation DimensionSize 5102Interpolation Zone DimensionSize 3Tie PointTie Point Indices:x_indices= 0, 9, 19, 20, 29 y_indices= 0, 7, 8, 15Interpolation Areas 210 \ No newline at end of file +901929Interpolated DimensionSize 3010243Subsampled DimensionSize 5102Interpolation Subarea DimensionSize 3Tie PointTie Point Indices:x_indices= 0, 9, 19, 20, 29 y_indices= 0, 7, 8, 15ContinuousAreas 210 \ No newline at end of file diff --git a/images/ci_interpolation_coefficients.svg b/images/ci_interpolation_coefficients.svg index d4e0a87e..8d50e331 100644 --- a/images/ci_interpolation_coefficients.svg +++ b/images/ci_interpolation_coefficients.svg @@ -1,734 +1 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - xy - Dimension (x_interpolation_zone)Example (1) - - - - - - - - Dimension (y_tie_point_interpolation,x_tie_point_interpolation)Example(0, 0) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Dimension (y_tie_point_interpolation , x_interpolation_zone )Example (2, 0) - - Dimension (y_interpolation_zone , x_tie_point_interpolation )Example (1, 2) - - Dimension (y_interpolation_zone , x_interpolation_zone ) -Example (0, 1) - - - - - - - +xyExample c)Dimension (y_ interpolation_subarea, x_subsampled)Example (1, 2) Example d)Dimension (y_subsampled, x_interpolation_subarea)Example (2, 0) Example b)Dimension (y_ interpolation_subarea, x_ interpolation_subarea)Example (0, 1) Example a)Dimension (y_subsampled, x_subsampled)Example (1, 1) \ No newline at end of file diff --git a/images/ci_interpolation_zone_generation_process.svg b/images/ci_interpolation_zone_generation_process.svg index 9a4baf91..3b5b3d17 100644 --- a/images/ci_interpolation_zone_generation_process.svg +++ b/images/ci_interpolation_zone_generation_process.svg @@ -1 +1 @@ -Coordinatesand AuxiliaryCoordinatesInterpolation Areasseparated byGrid DiscontinuitiesInterpolation Zones,sharing TiePoints within,but not between,Interpolation AreasGrid(0,0)(0,1)(1,1)(1,0)Grid with DiscontinuitiesCoordinate SpaceIndex Space(0,0)(0,1)(1,1)(1,0)(0,2)(1,2)(0,0)(0,1)(1,1)(1,0)(0,2)(1,2)(0,0)(0,0)(0,0)(0,1)(1,1)(1,0) \ No newline at end of file +Coordinatesand AuxiliaryCoordinatesContinuousAreasseparated byGrid DiscontinuitiesInterpolation Subareas,sharing TiePoints within,but not between,ContinuousAreasGrid(0,0)(0,1)(1,1)(1,0)Grid with DiscontinuitiesCoordinate SpaceIndex Space(0,0)(0,1)(1,1)(1,0)(0,2)(1,2)(0,0)(0,1)(1,1)(1,0)(0,2)(1,2)(0,0)(0,0)(0,0)(0,1)(1,1)(1,0) \ No newline at end of file From 577fbcc7996d85157ebd5d829240b121c8ca2a76 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 1 Jul 2021 19:08:32 +0200 Subject: [PATCH 198/249] Improve description of non-overlapping interpolation subareas --- ch08.adoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 7d94c4c3..acb7f1fa 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -131,13 +131,13 @@ discontinuities and for a domain with discontinuities is illustrated in <>, and described in more detail in <>. -Within an continuous area, interpolation subareas must share tie points with neighbouring interpolation subareas. Between continuous areas, interpolation subareas are not permitted to share tie points. This results in a different number of tie points in the two cases shown in <>. +For each __interpolated dimension__, i.e. a target domain dimension for which coordinate interpolation is required, the locations of the tie point coordinates are defined by a corresponding __tie point index variable__, which also indicates the location of the continuous areas (<>). + +The interpolation subareas within a continuous area do not overlap, ensuring that each coordinate of an interpolated dimension is computed from a unique interpolation subarea. These interpolation subareas, however, share the tie point coordinates that define their common boundaries. Such a shared tie point coordinate can only be located in one of a pair of adjacent interpolation subareas, which is always the first of the pair in index space. For instance, in <>, the interpolation subarea labeled `(0,0)` contains all four of its tie point coordinates, and the interpolation subarea `(0,1)` only contains two of them. When applied for a given interpolation subarea, interpolation methods, such as those described in <>, must ensure that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. + +Adjacent interpolation subareas that are in different continuous areas never share tie point coordinates, as consequence of the grid discontinuity between them. This results in a different number of tie point coordinates in the two cases shown in <>. + -For each __interpolated dimension__, i.e. a target domain dimension -for which coordinate interpolation is required, the location of the -tie points is defined by a corresponding __tie point index variable__, -which also indicates the location of the continuous areas -(<>). For each interpolated dimension, the number of interpolation subareas is equal to the number of tie points minus the number of continuous areas. From 839b49c63365a2f27a5bf47434def05636feaee3 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 1 Jul 2021 20:10:42 +0200 Subject: [PATCH 199/249] Improve description of non-overlapping interpolation subareas --- ch08.adoc | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index acb7f1fa..c0ee37cd 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -306,15 +306,9 @@ integer variable that must span the subsampled dimension. Each tie point index variable value is a zero-based index of the related interpolated dimension which maps an element of that interpolated dimension to the corresponding location in the subsampled -dimension. The tie point index values must be strictly monotonically -increasing. An interpolation subarea must span -at least two points in each of its corresponding interpolated -dimensions, therefore the tie point indices that -define an -interpolation subarea must all be different. When two adjacent values differ -by one, it indicates the location (in index space) of -an continuous area boundary relating to a grid discontinuity -(<>). +dimension. + +The tie point index values must be strictly monotonically increasing. The location in index space of a continuous area boundary that relates to a grid discontinuity (<>) is indicated by a pair of adjacent tie point index values differing by one. In this case, each tie point index of the pair defines a boundary of a different continuous area. As a consequence, any pair of tie point index values that defines an extent of an interpolation subarea must differ by two or more, i.e. in general, an interpolation subarea spans at least two points in each of its interpolated dimensions. For each subsampled dimension, the first interpolation subareas in index space of a continuous area are special, however, in that they contain tie points at both of the subarea boundaries with respect to that subsampled dimension and so must span at least three points in the corresponding interpolated dimension (see <>). For instance, in example <> the tie point coordinate variables represent a subset of the target domain and From 376fd271d9314aea350c79773063acc7601327b8 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 2 Jul 2021 11:55:45 +0200 Subject: [PATCH 200/249] Update Example 8.6 to correctly specify one dimension interpolation for X and Y --- ch08.adoc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index c0ee37cd..7906d749 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -545,7 +545,7 @@ variables: Temperature:standard_name = "air_temperature" ; Temperature:units = "K" ; Temperature:grid_mapping = "lambert_conformal" ; - Temperature:coordinate_interpolation = "lat: lon: bi_linear y: x: linear" ; + Temperature:coordinate_interpolation = "lat: lon: bi_linear x: linear_x y: linear_y" ; int lambert_conformal ; lambert_conformal:grid_mapping_name = "lambert_conformal_conic" ; @@ -558,9 +558,13 @@ variables: bi_linear:interpolation_name = "bi_linear" ; bi_linear:tie_point_mapping = "y: y_indices tp_y x: x_indices tp_x" ; - char linear ; + char linear_x ; linear:interpolation_name = "linear" ; - linear:tie_point_mapping = "y: y_indices tp_y x: x_indices tp_x" ; + linear:tie_point_mapping = "x: x_indices tp_x" ; + + char linear_y ; + linear:interpolation_name = "linear" ; + linear:tie_point_mapping = "y: y_indices tp_y" ; // tie point coordinate variables double time(time) ; @@ -581,10 +585,10 @@ variables: // Tie point index variables int y_indices(tp_y) ; - y_indices.long_name = "Mapping of y dimension to its ", + y_indices:long_name = "Mapping of y dimension to its ", "corresponding tie point dimension" ; int x_indices(tp_x) ; - x_indices.long_name = "Mapping of x dimension to its ", + x_indices:long_name = "Mapping of x dimension to its ", "corresponding tie point dimension" ; ---- From 2becd52c5f81920fa24b495de50a17cb0f488c5f Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 2 Jul 2021 14:25:18 +0200 Subject: [PATCH 201/249] Improve wording of Tie Point Index Mapping (Change 8) --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 7906d749..39f865bc 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -308,7 +308,7 @@ interpolated dimension which maps an element of that interpolated dimension to the corresponding location in the subsampled dimension. -The tie point index values must be strictly monotonically increasing. The location in index space of a continuous area boundary that relates to a grid discontinuity (<>) is indicated by a pair of adjacent tie point index values differing by one. In this case, each tie point index of the pair defines a boundary of a different continuous area. As a consequence, any pair of tie point index values that defines an extent of an interpolation subarea must differ by two or more, i.e. in general, an interpolation subarea spans at least two points in each of its interpolated dimensions. For each subsampled dimension, the first interpolation subareas in index space of a continuous area are special, however, in that they contain tie points at both of the subarea boundaries with respect to that subsampled dimension and so must span at least three points in the corresponding interpolated dimension (see <>). +The tie point index values must be strictly monotonically increasing. The location in index space of a continuous area boundary that relates to a grid discontinuity (<>) is indicated by a pair of adjacent tie point index values differing by one. In this case, each tie point index of the pair defines a boundary of a different continuous area. As a consequence, any pair of tie point index values that defines an extent of an interpolation subarea must differ by two or more, i.e. in general, an interpolation subarea spans at least two points in each of its interpolated dimensions. For each subsampled dimension, the first interpolation subarea in index space of each continuous area is special, however, in that it contains tie points at both of the subarea boundaries with respect to that subsampled dimension and so must span at least three points in the corresponding interpolated dimension (see <>). For instance, in example <> the tie point coordinate variables represent a subset of the target domain and From 5ff42831af6d9e045e6f4f862d14b73f34826c5a Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 5 Jul 2021 13:38:05 +0200 Subject: [PATCH 202/249] Clarify interpolation subarea size --- ch08.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 39f865bc..0d07b1af 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -282,6 +282,8 @@ tp_index_variable2 tp_dimension2`. This is necessary when two or more tie point coordinate variables have different tie point index variables corresponding to the same interpolated dimension. +Note that an interpolation subarea dimension has, by definition, the same size as the corresponding subsampled dimension, minus the number of continuous areas. + An overview of the different dimensions for coordinate interpolation is shown in <>. [[ci_dimensions_overview, figure 2]] @@ -289,8 +291,6 @@ An overview of the different dimensions for coordinate interpolation is shown in .Overview of the different dimensions for coordinate interpolation. image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] -Note that an interpolation subarea dimension has, by definition, the same size as the corresponding subsampled dimension, minus the number of continuous areas. - [[compression-by-coordinate-sampling-tie-point-index-mapping, Section 8.3.7, "Tie Point Index Mapping"]] ==== Tie Point Index Mapping @@ -308,7 +308,7 @@ interpolated dimension which maps an element of that interpolated dimension to the corresponding location in the subsampled dimension. -The tie point index values must be strictly monotonically increasing. The location in index space of a continuous area boundary that relates to a grid discontinuity (<>) is indicated by a pair of adjacent tie point index values differing by one. In this case, each tie point index of the pair defines a boundary of a different continuous area. As a consequence, any pair of tie point index values that defines an extent of an interpolation subarea must differ by two or more, i.e. in general, an interpolation subarea spans at least two points in each of its interpolated dimensions. For each subsampled dimension, the first interpolation subarea in index space of each continuous area is special, however, in that it contains tie points at both of the subarea boundaries with respect to that subsampled dimension and so must span at least three points in the corresponding interpolated dimension (see <>). +The tie point index values must be strictly monotonically increasing. The location in index space of a continuous area boundary that relates to a grid discontinuity (<>) is indicated by a pair of adjacent tie point index values differing by one. In this case, each tie point index of the pair defines a boundary of a different continuous area. As a consequence, any pair of tie point index values that defines an extent of an interpolation subarea must differ by two or more, i.e. in general, an interpolation subarea spans at least two points in each of its interpolated dimensions. Interpolation subareas that are the first in index space of a continuous area, in one or more of the subsampled dimensions are, however, special. These interpolation subareas contain tie points at both of the subarea boundaries with respect to those subsampled dimensions and so must span at least three points in the corresponding interpolated dimensions (see <>). For instance, in example <> the tie point coordinate variables represent a subset of the target domain and From 8eeb0a2f4cfb2d9f08080e248fb026b9576fc861 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 5 Jul 2021 13:50:34 +0200 Subject: [PATCH 203/249] Clarify dimensions in Figure 2 --- images/ci_dimensions_overview.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/images/ci_dimensions_overview.svg b/images/ci_dimensions_overview.svg index 907fd835..e7701417 100644 --- a/images/ci_dimensions_overview.svg +++ b/images/ci_dimensions_overview.svg @@ -1 +1 @@ -901929Interpolated DimensionSize 3010243Subsampled DimensionSize 5102Interpolation Subarea DimensionSize 3Tie PointTie Point Indices:x_indices= 0, 9, 19, 20, 29 y_indices= 0, 7, 8, 15ContinuousAreas 210 \ No newline at end of file +901929Interpolated DimensionSize 3010243Subsampled DimensionSize 5102Interpolation Subarea DimensionSize 3Tie PointTie Point Indices:x_indices= 0, 9, 19, 20, 29 y_indices= 0, 7, 8, 15ContinuousAreas 210xyForthe x-dimension: \ No newline at end of file From db15c0151696dfcfea3c4f4da2e82fcffbcca6b5 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 5 Jul 2021 21:38:04 +0200 Subject: [PATCH 204/249] Add new section 8.3.9, "Computational Precision" --- bibliography.adoc | 2 ++ ch08.adoc | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/bibliography.adoc b/bibliography.adoc index 7f38722e..98eed07b 100644 --- a/bibliography.adoc +++ b/bibliography.adoc @@ -14,6 +14,8 @@ - [[[FGDC]]] link:$$http://www.fgdc.gov/standards/projects/FGDC-standards-projects/metadata/base-metadata/v2_0698.pdf$$[Content Standard for Digital Geospatial Metadata] . Federal Geographic Data Committee, FGDC-STD-001-1998 . + +- [[[IEEE_754]]] link:$$https://ieeexplore.ieee.org/servlet/opac?punumber=8766227$$[IEEE Standard for Floating-Point Arithmetic], in __IEEE Std 754-2019 (Revision of IEEE 754-2008)__, vol., no., pp.1-84, 22 July 2019, doi: 10.1109/IEEESTD.2019.8766229. - [[[NetCDF]]] link:$$http://www.unidata.ucar.edu/netcdf/index.html$$[ NetCDF Software Package] . UNIDATA Program Center of the University Corporation for Atmospheric Research . diff --git a/ch08.adoc b/ch08.adoc index 0d07b1af..655edae9 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -434,7 +434,22 @@ The application of an interpolation parameter variable is independent of its non image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] -[[compression-by-coordinate-sampling-bounds, Section 8.3.9, "Interpolation of Tie Point Bounds"]] +[[compression-by-coordinate-sampling-computational_precision, Section 8.3.9, "Computational Precision"]] +==== Computational Precision + +The accuracy of the reconstituted coordinates depends mainly on the degree of subsampling and the choice of interpolation method, both of which are set by the creator of the dataset. The accuracy will also depend, however, on how the interpolation method is implemented and on the computer platform carrying out the computations. There are no restrictions on the choice of interpolation method implementation, for neither the data creator nor the data user, but the floating-point arithmetic precision used by the data creator during the preparation and validation of the compressed coordinates must be specified by setting the interpolation variable’s **`computational_precision**` attribute to one of the following values: + +[cols="3,10"] +|=============== +| ** Value ** | ** Description** +| "32" | 32-bit floating-point arithmetic, comparable to the binary32 standard in [<>] +| "64" | 64-bit floating-point arithmetic, comparable to the binary64 standard in [<>] +|=============== + + +Using the given computational precision in the interpolation computations is a necessary, but not sufficient, condition for the data user to be able to reconstitute the coordinates to an accuracy comparable to that intended by the data creator. For instance, a **`computational_precision**` value of **`"64"**` would specify that, using the same software and hardware as the creator of the compressed dataset, sufficient accuracy could not be reached when using a floating-point precision lower than 64-bit floating-point arithmetic in the interpolation computations required to reconstitute the coordinates. + +[[compression-by-coordinate-sampling-bounds, Section 8.3.10, "Interpolation of Tie Point Bounds"]] ==== Interpolation of Tie Point Bounds If reconstituted coordinates have cell boundaries, then the corresponding tie point coordinate variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. From 98075185eff417f6b666209709441f01f8935498 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 5 Jul 2021 22:04:26 +0200 Subject: [PATCH 205/249] Combine the tie_point_dimensions and tie_point_indices attributes (Change 1) --- ch08.adoc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 655edae9..bd8e6a82 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -261,15 +261,15 @@ subsampled_dimension [interpolation_subarea_dimension] ==== Tie Point Dimension Mapping The **`tie_point_mapping`** attribute defined above associates -each subsampled dimension and, if required, its corresponding -__interpolation subarea dimension__ that defines the number of -interpolation subareas which partition the interpolated dimension, -with their corresponding interpolated dimension. It is -only required to associate an interpolation subarea dimension to an -interpolated dimension in the case that the interpolation subarea -dimension is spanned by an interpolation parameter variable, as -described in -<>. +each interpolated dimension with its corresponding subsampled + dimension and, if required, its corresponding + __interpolation subarea dimension__ that defines the number of +interpolation subareas which partition the interpolated dimension. +It is only required to associate an interpolated dimension +to an interpolation subarea dimension in the case that the interpolation +subarea dimension is spanned by an interpolation parameter variable, +as described in +<>. If an interpolation subarea dimension is provided then it must be the second of the two named dimensions following the tie point index variable. From daaa3e0390a8f029ef56b67258c1f2586edde967 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 5 Jul 2021 22:09:58 +0200 Subject: [PATCH 206/249] Remove paragraph "A single interpolated dimension may be associated with multiple ...." no longer relevant --- ch08.adoc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index bd8e6a82..5f583039 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -273,15 +273,6 @@ as described in If an interpolation subarea dimension is provided then it must be the second of the two named dimensions following the tie point index variable. -A single interpolated dimension may be associated with multiple -subsampled dimensions by repeating the interpolated dimension in the -**`tie_point_mapping`** attribute. For instance, interpolated dimension -`dimension1` could be mapped to two different subsampled -dimensions with `dimension1: tp_index_variable1 tp_dimension1 dimension1: -tp_index_variable2 tp_dimension2`. This is necessary when two or more tie -point coordinate variables have different tie point index variables -corresponding to the same interpolated dimension. - Note that an interpolation subarea dimension has, by definition, the same size as the corresponding subsampled dimension, minus the number of continuous areas. An overview of the different dimensions for coordinate interpolation is shown in <>. From 5ddda3be5c4de9e0914bc8eb42c4c65dd81ae95d Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 6 Jul 2021 11:54:31 +0200 Subject: [PATCH 207/249] Update ch08.adoc Co-authored-by: David Hassell --- ch08.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 5f583039..3c352024 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -131,7 +131,7 @@ discontinuities and for a domain with discontinuities is illustrated in <>, and described in more detail in <>. -For each __interpolated dimension__, i.e. a target domain dimension for which coordinate interpolation is required, the locations of the tie point coordinates are defined by a corresponding __tie point index variable__, which also indicates the location of the continuous areas (<>). +For each __interpolated dimension__, i.e. a target domain dimension for which coordinate interpolation is required, the locations of the tie point coordinates are defined by a corresponding __tie point index variable__, which also indicates the locations of the continuous areas (<>). The interpolation subareas within a continuous area do not overlap, ensuring that each coordinate of an interpolated dimension is computed from a unique interpolation subarea. These interpolation subareas, however, share the tie point coordinates that define their common boundaries. Such a shared tie point coordinate can only be located in one of a pair of adjacent interpolation subareas, which is always the first of the pair in index space. For instance, in <>, the interpolation subarea labeled `(0,0)` contains all four of its tie point coordinates, and the interpolation subarea `(0,1)` only contains two of them. When applied for a given interpolation subarea, interpolation methods, such as those described in <>, must ensure that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. @@ -602,4 +602,4 @@ In this the projection coordinates are two-dimensional, but are only linearly interpolated in one of their dimensions - the one which is given by the **`tie_point_mapping`** attribute. -==== \ No newline at end of file +==== From cb91ac0e6885b578c2afefe8439f87b8ccaec2b8 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 6 Jul 2021 11:55:02 +0200 Subject: [PATCH 208/249] Update ch08.adoc Co-authored-by: David Hassell --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 3c352024..50ca7672 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -133,7 +133,7 @@ in <>, and described in more detail in For each __interpolated dimension__, i.e. a target domain dimension for which coordinate interpolation is required, the locations of the tie point coordinates are defined by a corresponding __tie point index variable__, which also indicates the locations of the continuous areas (<>). -The interpolation subareas within a continuous area do not overlap, ensuring that each coordinate of an interpolated dimension is computed from a unique interpolation subarea. These interpolation subareas, however, share the tie point coordinates that define their common boundaries. Such a shared tie point coordinate can only be located in one of a pair of adjacent interpolation subareas, which is always the first of the pair in index space. For instance, in <>, the interpolation subarea labeled `(0,0)` contains all four of its tie point coordinates, and the interpolation subarea `(0,1)` only contains two of them. When applied for a given interpolation subarea, interpolation methods, such as those described in <>, must ensure that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. +The interpolation subareas within a continuous area do not overlap, ensuring that each coordinate of an interpolated dimension is computed from a unique interpolation subarea. These interpolation subareas, however, share the tie point coordinates that define their common boundaries. Such a shared tie point coordinate can only be located in one of a pair of adjacent interpolation subareas, which is always the first of the pair in index space. For instance, in <>, the interpolation subarea labeled `(0,0)` contains all four of its tie point coordinates, and the interpolation subarea `(0,1)` only contains two of them. When applied for a given interpolation subarea, interpolation methods (such as those described in <>) must ensure that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. Adjacent interpolation subareas that are in different continuous areas never share tie point coordinates, as consequence of the grid discontinuity between them. This results in a different number of tie point coordinates in the two cases shown in <>. From f04a82f4394d8ce48dce43007460014352fe3950 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 6 Jul 2021 13:46:02 +0200 Subject: [PATCH 209/249] Update ch08.adoc Co-authored-by: David Hassell --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 50ca7672..2fc2d584 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -149,7 +149,7 @@ image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,a [[compression-by-coordinate-sampling-tie-points-attribute, Section 8.3.2, "Coordinate Interpolation Attribute"]] ==== Coordinate Interpolation Attribute -To indicate that coordinate interpolation is required, a **`coordinate_interpolation`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point coordinate variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_variable: [tie_point_variable: ...] interpolation_variable [tie_point_variable: [tie_point_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point coordinate variables `lat` and `lon` are to be interpolated according to the interpolation variable `bi_linear` could be indicated with `lat: lon: bi_linear`. +To indicate that coordinate interpolation is required, a **`coordinate_interpolation`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point coordinate variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_coordinate_variable: [tie_point_coordinate_variable: ...] interpolation_variable [tie_point_coordinate_variable: [tie_point_coordinate_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point coordinate variables `lat` and `lon` are to be interpolated according to the interpolation variable `bi_linear` could be indicated with `lat: lon: bi_linear`. [[compression-by-coordinate-sampling-interpolation-variable, Section 8.3.3, "Interpolation Variable"]] ==== Interpolation Variable From d4886b7bf0ee333070ec50ed0e13d5df8ca1b84a Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 7 Jul 2021 11:54:41 +0200 Subject: [PATCH 210/249] Update ch08.adoc Co-authored-by: David Hassell --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 2fc2d584..f686b031 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -273,7 +273,7 @@ as described in If an interpolation subarea dimension is provided then it must be the second of the two named dimensions following the tie point index variable. -Note that an interpolation subarea dimension has, by definition, the same size as the corresponding subsampled dimension, minus the number of continuous areas. +Note that the size of an interpolation subarea dimension is, by definition, the size of the corresponding subsampled dimension minus the number of continuous areas. An overview of the different dimensions for coordinate interpolation is shown in <>. From 32f0b84ccf54512ed4fc9ce495302178d0391aaf Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 14 Jul 2021 13:19:13 +0200 Subject: [PATCH 211/249] Change sampl... to subsampl... --- ch08.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 5f583039..156761d6 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -72,14 +72,14 @@ This information implies that the salinity field should be uncompressed to an ar ==== -[[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Sampling"]] -=== Lossy Compression by Coordinate Sampling +[[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Subsampling"]] +=== Lossy Compression by Coordinate Subsampling For some applications the coordinates of a data variable can require considerably more storage than the data itself. Space may be saved in -the netCDF file by storing a sample of the coordinates that describe +the netCDF file by storing a subsample of the coordinates that describe the data. The uncompressed coordinate and auxiliary coordinate -variables can be reconstituted by interpolation, from the sampled +variables can be reconstituted by interpolation, from the subsampled coordinate values to the domain of the data (i.e. the target domain). This process will likely result in a loss in accuracy (as opposed to precision) in the uncompressed variables, due to rounding @@ -90,7 +90,7 @@ dataset can control the accuracy of the reconstituted coordinates through the degree of subsampling and the choice of interpolation method, see <>. -The sampled coordinates are called __tie points__ and are stored in +The subsampled coordinates are called __tie points__ and are stored in __tie point coordinate variables__. In addition to the tie point coordinate variables themselves, metadata defining the coordinate interpolation method is stored in attributes of the data variable and of the associated __interpolation variable__. The partitioning of metadata between the data variable and the interpolation variable has been designed to minimise redundancy and maximise the reusability of the interpolation variable within a dataset. From f3de5085b4cec59515b0306b5dae2d4280d4a74d Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 20 Jul 2021 20:58:32 +0200 Subject: [PATCH 212/249] Rewrite section Interpolation of Cell Boundaries (Change 15) --- ch08.adoc | 119 ++++++++++++++++++++++++++--- images/ci_bounds_interpolation.svg | 1 + 2 files changed, 109 insertions(+), 11 deletions(-) create mode 100644 images/ci_bounds_interpolation.svg diff --git a/ch08.adoc b/ch08.adoc index b862b1c1..e11e0bdb 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -141,7 +141,7 @@ Adjacent interpolation subareas that are in different continuous areas never sha For each interpolated dimension, the number of interpolation subareas is equal to the number of tie points minus the number of continuous areas. -[[interpolation_subarea_generation, figure 1]] +[[interpolation_subarea_generation, Figure 1]] [.text-center] .Process for generating the interpolation subareas for a grid without discontinuities and for a grid with discontinuities. image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,align="center"] @@ -440,16 +440,6 @@ The accuracy of the reconstituted coordinates depends mainly on the degree of su Using the given computational precision in the interpolation computations is a necessary, but not sufficient, condition for the data user to be able to reconstitute the coordinates to an accuracy comparable to that intended by the data creator. For instance, a **`computational_precision**` value of **`"64"**` would specify that, using the same software and hardware as the creator of the compressed dataset, sufficient accuracy could not be reached when using a floating-point precision lower than 64-bit floating-point arithmetic in the interpolation computations required to reconstitute the coordinates. -[[compression-by-coordinate-sampling-bounds, Section 8.3.10, "Interpolation of Tie Point Bounds"]] -==== Interpolation of Tie Point Bounds - -If reconstituted coordinates have cell boundaries, then the corresponding tie point coordinate variable must also have cell boundaries, specified by the **`bounds`** attribute that names the variable that contains the vertices of the cell boundaries. -The bounds of a tie point must be the same as the bounds of the target grid cells whose coordinates are specified as the tie point. -It is therefore likely that tie point cells will be non-contiguous. - -The target domain cell bounds are calculated by interpolating each cell bound position independently of the others, using the same interpolation method and tie point index variables as used for the cell coordinates. In this case, though, the tie point index variables are the identifying target domain cells to which the bounds apply, rather than bounds values themselves. For instance, in the case of a two-dimensional tie point coordinate variable with four-sided cells, the target domain cell bounds would be calculated with four separate interpolations, one for each of the bounds positions (following the notation of <>) `(j-1,i-1)`, `(j-1,i+1)`, `(j+1,i+1)`, `(j+1,i-1)`. - -Note that an implementation of the interpolation method is free to calculate the uncompressed bounds locations in the manner of its choosing, as a long as the result is formally equivalent to each bounds position being treated independently. [[example-VIIRS]] [caption="Example 8.5. "] @@ -603,3 +593,110 @@ linearly interpolated in one of their dimensions - the one which is given by the **`tie_point_mapping`** attribute. ==== + + +[[compression-by-coordinate-sampling-bounds, Section 8.3.10, "Interpolation of Cell Boundaries"]] +==== Interpolation of Cell Boundaries + +Coordinates may have cell bounds. Equivalently to the way coordinates can be stored as coordinate tie points and reconstituted through interpolation, contiguous cell bounds of interpolated dimensions can be stored as __bounds tie points__ and reconstituted through interpolation. In this process, the coordinate tie points are a prerequisite for the bounds tie points and the same interpolation method used for the coordinate interpolation is used for the bounds interpolation. + +For the reconstituted coordinates, cell bounds are stored separately for each coordinate point, as shown in the left part of <> +for the example of 2D bounds. Since the cell bounds are contiguous, bounds points of adjacent cells will coincide and so the full set of bounds points may be represented as a grid, comparable to the coordinate points grid. In the middle part of <> +, both the reconstituted bounds points grid and the reconstituted coordinate points grid are shown for a continuous area, where each bounds point may be shared by up to four cells. + +For the purpose of bounds interpolation, a single bounds tie point is created for each coordinate tie point, and is selected as the vertex of the tie point cell that is the closest to the boundary of the interpolation subarea with respect to each interpolated dimension. For the example of 2D bounds, the resulting set of bounds tie points are marked in <>. + +Note that within a continuous area, there is one more reconstituted bounds point than there are reconstituted coordinate points in each dimension. For this reason, a virtual __interpolated bounds dimension__ is introduced for each dimension, having a size equal to the size of the interpolated dimension plus one. This dimension is used for solely descriptive purposes, and is not required in a compressed dataset. + + + +[[figure_interpolation_of_cell_boundaries, Figure 4]] +[.text-center] +.Example of 2D bounds interpolation showing the bounds tie points and reconstituted bound points within a continuous area consisting of four interpolation subareas. The dimensions are show for one of the two axes only. The index relationship between coordinate point indices and the related bound points indices is indicated. +image::images/ci_bounds_interpolation.svg[,100%,pdfwidth=50vw,align="center"] + + +Both the process of compressing bounds and the process of uncompressing bounds requires the steps to be carried out for a full continuous area, however, individual continuous areas can be processed independently. In the following description of these processes, indices relative to the origin of each continuous area are used for the interpolated dimension and the interpolated bounds dimension. Consequently, for both coordinate tie points and bounds tie points, the first point in index space of the continuous area has got index 0 in all the interpolated dimensions and interpolated bounds dimensions, respectively. + +Note that the numbering of the bounds `B0`, `B1`, etc, in this section is identical to the numbering in <>. + +A bounds tie point is located in the same interpolation subarea as its corresponding coordinate tie point. The interpolation subareas do not overlap, ensuring that each bound point is computed from a unique interpolation subarea, see also the description of interpolation subareas in <>. That bounds are computed only once ensures that the reconstituted bounds are contiguous. + +For the generation of bounds tie points as part of the process of compressing bounds, the indices of the corresponding coordinate tie points are available in the tie point index variables, see <>. + +[[compressing_one_dimensional, "Compressing one-dimensional coordinate bounds"]] +**Compressing one-dimensional coordinate bounds** + +In the one-dimensional case, a coordinate point at index `i` in the interpolated dimension will be bounded by the two bounds + +`B0 = (n0) = (i); B1 = (n1) = (i+1)` + +where `n` is the bound index in the interpolated bound dimension. + +For one-dimensional bound interpolation, an interpolation subarea is defined by two bounds tie points. The full set of bounds tie points is formed by appending, for each continuous area of the domain, the bound point `B0` of the first coordinate tie points of the continuous area, followed by the bound points `B1` of all subsequent coordinate tie point of the continuous area. + +[[compressing_two_dimensional, "Compressing two-dimensional coordinate bounds"]] +**Compressing two-dimensional coordinate bounds** + +In the two-dimensional case, a coordinate point at indices `(j, i)` in the interpolated dimension will be bounded by the four bounds + +`B0 = (n0, m0) = (j, i); B1 = (n1, m1) = (j, i+1)` + +`B3 = (n3, m3) = (j+1, i); B2 = (n2, m2) = (j+1, i+1)` + +where `(n, m)` are the bounds point indices in the interpolated bound dimensions. + +For two-dimensional bound interpolation, an interpolation subarea is defined by four bounds tie points. The full set of bounds tie points is formed by appending, for each continuous area of the domain, the bound point `B0` of the coordinate tie point at origin the of the continuous area `(0, 0)`, followed by the bound points `B1` of all remaining coordinate tie point of the continuous area with index `j = 0`, followed by the bound points `B3` of all remaining coordinate tie point of the continuous area with index `i = 0`, followed by the bound points `B2` of all remaining coordinate tie point of the continuous area. + +**Bounds Tie Point Attribute and Bounds Tie Point Variable** + +A **`bounds_tie_points`** attribute must be defined for each tie point coordinate variable corresponding to reconstituted coordinates with cell boundaries. It is a single word of the form __“bounds_tie_point_variable”__ that identifies a bounds tie point variable, containing a bounds tie point coordinate value for each tie point stored in its tie point coordinate variable, and therefore the bounds tie point variable has the same set of dimensions as its tie point coordinate variable. An example of the usage of the **`bounds_tie_points`** is shown in <>. Since a bounds tie point variable is considered to be part of a tie point coordinate variable’s metadata, it is not necessary to provide it with attributes such as long_name and units, following the same rules as for the bounds of an uncompressed coordinate variable, see <>. + +**Uncompressing coordinate bounds** + +The reconstitution of the full set of bounds from the bounds tie point is a two-step process. In a first step, which must be carried out for a full continuous area at a time, each bound point is reconstituted by interpolation between the bounds tie points within each interpolation subarea, using the same interpolation method as defined for the ordinary tie points. This step results in a grid of bound points spanning the interpolated bound dimensions. In a second step the reconstituted bounds vertices are replicated to the boundary variables of the reconstituted coordinates. + +**Uncompressing one-dimensional coordinate bounds** + +For one-dimensional coordinate bounds, in the second step of the process, for each index `i` of the interpolated dimension, the two bounds of the boundary variable are set to the value of the interpolated bounds point grid at the indices `B0` and `B1`, respectively, where the indices are defined above under <>. + +**Uncompression of two-dimensional coordinate bounds** + +For two-dimensional coordinate bounds, in the second step of the process, for each index pair `(j, i)` of the interpolated dimension, the four bounds of the boundary variable is set to the value of the interpolated bounds point grid at index pairs `B0` , `B1` , `B2` and `B3`, respectively, where the index pairs are defined above under <>. + + +[[example_interpolation_of_cell_boundaries, Example 8.7]] +[caption="Example 8.7 "] +.Interpolation of 2D Cell Boundaries corresponding to <> +==== +---- +dimensions: + ic = 10; + itp = 3; + + jc = 10; + jtp = 3; + +variables: + // Data variable + float Temperature(jc, ic) ; + Temperature:standard_name = "air_temperature" ; + Temperature:units = "K" ; + Temperature:coordinate_interpolation = "lat: lon: bl_interpolation" ; + + // Interpolation variable + char bl_interpolation ; + bl_interpolation:interpolation_name = "bi_linear" ; + bl_interpolation:tie_point_mapping = "ic: i_indices itp jc: j_indices jtp" ; + + // Tie point index variables + int i_indices(itp) ; + int j_indices(jtp) ; + + + // Tie point coordinate variables + double lat(jtp, itp) ; + lat:units = "degrees_north" ; + lat:standard_name = "latitude" ; + lat:bounds_tie_points = "lat_bounds" ; + + double lon(jtp, itp) ; + lon:units = "degrees_east" ; + lon:standard_name = "longitude" ; + lon:bounds_tie_points = "lon_bounds" ; + + // Bounds tie point variables + double lat_bounds(jtp, itp) ; + double lon_bounds(jtp, itp) ; + +---- +==== diff --git a/images/ci_bounds_interpolation.svg b/images/ci_bounds_interpolation.svg new file mode 100644 index 00000000..a9ce9fd2 --- /dev/null +++ b/images/ci_bounds_interpolation.svg @@ -0,0 +1 @@ +Interpolated Bound Dimension, mSize 11Interpolated Dimension, iSize 10490012Subsampled Dimension shared byCoordinate and Bounds Tie PointsSize 310Coordinate Tie PointsReconstituted CoordinateBounds Tie PointsReconstituted BoundsmnijCoordinatePoint(j, i)in Interpolated DimensionsRelated Cell defined by four Bound Points(n, m)in Bound DimensionsB0 = (n0, m0) = (j, i)B1 = (n1, m1)= (j, i+1)B3 = (n3, m3) = (j+1, i)B2 = (n2, m2) = (j+1, i+1)0(0,0)(0,1)(1,0)(1,1)5 \ No newline at end of file From 2ce5d66afbb3a93ee1cc4497d0ead05f38d1aee5 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 21 Jul 2021 17:15:36 +0200 Subject: [PATCH 213/249] Constrain interpolation parameters to support bounds interpolation --- ch08.adoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index e11e0bdb..5c47903a 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -409,7 +409,9 @@ assumed to be zero. The **`interpolation_parameters`** attribute may only be provided if allowed by the definition of the interpolation method. Interpolation parameters may always be provided to non-standardized interpolation -methods. +methods. + +The interpolation parameters are not permitted to contain absolute coordinate information, such as additional tie points, but may contain relative coordinate information, for example an offset with respect to a tie point or with respect to a combination of tie points. This is to ensure that interpolation methods are equally applicable to both coordinate and bounds interpolation. The interpolation parameter variable dimensions must include, for all of the interpolated dimensions, either the associated subsampled dimension or the associated interpolation subarea dimension. Additionally, any subset of zero or more of the non-interpolated dimensions of the tie point coordinate variable are permitted as interpolation parameter variable dimensions. From 3ea5989193f8dc3dd7bc14db8b047fc19d8234f0 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 21 Jul 2021 20:41:47 +0200 Subject: [PATCH 214/249] Update <> names and figure names to new terms --- ch08.adoc | 38 +++++++++---------- ...erpolation_subarea_generation_process.svg} | 0 2 files changed, 19 insertions(+), 19 deletions(-) rename images/{ci_interpolation_zone_generation_process.svg => ci_interpolation_subarea_generation_process.svg} (100%) diff --git a/ch08.adoc b/ch08.adoc index 5c47903a..4bbd7819 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -72,7 +72,7 @@ This information implies that the salinity field should be uncompressed to an ar ==== -[[compression-by-coordinate-sampling, Section 8.3, "Lossy Compression by Coordinate Subsampling"]] +[[compression-by-coordinate-subsampling, Section 8.3, "Lossy Compression by Coordinate Subsampling"]] === Lossy Compression by Coordinate Subsampling For some applications the coordinates of a data variable can require @@ -97,7 +97,7 @@ In addition to the tie point coordinate variables themselves, metadata defining The metadata that define the interpolation formula and its inputs are complete, so that the results of the coordinate reconstitution process are well defined and of a predictable accuracy. -[[compression-by-coordinate-sampling-tie-points-and-interpolation-subareas, Section 8.3.1, "Tie Points and Interpolation Subareas"]] +[[compression-by-coordinate-subsampling-tie-points-and-interpolation-subareas, Section 8.3.1, "Tie Points and Interpolation Subareas"]] ==== Tie Points and Interpolation Subareas Reconstitution of the uncompressed coordinate and auxiliary coordinate @@ -131,7 +131,7 @@ discontinuities and for a domain with discontinuities is illustrated in <>, and described in more detail in <>. -For each __interpolated dimension__, i.e. a target domain dimension for which coordinate interpolation is required, the locations of the tie point coordinates are defined by a corresponding __tie point index variable__, which also indicates the locations of the continuous areas (<>). +For each __interpolated dimension__, i.e. a target domain dimension for which coordinate interpolation is required, the locations of the tie point coordinates are defined by a corresponding __tie point index variable__, which also indicates the locations of the continuous areas (<>). The interpolation subareas within a continuous area do not overlap, ensuring that each coordinate of an interpolated dimension is computed from a unique interpolation subarea. These interpolation subareas, however, share the tie point coordinates that define their common boundaries. Such a shared tie point coordinate can only be located in one of a pair of adjacent interpolation subareas, which is always the first of the pair in index space. For instance, in <>, the interpolation subarea labeled `(0,0)` contains all four of its tie point coordinates, and the interpolation subarea `(0,1)` only contains two of them. When applied for a given interpolation subarea, interpolation methods (such as those described in <>) must ensure that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. @@ -144,14 +144,14 @@ For each interpolated dimension, the number of interpolation subareas is equal t [[interpolation_subarea_generation, Figure 1]] [.text-center] .Process for generating the interpolation subareas for a grid without discontinuities and for a grid with discontinuities. -image::images/ci_interpolation_zone_generation_process.svg[,100%,pdfwidth=50vw,align="center"] +image::images/ci_interpolation_subarea_generation_process.svg[,100%,pdfwidth=50vw,align="center"] -[[compression-by-coordinate-sampling-tie-points-attribute, Section 8.3.2, "Coordinate Interpolation Attribute"]] +[[compression-by-coordinate-subsampling-coordinate-interpolation-attribute, Section 8.3.2, "Coordinate Interpolation Attribute"]] ==== Coordinate Interpolation Attribute To indicate that coordinate interpolation is required, a **`coordinate_interpolation`** attribute must be defined for a data variable. This is a string attribute that both identifies the tie point coordinate variables, and maps non-overlapping subsets of them to their corresponding interpolation variables. It is a blank-separated list of words of the form "__tie_point_coordinate_variable: [tie_point_coordinate_variable: ...] interpolation_variable [tie_point_coordinate_variable: [tie_point_coordinate_variable: ...] interpolation_variable ...]__". For example, to specify that the tie point coordinate variables `lat` and `lon` are to be interpolated according to the interpolation variable `bi_linear` could be indicated with `lat: lon: bi_linear`. -[[compression-by-coordinate-sampling-interpolation-variable, Section 8.3.3, "Interpolation Variable"]] +[[compression-by-coordinate-subsampling-interpolation-variable, Section 8.3.3, "Interpolation Variable"]] ==== Interpolation Variable The method used to uncompress the tie point coordinate variables is described by @@ -197,9 +197,9 @@ interpolation subarea basis, for which the construction of the uncompressed coordinates may only access those tie points that define the extent of the of the interpolation subarea. -In addition to the **`interpolation_name`** and **`interpolation_description`** attributes described in this section, further attributes of the interpolation variable are described in <> and <>. +In addition to the **`interpolation_name`** and **`interpolation_description`** attributes described in this section, further attributes of the interpolation variable are described in <> and <>, <> and <>. -[[compression-by-coordinate-sampling-dimensions,Section 8.3.4, "Subsampled, Interpolated and Non-Interpolated Dimensions"]] +[[compression-by-coordinate-subsampling-dimensions,Section 8.3.4, "Subsampled, Interpolated and Non-Interpolated Dimensions"]] ==== Subsampled, Interpolated and Non-Interpolated Dimensions For each interpolation variable identified in the @@ -241,7 +241,7 @@ non-interpolated dimension `yc = 10`. The interpolation in the `xc` dimension would then be repeated for each of the 10 indices of the `yc` non-interpolated dimension. -[[compression-by-coordinate-sampling-tie-point-dimensions-attribute, Section 8.3.5, "Tie Point Mapping Attribute"]] +[[compression-by-coordinate-subsampling-tie-point-mapping-attribute, Section 8.3.5, "Tie Point Mapping Attribute"]] ==== Tie Point Mapping Attribute The **`tie_point_mapping`** attribute provides mapping at two levels. It associates @@ -257,7 +257,7 @@ list of words of the form __"interpolated_dimension: tie_point_index_variable subsampled_dimension [interpolation_subarea_dimension] [interpolated_dimension: ...]"__, the details of which are described in the following two sections. -[[compression-by-coordinate-sampling-tie-point-dimension-mapping, Section 8.3.6, "Tie Point Dimension Mapping"]] +[[compression-by-coordinate-subsampling-tie-point-dimension-mapping, Section 8.3.6, "Tie Point Dimension Mapping"]] ==== Tie Point Dimension Mapping The **`tie_point_mapping`** attribute defined above associates @@ -269,7 +269,7 @@ It is only required to associate an interpolated dimension to an interpolation subarea dimension in the case that the interpolation subarea dimension is spanned by an interpolation parameter variable, as described in -<>. +<>. If an interpolation subarea dimension is provided then it must be the second of the two named dimensions following the tie point index variable. @@ -282,11 +282,11 @@ An overview of the different dimensions for coordinate interpolation is shown in .Overview of the different dimensions for coordinate interpolation. image::images/ci_dimensions_overview.svg[,80%,pdfwidth=50vw,align="center"] -[[compression-by-coordinate-sampling-tie-point-index-mapping, Section 8.3.7, "Tie Point Index Mapping"]] +[[compression-by-coordinate-subsampling-tie-point-index-mapping, Section 8.3.7, "Tie Point Index Mapping"]] ==== Tie Point Index Mapping The **`tie_point_mapping`** attribute defined in -<> +<> identifies for each subsampled dimension a tie point index variable. The tie point index variable defines the relationship between the indices of the subsampled dimension and the indices of its @@ -299,7 +299,7 @@ interpolated dimension which maps an element of that interpolated dimension to the corresponding location in the subsampled dimension. -The tie point index values must be strictly monotonically increasing. The location in index space of a continuous area boundary that relates to a grid discontinuity (<>) is indicated by a pair of adjacent tie point index values differing by one. In this case, each tie point index of the pair defines a boundary of a different continuous area. As a consequence, any pair of tie point index values that defines an extent of an interpolation subarea must differ by two or more, i.e. in general, an interpolation subarea spans at least two points in each of its interpolated dimensions. Interpolation subareas that are the first in index space of a continuous area, in one or more of the subsampled dimensions are, however, special. These interpolation subareas contain tie points at both of the subarea boundaries with respect to those subsampled dimensions and so must span at least three points in the corresponding interpolated dimensions (see <>). +The tie point index values must be strictly monotonically increasing. The location in index space of a continuous area boundary that relates to a grid discontinuity (<>) is indicated by a pair of adjacent tie point index values differing by one. In this case, each tie point index of the pair defines a boundary of a different continuous area. As a consequence, any pair of tie point index values that defines an extent of an interpolation subarea must differ by two or more, i.e. in general, an interpolation subarea spans at least two points in each of its interpolated dimensions. Interpolation subareas that are the first in index space of a continuous area, in one or more of the subsampled dimensions are, however, special. These interpolation subareas contain tie points at both of the subarea boundaries with respect to those subsampled dimensions and so must span at least three points in the corresponding interpolated dimensions (see <>). For instance, in example <> the tie point coordinate variables represent a subset of the target domain and @@ -388,7 +388,7 @@ data: ---- ==== -[[compression-by-coordinate-sampling-interpolation-parameters, Section 8.3.8, "Interpolation Parameters"]] +[[compression-by-coordinate-subsampling-interpolation-parameters, Section 8.3.8, "Interpolation Parameters"]] ==== Interpolation Parameters The interpolation variable attribute **`interpolation_parameters`** @@ -427,7 +427,7 @@ The application of an interpolation parameter variable is independent of its non image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] -[[compression-by-coordinate-sampling-computational_precision, Section 8.3.9, "Computational Precision"]] +[[compression-by-coordinate-subsampling-computational-precision, Section 8.3.9, "Computational Precision"]] ==== Computational Precision The accuracy of the reconstituted coordinates depends mainly on the degree of subsampling and the choice of interpolation method, both of which are set by the creator of the dataset. The accuracy will also depend, however, on how the interpolation method is implemented and on the computer platform carrying out the computations. There are no restrictions on the choice of interpolation method implementation, for neither the data creator nor the data user, but the floating-point arithmetic precision used by the data creator during the preparation and validation of the compressed coordinates must be specified by setting the interpolation variable’s **`computational_precision**` attribute to one of the following values: @@ -597,7 +597,7 @@ given by the **`tie_point_mapping`** attribute. ==== -[[compression-by-coordinate-sampling-bounds, Section 8.3.10, "Interpolation of Cell Boundaries"]] +[[compression-by-coordinate-subsampling-interpolation-of-cell-boundaries, Section 8.3.10, "Interpolation of Cell Boundaries"]] ==== Interpolation of Cell Boundaries Coordinates may have cell bounds. Equivalently to the way coordinates can be stored as coordinate tie points and reconstituted through interpolation, contiguous cell bounds of interpolated dimensions can be stored as __bounds tie points__ and reconstituted through interpolation. In this process, the coordinate tie points are a prerequisite for the bounds tie points and the same interpolation method used for the coordinate interpolation is used for the bounds interpolation. @@ -622,9 +622,9 @@ Both the process of compressing bounds and the process of uncompressing bounds r Note that the numbering of the bounds `B0`, `B1`, etc, in this section is identical to the numbering in <>. -A bounds tie point is located in the same interpolation subarea as its corresponding coordinate tie point. The interpolation subareas do not overlap, ensuring that each bound point is computed from a unique interpolation subarea, see also the description of interpolation subareas in <>. That bounds are computed only once ensures that the reconstituted bounds are contiguous. +A bounds tie point is located in the same interpolation subarea as its corresponding coordinate tie point. The interpolation subareas do not overlap, ensuring that each bound point is computed from a unique interpolation subarea, see also the description of interpolation subareas in <>. That bounds are computed only once ensures that the reconstituted bounds are contiguous. -For the generation of bounds tie points as part of the process of compressing bounds, the indices of the corresponding coordinate tie points are available in the tie point index variables, see <>. +For the generation of bounds tie points as part of the process of compressing bounds, the indices of the corresponding coordinate tie points are available in the tie point index variables, see <>. [[compressing_one_dimensional, "Compressing one-dimensional coordinate bounds"]] **Compressing one-dimensional coordinate bounds** + diff --git a/images/ci_interpolation_zone_generation_process.svg b/images/ci_interpolation_subarea_generation_process.svg similarity index 100% rename from images/ci_interpolation_zone_generation_process.svg rename to images/ci_interpolation_subarea_generation_process.svg From 0c5b732cbbf7d2ddc006e3708813e7c70a722e16 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 21 Jul 2021 21:35:51 +0200 Subject: [PATCH 215/249] Require tie points to be numeric type and have no missing values --- ch08.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 4bbd7819..52f7556a 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -137,10 +137,10 @@ The interpolation subareas within a continuous area do not overlap, ensuring tha Adjacent interpolation subareas that are in different continuous areas never share tie point coordinates, as consequence of the grid discontinuity between them. This results in a different number of tie point coordinates in the two cases shown in <>. - - For each interpolated dimension, the number of interpolation subareas is equal to the number of tie points minus the number of continuous areas. +Tie point coordinate variables for both coordinate and auxiliary coordinate variables must be defined as numeric data types and are not allowed to have missing values. + [[interpolation_subarea_generation, Figure 1]] [.text-center] .Process for generating the interpolation subareas for a grid without discontinuities and for a grid with discontinuities. From 0ef79f53ef5b0713969fa9d2b400a4c5205f3c13 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 21 Jul 2021 23:09:41 +0200 Subject: [PATCH 216/249] Update Appendix J with new terms and names --- appj.adoc | 193 ++++++++++++++----------- images/ci_1d_interpolation_subarea.svg | 1 + images/ci_2d_interpolation_subarea.svg | 1 + images/ci_interpolation.svg | 1 - 4 files changed, 107 insertions(+), 89 deletions(-) create mode 100644 images/ci_1d_interpolation_subarea.svg create mode 100644 images/ci_2d_interpolation_subarea.svg delete mode 100644 images/ci_interpolation.svg diff --git a/appj.adoc b/appj.adoc index 9ad305a9..4d4e4691 100644 --- a/appj.adoc +++ b/appj.adoc @@ -1,36 +1,41 @@ -[[appendix-coordinate-sampling, Appendix J, Coordinate Sampling]] +[[appendix-coordinate-subsampling, Appendix J, Coordinate Subsampling]] [appendix] -== Coordinate Sampling Methods +== Coordinate Subsampling Methods -The general description of of the compression by coordinate sampling is given in section <>. This appendix provides details on the available methods for compression by coordinate sampling. +The general description of of the compression by coordinate subsampling is given in section <>. This appendix provides details on the available methods for compression by coordinate subsampling. -The definitions and guidance given here allow an application to compress an existing data set using coordinate sampling, while letting the creator of the compressed dataset control the accuracy of the reconstituted coordinates through the degree of subsampling and the choice of interpolation method. +The definitions and guidance given here allow an application to compress an existing data set using coordinate subsampling, while letting the creator of the compressed dataset control the accuracy of the reconstituted coordinates through the degree of subsampling, the choice of interpolation method and by setting the computational precision. -Futhermore, the definitions given here allow an application to uncompress coordinate and auxiliary coordinate variables that have been compressed using coordinate sampling. The key element of this process is the reconstitution of the full resolution coordinates in the domain of the data by interpolation between the lower resolution coordinates, the tie points, stored in the compressed dataset. +Futhermore, the definitions given here allow an application to uncompress coordinate and auxiliary coordinate variables that have been compressed using coordinate subsampling. The key element of this process is the reconstitution of the full resolution coordinates in the domain of the data by interpolation between the subsampled coordinates, the tie points, stored in the compressed dataset. -All floating point calculations defined in this appendix must be carried out in 64 bit floating point, even if the related coordinates and interpolation parameters are stored in the netCDF files with a lower precision. The appendix is organised in a sections on <>, <>, <> and finally two sections with step procedures <> and <>. [[common_definitions_and_notation]] === Common Definitions and Notation -The target domain is segmented into smaller interpolation zones as described in <>. +The target domain is segmented into smaller interpolation subareas as described in <>. -For one-dimensional interpolation, an interpolation zone is defined by two tie points, one at each end of the interpolation zone; for two-dimensional interpolation, an interpolation zone is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes; etc. Examples of one-dimensional and two-dimensional interpolation zones are shown in <>. +For one-dimensional interpolation, an interpolation subarea is defined by two tie points, one at each end of the interpolation subarea. However, the tie points may be inside or outside the interpolation subareas as shownb in <>. When interpolation methods are applied for a given interpolation subarea, it must be ensured that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. See also description in <>. +[[interpolation_subareas_1d, Figure 1]] +[.text-center] +.One-dimensional interpolation subareas, one including and one excluding tie point A. +image::images/ci_1d_interpolation_subarea.svg[,100%,pdfwidth=50vw,align="center"] + +For two-dimensional interpolation, an interpolation subarea is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes, see <>. -[[interpolation, figure 1]] +[[interpolation_subarea_2d, Figure 2]] [.text-center] -.Tie Points A, B, C and D, interpolation indices i, interpolation variables s and coordinate values c for one and two dimensional interpolation. -image::images/ci_interpolation.svg[,100%,pdfwidth=50vw,align="center"] +.Two-dimensional interpolation subarea. +image::images/ci_2d_interpolation_subarea.svg[,60%,pdfwidth=50vw,align="center"] The coordinate interpolation methods are named to indicate the number of dimensions they interpolate as well as the type of interpolation provided. For example, the interpolation method named `linear` provides linear interpolation in one dimension and the method named `bi_linear` provides linear interpolation in two dimensions. Equivalently, the interpolation method named `quadratic` provides quadratic interpolation in one dimension and the interpolation method named `bi_quadratic` provides quadratic interpolation in two dimensions. -When an interpolation method is referred to as linear or quadratic, it means that the method is linear or quadratic in the indices of the interpolation dimensions. +When an interpolation method is referred to as linear or quadratic, it means that the method is linear or quadratic in the indices of the interpolated dimensions. -For convenience, an interpolation variable `s` is introduced, calculated as a function of the index in the target domain of the coordinate value to be reconstituted. In the case of one dimensional interpolation the interpolation variable is computed as +For convenience, a variable `s` is introduced, calculated as a function of the index in the target domain of the coordinate value to be reconstituted. In the case of one dimensional interpolation the variable is computed as `s = s(ia, ib, i) = (i - ia)/(ib - ia)` @@ -38,22 +43,22 @@ where `ia` and `ib` are the indices in the target domain of the tie points `A` a Note that the value of `s` varies from `0.0` at the tie point `A` to `1.0` at tie point `B`. For example, if `ia = 100` and `ib = 110` and the index in the target domain of the coordinate value to be reconstituted is `i = 105`, then `s = (105 - 100)/(110 - 100) = 0.5`. -In the case of two dimensional interpolation, the two interpolation variables are equivalently computed as +In the case of two dimensional interpolation, the two variables are equivalently computed as `s1 = s(ia1, ib1, i1) = (i1 - ia1)/(ib1 - ia1)` + `s2 = s(ia2, ic2, i2) = (i2 - ia2)/(ic2 - ia2)` -where `ia1` and `ib1` are the first dimension indices in the target domain of the tie points `A` and `B` respectively, `ia2` and `ic2` are the second dimension indices in the target domain of the tie points `A` and `D` respectively and the indices `i1` and `i2` are the first and second dimension indices respectively in the target domain of the coordinate value to be reconstituted. +where `ia1` and `ib1` are the first dimension indices in the target domain of the tie points `A` and `B` respectively, `ia2` and `ic2` are the second dimension indices in the target domain of the tie points `A` and `C` respectively and the indices `i1` and `i2` are the first and second dimension indices respectively in the target domain of the coordinate value to be reconstituted. -For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables the interpolation method can be applied independently for each interpolation zone, making it possible to parallelize the computational process. +For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables the interpolation method can be applied independently for each interpolation subarea, making it possible to parallelize the computational process. The following notation is used: + A variable staring with `v` denotes a vector and `v.x` , `v.y` and `v.z` refer to the three coordinates of that vector. + A variable staring with `ll` denotes a latitude-longitude coordinate pair and `ll.lat` and `ll.lon` refer to the latitude and longitude coordinates. + -For one dimensional interpolation, `i` is an index in the interpolation dimension, `tp` is an index in the tie point interpolation dimension and `iz` is an index in the interpolation zone dimensions. -For two dimensional interpolation, `i1` and `i2` are indices in the interpolation dimensions, `tp1` and `tp2` are indices in the tie point interpolation dimensions and `iz1` and `iz2` are indices in the interpolation zone dimensions. + +For one dimensional interpolation, `i` is an index in the interpolated dimension, `tpi` is an index in the subsampled dimension and `iz` is an index in the interpolation subarea dimensions. +For two dimensional interpolation, `i1` and `i2` are indices in the interpolated dimensions, `tpi1` and `tpi2` are indices in the subsampled dimensions and `is1` and `is2` are indices in the interpolation subarea dimensions. + -Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refer to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. In the two dimensional case, `a = tp(tp2, tp1)`, `b = tp(tp2, tp1+1)`, `c = tp(tp2+1, tp1)` and `d = tp(tp2+1, tp1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. +Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refer to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. In the two dimensional case, `a = tp(tpi2, tpi1)`, `b = tp(tpi2, tpi1+1)`, `c = tp(tpi2+1, tpi1)` and `d = tp(tpi2+1, tpi1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. [[interpolation_methods]] === Interpolation Methods @@ -68,7 +73,7 @@ Note that, for simplicity of notation, the descriptions of the interpolation met | Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | The coordinate value `u(i)` at index `i` between tie points `A` and `B` is calculated from: + - `u(i) = fl(ua, ub, s(i)) = (1 - s)*ua + s*ub`; + + `u(i) = fl(ua, ub, s(i)) = ua + s*(ub-ua)`; + where `ua` and `ub` are the coordinate values at tie points `A` and `B` respectively. + |=============== @@ -82,7 +87,7 @@ where `ua` and `ub` are the coordinate values at tie points `A` and `B` respecti | Interpolation Parameter terms | None | Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | -The interpolation function fl() defined for linear interpolation above is first applied twice in the interpolation dimension 2, once between tie points `A` and `C` and once between tie points `B` and `D`. It is then applied once in the interpolation dimension 1, between the two resulting coordinate points, yielding the interpolated coordinate value `u(i2, i1)`: + +The interpolation function fl() defined for linear interpolation above is first applied twice in the interpolated dimension 2, once between tie points `A` and `C` and once between tie points `B` and `D`. It is then applied once in the interpolated dimension 1, between the two resulting coordinate points, yielding the interpolated coordinate value `u(i2, i1)`: + `uac = fl(ua, uc, s(ia2, ic2, i2))`; + `ubd = fl(ub, ud, s(ia2, ic2, i2))`; + `u(i2, i1) = fl(uac, ubd, s(ia1, ib1, i1))`; + @@ -98,16 +103,16 @@ The interpolation function fl() defined for linear interpolation above is first | Name | **`interpolation_name = "quadratic"`** | Description | General purpose one dimensional quadratic interpolation method for one coordinate. -| Interpolation Parameter terms | Optionally interpolation coefficient `c`, which must span the interpolation_zone dimension. +| Interpolation Parameter terms | Optionally interpolation coefficient `c`, which must span the interpolation subarea dimension. | Coordinate Compression Calculations | The expression + `c = fc(ua, ub, u(i), s(i)) = ((u - (1 - s) * ua - s * ub)/( 4 * (1 - s) * s)` + -enables the creator of the dataset to calculate `c` from the coordinate values `ua` and `ub` at tie points `A` and `B` respectively, and the coordinate value `u(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib + ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib + ia - 1)/2` shall be selected. +enables the creator of the dataset to calculate `c` from the coordinate values `ua` and `ub` at tie points `A` and `B` respectively, and the coordinate value `u(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation subarea `(ib - ia)` is an even number, then the data point at index `i = (ib + ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib + ia - 1)/2` shall be selected. | Coordinate Uncompression Calculations | The coordinate value `u(i)` at index `i` between tie points `A` and `B` is calculated from: + - `u(i) = fq(ua, ub, c, s(i)) = (1 - s) * ua + 4 * (1 - s) * s * c + s * ub`; + + `u(i) = fq(ua, ub, c, s(i)) = ua + s * (ub - ua + 4 * c * (1 - s))`; + where `ua` and `ub` are the coordinate values at tie points `A` and `B` respectively and the coefficient `c` is available as a term in the `interpolation_parameters`, or otherwise defaults to `0.0`. + |=============== @@ -119,9 +124,9 @@ where `ua` and `ub` are the coordinate values at tie points `A` and `B` respecti | Name | **`interpolation_name = "quadratic_remote_sensing"`** | Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. + -Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. +Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. For each interpolation subarea, none of the tie points defining the interpolation subarea are permitted to coincide. -By default, interpolation is performed directly in the latitude and longitude coordinates, but may be performed in cartesian coordinates where required for achieving the desired accuracy. This must be indicated by setting the `location_use_cartesian` flag within the interpolation parameter `interpolation_zone_flags` for each interpolation zone where interpolation in cartesian coordinates is required. +By default, interpolation is performed directly in the latitude and longitude coordinates, but may be performed in cartesian coordinates where required for achieving the desired accuracy. This must be indicated by setting the `location_use_cartesian` flag within the interpolation parameter `interpolation_subarea_flags` for each interpolation subarea where interpolation in cartesian coordinates is required. The quadratic interpolation coefficients `cea = (ce, ca)`, stored as interpolation parameters in the product, describe a point `P` between the tie points `A` and `B`, which is equivalent of an additional tie point in the sense that the method will accurately reconstitute the point `P` in the same way as it accurately reconstitutes the tie points `A` and `B`. See <> and <>. @@ -137,19 +142,19 @@ For interpolation in geographic coordinates latitude and longitude as the coeffi The functions `fq()` and `fc()` referenced in the following are defined in <>. -| Interpolation Parameter terms | Any subset of interpolation coefficients `ce, ca`, which must each span the interpolation_zone dimension. + -Optionally the flag variable `interpolation_zone_flags`, which must span the `interpolation_zone` dimension and must include `location_use_cartesian` in the `flag_meanings` attribute. +| Interpolation Parameter terms | Any subset of interpolation coefficients `ce, ca`, which must each span the interpolation subarea dimension. + +Optionally the flag variable `interpolation_subarea_flags`, which must span the interpolation subarea dimension and must include `location_use_cartesian` in the `flag_meanings` attribute. | Coordinate Compression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb);` + -Then calculate the cartesian representation of the interpolation coefficients from the tie points `va` and `vb` as well as the point `vp(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation zone `(ib - ia)` is an even number, then the data point at index `i = (ib + ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib + ia - 1)/2` shall be selected. + +Then calculate the cartesian representation of the interpolation coefficients from the tie points `va` and `vb` as well as the point `vp(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation subarea `(ib - ia)` is an even number, then the data point at index `i = (ib + ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib + ia - 1)/2` shall be selected. + The cartesian interpolation coefficients are found from + `cv = fcv(va, vb, vp(i), s(i)) = (fc(va.x, vb.x, vp(i).x, s(i)), fc(va.y, vb.y, vp(i).y, s(i)), fc(va.z, vb.z, vp(i).z, s(i))).` + Finally, for storage in the dataset, convert the coefficients to the parametric representation + `cea(iz) = (ce(iz), ca(iz)) = fcv2cea(va, vb, cv) = (fdot(cv, fminus(va, vb))/ gsqr), fdot(cv, fcross(va, vb))/(rsqr*gsqr));` + where `vr = fmultiply(0.5, fplus(va, vb))`, `rsqr = fdot(vr, vr)`, `vg = fminus(va, vb)` and `gsqr = fdot(vg, vg).` + -The interpolation parameter term `interpolation_zone_flags(iz)` shall have the flag `location_use_cartesian` set if the interpolation zone intersects the `longitude = 180.0` or if the interpolation zone extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. +The interpolation parameter term `interpolation_subarea_flags(iz)` shall have the flag `location_use_cartesian` set if the interpolation subarea intersects the `longitude = 180.0` or if the interpolation subarea extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb);` + @@ -159,7 +164,7 @@ where + `vr = fmultiply(0.5, fplus(va, vb))`; + `rsqr = fdot(vr, vr);` + `cr = fsqrt(1 - ce(iz)*ce(iz) - ca(iz)*ca(iz)) - fsqrt(rsqr).` + -If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_zone_flags(iz2, iz1)` is set, use the following expression to reconstitute any point `llp(i)` between the tie points `A` and `B` using interpolation in cartesian coordinates + +If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_subarea_flags(is2, is1)` is set, use the following expression to reconstitute any point `llp(i)` between the tie points `A` and `B` using interpolation in cartesian coordinates + `vp(i) = fqv(va, vb, cv, s(i)) = (fq(va.x, vb.x, cv.x, s(i)), fq(va.y, vb.y, cv.y, s(i)), fq(va.z, vb.z, cv.z, s(i)));` + `llp(i) = fv2ll(vp(i)).` + Otherwise, first calculate latitude-longitude representation of the interpolation coefficients + @@ -188,25 +193,25 @@ image::images/ci_quadratic2.svg[,100%,pdfwidth=50vw,align="center"] | Name | **`interpolation_name = "bi_quadratic_remote_sensing"`** | Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. -Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. +Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. For each interpolation subarea, none of the tie points defining the interpolation subarea are permitted to coincide. The functions `fcv()`, `fcv2cea()`, `fcea2cv()`, `fcll()`, `fqv()` and `fqll()` referenced in the following are defined in <>. As for that method, interpolation is performed directly in the latitude and longitude coordinates or in cartesian coordinates, where required for achieving the desired accuracy. Similarly, it shares the three different representations of the quadratic interpolation coefficients, the parametric representation `cea = (ce, ca)` for storage in the dataset, `cll = (cll.lat, cll.lon)` for interpolation in geographic coordinates latitude and longitude and `cv = (cv.x, cv.y, cv.z)` for interpolation in cartesian coordinates. -The parametric representation of the interpolation coefficients, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation zone as shown in <>, which also shows the orientation and indices of the parameters. +The parametric representation of the interpolation coefficients, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation subarea as shown in <>, which also shows the orientation and indices of the parameters. | Interpolation Parameter terms | -Any subset of interpolation coefficients `ce1, ca1`, which must each span the `tie_point_interpolation_2` and `interpolation_zone_1` dimensions; + -Any subset of interpolation coefficients `ce2, ca2`, which must each span the `interpolation_zone_2` and `tie_point_interpolation_1` dimensions; + -Any subset of interpolation coefficients `ce3, ca3`, which must each span the `interpolation_zone_2` and `interpolation_zone_1` dimensions; + +Any subset of interpolation coefficients `ce1, ca1`, which must each span the subsampled dimension 2 and interpolation subarea dimension 1; + +Any subset of interpolation coefficients `ce2, ca2`, which must each span the interpolation subarea dimension 2 and subsampled dimension 1; + +Any subset of interpolation coefficients `ce3, ca3`, which must each span the interpolation subarea dimension 2 and interpolation subarea dimension 1; + -Optionally the flag variable `interpolation_zone_flags`, which must span the `interpolation_zone_2` and `interpolation_zone_1` dimensions and must include `location_use_cartesian` in the `flag_meanings` attribute. +Optionally the flag variable `interpolation_subarea_flags`, which must span the interpolation subarea dimension 2 and interpolation subarea dimension 1 and must include `location_use_cartesian` in the `flag_meanings` attribute. | Coordinate Compression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb); vc = fll2v(llc); vd = fll2v(lld).` + -Then calculate the cartesian representation of the interpolation coefficients sets from the tie points as well as a point `vp(i2, i1)` between the tie points. If the size of the interpolation zone in the first dimension `(ib1 - ia1)` is an even number, then the index +Then calculate the cartesian representation of the interpolation coefficients sets from the tie points as well as a point `vp(i2, i1)` between the tie points. If the size of the interpolation subarea in the first dimension `(ib1 - ia1)` is an even number, then the index `i1 = (ib1 + ia1)/2` shall be selected for this calculation, otherwise the index -`i1 = (ib1 + ia1 - 1)/2` shall be selected. If the size of the interpolation zone in the second dimension `(ib2 - ic2)` is an even number, then the index `i2 = (ib2 + ic2)/2` shall be selected for this calculation, otherwise the index `i2 = (ib2 + ic2 - 1)/2` shall be selected. + +`i1 = (ib1 + ia1 - 1)/2` shall be selected. If the size of the interpolation subarea in the second dimension `(ib2 - ic2)` is an even number, then the index `i2 = (ib2 + ic2)/2` shall be selected for this calculation, otherwise the index `i2 = (ib2 + ic2 - 1)/2` shall be selected. + Using the selected `(i2, i1)`, the cartesian interpolation coefficients are found from + `s1 = s(ia1, ib1, i1);` `s2 = s(ia2, ic2, i2);` + @@ -222,22 +227,22 @@ Using the selected `(i2, i1)`, the cartesian interpolation coefficients are foun `vcd = fqv(vc, vd, cv_cd, 0.5);` + `cv_z = fcv(vab, vcd, vz, s2);` + Finally, before storing them in the dataset's interpolation parameters, convert the coefficients to the parametric representation + -`cea1(tp2, iz1) = fcv2cea( va, vb, cv_ab);` + -`cea1(tp2+1, iz1) = fcv2cea( vc, vd, cv_cd);` + -`cea2(iz2, tp1) = fcv2cea( va, vc, cv_ac);` + -`cea2(iz2, tp1+1) = fcv2cea( vb, vd, cv_bd);` + -`cea3(iz2, iz1) = fcv2cea( vab, vcd, cv_z).` + -The interpolation parameter term `interpolation_zone_flags(iz2, iz1)` shall have the flag `location_use_cartesian` set if the interpolation zone intersects the `longitude = 180.0` or if the interpolation zone extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. +`cea1(tpi2, is1) = fcv2cea( va, vb, cv_ab);` + +`cea1(tpi2+1, is1) = fcv2cea( vc, vd, cv_cd);` + +`cea2(is2, tpi1) = fcv2cea( va, vc, cv_ac);` + +`cea2(is2, tpi1+1) = fcv2cea( vb, vd, cv_bd);` + +`cea3(is2, is1) = fcv2cea( vab, vcd, cv_z).` + +The interpolation parameter term `interpolation_subarea_flags(is2, is1)` shall have the flag `location_use_cartesian` set if the interpolation subarea intersects the `longitude = 180.0` or if the interpolation subarea extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb); vc = fll2v(llc); vd = fll2v(lld).` + Then calculate the cartesian representation of the interpolation coefficient sets from the parametric representation stored in the dataset + -`cv_ac = fcea2cv(va, vc, cea2(iz2, tp1));` + -`cv_bd = fcea2cv(vb, vd, cea2(iz2, tp1 + 1));` + -`vab = fqv(va, vb, fcea2cv(va, vb, cea1(tp2, iz1)), 0.5);` + -`vcd = fqv(vc, vd, fcea2cv(vc, vd, cea1(tp2 + 1, iz1)), 0.5);` + -`cv_z = fcea2cv(vab, vcd, cea3(iz2, iz1));` + -If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_zone_flags` is set, use the following expression to reconstitute any point `llp(i2, i1)` between the tie points `A` and `B` using interpolation in cartesian coordinates + +`cv_ac = fcea2cv(va, vc, cea2(is2, tpi1));` + +`cv_bd = fcea2cv(vb, vd, cea2(is2, tpi1 + 1));` + +`vab = fqv(va, vb, fcea2cv(va, vb, cea1(tpi2, is1)), 0.5);` + +`vcd = fqv(vc, vd, fcea2cv(vc, vd, cea1(tpi2 + 1, is1)), 0.5);` + +`cv_z = fcea2cv(vab, vcd, cea3(is2, is1));` + +If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_subarea_flags` is set, use the following expression to reconstitute any point `llp(i2, i1)` between the tie points `A` and `B` using interpolation in cartesian coordinates + `llp(i2, i1) = fv2ll(fqv(vac, vbd, cv_zz, s(ia1, ib1, i1)));` + where + `s2 = s(ia2, ic2, i2);` + @@ -251,7 +256,7 @@ Otherwise, first calculate latitude-longitude representation of the interpolatio `llab = fv2ll(vab);` + `llcd = fv2ll(vcd);` + `llc_z = fcll(llab, llcd, fv2ll(fqv(vab, vcd, cv_z, 0.5)), 0.5);` + -Then use the following expression to reconstitute any point `llp(i2, i1)` in the tie point zone using interpolation in latitude-longitude coordinates + +Then use the following expression to reconstitute any point `llp(i2, i1)` in the interpolation subarea using interpolation in latitude-longitude coordinates + `llp(i2, i1) = fqll(llac, llbd, cl_zz, s(ia1, ib1, i1));` + where + `s2 = s(ia2, ic2, i2);` + @@ -263,7 +268,7 @@ where + [[quadratic3, figure 4]] [.text-center] -.The parametric representation of the interpolation coefficients `cea = (ce, ca)`, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation zone. Shown with parameter orientation and indices. +.The parametric representation of the interpolation coefficients `cea = (ce, ca)`, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation subarea. Shown with parameter orientation and indices. image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] @@ -304,7 +309,7 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] [[coordinate_compression_steps]] === Coordinate Compression Steps -[[compression-by-coordinate-sampling-generation-of-tie-points]] +[[compression-by-coordinate-subsampling-generation-of-tie-points]] .Generation of Tie Point Variables and Interpolation Variables [options="header",cols="1,16,6",caption="Table J.1. "] |=============== @@ -316,91 +321,103 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] | 2 | Identify non-overlapping subsets of the coordinate variables to be interpolated by the same interpolation method. For each coordinate variable subset, create an interpolation variable and specify the selected interpolation method using the **`interpolation_name`** attribute of the interpolation variable. -| <> +| <> | 3 -| For each coordinate variable subset, add the coordinates variable subset and the corresponding interpolation variable to the the **`tie_points`** attribute of the data variable. -| <> +| For each coordinate variable subset, add the coordinates variable subset and the corresponding interpolation variable name to the the **`coordinate_interpolation`** attribute of the data variable. +| <> | 4 -| For each coordinate variable subset, identify the set of interpolation dimensions and the set of non-interpolation dimensions. -| <> +| For each coordinate variable subset, identify the set of interpolated dimensions and the set of non-interpolated dimensions. +| <> | 5 -| For each set of the interpolation dimensions, identify the interpolation areas and select the interpolation zones and the tie points, taking into account the required coordinate reconstitution accuracy when selecting the density of tie points. -| <> +| For each set of the interpolated dimensions, identify the continuous areas and select the interpolation subareas and the tie points, taking into account the required coordinate reconstitution accuracy when selecting the density of tie points. +| <> | 6 -| For each of the interpolation dimensions, add the interpolation dimension, the corresponding tie point interpolation dimension and, if required by the selected interpolation method, its corresponding interpolation zone dimension to the **`tie_point_dimensions`** attribute of the interpolation variable. -| <> +| For each of the interpolated dimension, add the interpolated dimension, the corresponding subsampled dimension and, if required by the selected interpolation method, its corresponding interpolation subarea dimension to the **`tie_point_mapping`** attribute of the interpolation variable. +| <> + +<> | 7 -| For each of the interpolation dimensions, record the location of each identified tie point in a tie point index variable. For each interpolation dimension, add the interpolation dimension and its tie point index variable to the **`tie_point_indices`** attribute of the interpolation variable. -| <> +| For each of the interpolated dimension, record the location of each identified tie point in a tie point index variable. For each interpolated dimension, add the tie point index variable name to the **`tie_point_mapping`** attribute of the interpolation variable. +| <> + +<> | 8 -| For each of the target coordinate and auxillary coordinate variables, create the corresponding tie point coordinate variable and copy the coordinate values from the target domain coordinate variables to the tie point variables for the target domain indices identified by the tie point index variable. Repeat this step for each combination of indices of the non-interpolation dimensions. -| <> +| For each of the target coordinate and auxillary coordinate variables, create the corresponding tie point coordinate variable and copy the coordinate values from the target domain coordinate variables to the tie point variables for the target domain indices identified by the tie point index variable. Repeat this step for each combination of indices of the non-interpolated dimensions. +| <> + +<> | 9 -| For each of the target coordinate and auxillary coordinate variable having a **`bounds`** attribute, add the **`bounds`** attribute to the tie point coordinate variable, create the tie point bounds variable and copy the bounds values from the target domain bounds variable to the tie point bounds variable for the target domain indices identified by the tie point index variable. Repeat this step for each combination of indices of the non-interpolation dimensions. -| <> +| For each of the target coordinate and auxillary coordinate variable having a **`bounds`** attribute, add the **`bounds_tie_points`** attribute to the tie point coordinate variable and create the bounds tie point variable. For each continuous area, copy the selected set of bounds tie points values from the target domain bounds variable to the bounds tie point variable for the target domain indices identified by the tie point index variable. Repeat this step for each combination of indices of the non-interpolated dimensions. +| <> | 10 -| Finally, if required by the selected interpolation method, follow the steps defined for the method in <> to create any required interpolation parameter variables. As relevant, create the **`interpolation_parameters`** attribute and populate it with the interpolation parameter variables. -| <> + +| If required by the selected interpolation method, follow the steps defined for the method in <> to create any required interpolation parameter variables. As relevant, create the **`interpolation_parameters`** attribute and populate it with the interpolation parameter variables. +| <> + <> +| 1 +| Optionally, check the consistency of the original coordinates and the reconstructed coordinates and add a **`comments`** attribute to one or more of the tie point coordinate variables reporting key figures like maximum error, mean error, etc. +| + + |=============== [[coordinate_uncompression_steps]] === Coordinate Uncompression Steps -[[compression-by-coordinate-sampling-reconstitution-of-coordinates]] +[[compression-by-coordinate-subsampling-reconstitution-of-coordinates]] .Reconstitution of Coordinate and Auxillary Coordinate Variables [options="header",cols="1,16,6",caption="Table J.2. "] |=============== | Step | Description | Link | 1 -| From the **`tie_points`** attribute of the data variable, identify the coordinate and auxillary coordinate variable subsets, for which tie point interpolation is required, and the interpolation variable corresponding to each subset. -| <> +| From the **`coordinate_interpolation`** attribute of the data variable, identify the coordinate and auxillary coordinate variable subsets, for which tie point interpolation is required, and the interpolation variable corresponding to each subset. +| <> | 2 | For each coordinate variable subset, identify the interpolation method from the **`interpolation_name`** attribute of the interpolation variable. -| <> +| <> | 3 -| For each coordinate variable subset, identify the set of interpolation dimensions and the set of non-interpolation dimensions from the **`tie_point_dimensions`** attribute of the interpolation variable. -| <> <> +| For each coordinate variable subset, identify the set of interpolated dimensions and the set of non-interpolated dimensions from the **`tie_point_mapping`** attribute of the interpolation variable. +| <> + +<> + | 4 -| From the **`tie_point_dimensions`** attribute of the interpolation variable, identify for each of the interpolation dimensions the corresponding tie point interpolation dimension and, if defined, the corresponding interpolation zone dimension. -| <> +| From the **`tie_point_mapping`** attribute of the interpolation variable, identify for each of the interpolated dimensions the corresponding subsampled dimension and, if defined, the corresponding interpolation subarea dimension.| <> + +<> + | 5 -| From the tie point index variables referenced in the **`tie_point_indices`** attribute of the interpolation variable, identify the location of the tie points in the corresponding interpolation dimension. -| <> +| From the tie point index variables referenced in the **`tie_point_mapping`** attribute of the interpolation variable, identify the location of the tie points in the corresponding interpolated dimension. +| <> + +<> | 6 -| For each of the interpolation dimensions, identify pairs of adjacent indices in the tie point index variable with index values differing by more than one, each index pair defining the extend of an interpolation zone in that dimension. A full interpolation zone is defined by one such index pair per interpolation dimension, with combinations of one index from each pair defining the interpolation zone tie points. -| <> +| For each of the interpolated dimension, identify pairs of adjacent indices in the tie point index variable with index values differing by more than one, each index pair defining the extend of an interpolation subarea in that dimension. A full interpolation subarea is defined by one such index pair per interpolated dimension, with combinations of one index from each pair defining the interpolation subarea tie points. +| <> | 7 | As required by the selected interpolation method, identify the interpolation parameter variables from the interpolation variable attribute **`interpolation_parameters`**. -| <> +| <> | 8 -| For each of the tie point coordinate and auxillary coordinate variables, create the corresponding target coordinate variable. For each interpolation zone, apply the interpolation method, as described in <>, to reconstitute the target domain coordinate values and store these in the target domain coordinate variables. Repeat this step for each combination of indices of the non-interpolation dimensions. -| <> + +| For each of the tie point coordinate and auxillary coordinate variables, create the corresponding target coordinate variable. For each interpolation subarea, apply the interpolation method, as described in <>, to reconstitute the target domain coordinate values and store these in the target domain coordinate variables. Repeat this step for each combination of indices of the non-interpolated dimensions. +| <> + <> | 9 -| For each of the tie point coordinate and auxillary coordinate variables having a **`bounds`** attribute, add the **`bounds`** attribute to the target coordinate variable and create the target domain bounds variable. For each interpolation zone, apply the interpolation method to reconstitute the target domain bound values and store these in the target domain bound variables. Repeat this step for each combination of indices of the non-interpolation dimensions. -| <> +| For each of the tie point coordinate and auxillary coordinate variables having a **`bounds_tie_points`** attribute, add the **`bounds`** attribute to the target coordinate variable and create the target domain bounds variable. For each interpolation subarea, apply the interpolation method to reconstitute the target domain bound values and store these in the target domain bound variables. Repeat this step for each combination of indices of the non-interpolated dimensions. +| <> | 10 | If auxiliary coordinate variables have been reconstituted, then, if not already present, add a **`coordinates`** attribute to the data variable and add to the attribute the list of the names of the reconstituted auxiliary coordinate variables. diff --git a/images/ci_1d_interpolation_subarea.svg b/images/ci_1d_interpolation_subarea.svg new file mode 100644 index 00000000..f3d88567 --- /dev/null +++ b/images/ci_1d_interpolation_subarea.svg @@ -0,0 +1 @@ +ABAB0.0……1.0s0.0……1.0sibiaiibiaiInterpolated DimensionuaubuuaubuCoordinate valuetpi1+1tpi1tpi1+1tpi1Subsampled Dimension(0)(1)Interpolation Subarea (0) including Tie Pont A Interpolation Subarea (1) excluding Tie Pont A \ No newline at end of file diff --git a/images/ci_2d_interpolation_subarea.svg b/images/ci_2d_interpolation_subarea.svg new file mode 100644 index 00000000..b6f2012f --- /dev/null +++ b/images/ci_2d_interpolation_subarea.svg @@ -0,0 +1 @@ +uaADCB...01.0...s20.0……1.0s1uia1id2ia2i2uducucdtpi1tpi2+1tpi2Interpolated DimensionCoordinate valueSubsampled Dimensionubib1tpi1+1i1uab \ No newline at end of file diff --git a/images/ci_interpolation.svg b/images/ci_interpolation.svg deleted file mode 100644 index 3eb4dc19..00000000 --- a/images/ci_interpolation.svg +++ /dev/null @@ -1 +0,0 @@ -ubuaAB0.0……1.0suaubACDB...01.0...s20.0……1.0s1ibiaiuuib1ia1i1id2ia2i2ucududcuabtp1+1tp1tp2+1tp2tp1+1tp1 \ No newline at end of file From a285b42869c278d948ec387a47e74e64e4ed07f4 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 21 Jul 2021 23:26:08 +0200 Subject: [PATCH 217/249] Correct spelling mistake in Appendix J --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 4d4e4691..d6e995ee 100644 --- a/appj.adoc +++ b/appj.adoc @@ -16,7 +16,7 @@ The appendix is organised in a sections on <>, The target domain is segmented into smaller interpolation subareas as described in <>. -For one-dimensional interpolation, an interpolation subarea is defined by two tie points, one at each end of the interpolation subarea. However, the tie points may be inside or outside the interpolation subareas as shownb in <>. When interpolation methods are applied for a given interpolation subarea, it must be ensured that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. See also description in <>. +For one-dimensional interpolation, an interpolation subarea is defined by two tie points, one at each end of the interpolation subarea. However, the tie points may be inside or outside the interpolation subareas as shown in <>. When interpolation methods are applied for a given interpolation subarea, it must be ensured that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. See also description in <>. [[interpolation_subareas_1d, Figure 1]] [.text-center] From ecdaf926c5b6ba87045d47f5dabffe25715429c8 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 21 Jul 2021 23:27:44 +0200 Subject: [PATCH 218/249] Correct numbering mistake in Appendix J --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index d6e995ee..260dcecd 100644 --- a/appj.adoc +++ b/appj.adoc @@ -360,7 +360,7 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] | <> + <> -| 1 +| 11 | Optionally, check the consistency of the original coordinates and the reconstructed coordinates and add a **`comments`** attribute to one or more of the tie point coordinate variables reporting key figures like maximum error, mean error, etc. | From d033feeb798aa4c63e3d0d8ce04d27809dde2d0f Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Thu, 22 Jul 2021 10:08:06 +0200 Subject: [PATCH 219/249] Change "iz" (interpolation zone) to "is" (interpolation subarea) in App J (Change 3) --- appj.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/appj.adoc b/appj.adoc index 260dcecd..abfd3fc7 100644 --- a/appj.adoc +++ b/appj.adoc @@ -55,7 +55,7 @@ For the reconstitution of the uncompressed coordinate and auxiliary coordinate v The following notation is used: + A variable staring with `v` denotes a vector and `v.x` , `v.y` and `v.z` refer to the three coordinates of that vector. + A variable staring with `ll` denotes a latitude-longitude coordinate pair and `ll.lat` and `ll.lon` refer to the latitude and longitude coordinates. + -For one dimensional interpolation, `i` is an index in the interpolated dimension, `tpi` is an index in the subsampled dimension and `iz` is an index in the interpolation subarea dimensions. +For one dimensional interpolation, `i` is an index in the interpolated dimension, `tpi` is an index in the subsampled dimension and `is` is an index in the interpolation subarea dimensions. For two dimensional interpolation, `i1` and `i2` are indices in the interpolated dimensions, `tpi1` and `tpi2` are indices in the subsampled dimensions and `is1` and `is2` are indices in the interpolation subarea dimensions. + Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refer to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. In the two dimensional case, `a = tp(tpi2, tpi1)`, `b = tp(tpi2, tpi1+1)`, `c = tp(tpi2+1, tpi1)` and `d = tp(tpi2+1, tpi1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. @@ -152,18 +152,18 @@ Then calculate the cartesian representation of the interpolation coefficients fr The cartesian interpolation coefficients are found from + `cv = fcv(va, vb, vp(i), s(i)) = (fc(va.x, vb.x, vp(i).x, s(i)), fc(va.y, vb.y, vp(i).y, s(i)), fc(va.z, vb.z, vp(i).z, s(i))).` + Finally, for storage in the dataset, convert the coefficients to the parametric representation + -`cea(iz) = (ce(iz), ca(iz)) = fcv2cea(va, vb, cv) = (fdot(cv, fminus(va, vb))/ gsqr), fdot(cv, fcross(va, vb))/(rsqr*gsqr));` + +`cea(is) = (ce(is), ca(is)) = fcv2cea(va, vb, cv) = (fdot(cv, fminus(va, vb))/ gsqr), fdot(cv, fcross(va, vb))/(rsqr*gsqr));` + where `vr = fmultiply(0.5, fplus(va, vb))`, `rsqr = fdot(vr, vr)`, `vg = fminus(va, vb)` and `gsqr = fdot(vg, vg).` + -The interpolation parameter term `interpolation_subarea_flags(iz)` shall have the flag `location_use_cartesian` set if the interpolation subarea intersects the `longitude = 180.0` or if the interpolation subarea extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. +The interpolation parameter term `interpolation_subarea_flags(is)` shall have the flag `location_use_cartesian` set if the interpolation subarea intersects the `longitude = 180.0` or if the interpolation subarea extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb);` + Then calculate the cartesian representation of the interpolation coefficients from the parametric representation stored in the dataset using + -`cv = fcea2cv(va, vb, cea(iz)) = fplus(fmultiply(ce, fminus(va, vb)), fmultiply(ca, fcross(va, vb)), fmultiply(cr, vr));` + +`cv = fcea2cv(va, vb, cea(is)) = fplus(fmultiply(ce, fminus(va, vb)), fmultiply(ca, fcross(va, vb)), fmultiply(cr, vr));` + where + `vr = fmultiply(0.5, fplus(va, vb))`; + `rsqr = fdot(vr, vr);` + -`cr = fsqrt(1 - ce(iz)*ce(iz) - ca(iz)*ca(iz)) - fsqrt(rsqr).` + +`cr = fsqrt(1 - ce(is)*ce(is) - ca(is)*ca(is)) - fsqrt(rsqr).` + If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_subarea_flags(is2, is1)` is set, use the following expression to reconstitute any point `llp(i)` between the tie points `A` and `B` using interpolation in cartesian coordinates + `vp(i) = fqv(va, vb, cv, s(i)) = (fq(va.x, vb.x, cv.x, s(i)), fq(va.y, vb.y, cv.y, s(i)), fq(va.z, vb.z, cv.z, s(i)));` + `llp(i) = fv2ll(vp(i)).` + From ca816180507dee3cd7633836e85c64f3356b514b Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 23 Jul 2021 16:34:08 +0200 Subject: [PATCH 220/249] Correct "target dimension" to "interpolated dimension" (Change 17) --- ch08.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index 52f7556a..893ac9cd 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -245,9 +245,9 @@ the 10 indices of the `yc` non-interpolated dimension. ==== Tie Point Mapping Attribute The **`tie_point_mapping`** attribute provides mapping at two levels. It associates -subsampled dimensions with the corresponding target dimensions, and for each +interpolated dimensions with the corresponding subsampled dimensions, and for each of these sets of corresponding dimensions, it associates index values -of the subsampled dimension with index values of the target dimension, thereby +of the interpolated dimension with index values of the subsampled dimension, thereby uniquely associating the tie points with their corresponding location in the target domain. From f6f48fbea3b4780cb439a00dced0ee770592418f Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 23 Jul 2021 17:04:05 +0200 Subject: [PATCH 221/249] Introduce section numbering and remove table captions in Appendix J --- appj.adoc | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/appj.adoc b/appj.adoc index abfd3fc7..5f8a5993 100644 --- a/appj.adoc +++ b/appj.adoc @@ -9,9 +9,9 @@ The definitions and guidance given here allow an application to compress an exis Futhermore, the definitions given here allow an application to uncompress coordinate and auxiliary coordinate variables that have been compressed using coordinate subsampling. The key element of this process is the reconstitution of the full resolution coordinates in the domain of the data by interpolation between the subsampled coordinates, the tie points, stored in the compressed dataset. -The appendix is organised in a sections on <>, <>, <> and finally two sections with step procedures <> and <>. +The appendix is organised in a sections on <>, <>, <> and finally two sections with step procedures <> and <>. -[[common_definitions_and_notation]] +[[common-definitions-and-notation, Section J.1, "Common Definitions and Notation"]] === Common Definitions and Notation The target domain is segmented into smaller interpolation subareas as described in <>. @@ -60,7 +60,7 @@ For two dimensional interpolation, `i1` and `i2` are indices in the interpolated Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refer to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. In the two dimensional case, `a = tp(tpi2, tpi1)`, `b = tp(tpi2, tpi1+1)`, `c = tp(tpi2+1, tpi1)` and `d = tp(tpi2+1, tpi1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. -[[interpolation_methods]] +[[interpolation-methods, Section J.2, "Interpolation Methods"]] === Interpolation Methods ==== Linear Interpolation @@ -272,8 +272,8 @@ where + image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] -[[common_conversions_and_formulas]] -==== Common conversions and formulas +[[common-conversions-and-formulas, Section J.3, "Common Conversions and Formulas"]] +==== Common Conversions and Formulas [cols="1, 8, 8"] |=============== @@ -305,13 +305,9 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] |=============== - -[[coordinate_compression_steps]] +[[coordinate-compression-steps, Section J.4, "Coordinate Compression Steps"]] === Coordinate Compression Steps -[[compression-by-coordinate-subsampling-generation-of-tie-points]] -.Generation of Tie Point Variables and Interpolation Variables -[options="header",cols="1,16,6",caption="Table J.1. "] |=============== | Step | Description | Link @@ -356,9 +352,9 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] | <> | 10 -| If required by the selected interpolation method, follow the steps defined for the method in <> to create any required interpolation parameter variables. As relevant, create the **`interpolation_parameters`** attribute and populate it with the interpolation parameter variables. +| If required by the selected interpolation method, follow the steps defined for the method in <> to create any required interpolation parameter variables. As relevant, create the **`interpolation_parameters`** attribute and populate it with the interpolation parameter variables. | <> + -<> +<> | 11 | Optionally, check the consistency of the original coordinates and the reconstructed coordinates and add a **`comments`** attribute to one or more of the tie point coordinate variables reporting key figures like maximum error, mean error, etc. @@ -367,13 +363,9 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] |=============== -[[coordinate_uncompression_steps]] +[[coordinate-uncompression-steps, Section J.5, "Coordinate Uncompression Steps"]] === Coordinate Uncompression Steps - -[[compression-by-coordinate-subsampling-reconstitution-of-coordinates]] -.Reconstitution of Coordinate and Auxillary Coordinate Variables -[options="header",cols="1,16,6",caption="Table J.2. "] |=============== | Step | Description | Link @@ -411,9 +403,9 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] | <> | 8 -| For each of the tie point coordinate and auxillary coordinate variables, create the corresponding target coordinate variable. For each interpolation subarea, apply the interpolation method, as described in <>, to reconstitute the target domain coordinate values and store these in the target domain coordinate variables. Repeat this step for each combination of indices of the non-interpolated dimensions. +| For each of the tie point coordinate and auxillary coordinate variables, create the corresponding target coordinate variable. For each interpolation subarea, apply the interpolation method, as described in <>, to reconstitute the target domain coordinate values and store these in the target domain coordinate variables. Repeat this step for each combination of indices of the non-interpolated dimensions. | <> + -<> +<> | 9 | For each of the tie point coordinate and auxillary coordinate variables having a **`bounds_tie_points`** attribute, add the **`bounds`** attribute to the target coordinate variable and create the target domain bounds variable. For each interpolation subarea, apply the interpolation method to reconstitute the target domain bound values and store these in the target domain bound variables. Repeat this step for each combination of indices of the non-interpolated dimensions. From 1002806c944e105644cdc6afc35128738ac676c0 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 23 Jul 2021 17:24:23 +0200 Subject: [PATCH 222/249] Include interpolation argument s in figure 1 and 2 --- appj.adoc | 4 ++-- images/ci_1d_interpolation_subarea.svg | 2 +- images/ci_2d_interpolation_subarea.svg | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/appj.adoc b/appj.adoc index 5f8a5993..8bc5eb58 100644 --- a/appj.adoc +++ b/appj.adoc @@ -35,7 +35,7 @@ The coordinate interpolation methods are named to indicate the number of dimensi When an interpolation method is referred to as linear or quadratic, it means that the method is linear or quadratic in the indices of the interpolated dimensions. -For convenience, a variable `s` is introduced, calculated as a function of the index in the target domain of the coordinate value to be reconstituted. In the case of one dimensional interpolation the variable is computed as +For convenience, an interpolation argument `s` is introduced, calculated as a function of the index in the target domain of the coordinate value to be reconstituted. In the case of one dimensional interpolation the variable is computed as `s = s(ia, ib, i) = (i - ia)/(ib - ia)` @@ -43,7 +43,7 @@ where `ia` and `ib` are the indices in the target domain of the tie points `A` a Note that the value of `s` varies from `0.0` at the tie point `A` to `1.0` at tie point `B`. For example, if `ia = 100` and `ib = 110` and the index in the target domain of the coordinate value to be reconstituted is `i = 105`, then `s = (105 - 100)/(110 - 100) = 0.5`. -In the case of two dimensional interpolation, the two variables are equivalently computed as +In the case of two dimensional interpolation, the interpolation arguments are equivalently computed as `s1 = s(ia1, ib1, i1) = (i1 - ia1)/(ib1 - ia1)` + `s2 = s(ia2, ic2, i2) = (i2 - ia2)/(ic2 - ia2)` diff --git a/images/ci_1d_interpolation_subarea.svg b/images/ci_1d_interpolation_subarea.svg index f3d88567..0a38d0fc 100644 --- a/images/ci_1d_interpolation_subarea.svg +++ b/images/ci_1d_interpolation_subarea.svg @@ -1 +1 @@ -ABAB0.0……1.0s0.0……1.0sibiaiibiaiInterpolated DimensionuaubuuaubuCoordinate valuetpi1+1tpi1tpi1+1tpi1Subsampled Dimension(0)(1)Interpolation Subarea (0) including Tie Pont A Interpolation Subarea (1) excluding Tie Pont A \ No newline at end of file +ABAB0.0……1.0s0.0……1.0sibiaiibiaiInterpolated DimensionuaubuuaubuCoordinate valuetpi1+1tpi1tpi1+1tpi1Subsampled Dimension(0)(1)Interpolation Subarea (0) including Tie Pont A Interpolation Subarea (1) excluding Tie Pont A Interpolation argument \ No newline at end of file diff --git a/images/ci_2d_interpolation_subarea.svg b/images/ci_2d_interpolation_subarea.svg index b6f2012f..27708dc6 100644 --- a/images/ci_2d_interpolation_subarea.svg +++ b/images/ci_2d_interpolation_subarea.svg @@ -1 +1 @@ -uaADCB...01.0...s20.0……1.0s1uia1id2ia2i2uducucdtpi1tpi2+1tpi2Interpolated DimensionCoordinate valueSubsampled Dimensionubib1tpi1+1i1uab \ No newline at end of file +uaADCB...01.0...s20.0……1.0s1uia1id2ia2i2uducucdtpi1tpi2+1tpi2Interpolated DimensionCoordinate valueSubsampled Dimensionubib1tpi1+1i1uabInterpolation argument \ No newline at end of file From 0fdc7e448cb9798814c40c0b490ab8df35b7fc3e Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 23 Jul 2021 17:31:57 +0200 Subject: [PATCH 223/249] Move Figure 1 and 2 in Appendix J futher down --- appj.adoc | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/appj.adoc b/appj.adoc index 8bc5eb58..3b7539f7 100644 --- a/appj.adoc +++ b/appj.adoc @@ -14,23 +14,6 @@ The appendix is organised in a sections on <>, [[common-definitions-and-notation, Section J.1, "Common Definitions and Notation"]] === Common Definitions and Notation -The target domain is segmented into smaller interpolation subareas as described in <>. - -For one-dimensional interpolation, an interpolation subarea is defined by two tie points, one at each end of the interpolation subarea. However, the tie points may be inside or outside the interpolation subareas as shown in <>. When interpolation methods are applied for a given interpolation subarea, it must be ensured that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. See also description in <>. - -[[interpolation_subareas_1d, Figure 1]] -[.text-center] -.One-dimensional interpolation subareas, one including and one excluding tie point A. -image::images/ci_1d_interpolation_subarea.svg[,100%,pdfwidth=50vw,align="center"] - -For two-dimensional interpolation, an interpolation subarea is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes, see <>. - -[[interpolation_subarea_2d, Figure 2]] -[.text-center] -.Two-dimensional interpolation subarea. -image::images/ci_2d_interpolation_subarea.svg[,60%,pdfwidth=50vw,align="center"] - - The coordinate interpolation methods are named to indicate the number of dimensions they interpolate as well as the type of interpolation provided. For example, the interpolation method named `linear` provides linear interpolation in one dimension and the method named `bi_linear` provides linear interpolation in two dimensions. Equivalently, the interpolation method named `quadratic` provides quadratic interpolation in one dimension and the interpolation method named `bi_quadratic` provides quadratic interpolation in two dimensions. When an interpolation method is referred to as linear or quadratic, it means that the method is linear or quadratic in the indices of the interpolated dimensions. @@ -50,6 +33,22 @@ In the case of two dimensional interpolation, the interpolation arguments are eq where `ia1` and `ib1` are the first dimension indices in the target domain of the tie points `A` and `B` respectively, `ia2` and `ic2` are the second dimension indices in the target domain of the tie points `A` and `C` respectively and the indices `i1` and `i2` are the first and second dimension indices respectively in the target domain of the coordinate value to be reconstituted. +The target domain is segmented into smaller interpolation subareas as described in <>. + +For one-dimensional interpolation, an interpolation subarea is defined by two tie points, one at each end of the interpolation subarea. However, the tie points may be inside or outside the interpolation subareas as shown in <>. When interpolation methods are applied for a given interpolation subarea, it must be ensured that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. See also description in <>. + +[[interpolation_subareas_1d, Figure 1]] +[.text-center] +.One-dimensional interpolation subareas, one including and one excluding tie point A. +image::images/ci_1d_interpolation_subarea.svg[,100%,pdfwidth=50vw,align="center"] + +For two-dimensional interpolation, an interpolation subarea is defined by four tie points, one at each corner of a rectangular area aligned with the domain axes, see <>. + +[[interpolation_subarea_2d, Figure 2]] +[.text-center] +.Two-dimensional interpolation subarea. +image::images/ci_2d_interpolation_subarea.svg[,60%,pdfwidth=50vw,align="center"] + For the reconstitution of the uncompressed coordinate and auxiliary coordinate variables the interpolation method can be applied independently for each interpolation subarea, making it possible to parallelize the computational process. The following notation is used: + From 5f9ad9ac3616131cd3263f2eaa7d2781ff088df8 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 23 Jul 2021 17:37:50 +0200 Subject: [PATCH 224/249] State tht for linear interpolation, the coordinates of the interpolated points are evenly spaced. --- appj.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/appj.adoc b/appj.adoc index 3b7539f7..8b855c99 100644 --- a/appj.adoc +++ b/appj.adoc @@ -17,6 +17,7 @@ The appendix is organised in a sections on <>, The coordinate interpolation methods are named to indicate the number of dimensions they interpolate as well as the type of interpolation provided. For example, the interpolation method named `linear` provides linear interpolation in one dimension and the method named `bi_linear` provides linear interpolation in two dimensions. Equivalently, the interpolation method named `quadratic` provides quadratic interpolation in one dimension and the interpolation method named `bi_quadratic` provides quadratic interpolation in two dimensions. When an interpolation method is referred to as linear or quadratic, it means that the method is linear or quadratic in the indices of the interpolated dimensions. +Consequently, for a linear interpolation, the coordinates of the interpolated points are evenly spaced. For convenience, an interpolation argument `s` is introduced, calculated as a function of the index in the target domain of the coordinate value to be reconstituted. In the case of one dimensional interpolation the variable is computed as From 0116283e6cda5d94e3ccf3ff2731d8fd2fda8515 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 23 Jul 2021 17:43:18 +0200 Subject: [PATCH 225/249] Change "equivalently" to "similarly" in explanation of s1 and s2 in App J --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 8b855c99..aa352431 100644 --- a/appj.adoc +++ b/appj.adoc @@ -27,7 +27,7 @@ where `ia` and `ib` are the indices in the target domain of the tie points `A` a Note that the value of `s` varies from `0.0` at the tie point `A` to `1.0` at tie point `B`. For example, if `ia = 100` and `ib = 110` and the index in the target domain of the coordinate value to be reconstituted is `i = 105`, then `s = (105 - 100)/(110 - 100) = 0.5`. -In the case of two dimensional interpolation, the interpolation arguments are equivalently computed as +In the case of two dimensional interpolation, the interpolation arguments are similarly computed as `s1 = s(ia1, ib1, i1) = (i1 - ia1)/(ib1 - ia1)` + `s2 = s(ia2, ic2, i2) = (i2 - ia2)/(ic2 - ia2)` From ea474a57a803015fdf166fcea420746620774daa Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 23 Jul 2021 17:53:24 +0200 Subject: [PATCH 226/249] Rename cofficeint "c" to "w" in Appendix J to avoid confusion with point C --- appj.adoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/appj.adoc b/appj.adoc index aa352431..21990d26 100644 --- a/appj.adoc +++ b/appj.adoc @@ -103,17 +103,17 @@ The interpolation function fl() defined for linear interpolation above is first | Name | **`interpolation_name = "quadratic"`** | Description | General purpose one dimensional quadratic interpolation method for one coordinate. -| Interpolation Parameter terms | Optionally interpolation coefficient `c`, which must span the interpolation subarea dimension. +| Interpolation Parameter terms | Optionally coefficient `w`, which must span the interpolation subarea dimension. | Coordinate Compression Calculations | The expression + -`c = fc(ua, ub, u(i), s(i)) = ((u - (1 - s) * ua - s * ub)/( 4 * (1 - s) * s)` + -enables the creator of the dataset to calculate `c` from the coordinate values `ua` and `ub` at tie points `A` and `B` respectively, and the coordinate value `u(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation subarea `(ib - ia)` is an even number, then the data point at index `i = (ib + ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib + ia - 1)/2` shall be selected. +`w = fw(ua, ub, u(i), s(i)) = ((u - (1 - s) * ua - s * ub)/( 4 * (1 - s) * s)` + +enables the creator of the dataset to calculate the coefficient `w` from the coordinate values `ua` and `ub` at tie points `A` and `B` respectively, and the coordinate value `u(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation subarea `(ib - ia)` is an even number, then the data point at index `i = (ib + ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib + ia - 1)/2` shall be selected. | Coordinate Uncompression Calculations | The coordinate value `u(i)` at index `i` between tie points `A` and `B` is calculated from: + - `u(i) = fq(ua, ub, c, s(i)) = ua + s * (ub - ua + 4 * c * (1 - s))`; + -where `ua` and `ub` are the coordinate values at tie points `A` and `B` respectively and the coefficient `c` is available as a term in the `interpolation_parameters`, or otherwise defaults to `0.0`. + + `u(i) = fq(ua, ub, w, s(i)) = ua + s * (ub - ua + 4 * w * (1 - s))`; + +where `ua` and `ub` are the coordinate values at tie points `A` and `B` respectively and the coefficient `w` is available as a term in the `interpolation_parameters`, or otherwise defaults to `0.0`. + |=============== [[quadratic_geo]] @@ -140,7 +140,7 @@ For interpolation in cartesian coordinates as the coefficients `cv = (cv.x, cv.y For interpolation in geographic coordinates latitude and longitude as the coefficients `cll = (cll.lat, cll.lon)`, expressing the offset components along the longitude and latitude directions respectively. -The functions `fq()` and `fc()` referenced in the following are defined in <>. +The functions `fq()` and `fw()` referenced in the following are defined in <>. | Interpolation Parameter terms | Any subset of interpolation coefficients `ce, ca`, which must each span the interpolation subarea dimension. + Optionally the flag variable `interpolation_subarea_flags`, which must span the interpolation subarea dimension and must include `location_use_cartesian` in the `flag_meanings` attribute. @@ -150,7 +150,7 @@ First calculate the tie point vector representations from the tie point latitude `va = fll2v(lla); vb = fll2v(llb);` + Then calculate the cartesian representation of the interpolation coefficients from the tie points `va` and `vb` as well as the point `vp(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation subarea `(ib - ia)` is an even number, then the data point at index `i = (ib + ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib + ia - 1)/2` shall be selected. + The cartesian interpolation coefficients are found from + -`cv = fcv(va, vb, vp(i), s(i)) = (fc(va.x, vb.x, vp(i).x, s(i)), fc(va.y, vb.y, vp(i).y, s(i)), fc(va.z, vb.z, vp(i).z, s(i))).` + +`cv = fcv(va, vb, vp(i), s(i)) = (fw(va.x, vb.x, vp(i).x, s(i)), fw(va.y, vb.y, vp(i).y, s(i)), fw(va.z, vb.z, vp(i).z, s(i))).` + Finally, for storage in the dataset, convert the coefficients to the parametric representation + `cea(is) = (ce(is), ca(is)) = fcv2cea(va, vb, cv) = (fdot(cv, fminus(va, vb))/ gsqr), fdot(cv, fcross(va, vb))/(rsqr*gsqr));` + where `vr = fmultiply(0.5, fplus(va, vb))`, `rsqr = fdot(vr, vr)`, `vg = fminus(va, vb)` and `gsqr = fdot(vg, vg).` + @@ -168,7 +168,7 @@ If the flag `location_use_cartesian` of the interpolation parameter term `interp `vp(i) = fqv(va, vb, cv, s(i)) = (fq(va.x, vb.x, cv.x, s(i)), fq(va.y, vb.y, cv.y, s(i)), fq(va.z, vb.z, cv.z, s(i)));` + `llp(i) = fv2ll(vp(i)).` + Otherwise, first calculate latitude-longitude representation of the interpolation coefficients + -`cll = fcll(lla, llb, llab) = (fc(lla.lat, llb.lat, llab.lat, 0.5), fc(lla.lon, llb.lon, llab.lon, 0.5));` + +`cll = fcll(lla, llb, llab) = (fw(lla.lat, llb.lat, llab.lat, 0.5), fw(lla.lon, llb.lon, llab.lon, 0.5));` + where `llab = fv2ll(fqv(va, vb, cv, 0.5))`. + Then use the following expression to reconstitute any point `llp(i)` between the tie points `A` and `B` using interpolation in latitude-longitude coordinates + `llp(i) = (llp(i).lat, llp(i).lon) = fqll(lla, llb, cll, s(i)) = (fq(lla.lat, llb.lat, cll.lat, s(i)), fq(lla.lon, llb.lon, cll.lon, s(i)))`. + From 4efef82a424181cfc477bdb1b07fc83026f2c949 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 23 Jul 2021 17:59:34 +0200 Subject: [PATCH 227/249] Move "Common Conversions and Formulas" in front of "Interpolation Methods" in Appendix J --- appj.adoc | 70 +++++++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/appj.adoc b/appj.adoc index 21990d26..2947a37d 100644 --- a/appj.adoc +++ b/appj.adoc @@ -9,7 +9,7 @@ The definitions and guidance given here allow an application to compress an exis Futhermore, the definitions given here allow an application to uncompress coordinate and auxiliary coordinate variables that have been compressed using coordinate subsampling. The key element of this process is the reconstitution of the full resolution coordinates in the domain of the data by interpolation between the subsampled coordinates, the tie points, stored in the compressed dataset. -The appendix is organised in a sections on <>, <>, <> and finally two sections with step procedures <> and <>. +The appendix is organised in a sections on <>, <>, <> and finally two sections with step procedures <> and <>. [[common-definitions-and-notation, Section J.1, "Common Definitions and Notation"]] === Common Definitions and Notation @@ -60,7 +60,40 @@ For two dimensional interpolation, `i1` and `i2` are indices in the interpolated Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refer to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. In the two dimensional case, `a = tp(tpi2, tpi1)`, `b = tp(tpi2, tpi1+1)`, `c = tp(tpi2+1, tpi1)` and `d = tp(tpi2+1, tpi1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. -[[interpolation-methods, Section J.2, "Interpolation Methods"]] + +[[common-conversions-and-formulas, Section J.2, "Common Conversions and Formulas"]] +==== Common Conversions and Formulas + +[cols="1, 8, 8"] +|=============== +| |Description | Formula + +| fll2v | Conversion from geocentric `(latitude, longitude)` to cartesian vector `(x, y, z)` | `(x, y, z) = fll2v(ll) = (cos⁡(ll.lat)*cos⁡(ll.lon), cos⁡(ll.lat)*sin⁡(ll.lon), sin⁡(ll.lat))` + + +| fv2ll | Conversion from cartesian vector `(x, y, z)` to geocentric `(latitude, longitude)`| `(lat, lon) = fv2ll(v) = (atan2(v.y, v.x), atan2(z, sqrt(v.x * v.x + v.y * v.y))` + + +| faz2v | Conversion from `(azimuth, zenith)` angles to cartesian vector `(x, y, z)` | `(x, y, z) = faz2v(az) = (sin⁡(az.zenith) * sin⁡(az.azimuth), sin⁡(az.zenith) * cos⁡(az.azimuth), cos⁡(az.zenith))` + + +| fv2az | Conversion from cartesian vector `(x, y, z)` to `(azimuth, zenith)` angles | `(azimuth, zenith) = fv2az(v) = (atan2(y, x), atan2(sqrt(x * x + y * y), z)` + + +| fsqrt | Square Root | `s = fsqrt(t)` + +| fplus | Vector Sum | `(x, y, z) = fplus(va , vb) = (va.x + vb.x, va.y + vb.y, va.z + vb.z)` + +`(x, y, z) = fplus(va , vb, vc) = (va.x + vb.x + vc.x, va.y + vb.y + vc.y, va.z + vb.z + vc.z)` + +| fminus | Vector Difference | `(x, y, z) = fminus(va, vb) = (va.x - vb.x, va.y - vb.y, va.z - vb.z)` + + +| fmultiply | Vector multiplied by Scalar | `(x, y, z) = fmultiply(r, v) = (r * v.x, r * v.y, r * v.z)` + + +| fcross | Vector Cross Product | `(x, y, z) = fcross(va, vb) = (va.y*vb.z - va.z*vb.y, va.z*vb.x - va.x*vb.z, va.x*vb.y - va.y*vb.x)` + + +| norm | Normalised Vector | `(x, y, z) = norm(v) = (v.x, v.y, v.z) / sqrt (v.x*v.x + v.y*v.y + v.z*v.z)` + + +| fdot | Vector Dot Product | `d = fdot(va, vb) = va.x*vb.x + va.y*vb.y + va.z*vb.z` + +|=============== + +[[interpolation-methods, Section J.3, "Interpolation Methods"]] === Interpolation Methods ==== Linear Interpolation @@ -272,39 +305,6 @@ where + image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] -[[common-conversions-and-formulas, Section J.3, "Common Conversions and Formulas"]] -==== Common Conversions and Formulas - -[cols="1, 8, 8"] -|=============== -| |Description | Formula - -| fll2v | Conversion from geocentric `(latitude, longitude)` to cartesian vector `(x, y, z)` | `(x, y, z) = fll2v(ll) = (cos⁡(ll.lat)*cos⁡(ll.lon), cos⁡(ll.lat)*sin⁡(ll.lon), sin⁡(ll.lat))` + - -| fv2ll | Conversion from cartesian vector `(x, y, z)` to geocentric `(latitude, longitude)`| `(lat, lon) = fv2ll(v) = (atan2(v.y, v.x), atan2(z, sqrt(v.x * v.x + v.y * v.y))` + - -| faz2v | Conversion from `(azimuth, zenith)` angles to cartesian vector `(x, y, z)` | `(x, y, z) = faz2v(az) = (sin⁡(az.zenith) * sin⁡(az.azimuth), sin⁡(az.zenith) * cos⁡(az.azimuth), cos⁡(az.zenith))` + - -| fv2az | Conversion from cartesian vector `(x, y, z)` to `(azimuth, zenith)` angles | `(azimuth, zenith) = fv2az(v) = (atan2(y, x), atan2(sqrt(x * x + y * y), z)` + - -| fsqrt | Square Root | `s = fsqrt(t)` - -| fplus | Vector Sum | `(x, y, z) = fplus(va , vb) = (va.x + vb.x, va.y + vb.y, va.z + vb.z)` + -`(x, y, z) = fplus(va , vb, vc) = (va.x + vb.x + vc.x, va.y + vb.y + vc.y, va.z + vb.z + vc.z)` - -| fminus | Vector Difference | `(x, y, z) = fminus(va, vb) = (va.x - vb.x, va.y - vb.y, va.z - vb.z)` + - -| fmultiply | Vector multiplied by Scalar | `(x, y, z) = fmultiply(r, v) = (r * v.x, r * v.y, r * v.z)` + - -| fcross | Vector Cross Product | `(x, y, z) = fcross(va, vb) = (va.y*vb.z - va.z*vb.y, va.z*vb.x - va.x*vb.z, va.x*vb.y - va.y*vb.x)` + - -| norm | Normalised Vector | `(x, y, z) = norm(v) = (v.x, v.y, v.z) / sqrt (v.x*v.x + v.y*v.y + v.z*v.z)` + - -| fdot | Vector Dot Product | `d = fdot(va, vb) = va.x*vb.x + va.y*vb.y + va.z*vb.z` - -|=============== - - [[coordinate-compression-steps, Section J.4, "Coordinate Compression Steps"]] === Coordinate Compression Steps From 303aaa440351b05a7ff52d4329426d81a5c1e7bc Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Fri, 23 Jul 2021 19:40:33 +0200 Subject: [PATCH 228/249] Add "s" to "each of the interpolated dimension" in Appendix J --- appj.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/appj.adoc b/appj.adoc index 2947a37d..5bc0dd5c 100644 --- a/appj.adoc +++ b/appj.adoc @@ -333,12 +333,12 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] | <> | 6 -| For each of the interpolated dimension, add the interpolated dimension, the corresponding subsampled dimension and, if required by the selected interpolation method, its corresponding interpolation subarea dimension to the **`tie_point_mapping`** attribute of the interpolation variable. +| For each of the interpolated dimensions, add the interpolated dimension, the corresponding subsampled dimension and, if required by the selected interpolation method, its corresponding interpolation subarea dimension to the **`tie_point_mapping`** attribute of the interpolation variable. | <> + <> | 7 -| For each of the interpolated dimension, record the location of each identified tie point in a tie point index variable. For each interpolated dimension, add the tie point index variable name to the **`tie_point_mapping`** attribute of the interpolation variable. +| For each of the interpolated dimensions, record the location of each identified tie point in a tie point index variable. For each interpolated dimension, add the tie point index variable name to the **`tie_point_mapping`** attribute of the interpolation variable. | <> + <> @@ -395,7 +395,7 @@ image::images/ci_quadratic3.svg[,50%,pdfwidth=50vw,align="center"] <> | 6 -| For each of the interpolated dimension, identify pairs of adjacent indices in the tie point index variable with index values differing by more than one, each index pair defining the extend of an interpolation subarea in that dimension. A full interpolation subarea is defined by one such index pair per interpolated dimension, with combinations of one index from each pair defining the interpolation subarea tie points. +| For each of the interpolated dimensions, identify pairs of adjacent indices in the tie point index variable with index values differing by more than one, each index pair defining the extend of an interpolation subarea in that dimension. A full interpolation subarea is defined by one such index pair per interpolated dimension, with combinations of one index from each pair defining the interpolation subarea tie points. | <> | 7 From ec65f107617d4ae9a2bad371f279061971755724 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 2 Aug 2021 07:58:47 +0200 Subject: [PATCH 229/249] Change font in Common Conversions and Formulas table --- appj.adoc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/appj.adoc b/appj.adoc index 5bc0dd5c..1473c9ca 100644 --- a/appj.adoc +++ b/appj.adoc @@ -68,28 +68,28 @@ Note that, for simplicity of notation, the descriptions of the interpolation met |=============== | |Description | Formula -| fll2v | Conversion from geocentric `(latitude, longitude)` to cartesian vector `(x, y, z)` | `(x, y, z) = fll2v(ll) = (cos⁡(ll.lat)*cos⁡(ll.lon), cos⁡(ll.lat)*sin⁡(ll.lon), sin⁡(ll.lat))` + +| `fll2v` | Conversion from geocentric `(latitude, longitude)` to cartesian vector `(x, y, z)` | `(x, y, z) = fll2v(ll) = (cos⁡(ll.lat)*cos⁡(ll.lon), cos⁡(ll.lat)*sin⁡(ll.lon), sin⁡(ll.lat))` + -| fv2ll | Conversion from cartesian vector `(x, y, z)` to geocentric `(latitude, longitude)`| `(lat, lon) = fv2ll(v) = (atan2(v.y, v.x), atan2(z, sqrt(v.x * v.x + v.y * v.y))` + +| `fv2ll` | Conversion from cartesian vector `(x, y, z)` to geocentric `(latitude, longitude)`| `(lat, lon) = fv2ll(v) = (atan2(v.y, v.x), atan2(z, sqrt(v.x * v.x + v.y * v.y))` + -| faz2v | Conversion from `(azimuth, zenith)` angles to cartesian vector `(x, y, z)` | `(x, y, z) = faz2v(az) = (sin⁡(az.zenith) * sin⁡(az.azimuth), sin⁡(az.zenith) * cos⁡(az.azimuth), cos⁡(az.zenith))` + +| `faz2v` | Conversion from `(azimuth, zenith)` angles to cartesian vector `(x, y, z)` | `(x, y, z) = faz2v(az) = (sin⁡(az.zenith) * sin⁡(az.azimuth), sin⁡(az.zenith) * cos⁡(az.azimuth), cos⁡(az.zenith))` + -| fv2az | Conversion from cartesian vector `(x, y, z)` to `(azimuth, zenith)` angles | `(azimuth, zenith) = fv2az(v) = (atan2(y, x), atan2(sqrt(x * x + y * y), z)` + +| `fv2az` | Conversion from cartesian vector `(x, y, z)` to `(azimuth, zenith)` angles | `(azimuth, zenith) = fv2az(v) = (atan2(y, x), atan2(sqrt(x * x + y * y), z)` + -| fsqrt | Square Root | `s = fsqrt(t)` +| `fsqrt` | Square Root | `s = fsqrt(t)` -| fplus | Vector Sum | `(x, y, z) = fplus(va , vb) = (va.x + vb.x, va.y + vb.y, va.z + vb.z)` + +| `fplus` | Vector Sum | `(x, y, z) = fplus(va , vb) = (va.x + vb.x, va.y + vb.y, va.z + vb.z)` + `(x, y, z) = fplus(va , vb, vc) = (va.x + vb.x + vc.x, va.y + vb.y + vc.y, va.z + vb.z + vc.z)` -| fminus | Vector Difference | `(x, y, z) = fminus(va, vb) = (va.x - vb.x, va.y - vb.y, va.z - vb.z)` + +| `fminus` | Vector Difference | `(x, y, z) = fminus(va, vb) = (va.x - vb.x, va.y - vb.y, va.z - vb.z)` + -| fmultiply | Vector multiplied by Scalar | `(x, y, z) = fmultiply(r, v) = (r * v.x, r * v.y, r * v.z)` + +| `fmultiply` | Vector multiplied by Scalar | `(x, y, z) = fmultiply(r, v) = (r * v.x, r * v.y, r * v.z)` + -| fcross | Vector Cross Product | `(x, y, z) = fcross(va, vb) = (va.y*vb.z - va.z*vb.y, va.z*vb.x - va.x*vb.z, va.x*vb.y - va.y*vb.x)` + +| `fcross` | Vector Cross Product | `(x, y, z) = fcross(va, vb) = (va.y*vb.z - va.z*vb.y, va.z*vb.x - va.x*vb.z, va.x*vb.y - va.y*vb.x)` + -| norm | Normalised Vector | `(x, y, z) = norm(v) = (v.x, v.y, v.z) / sqrt (v.x*v.x + v.y*v.y + v.z*v.z)` + +| `norm` | Normalised Vector | `(x, y, z) = norm(v) = (v.x, v.y, v.z) / sqrt (v.x*v.x + v.y*v.y + v.z*v.z)` + -| fdot | Vector Dot Product | `d = fdot(va, vb) = va.x*vb.x + va.y*vb.y + va.z*vb.z` +| `fdot` | Vector Dot Product | `d = fdot(va, vb) = va.x*vb.x + va.y*vb.y + va.z*vb.z` |=============== From 06dac3aeb6d8b6dd9b8356258193b3923aa03b3f Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 2 Aug 2021 08:05:42 +0200 Subject: [PATCH 230/249] Revert change 5f9ad9a (Change 23) --- appj.adoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/appj.adoc b/appj.adoc index 1473c9ca..8ca958f3 100644 --- a/appj.adoc +++ b/appj.adoc @@ -16,8 +16,7 @@ The appendix is organised in a sections on <>, The coordinate interpolation methods are named to indicate the number of dimensions they interpolate as well as the type of interpolation provided. For example, the interpolation method named `linear` provides linear interpolation in one dimension and the method named `bi_linear` provides linear interpolation in two dimensions. Equivalently, the interpolation method named `quadratic` provides quadratic interpolation in one dimension and the interpolation method named `bi_quadratic` provides quadratic interpolation in two dimensions. -When an interpolation method is referred to as linear or quadratic, it means that the method is linear or quadratic in the indices of the interpolated dimensions. -Consequently, for a linear interpolation, the coordinates of the interpolated points are evenly spaced. +When an interpolation method is referred to as linear or quadratic, it means that the method is linear or quadratic in the indices of the interpolated dimensions. For convenience, an interpolation argument `s` is introduced, calculated as a function of the index in the target domain of the coordinate value to be reconstituted. In the case of one dimensional interpolation the variable is computed as From a30c58f4e34e5b1b76c823ccadbb0dd386dcff25 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 2 Aug 2021 08:27:46 +0200 Subject: [PATCH 231/249] Improve wording of bounds interpolation tie point selection (Change 18) --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 893ac9cd..33843969 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -606,7 +606,7 @@ For the reconstituted coordinates, cell bounds are stored separately for each co for the example of 2D bounds. Since the cell bounds are contiguous, bounds points of adjacent cells will coincide and so the full set of bounds points may be represented as a grid, comparable to the coordinate points grid. In the middle part of <> , both the reconstituted bounds points grid and the reconstituted coordinate points grid are shown for a continuous area, where each bounds point may be shared by up to four cells. -For the purpose of bounds interpolation, a single bounds tie point is created for each coordinate tie point, and is selected as the vertex of the tie point cell that is the closest to the boundary of the interpolation subarea with respect to each interpolated dimension. For the example of 2D bounds, the resulting set of bounds tie points are marked in <>. +Bounds interpolation uses the same tie point index variables and therefore the same tie point cells as coordinate interpolation. One of the vertices of each coordinate tie point cell is chosen as the bounds tie point for the cell. It is selected as the vertex of the tie point cell that is the closest to the boundary of the interpolation subarea with respect to each interpolated dimension. For the example of 2D bounds, the resulting set of bounds tie points are marked in <>, where the selected vertices are those closets to the corners of the interpolation subareas. Note that within a continuous area, there is one more reconstituted bounds point than there are reconstituted coordinate points in each dimension. For this reason, a virtual __interpolated bounds dimension__ is introduced for each dimension, having a size equal to the size of the interpolated dimension plus one. This dimension is used for solely descriptive purposes, and is not required in a compressed dataset. From af2a2eabaa6f86a25669a9b038e3e1e2147c8935 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 2 Aug 2021 08:42:56 +0200 Subject: [PATCH 232/249] Change cartesian to 3d cartesian (Change 27) --- appj.adoc | 38 +++++++++++++++++++------------------- ch08.adoc | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/appj.adoc b/appj.adoc index 8ca958f3..59331baf 100644 --- a/appj.adoc +++ b/appj.adoc @@ -67,13 +67,13 @@ Note that, for simplicity of notation, the descriptions of the interpolation met |=============== | |Description | Formula -| `fll2v` | Conversion from geocentric `(latitude, longitude)` to cartesian vector `(x, y, z)` | `(x, y, z) = fll2v(ll) = (cos⁡(ll.lat)*cos⁡(ll.lon), cos⁡(ll.lat)*sin⁡(ll.lon), sin⁡(ll.lat))` + +| `fll2v` | Conversion from geocentric `(latitude, longitude)` to three-dimensional cartesian vector `(x, y, z)` | `(x, y, z) = fll2v(ll) = (cos⁡(ll.lat)*cos⁡(ll.lon), cos⁡(ll.lat)*sin⁡(ll.lon), sin⁡(ll.lat))` + -| `fv2ll` | Conversion from cartesian vector `(x, y, z)` to geocentric `(latitude, longitude)`| `(lat, lon) = fv2ll(v) = (atan2(v.y, v.x), atan2(z, sqrt(v.x * v.x + v.y * v.y))` + +| `fv2ll` | Conversion from three-dimensional cartesian vector `(x, y, z)` to geocentric `(latitude, longitude)`| `(lat, lon) = fv2ll(v) = (atan2(v.y, v.x), atan2(z, sqrt(v.x * v.x + v.y * v.y))` + -| `faz2v` | Conversion from `(azimuth, zenith)` angles to cartesian vector `(x, y, z)` | `(x, y, z) = faz2v(az) = (sin⁡(az.zenith) * sin⁡(az.azimuth), sin⁡(az.zenith) * cos⁡(az.azimuth), cos⁡(az.zenith))` + +| `faz2v` | Conversion from `(azimuth, zenith)` angles to three-dimensional cartesian vector `(x, y, z)` | `(x, y, z) = faz2v(az) = (sin⁡(az.zenith) * sin⁡(az.azimuth), sin⁡(az.zenith) * cos⁡(az.azimuth), cos⁡(az.zenith))` + -| `fv2az` | Conversion from cartesian vector `(x, y, z)` to `(azimuth, zenith)` angles | `(azimuth, zenith) = fv2az(v) = (atan2(y, x), atan2(sqrt(x * x + y * y), z)` + +| `fv2az` | Conversion from three-dimensional cartesian vector `(x, y, z)` to `(azimuth, zenith)` angles | `(azimuth, zenith) = fv2az(v) = (atan2(y, x), atan2(sqrt(x * x + y * y), z)` + | `fsqrt` | Square Root | `s = fsqrt(t)` @@ -158,7 +158,7 @@ where `ua` and `ub` are the coordinate values at tie points `A` and `B` respecti Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. For each interpolation subarea, none of the tie points defining the interpolation subarea are permitted to coincide. -By default, interpolation is performed directly in the latitude and longitude coordinates, but may be performed in cartesian coordinates where required for achieving the desired accuracy. This must be indicated by setting the `location_use_cartesian` flag within the interpolation parameter `interpolation_subarea_flags` for each interpolation subarea where interpolation in cartesian coordinates is required. +By default, interpolation is performed directly in the latitude and longitude coordinates, but may be performed in three-dimensional cartesian coordinates where required for achieving the desired accuracy. This must be indicated by setting the `location_use_3d_cartesian` flag within the interpolation parameter `interpolation_subarea_flags` for each interpolation subarea where interpolation in three-dimensional cartesian coordinates is required. The quadratic interpolation coefficients `cea = (ce, ca)`, stored as interpolation parameters in the product, describe a point `P` between the tie points `A` and `B`, which is equivalent of an additional tie point in the sense that the method will accurately reconstitute the point `P` in the same way as it accurately reconstitutes the tie points `A` and `B`. See <> and <>. @@ -168,35 +168,35 @@ The coefficients may be represented in three different ways: For storage in the dataset as the non-dimensional coefficients `cea = (ce, ca)`, referred to as the parametric representation. The component `ce` is the offset projected on the line from tie point `B` to tie point `A` and expressed as a fraction of the distance between `A` and `B`. The component `ca` is the offset projected on the line perpendicular to the line from tie point `B` to tie point `A` and perpendicular to the plane spanned by `va` and `vb`, the vector representations of the two tie points, and expressed as a fraction of the length of `A x B`. + -For interpolation in cartesian coordinates as the coefficients `cv = (cv.x, cv.y, cv.z)`, expressing the offset components along the cartesian axes X, Y and Z respectively. +For interpolation in three-dimensional cartesian coordinates as the coefficients `cv = (cv.x, cv.y, cv.z)`, expressing the offset components along the three-dimensional cartesian axes X, Y and Z respectively. For interpolation in geographic coordinates latitude and longitude as the coefficients `cll = (cll.lat, cll.lon)`, expressing the offset components along the longitude and latitude directions respectively. The functions `fq()` and `fw()` referenced in the following are defined in <>. | Interpolation Parameter terms | Any subset of interpolation coefficients `ce, ca`, which must each span the interpolation subarea dimension. + -Optionally the flag variable `interpolation_subarea_flags`, which must span the interpolation subarea dimension and must include `location_use_cartesian` in the `flag_meanings` attribute. +Optionally the flag variable `interpolation_subarea_flags`, which must span the interpolation subarea dimension and must include `location_use_3d_cartesian` in the `flag_meanings` attribute. | Coordinate Compression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb);` + -Then calculate the cartesian representation of the interpolation coefficients from the tie points `va` and `vb` as well as the point `vp(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation subarea `(ib - ia)` is an even number, then the data point at index `i = (ib + ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib + ia - 1)/2` shall be selected. + -The cartesian interpolation coefficients are found from + +Then calculate the three-dimensional cartesian representation of the interpolation coefficients from the tie points `va` and `vb` as well as the point `vp(i)` at index `i` between the tie points `A` and `B`. If the size of the interpolation subarea `(ib - ia)` is an even number, then the data point at index `i = (ib + ia)/2` shall be selected for this calculation, otherwise the data point at index `i = (ib + ia - 1)/2` shall be selected. + +The three-dimensional cartesian interpolation coefficients are found from + `cv = fcv(va, vb, vp(i), s(i)) = (fw(va.x, vb.x, vp(i).x, s(i)), fw(va.y, vb.y, vp(i).y, s(i)), fw(va.z, vb.z, vp(i).z, s(i))).` + Finally, for storage in the dataset, convert the coefficients to the parametric representation + `cea(is) = (ce(is), ca(is)) = fcv2cea(va, vb, cv) = (fdot(cv, fminus(va, vb))/ gsqr), fdot(cv, fcross(va, vb))/(rsqr*gsqr));` + where `vr = fmultiply(0.5, fplus(va, vb))`, `rsqr = fdot(vr, vr)`, `vg = fminus(va, vb)` and `gsqr = fdot(vg, vg).` + -The interpolation parameter term `interpolation_subarea_flags(is)` shall have the flag `location_use_cartesian` set if the interpolation subarea intersects the `longitude = 180.0` or if the interpolation subarea extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. +The interpolation parameter term `interpolation_subarea_flags(is)` shall have the flag `location_use_3d_cartesian` set if the interpolation subarea intersects the `longitude = 180.0` or if the interpolation subarea extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb);` + -Then calculate the cartesian representation of the interpolation coefficients from the parametric representation stored in the dataset using + +Then calculate the three-dimensional cartesian representation of the interpolation coefficients from the parametric representation stored in the dataset using + `cv = fcea2cv(va, vb, cea(is)) = fplus(fmultiply(ce, fminus(va, vb)), fmultiply(ca, fcross(va, vb)), fmultiply(cr, vr));` + where + `vr = fmultiply(0.5, fplus(va, vb))`; + `rsqr = fdot(vr, vr);` + `cr = fsqrt(1 - ce(is)*ce(is) - ca(is)*ca(is)) - fsqrt(rsqr).` + -If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_subarea_flags(is2, is1)` is set, use the following expression to reconstitute any point `llp(i)` between the tie points `A` and `B` using interpolation in cartesian coordinates + +If the flag `location_use_3d_cartesian` of the interpolation parameter term `interpolation_subarea_flags(is2, is1)` is set, use the following expression to reconstitute any point `llp(i)` between the tie points `A` and `B` using interpolation in three-dimensional cartesian coordinates + `vp(i) = fqv(va, vb, cv, s(i)) = (fq(va.x, vb.x, cv.x, s(i)), fq(va.y, vb.y, cv.y, s(i)), fq(va.z, vb.z, cv.z, s(i)));` + `llp(i) = fv2ll(vp(i)).` + Otherwise, first calculate latitude-longitude representation of the interpolation coefficients + @@ -227,7 +227,7 @@ image::images/ci_quadratic2.svg[,100%,pdfwidth=50vw,align="center"] Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. For each interpolation subarea, none of the tie points defining the interpolation subarea are permitted to coincide. -The functions `fcv()`, `fcv2cea()`, `fcea2cv()`, `fcll()`, `fqv()` and `fqll()` referenced in the following are defined in <>. As for that method, interpolation is performed directly in the latitude and longitude coordinates or in cartesian coordinates, where required for achieving the desired accuracy. Similarly, it shares the three different representations of the quadratic interpolation coefficients, the parametric representation `cea = (ce, ca)` for storage in the dataset, `cll = (cll.lat, cll.lon)` for interpolation in geographic coordinates latitude and longitude and `cv = (cv.x, cv.y, cv.z)` for interpolation in cartesian coordinates. +The functions `fcv()`, `fcv2cea()`, `fcea2cv()`, `fcll()`, `fqv()` and `fqll()` referenced in the following are defined in <>. As for that method, interpolation is performed directly in the latitude and longitude coordinates or in three-dimensional cartesian coordinates, where required for achieving the desired accuracy. Similarly, it shares the three different representations of the quadratic interpolation coefficients, the parametric representation `cea = (ce, ca)` for storage in the dataset, `cll = (cll.lat, cll.lon)` for interpolation in geographic coordinates latitude and longitude and `cv = (cv.x, cv.y, cv.z)` for interpolation in three-dimensional cartesian coordinates. The parametric representation of the interpolation coefficients, stored in the interpolation parameters `ce1, ca1, ce2, ca2, ce3` and `ca3`, is equivalent to five additional tie points for the interpolation subarea as shown in <>, which also shows the orientation and indices of the parameters. @@ -236,15 +236,15 @@ Any subset of interpolation coefficients `ce1, ca1`, which must each span the su Any subset of interpolation coefficients `ce2, ca2`, which must each span the interpolation subarea dimension 2 and subsampled dimension 1; + Any subset of interpolation coefficients `ce3, ca3`, which must each span the interpolation subarea dimension 2 and interpolation subarea dimension 1; + -Optionally the flag variable `interpolation_subarea_flags`, which must span the interpolation subarea dimension 2 and interpolation subarea dimension 1 and must include `location_use_cartesian` in the `flag_meanings` attribute. +Optionally the flag variable `interpolation_subarea_flags`, which must span the interpolation subarea dimension 2 and interpolation subarea dimension 1 and must include `location_use_3d_cartesian` in the `flag_meanings` attribute. | Coordinate Compression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb); vc = fll2v(llc); vd = fll2v(lld).` + -Then calculate the cartesian representation of the interpolation coefficients sets from the tie points as well as a point `vp(i2, i1)` between the tie points. If the size of the interpolation subarea in the first dimension `(ib1 - ia1)` is an even number, then the index +Then calculate the three-dimensional cartesian representation of the interpolation coefficients sets from the tie points as well as a point `vp(i2, i1)` between the tie points. If the size of the interpolation subarea in the first dimension `(ib1 - ia1)` is an even number, then the index `i1 = (ib1 + ia1)/2` shall be selected for this calculation, otherwise the index `i1 = (ib1 + ia1 - 1)/2` shall be selected. If the size of the interpolation subarea in the second dimension `(ib2 - ic2)` is an even number, then the index `i2 = (ib2 + ic2)/2` shall be selected for this calculation, otherwise the index `i2 = (ib2 + ic2 - 1)/2` shall be selected. + -Using the selected `(i2, i1)`, the cartesian interpolation coefficients are found from + +Using the selected `(i2, i1)`, the three-dimensional cartesian interpolation coefficients are found from + `s1 = s(ia1, ib1, i1);` `s2 = s(ia2, ic2, i2);` + `vac = fll2v(ll(i2, ia1));` @@ -264,17 +264,17 @@ Finally, before storing them in the dataset's interpolation parameters, convert `cea2(is2, tpi1) = fcv2cea( va, vc, cv_ac);` + `cea2(is2, tpi1+1) = fcv2cea( vb, vd, cv_bd);` + `cea3(is2, is1) = fcv2cea( vab, vcd, cv_z).` + -The interpolation parameter term `interpolation_subarea_flags(is2, is1)` shall have the flag `location_use_cartesian` set if the interpolation subarea intersects the `longitude = 180.0` or if the interpolation subarea extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. +The interpolation parameter term `interpolation_subarea_flags(is2, is1)` shall have the flag `location_use_3d_cartesian` set if the interpolation subarea intersects the `longitude = 180.0` or if the interpolation subarea extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. | Coordinate Uncompression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb); vc = fll2v(llc); vd = fll2v(lld).` + -Then calculate the cartesian representation of the interpolation coefficient sets from the parametric representation stored in the dataset + +Then calculate the three-dimensional cartesian representation of the interpolation coefficient sets from the parametric representation stored in the dataset + `cv_ac = fcea2cv(va, vc, cea2(is2, tpi1));` + `cv_bd = fcea2cv(vb, vd, cea2(is2, tpi1 + 1));` + `vab = fqv(va, vb, fcea2cv(va, vb, cea1(tpi2, is1)), 0.5);` + `vcd = fqv(vc, vd, fcea2cv(vc, vd, cea1(tpi2 + 1, is1)), 0.5);` + `cv_z = fcea2cv(vab, vcd, cea3(is2, is1));` + -If the flag `location_use_cartesian` of the interpolation parameter term `interpolation_subarea_flags` is set, use the following expression to reconstitute any point `llp(i2, i1)` between the tie points `A` and `B` using interpolation in cartesian coordinates + +If the flag `location_use_3d_cartesian` of the interpolation parameter term `interpolation_subarea_flags` is set, use the following expression to reconstitute any point `llp(i2, i1)` between the tie points `A` and `B` using interpolation in three-dimensional cartesian coordinates + `llp(i2, i1) = fv2ll(fqv(vac, vbd, cv_zz, s(ia1, ib1, i1)));` + where + `s2 = s(ia2, ic2, i2);` + diff --git a/ch08.adoc b/ch08.adoc index 33843969..c70397ca 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -487,7 +487,7 @@ variables: interpolation_subarea_flags : valid_range = "1b, 7b" ; interpolation_subarea_flags : flag_masks = "1b, 2b, 4b" ; interpolation_subarea_flags : flag_meanings = - "location_use_cartesian + "location_use_3d_cartesian sensor_direction_use_cartesian solar_direction_use_cartesian" ; From 4cc00cb90b8250417fd9eb7b1a832551d22492aa Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 2 Aug 2021 08:47:16 +0200 Subject: [PATCH 233/249] Change cartesian to 3d cartesian (Change 27) --- ch08.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index c70397ca..ee0ca114 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -488,8 +488,8 @@ variables: interpolation_subarea_flags : flag_masks = "1b, 2b, 4b" ; interpolation_subarea_flags : flag_meanings = "location_use_3d_cartesian - sensor_direction_use_cartesian - solar_direction_use_cartesian" ; + sensor_direction_use_3d_cartesian + solar_direction_use_3d_cartesian" ; // Tie point index variables int track_indices(tp_track) ; // shared by tp_interpolation and time_interpolation From d9436e48c4b6aabb87b6bcc9ba3dd4ec61c37377 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 2 Aug 2021 08:51:29 +0200 Subject: [PATCH 234/249] Rename [bi_]quadratic_remote_sensing to [bi_]quadratic_latitude_longitude (Change 27) --- appj.adoc | 4 ++-- ch08.adoc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/appj.adoc b/appj.adoc index 59331baf..def99f25 100644 --- a/appj.adoc +++ b/appj.adoc @@ -153,7 +153,7 @@ where `ua` and `ub` are the coordinate values at tie points `A` and `B` respecti [cols="6,15"] |=============== -| Name | **`interpolation_name = "quadratic_remote_sensing"`** +| Name | **`interpolation_name = "quadratic_latitude_longitude"`** | Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. + Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. For each interpolation subarea, none of the tie points defining the interpolation subarea are permitted to coincide. @@ -222,7 +222,7 @@ image::images/ci_quadratic2.svg[,100%,pdfwidth=50vw,align="center"] [cols="6,15"] |=============== -| Name | **`interpolation_name = "bi_quadratic_remote_sensing"`** +| Name | **`interpolation_name = "bi_quadratic_latitude_longitude"`** | Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. For each interpolation subarea, none of the tie points defining the interpolation subarea are permitted to coincide. diff --git a/ch08.adoc b/ch08.adoc index ee0ca114..b7b955fa 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -473,7 +473,7 @@ variables: // Interpolation variable char tp_interpolation ; - tp_interpolation:interpolation_name = "bi_quadratic_remote_sensing" ; + tp_interpolation:interpolation_name = "bi_quadratic_latitude_longitude" ; tp_interpolation:tie_point_mapping = "track: track_indices tp_track subarea_track scan: scan_indices tp_scan subarea_scan ;; From 546d288092650fa8d23ff7ddc6728537b2992342 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 2 Aug 2021 09:12:24 +0200 Subject: [PATCH 235/249] Improve explanation of latitude_limit (Change 28) --- appj.adoc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/appj.adoc b/appj.adoc index def99f25..ef4f7bb6 100644 --- a/appj.adoc +++ b/appj.adoc @@ -186,7 +186,8 @@ The three-dimensional cartesian interpolation coefficients are found from + Finally, for storage in the dataset, convert the coefficients to the parametric representation + `cea(is) = (ce(is), ca(is)) = fcv2cea(va, vb, cv) = (fdot(cv, fminus(va, vb))/ gsqr), fdot(cv, fcross(va, vb))/(rsqr*gsqr));` + where `vr = fmultiply(0.5, fplus(va, vb))`, `rsqr = fdot(vr, vr)`, `vg = fminus(va, vb)` and `gsqr = fdot(vg, vg).` + -The interpolation parameter term `interpolation_subarea_flags(is)` shall have the flag `location_use_3d_cartesian` set if the interpolation subarea intersects the `longitude = 180.0` or if the interpolation subarea extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. +The interpolation parameter term `interpolation_subarea_flags(is)` shall have the flag `location_use_3d_cartesian` set if the interpolation subarea intersects the `longitude = 180.0` or if the interpolation subarea extends into `latitude > latitude_limit` or `latitude < -latitude_limit`. +The value of `latitude_limit` is set by the data set creator and defines the high latitude areas where interpolation in three-dimensional cartesian coordinates is required for reasons of coordinate reconstitution accuracy. The `latitude_limit` is used solely for setting the flag `location_use_3d_cartesian`, and is not required in a compressed dataset. | Coordinate Uncompression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb);` + @@ -264,7 +265,9 @@ Finally, before storing them in the dataset's interpolation parameters, convert `cea2(is2, tpi1) = fcv2cea( va, vc, cv_ac);` + `cea2(is2, tpi1+1) = fcv2cea( vb, vd, cv_bd);` + `cea3(is2, is1) = fcv2cea( vab, vcd, cv_z).` + -The interpolation parameter term `interpolation_subarea_flags(is2, is1)` shall have the flag `location_use_3d_cartesian` set if the interpolation subarea intersects the `longitude = 180.0` or if the interpolation subarea extends into `latitude > latitude_limit` or `latitude < -latitude_limit`, where the choice of `latitude_limit` will impact the coordinate reconstitution accuracy. +The interpolation parameter term `interpolation_subarea_flags(is2, is1)` shall have the flag `location_use_3d_cartesian` set if the interpolation subarea intersects the `longitude = 180.0` or if the interpolation subarea extends into `latitude > latitude_limit` or `latitude < -latitude_limit`. +The value of `latitude_limit` is set by the data set creator and defines the high latitude areas where interpolation in three-dimensional cartesian coordinates is required for reasons of coordinate reconstitution accuracy. The `latitude_limit` is used solely for setting the flag `location_use_3d_cartesian`, and is not required in a compressed dataset. + | Coordinate Uncompression Calculations | First calculate the tie point vector representations from the tie point latitude-longitude representations + `va = fll2v(lla); vb = fll2v(llb); vc = fll2v(llc); vd = fll2v(lld).` + From bf952344788260709394d0cda74aa5ee3d70dff0 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 2 Aug 2021 09:16:01 +0200 Subject: [PATCH 236/249] Editorial, heading capitalisation --- appj.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appj.adoc b/appj.adoc index ef4f7bb6..e3a2d926 100644 --- a/appj.adoc +++ b/appj.adoc @@ -149,7 +149,7 @@ where `ua` and `ub` are the coordinate values at tie points `A` and `B` respecti |=============== [[quadratic_geo]] -==== Quadratic Interpolation of geographic coordinates latitude and longitude +==== Quadratic Interpolation of Geographic Coordinates Latitude and Longitude [cols="6,15"] |=============== @@ -219,7 +219,7 @@ image::images/ci_quadratic2.svg[,100%,pdfwidth=50vw,align="center"] [[bi_quadratic_geo]] -==== Biquadratic Interpolation of geographic coordinates +==== Biquadratic Interpolation of Geographic Coordinates Latitude and Longitude [cols="6,15"] |=============== From 09b107edb7af0b90e333a46d052e34d716e21790 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 2 Aug 2021 09:46:22 +0200 Subject: [PATCH 237/249] Reword and move to end of chapter the section on computational precision, update all examples to have computational_precision attribute --- ch08.adoc | 65 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index b7b955fa..1e49d03d 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -197,7 +197,7 @@ interpolation subarea basis, for which the construction of the uncompressed coordinates may only access those tie points that define the extent of the of the interpolation subarea. -In addition to the **`interpolation_name`** and **`interpolation_description`** attributes described in this section, further attributes of the interpolation variable are described in <> and <>, <> and <>. +In addition to the **`interpolation_name`** and **`interpolation_description`** attributes described in this section, further attributes of the interpolation variable are described in <> and <>, <> and <>. [[compression-by-coordinate-subsampling-dimensions,Section 8.3.4, "Subsampled, Interpolated and Non-Interpolated Dimensions"]] ==== Subsampled, Interpolated and Non-Interpolated Dimensions @@ -329,6 +329,7 @@ variables: char bl_interpolation ; bl_interpolation:interpolation_name = "bi_linear" ; bl_interpolation:tie_point_mapping = "xc: x_indices tp_xc yc: y_indices tp_yc" ; + bl_interpolation:computational_precision = "64" // tie point coordinate variables double lat(tp_yc, tp_xc) ; @@ -370,6 +371,7 @@ variables: char l_interpolation ; l_interpolation:interpolation_name = "linear" ; l_interpolation:tie_point_mapping = "xc: x_indices tp_xc" ; + l_interpolation:computational_precision = "64" // tie point coordinate variables double lat(yc, tp_xc) ; @@ -426,23 +428,6 @@ The application of an interpolation parameter variable is independent of its non .Through combination of dimensions, interpolation parameter variables may provide values for a) interpolation subareas sharing a tie point, b) each interpolation subarea, c) and d) interpolation subareas sharing a boundary. image::images/ci_interpolation_coefficients.svg[,100%,pdfwidth=50vw,align="center"] - -[[compression-by-coordinate-subsampling-computational-precision, Section 8.3.9, "Computational Precision"]] -==== Computational Precision - -The accuracy of the reconstituted coordinates depends mainly on the degree of subsampling and the choice of interpolation method, both of which are set by the creator of the dataset. The accuracy will also depend, however, on how the interpolation method is implemented and on the computer platform carrying out the computations. There are no restrictions on the choice of interpolation method implementation, for neither the data creator nor the data user, but the floating-point arithmetic precision used by the data creator during the preparation and validation of the compressed coordinates must be specified by setting the interpolation variable’s **`computational_precision**` attribute to one of the following values: - -[cols="3,10"] -|=============== -| ** Value ** | ** Description** -| "32" | 32-bit floating-point arithmetic, comparable to the binary32 standard in [<>] -| "64" | 64-bit floating-point arithmetic, comparable to the binary64 standard in [<>] -|=============== - - -Using the given computational precision in the interpolation computations is a necessary, but not sufficient, condition for the data user to be able to reconstitute the coordinates to an accuracy comparable to that intended by the data creator. For instance, a **`computational_precision**` value of **`"64"**` would specify that, using the same software and hardware as the creator of the compressed dataset, sufficient accuracy could not be reached when using a floating-point precision lower than 64-bit floating-point arithmetic in the interpolation computations required to reconstitute the coordinates. - - [[example-VIIRS]] [caption="Example 8.5. "] .Multiple interpolation variables with interpolation parameter attributes. @@ -474,10 +459,9 @@ variables: // Interpolation variable char tp_interpolation ; tp_interpolation:interpolation_name = "bi_quadratic_latitude_longitude" ; - tp_interpolation:tie_point_mapping = "track: track_indices tp_track subarea_track - scan: scan_indices tp_scan subarea_scan -;; + tp_interpolation:tie_point_mapping = "track: track_indices tp_track subarea_track scan: scan_indices tp_scan subarea_scan" ; tp_interpolation:interpolation_parameters = "ce1: ce1 ca2: ca2 ce3: ce3 flags: interpolation_subarea_flags" ; + tp_interpolation:computational_precision = "32" // Interpolation parameters short ce1(tp_track , subarea_scan) ; @@ -507,8 +491,8 @@ variables: // Time interpolation variable char time_interpolation ; time_interpolation:interpolation_name = "bi_linear" ; - time_interpolation:tie_point_mapping = "track: track_indices tp_track - scan: time_scan_indices tp_time_scan" ; + time_interpolation:tie_point_mapping = "track: track_indices tp_track scan: time_scan_indices tp_time_scan" ; + time_interpolation:computational_precision = "64" // Time tie points double t(tp_track, tp_time_scan) ; @@ -555,14 +539,17 @@ variables: char bi_linear ; bi_linear:interpolation_name = "bi_linear" ; bi_linear:tie_point_mapping = "y: y_indices tp_y x: x_indices tp_x" ; + bi_linear:computational_precision = "64" char linear_x ; - linear:interpolation_name = "linear" ; - linear:tie_point_mapping = "x: x_indices tp_x" ; + linear_x:interpolation_name = "linear" ; + linear_x:tie_point_mapping = "x: x_indices tp_x" ; + linear_x:computational_precision = "64" char linear_y ; - linear:interpolation_name = "linear" ; - linear:tie_point_mapping = "y: y_indices tp_y" ; + linear_y:interpolation_name = "linear" ; + linear_y:tie_point_mapping = "y: y_indices tp_y" ; + linear_y:computational_precision = "64" // tie point coordinate variables double time(time) ; @@ -597,7 +584,7 @@ given by the **`tie_point_mapping`** attribute. ==== -[[compression-by-coordinate-subsampling-interpolation-of-cell-boundaries, Section 8.3.10, "Interpolation of Cell Boundaries"]] +[[compression-by-coordinate-subsampling-interpolation-of-cell-boundaries, Section 8.3.9, "Interpolation of Cell Boundaries"]] ==== Interpolation of Cell Boundaries Coordinates may have cell bounds. Equivalently to the way coordinates can be stored as coordinate tie points and reconstituted through interpolation, contiguous cell bounds of interpolated dimensions can be stored as __bounds tie points__ and reconstituted through interpolation. In this process, the coordinate tie points are a prerequisite for the bounds tie points and the same interpolation method used for the coordinate interpolation is used for the bounds interpolation. @@ -679,12 +666,12 @@ variables: char bl_interpolation ; bl_interpolation:interpolation_name = "bi_linear" ; bl_interpolation:tie_point_mapping = "ic: i_indices itp jc: j_indices jtp" ; + bl_interpolation:computational_precision = "64" // Tie point index variables int i_indices(itp) ; int j_indices(jtp) ; - // Tie point coordinate variables double lat(jtp, itp) ; lat:units = "degrees_north" ; @@ -702,3 +689,23 @@ variables: ---- ==== + +[[compression-by-coordinate-subsampling-interpolation-method-implementation, Section 8.3.10, "Interpolation Method Implementation"]] +==== Interpolation Method Implementation + +The accuracy of the reconstituted coordinates depends mainly on the degree of subsampling and the choice of interpolation method, both of which are set by the creator of the dataset. The accuracy and reproducibility will also depend, however, on how the interpolation method is implemented and on the computer platform carrying out the computations. To facilitate a good level of reproducibility of the processes of compressing and uncompressing coordinates, requirements are placed on the specification of interpolation methods and on stating the computational precision. + +**Interpolation Method Specification** + +The interpolation method specifications provided in Appendix J are complete in their description of steps and formulas required for compressing and uncompressing coordinate data. Formulas are structured in a way that encourages an efficient implementation of the interpolation method in a high-level programming language. For instance, expressions that are constant within a computational loop should be externalised from that loop. + +**Computational Precision Attribute** + +The data creator shall specify the floating-point arithmetic precision used during the preparation and validation of the compressed coordinates by setting the interpolation variable’s **`computational_precision**` attribute to one of the following values: + +[cols="3,10"] +|=============== +| ** Value ** | ** Description** +| "32" | 32-bit floating-point arithmetic, comparable to the binary32 standard in [<>] +| "64" | 64-bit floating-point arithmetic, comparable to the binary64 standard in [<>] +|=============== + +Using the given computational precision in the interpolation computations is a necessary, but not sufficient, condition for the data user to be able to reconstitute the coordinates to an accuracy comparable to that intended by the data creator. For instance, a **`computational_precision**` value of **`"64"**` would specify that, using the same implementation and hardware as the creator of the compressed dataset, sufficient accuracy could not be reached when using a floating-point precision lower than 64-bit floating-point arithmetic in the interpolation computations required to reconstitute the coordinates. \ No newline at end of file From 2711322ced19d5597f3fa69fc0941bdce8eb7c55 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Mon, 2 Aug 2021 09:52:51 +0200 Subject: [PATCH 238/249] Correct section link --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 1e49d03d..a8ae0acd 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -197,7 +197,7 @@ interpolation subarea basis, for which the construction of the uncompressed coordinates may only access those tie points that define the extent of the of the interpolation subarea. -In addition to the **`interpolation_name`** and **`interpolation_description`** attributes described in this section, further attributes of the interpolation variable are described in <> and <>, <> and <>. +In addition to the **`interpolation_name`** and **`interpolation_description`** attributes described in this section, further attributes of the interpolation variable are described in <> and <>, <> and <>. [[compression-by-coordinate-subsampling-dimensions,Section 8.3.4, "Subsampled, Interpolated and Non-Interpolated Dimensions"]] ==== Subsampled, Interpolated and Non-Interpolated Dimensions From be8f18da851a6835a7de60695ac0ae6dc5d1c9d6 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 3 Aug 2021 08:16:26 +0200 Subject: [PATCH 239/249] Minor editorial corrections --- ch08.adoc | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/ch08.adoc b/ch08.adoc index a8ae0acd..38ecb3a6 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -329,7 +329,7 @@ variables: char bl_interpolation ; bl_interpolation:interpolation_name = "bi_linear" ; bl_interpolation:tie_point_mapping = "xc: x_indices tp_xc yc: y_indices tp_yc" ; - bl_interpolation:computational_precision = "64" + bl_interpolation:computational_precision = "64" ; // tie point coordinate variables double lat(tp_yc, tp_xc) ; @@ -371,7 +371,7 @@ variables: char l_interpolation ; l_interpolation:interpolation_name = "linear" ; l_interpolation:tie_point_mapping = "xc: x_indices tp_xc" ; - l_interpolation:computational_precision = "64" + l_interpolation:computational_precision = "64" ; // tie point coordinate variables double lat(yc, tp_xc) ; @@ -459,9 +459,10 @@ variables: // Interpolation variable char tp_interpolation ; tp_interpolation:interpolation_name = "bi_quadratic_latitude_longitude" ; - tp_interpolation:tie_point_mapping = "track: track_indices tp_track subarea_track scan: scan_indices tp_scan subarea_scan" ; + tp_interpolation:tie_point_mapping = "track: track_indices tp_track subarea_track + scan: scan_indices tp_scan subarea_scan" ; tp_interpolation:interpolation_parameters = "ce1: ce1 ca2: ca2 ce3: ce3 flags: interpolation_subarea_flags" ; - tp_interpolation:computational_precision = "32" + tp_interpolation:computational_precision = "32" ; // Interpolation parameters short ce1(tp_track , subarea_scan) ; @@ -492,11 +493,11 @@ variables: char time_interpolation ; time_interpolation:interpolation_name = "bi_linear" ; time_interpolation:tie_point_mapping = "track: track_indices tp_track scan: time_scan_indices tp_time_scan" ; - time_interpolation:computational_precision = "64" + time_interpolation:computational_precision = "64" ; // Time tie points double t(tp_track, tp_time_scan) ; - t:standard_name = "time" ; ; + t:standard_name = "time" ; t:units = "days since 1990-1-1 0:0:0" ; ---- @@ -539,17 +540,17 @@ variables: char bi_linear ; bi_linear:interpolation_name = "bi_linear" ; bi_linear:tie_point_mapping = "y: y_indices tp_y x: x_indices tp_x" ; - bi_linear:computational_precision = "64" + bi_linear:computational_precision = "64" ; char linear_x ; linear_x:interpolation_name = "linear" ; linear_x:tie_point_mapping = "x: x_indices tp_x" ; - linear_x:computational_precision = "64" + linear_x:computational_precision = "64" ; char linear_y ; linear_y:interpolation_name = "linear" ; linear_y:tie_point_mapping = "y: y_indices tp_y" ; - linear_y:computational_precision = "64" + linear_y:computational_precision = "64" ; // tie point coordinate variables double time(time) ; @@ -593,7 +594,7 @@ For the reconstituted coordinates, cell bounds are stored separately for each co for the example of 2D bounds. Since the cell bounds are contiguous, bounds points of adjacent cells will coincide and so the full set of bounds points may be represented as a grid, comparable to the coordinate points grid. In the middle part of <> , both the reconstituted bounds points grid and the reconstituted coordinate points grid are shown for a continuous area, where each bounds point may be shared by up to four cells. -Bounds interpolation uses the same tie point index variables and therefore the same tie point cells as coordinate interpolation. One of the vertices of each coordinate tie point cell is chosen as the bounds tie point for the cell. It is selected as the vertex of the tie point cell that is the closest to the boundary of the interpolation subarea with respect to each interpolated dimension. For the example of 2D bounds, the resulting set of bounds tie points are marked in <>, where the selected vertices are those closets to the corners of the interpolation subareas. +Bounds interpolation uses the same tie point index variables and therefore the same tie point cells as coordinate interpolation. One of the vertices of each coordinate tie point cell is chosen as the bounds tie point for the cell. It is selected as the vertex of the tie point cell that is the closest to the boundary of the interpolation subarea with respect to each interpolated dimension. For the example of 2D bounds, the resulting set of bounds tie points are marked in <>, where the selected vertices are those closest to the corners of the interpolation subareas. Note that within a continuous area, there is one more reconstituted bounds point than there are reconstituted coordinate points in each dimension. For this reason, a virtual __interpolated bounds dimension__ is introduced for each dimension, having a size equal to the size of the interpolated dimension plus one. This dimension is used for solely descriptive purposes, and is not required in a compressed dataset. @@ -666,7 +667,7 @@ variables: char bl_interpolation ; bl_interpolation:interpolation_name = "bi_linear" ; bl_interpolation:tie_point_mapping = "ic: i_indices itp jc: j_indices jtp" ; - bl_interpolation:computational_precision = "64" + bl_interpolation:computational_precision = "64" ; // Tie point index variables int i_indices(itp) ; From b2bb0176c7be721fe6e4e9c42264cb66fe476abc Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 3 Aug 2021 08:54:29 +0200 Subject: [PATCH 240/249] Corrections of typos --- appj.adoc | 26 +++++++++++++------------- ch08.adoc | 14 +++++++------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/appj.adoc b/appj.adoc index e3a2d926..9d187c0a 100644 --- a/appj.adoc +++ b/appj.adoc @@ -2,14 +2,14 @@ [appendix] == Coordinate Subsampling Methods -The general description of of the compression by coordinate subsampling is given in section <>. This appendix provides details on the available methods for compression by coordinate subsampling. +The general description of the compression by coordinate subsampling is given in section <>. This appendix provides details on the available methods for compression by coordinate subsampling. The definitions and guidance given here allow an application to compress an existing data set using coordinate subsampling, while letting the creator of the compressed dataset control the accuracy of the reconstituted coordinates through the degree of subsampling, the choice of interpolation method and by setting the computational precision. Futhermore, the definitions given here allow an application to uncompress coordinate and auxiliary coordinate variables that have been compressed using coordinate subsampling. The key element of this process is the reconstitution of the full resolution coordinates in the domain of the data by interpolation between the subsampled coordinates, the tie points, stored in the compressed dataset. -The appendix is organised in a sections on <>, <>, <> and finally two sections with step procedures <> and <>. +The appendix is organised in a sections on <>, <>, <> and finally two sections with step procedures <> and <>. [[common-definitions-and-notation, Section J.1, "Common Definitions and Notation"]] === Common Definitions and Notation @@ -18,7 +18,7 @@ The coordinate interpolation methods are named to indicate the number of dimensi When an interpolation method is referred to as linear or quadratic, it means that the method is linear or quadratic in the indices of the interpolated dimensions. -For convenience, an interpolation argument `s` is introduced, calculated as a function of the index in the target domain of the coordinate value to be reconstituted. In the case of one dimensional interpolation the variable is computed as +For convenience, an interpolation argument `s` is introduced, calculated as a function of the index in the target domain of the coordinate value to be reconstituted. In the case of one-dimensional interpolation the variable is computed as `s = s(ia, ib, i) = (i - ia)/(ib - ia)` @@ -26,7 +26,7 @@ where `ia` and `ib` are the indices in the target domain of the tie points `A` a Note that the value of `s` varies from `0.0` at the tie point `A` to `1.0` at tie point `B`. For example, if `ia = 100` and `ib = 110` and the index in the target domain of the coordinate value to be reconstituted is `i = 105`, then `s = (105 - 100)/(110 - 100) = 0.5`. -In the case of two dimensional interpolation, the interpolation arguments are similarly computed as +In the case of two-dimensional interpolation, the interpolation arguments are similarly computed as `s1 = s(ia1, ib1, i1) = (i1 - ia1)/(ib1 - ia1)` + `s2 = s(ia2, ic2, i2) = (i2 - ia2)/(ic2 - ia2)` @@ -54,10 +54,10 @@ For the reconstitution of the uncompressed coordinate and auxiliary coordinate v The following notation is used: + A variable staring with `v` denotes a vector and `v.x` , `v.y` and `v.z` refer to the three coordinates of that vector. + A variable staring with `ll` denotes a latitude-longitude coordinate pair and `ll.lat` and `ll.lon` refer to the latitude and longitude coordinates. + -For one dimensional interpolation, `i` is an index in the interpolated dimension, `tpi` is an index in the subsampled dimension and `is` is an index in the interpolation subarea dimensions. -For two dimensional interpolation, `i1` and `i2` are indices in the interpolated dimensions, `tpi1` and `tpi2` are indices in the subsampled dimensions and `is1` and `is2` are indices in the interpolation subarea dimensions. + +For one-dimensional interpolation, `i` is an index in the interpolated dimension, `tpi` is an index in the subsampled dimension and `is` is an index in the interpolation subarea dimensions. +For two-dimensional interpolation, `i1` and `i2` are indices in the interpolated dimensions, `tpi1` and `tpi2` are indices in the subsampled dimensions and `is1` and `is2` are indices in the interpolation subarea dimensions. + -Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refer to these with `a` and `b` in the one dimensional case and with `a`, `b`, `c` and `d` in the two dimensional case. In the two dimensional case, `a = tp(tpi2, tpi1)`, `b = tp(tpi2, tpi1+1)`, `c = tp(tpi2+1, tpi1)` and `d = tp(tpi2+1, tpi1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. +Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refer to these with `a` and `b` in the one-dimensional case and with `a`, `b`, `c` and `d` in the two-dimensional case. In the two-dimensional case, `a = tp(tpi2, tpi1)`, `b = tp(tpi2, tpi1+1)`, `c = tp(tpi2+1, tpi1)` and `d = tp(tpi2+1, tpi1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. [[common-conversions-and-formulas, Section J.2, "Common Conversions and Formulas"]] @@ -100,7 +100,7 @@ Note that, for simplicity of notation, the descriptions of the interpolation met [cols="6,15"] |=============== | Name | **`interpolation_name = "linear"`** -| Description | General purpose one dimensional linear interpolation method for one or more coordinates +| Description | General purpose one-dimensional linear interpolation method for one or more coordinates | Interpolation Parameter terms | None | Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | @@ -115,7 +115,7 @@ where `ua` and `ub` are the coordinate values at tie points `A` and `B` respecti [cols="6,15"] |=============== | Name | **`interpolation_name = "bi_linear"`** -| Description | General purpose two dimensional linear interpolation method for one or more coordinates +| Description | General purpose two-dimensional linear interpolation method for one or more coordinates | Interpolation Parameter terms | None | Coordinate Compression Calculations | None | Coordinate Uncompression Calculations | @@ -133,7 +133,7 @@ The interpolation function fl() defined for linear interpolation above is first [cols="6,15"] |=============== | Name | **`interpolation_name = "quadratic"`** -| Description | General purpose one dimensional quadratic interpolation method for one coordinate. +| Description | General purpose one-dimensional quadratic interpolation method for one coordinate. | Interpolation Parameter terms | Optionally coefficient `w`, which must span the interpolation subarea dimension. @@ -154,7 +154,7 @@ where `ua` and `ub` are the coordinate values at tie points `A` and `B` respecti [cols="6,15"] |=============== | Name | **`interpolation_name = "quadratic_latitude_longitude"`** -| Description | A one dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. + +| Description | A one-dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. + Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. For each interpolation subarea, none of the tie points defining the interpolation subarea are permitted to coincide. @@ -166,7 +166,7 @@ Although equivalent to a tie point, the coefficients `ce` and `ca` have two adva The coefficients may be represented in three different ways: -For storage in the dataset as the non-dimensional coefficients `cea = (ce, ca)`, referred to as the parametric representation. The component `ce` is the offset projected on the line from tie point `B` to tie point `A` and expressed as a fraction of the distance between `A` and `B`. The component `ca` is the offset projected on the line perpendicular to the line from tie point `B` to tie point `A` and perpendicular to the plane spanned by `va` and `vb`, the vector representations of the two tie points, and expressed as a fraction of the length of `A x B`. + +For storage in the dataset as the non-dimensional coefficients `cea = (ce, ca)`, referred to as the parametric representation. The component `ce` is the offset projected on the line from tie point `B` to tie point `A` and expressed as a fraction of the distance between `A` and `B`. The component `ca` is the offset projected on the line perpendicular to the line from tie point `B` to tie point `A` and perpendicular to the plane spanned by `va` and `vb`, the vector representations of the two tie points, and expressed as a fraction of the length of `A x B`. + For interpolation in three-dimensional cartesian coordinates as the coefficients `cv = (cv.x, cv.y, cv.z)`, expressing the offset components along the three-dimensional cartesian axes X, Y and Z respectively. @@ -224,7 +224,7 @@ image::images/ci_quadratic2.svg[,100%,pdfwidth=50vw,align="center"] [cols="6,15"] |=============== | Name | **`interpolation_name = "bi_quadratic_latitude_longitude"`** -| Description | A two dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. +| Description | A two-dimensional quadratic method for interpolation of the geographic coordinates latitude and longitude, typically used for remote sensing products with geographic coordinates on the reference ellipsoid. Requires a pair of latitude and longitude tie point variables, as defined unambiguously in <> and <>. For each interpolation subarea, none of the tie points defining the interpolation subarea are permitted to coincide. diff --git a/ch08.adoc b/ch08.adoc index 38ecb3a6..0fe537cb 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -133,9 +133,9 @@ in <>, and described in more detail in For each __interpolated dimension__, i.e. a target domain dimension for which coordinate interpolation is required, the locations of the tie point coordinates are defined by a corresponding __tie point index variable__, which also indicates the locations of the continuous areas (<>). -The interpolation subareas within a continuous area do not overlap, ensuring that each coordinate of an interpolated dimension is computed from a unique interpolation subarea. These interpolation subareas, however, share the tie point coordinates that define their common boundaries. Such a shared tie point coordinate can only be located in one of a pair of adjacent interpolation subareas, which is always the first of the pair in index space. For instance, in <>, the interpolation subarea labeled `(0,0)` contains all four of its tie point coordinates, and the interpolation subarea `(0,1)` only contains two of them. When applied for a given interpolation subarea, interpolation methods (such as those described in <>) must ensure that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. +The interpolation subareas within a continuous area do not overlap, ensuring that each coordinate of an interpolated dimension is computed from a unique interpolation subarea. These interpolation subareas, however, share the tie point coordinates that define their common boundaries. Such a shared tie point coordinate can only be located in one of a pair of adjacent interpolation subareas, which is always the first of the pair in index space. For instance, in <>, the interpolation subarea labelled `(0,0)` contains all four of its tie point coordinates, and the interpolation subarea `(0,1)` only contains two of them. When applied for a given interpolation subarea, interpolation methods (such as those described in <>) must ensure that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. -Adjacent interpolation subareas that are in different continuous areas never share tie point coordinates, as consequence of the grid discontinuity between them. This results in a different number of tie point coordinates in the two cases shown in <>. +Adjacent interpolation subareas that are in different continuous areas never share tie point coordinates, as consequence of the grid discontinuity between them. This results in a different number of tie point coordinates in the two cases shown in <>. For each interpolated dimension, the number of interpolation subareas is equal to the number of tie points minus the number of continuous areas. @@ -222,7 +222,7 @@ interpolated dimension cannot be included. The size of a subsampled dimension will be less than the size of the corresponding interpolated dimension. For example, if the -interpolated dimensions are `xc = 30` and `yc = 10`, interpolation +interpolated dimensions are `xc = 30` and `yc = 10`, interpolation could be applied in both of these dimensions, based on tie point variables of the dimensions `tp_xc = 4` and `tp_yc = 2`. Here, `tp_xc` is the subsampled dimension related to the @@ -270,7 +270,7 @@ to an interpolation subarea dimension in the case that the interpolation subarea dimension is spanned by an interpolation parameter variable, as described in <>. -If an interpolation subarea dimension is provided then it must be +If an interpolation subarea dimension is provided, then it must be the second of the two named dimensions following the tie point index variable. Note that the size of an interpolation subarea dimension is, by definition, the size of the corresponding subsampled dimension minus the number of continuous areas. @@ -591,8 +591,8 @@ given by the **`tie_point_mapping`** attribute. Coordinates may have cell bounds. Equivalently to the way coordinates can be stored as coordinate tie points and reconstituted through interpolation, contiguous cell bounds of interpolated dimensions can be stored as __bounds tie points__ and reconstituted through interpolation. In this process, the coordinate tie points are a prerequisite for the bounds tie points and the same interpolation method used for the coordinate interpolation is used for the bounds interpolation. For the reconstituted coordinates, cell bounds are stored separately for each coordinate point, as shown in the left part of <> -for the example of 2D bounds. Since the cell bounds are contiguous, bounds points of adjacent cells will coincide and so the full set of bounds points may be represented as a grid, comparable to the coordinate points grid. In the middle part of <> -, both the reconstituted bounds points grid and the reconstituted coordinate points grid are shown for a continuous area, where each bounds point may be shared by up to four cells. +for the example of 2D bounds. Since the cell bounds are contiguous, bounds points of adjacent cells will coincide and so the full set of bounds points may be represented as a grid, comparable to the coordinate points grid. In the middle part of <> +, both the reconstituted bounds points grid and the reconstituted coordinate points grid are shown for a continuous area, where each bounds point may be shared by up to four cells. Bounds interpolation uses the same tie point index variables and therefore the same tie point cells as coordinate interpolation. One of the vertices of each coordinate tie point cell is chosen as the bounds tie point for the cell. It is selected as the vertex of the tie point cell that is the closest to the boundary of the interpolation subarea with respect to each interpolated dimension. For the example of 2D bounds, the resulting set of bounds tie points are marked in <>, where the selected vertices are those closest to the corners of the interpolation subareas. @@ -634,7 +634,7 @@ For two-dimensional bound interpolation, an interpolation subarea is defined by **Bounds Tie Point Attribute and Bounds Tie Point Variable** + A **`bounds_tie_points`** attribute must be defined for each tie point coordinate variable corresponding to reconstituted coordinates with cell boundaries. It is a single word of the form __“bounds_tie_point_variable”__ that identifies a bounds tie point variable, containing a bounds tie point coordinate value for each tie point stored in its tie point coordinate variable, and therefore the bounds tie point variable has the same set of dimensions as its tie point coordinate variable. An example of the usage of the **`bounds_tie_points`** is shown in <>. Since a bounds tie point variable is considered to be part of a tie point coordinate variable’s metadata, it is not necessary to provide it with attributes such as long_name and units, following the same rules as for the bounds of an uncompressed coordinate variable, see <>. -**Uncompressing coordinate bounds** + +**Uncompressing coordinate bounds** + The reconstitution of the full set of bounds from the bounds tie point is a two-step process. In a first step, which must be carried out for a full continuous area at a time, each bound point is reconstituted by interpolation between the bounds tie points within each interpolation subarea, using the same interpolation method as defined for the ordinary tie points. This step results in a grid of bound points spanning the interpolated bound dimensions. In a second step the reconstituted bounds vertices are replicated to the boundary variables of the reconstituted coordinates. **Uncompressing one-dimensional coordinate bounds** + From b6cd5e6ceb6e7cdbc1af2debe884d16263748923 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 3 Aug 2021 08:57:02 +0200 Subject: [PATCH 241/249] Correct Futhermore -> Furthermore --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index 9d187c0a..73c34528 100644 --- a/appj.adoc +++ b/appj.adoc @@ -6,7 +6,7 @@ The general description of the compression by coordinate subsampling is given in The definitions and guidance given here allow an application to compress an existing data set using coordinate subsampling, while letting the creator of the compressed dataset control the accuracy of the reconstituted coordinates through the degree of subsampling, the choice of interpolation method and by setting the computational precision. -Futhermore, the definitions given here allow an application to uncompress coordinate and auxiliary coordinate variables that have been compressed using coordinate subsampling. The key element of this process is the reconstitution of the full resolution coordinates in the domain of the data by interpolation between the subsampled coordinates, the tie points, stored in the compressed dataset. +Furthermore, the definitions given here allow an application to uncompress coordinate and auxiliary coordinate variables that have been compressed using coordinate subsampling. The key element of this process is the reconstitution of the full resolution coordinates in the domain of the data by interpolation between the subsampled coordinates, the tie points, stored in the compressed dataset. The appendix is organised in a sections on <>, <>, <> and finally two sections with step procedures <> and <>. From 5a7b198574f72f2541d5e13698ab8e05ec358e1d Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 27 Jul 2021 10:31:31 +0100 Subject: [PATCH 242/249] Minor wording improvements arising from review --- conformance.adoc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/conformance.adoc b/conformance.adoc index 38b19cdf..96ad2738 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -706,13 +706,14 @@ sizes minus 1 (CDL index conventions). text: **`tie_point_variable: [tie_point_variable: ...] interpolation_variable`**. Each **`tie_point_variable`** token specifies a tie point variable that must exist in the file, and each - **`interpolation_variable`** token specifies an interpolation - variable that must exist in the file. + **`interpolation_variable`** token specifies a variable that must + exist in the file. * An interpolation variable must have one of the string-valued attributes **`interpolation_name`** or **`interpolation_description`**, but not both. The legal values for - the **`interpolation_name`** attribute are contained in Appendix J. + the **`interpolation_name`** attribute are contained in the + Interpolation Methods section of Appendix J. * An interpolation variable must have a **`tie_point_dimensions`** attribute that is a string whose value is a list of blank separated @@ -769,10 +770,12 @@ sizes minus 1 (CDL index conventions). * When attached to an interpolation variable, the type of the **`interpolation_parameters`** attribute is a string whose value is - list of blank separated word pairs in the form **`term: var`**. The - legal values **`term`** are contained in Appendix J for each valid - **`interpolation_name`**. The values of **`var`** must be - interpolation parameter variables that exist in the file. + list of blank separated word pairs in the form **`term: var`**. For + each valid **`interpolation_name`**, the legal values for **`term`** + are described by the "Interpolation Parameter terms" table entry in + the Interpolation Methods section of Appendix J. The values of + **`var`** must be interpolation parameter variables that exist in + the file. * The dimensions of an interpolation parameter variable must be a subset of zero or more of the dimensions of the corresponding tie From ce754054b57291ccfd7a71d45e06d3d6cb7b3f6f Mon Sep 17 00:00:00 2001 From: David Hassell Date: Tue, 27 Jul 2021 10:49:21 +0100 Subject: [PATCH 243/249] Conformance for bounds tie points --- conformance.adoc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/conformance.adoc b/conformance.adoc index 96ad2738..2a09db0a 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -783,8 +783,25 @@ sizes minus 1 (CDL index conventions). dimension may be replaced with its corresponding interpolation zone dimension, as defined by the **`tie_point_dimensions`** mapping. +* If a tie point variable has **`bounds_tie_points`** attribute then + it must be a string whose value is a single variable name. The + specified variable must exist in the file. + +* A bounds tie point variable must have the same dimensions as its + associated tie points coordinate variable. + +* A bounds tie point variable must be a numeric data type. + +* A bounds tie point variable must not have the **`_FillValue`** or + **`missing_value`** attributes. The requirements on all other bounds + tie point variable attributes are the same as for bounds variables + described in <>. + *Recommendations:* * An interpolation variable should have 0 dimensions. +* The recommendations on bounds tie point variable attributes are the + same as for bounds variables described in <>. +   From b431e9df8a00a7dea82469c1de2ea05d9448337a Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 2 Aug 2021 12:38:08 +0100 Subject: [PATCH 244/249] computational_precision conformance --- conformance.adoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conformance.adoc b/conformance.adoc index 2a09db0a..05830487 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -715,6 +715,9 @@ sizes minus 1 (CDL index conventions). the **`interpolation_name`** attribute are contained in the Interpolation Methods section of Appendix J. +* An interpolation variable must have the attribute **`computational_precision`**. + The legal values for the **`computational_precision`** attribute are contained in the Interpolation Method Implementation subsection of the Lossy Compression by Coordinate Subsampling section of chapter 8. + * An interpolation variable must have a **`tie_point_dimensions`** attribute that is a string whose value is a list of blank separated word groups of the following form, in which brackets indicate From 062debe2fb03cd7d48eaad0a84ec9044fded3980 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 3 Aug 2021 15:37:49 +0200 Subject: [PATCH 245/249] Correct references --- appa.adoc | 6 +++--- appj.adoc | 6 +++--- ch08.adoc | 15 +++++++-------- conformance.adoc | 9 +++++---- history.adoc | 12 ++++++------ 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/appa.adoc b/appa.adoc index 754ba42b..2bae4802 100644 --- a/appa.adoc +++ b/appa.adoc @@ -309,11 +309,11 @@ formula in the definition. | <> | A standard name that references a description of a variable"s content in the standard name table. -| **`tie_points`** +| **`coordinate_interpolation`** | S | D, Do -| <> -| Indicates that coordinates have been compressed by sampling and identifies the tie point variables and their associated interpolation variables. +| <> +| Indicates that coordinates have been compressed by sampling and identifies the tie point coordinate variables and their associated interpolation variables. | **`title`** | S diff --git a/appj.adoc b/appj.adoc index 73c34528..b25c2511 100644 --- a/appj.adoc +++ b/appj.adoc @@ -1,6 +1,6 @@ -[[appendix-coordinate-subsampling, Appendix J, Coordinate Subsampling]] +[[appendix-coordinate-subsampling, Appendix J, Coordinate Interpolation Methods]] [appendix] -== Coordinate Subsampling Methods +== Coordinate Interpolation Methods The general description of the compression by coordinate subsampling is given in section <>. This appendix provides details on the available methods for compression by coordinate subsampling. @@ -57,7 +57,7 @@ A variable staring with `ll` denotes a latitude-longitude coordinate pair and `l For one-dimensional interpolation, `i` is an index in the interpolated dimension, `tpi` is an index in the subsampled dimension and `is` is an index in the interpolation subarea dimensions. For two-dimensional interpolation, `i1` and `i2` are indices in the interpolated dimensions, `tpi1` and `tpi2` are indices in the subsampled dimensions and `is1` and `is2` are indices in the interpolation subarea dimensions. + -Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refer to these with `a` and `b` in the one-dimensional case and with `a`, `b`, `c` and `d` in the two-dimensional case. In the two-dimensional case, `a = tp(tpi2, tpi1)`, `b = tp(tpi2, tpi1+1)`, `c = tp(tpi2+1, tpi1)` and `d = tp(tpi2+1, tpi1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. +Note that, for simplicity of notation, the descriptions of the interpolation methods in most places leave out the indices of tie point related variables and refer to these with `a` and `b` in the one-dimensional case and with `a`, `b`, `c` and `d` in the two-dimensional case. In the two-dimensional case, `a = tp(tpi2, tpi1)`, `b = tp(tpi2, tpi1+1)`, `c = tp(tpi2+1, tpi1)` and `d = tp(tpi2+1, tpi1+1)` would reflect the way the tie point data would be stored in the data set, see also <>. [[common-conversions-and-formulas, Section J.2, "Common Conversions and Formulas"]] diff --git a/ch08.adoc b/ch08.adoc index 0fe537cb..14755120 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -88,7 +88,7 @@ assumed that these errors will be small enough to not be of concern to users of the uncompressed dataset. The creator of the compressed dataset can control the accuracy of the reconstituted coordinates through the degree of subsampling and the choice of interpolation -method, see <>. +method, see <>. The subsampled coordinates are called __tie points__ and are stored in __tie point coordinate variables__. @@ -129,11 +129,11 @@ continuous area is segmented into interpolation subareas. The processes of generating interpolation subareas for a domain without discontinuities and for a domain with discontinuities is illustrated in <>, and described in more detail in -<>. +<>. For each __interpolated dimension__, i.e. a target domain dimension for which coordinate interpolation is required, the locations of the tie point coordinates are defined by a corresponding __tie point index variable__, which also indicates the locations of the continuous areas (<>). -The interpolation subareas within a continuous area do not overlap, ensuring that each coordinate of an interpolated dimension is computed from a unique interpolation subarea. These interpolation subareas, however, share the tie point coordinates that define their common boundaries. Such a shared tie point coordinate can only be located in one of a pair of adjacent interpolation subareas, which is always the first of the pair in index space. For instance, in <>, the interpolation subarea labelled `(0,0)` contains all four of its tie point coordinates, and the interpolation subarea `(0,1)` only contains two of them. When applied for a given interpolation subarea, interpolation methods (such as those described in <>) must ensure that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. +The interpolation subareas within a continuous area do not overlap, ensuring that each coordinate of an interpolated dimension is computed from a unique interpolation subarea. These interpolation subareas, however, share the tie point coordinates that define their common boundaries. Such a shared tie point coordinate can only be located in one of a pair of adjacent interpolation subareas, which is always the first of the pair in index space. For instance, in <>, the interpolation subarea labelled `(0,0)` contains all four of its tie point coordinates, and the interpolation subarea `(0,1)` only contains two of them. When applied for a given interpolation subarea, interpolation methods (such as those described in <>) must ensure that reconstituted coordinate points are only generated inside the interpolation subarea being processed, even if some of the tie point coordinates lie outside of that interpolation subarea. Adjacent interpolation subareas that are in different continuous areas never share tie point coordinates, as consequence of the grid discontinuity between them. This results in a different number of tie point coordinates in the two cases shown in <>. @@ -167,8 +167,7 @@ that contains the method's name, or else by the that contains a non-standardized description of the method. These attributes must not be both set. -The valid values of **`interpolation_name`** are given in <>. This appendix describes the interpolation technique for each +The valid values of **`interpolation_name`** are given in <>. This appendix describes the interpolation technique for each method, and optional interpolation variable attributes for configuring the interpolation process. @@ -402,7 +401,7 @@ process. The **`interpolation_parameters`** attribute takes a string value, the string comprising blank-separated elements of the form `"term: variable"`, where `term` is a case-insensitive keyword that defines one of the terms in the interpolation method's definition -given in <>, and `variable` is the name of the +given in <>, and `variable` is the name of the interpolation parameter variable that contains the values for that term. The order of elements is not significant. A numerical term that is omitted from the **`interpolation_parameters`** attribute should be @@ -697,7 +696,7 @@ variables: The accuracy of the reconstituted coordinates depends mainly on the degree of subsampling and the choice of interpolation method, both of which are set by the creator of the dataset. The accuracy and reproducibility will also depend, however, on how the interpolation method is implemented and on the computer platform carrying out the computations. To facilitate a good level of reproducibility of the processes of compressing and uncompressing coordinates, requirements are placed on the specification of interpolation methods and on stating the computational precision. **Interpolation Method Specification** + -The interpolation method specifications provided in Appendix J are complete in their description of steps and formulas required for compressing and uncompressing coordinate data. Formulas are structured in a way that encourages an efficient implementation of the interpolation method in a high-level programming language. For instance, expressions that are constant within a computational loop should be externalised from that loop. +The interpolation method specifications provided in <> are complete in their description of steps and formulas required for compressing and uncompressing coordinate data. Formulas are structured in a way that encourages an efficient implementation of the interpolation method in a high-level programming language. For instance, expressions that are constant within a computational loop should be externalised from that loop. **Computational Precision Attribute** + The data creator shall specify the floating-point arithmetic precision used during the preparation and validation of the compressed coordinates by setting the interpolation variable’s **`computational_precision**` attribute to one of the following values: @@ -709,4 +708,4 @@ The data creator shall specify the floating-point arithmetic precision used duri | "64" | 64-bit floating-point arithmetic, comparable to the binary64 standard in [<>] |=============== -Using the given computational precision in the interpolation computations is a necessary, but not sufficient, condition for the data user to be able to reconstitute the coordinates to an accuracy comparable to that intended by the data creator. For instance, a **`computational_precision**` value of **`"64"**` would specify that, using the same implementation and hardware as the creator of the compressed dataset, sufficient accuracy could not be reached when using a floating-point precision lower than 64-bit floating-point arithmetic in the interpolation computations required to reconstitute the coordinates. \ No newline at end of file +Using the given computational precision in the interpolation computations is a necessary, but not sufficient, condition for the data user to be able to reconstitute the coordinates to an accuracy comparable to that intended by the data creator. For instance, a **`computational_precision**` value of **`"64"**` would specify that, using the same implementation and hardware as the creator of the compressed dataset, sufficient accuracy could not be reached when using a floating-point precision lower than 64-bit floating-point arithmetic in the interpolation computations required to reconstitute the coordinates. diff --git a/conformance.adoc b/conformance.adoc index 05830487..0c1c01a9 100644 --- a/conformance.adoc +++ b/conformance.adoc @@ -695,8 +695,8 @@ in the file. starting with 0 and going up to the product of the compressed dimension sizes minus 1 (CDL index conventions). -[[compression-by-coordinate-sampling]] -=== 8.3 Lossy Compression by Coordinate Sampling +[[compression-by-coordinate-subsampling]] +=== 8.3 Lossy Compression by Coordinate Subsampling *Requirements:* @@ -713,7 +713,7 @@ sizes minus 1 (CDL index conventions). attributes **`interpolation_name`** or **`interpolation_description`**, but not both. The legal values for the **`interpolation_name`** attribute are contained in the - Interpolation Methods section of Appendix J. + Interpolation Methods section of http://cfconventions.org/cf-conventions/cf-conventions.html#appendix-coordinate-subsampling[Appendix J]. * An interpolation variable must have the attribute **`computational_precision`**. The legal values for the **`computational_precision`** attribute are contained in the Interpolation Method Implementation subsection of the Lossy Compression by Coordinate Subsampling section of chapter 8. @@ -776,7 +776,8 @@ sizes minus 1 (CDL index conventions). list of blank separated word pairs in the form **`term: var`**. For each valid **`interpolation_name`**, the legal values for **`term`** are described by the "Interpolation Parameter terms" table entry in - the Interpolation Methods section of Appendix J. The values of + the Interpolation Methods section of http://cfconventions.org/cf-conventions/cf-conventions.html#appendix-coordinate-subsampling[Appendix J]. + The values of **`var`** must be interpolation parameter variables that exist in the file. diff --git a/history.adoc b/history.adoc index db8429dd..46739f98 100644 --- a/history.adoc +++ b/history.adoc @@ -1,12 +1,6 @@ [[revhistory, Revision History]] == Revision History -.Pending -. Added <>. -. Updated definitions in chapter 1 and Appendix A -. Added <>. - - .14 June 2004 . Added <>. . <> : Added **`latitude_of_projection_origin`** map parameter. @@ -284,3 +278,9 @@ node coordinate variables to be one of the dimensions of the data variable. .10 March 2021 . link:$$https://github.com/cf-convention/cf-conventions/issues/313$$[Issue #313]: Clarification of the handling of leap seconds + +.Pending +. Added <>. +. Updated definitions in chapter 1 and Appendix A +. Added <>. + From 7802b6ec8d3f33237472a81ed106b5ca74662e02 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 3 Aug 2021 16:50:57 +0200 Subject: [PATCH 246/249] Move coordinate_interpolation to correct alphabetic position in table --- appa.adoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/appa.adoc b/appa.adoc index 2bae4802..6495730a 100644 --- a/appa.adoc +++ b/appa.adoc @@ -115,6 +115,12 @@ formula in the definition. | link:$$http://www.unidata.ucar.edu/software/netcdf/docs/attribute_conventions.html$$[NUG Appendix A, "Attribute Conventions"] | Name of the conventions followed by the dataset. +| **`coordinate_interpolation`** +| S +| D, Do +| <> +| Indicates that coordinates have been compressed by sampling and identifies the tie point coordinate variables and their associated interpolation variables. + | **`coordinates`** | S | D, M, Do @@ -309,12 +315,6 @@ formula in the definition. | <> | A standard name that references a description of a variable"s content in the standard name table. -| **`coordinate_interpolation`** -| S -| D, Do -| <> -| Indicates that coordinates have been compressed by sampling and identifies the tie point coordinate variables and their associated interpolation variables. - | **`title`** | S | G, Gr From d28dfd1a4dfb3fe42ef3ed702d61cca05d8c8cdd Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 3 Aug 2021 16:54:25 +0200 Subject: [PATCH 247/249] Increase column width in Common Conversions and Formulas --- appj.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appj.adoc b/appj.adoc index b25c2511..06553dda 100644 --- a/appj.adoc +++ b/appj.adoc @@ -63,7 +63,7 @@ Note that, for simplicity of notation, the descriptions of the interpolation met [[common-conversions-and-formulas, Section J.2, "Common Conversions and Formulas"]] ==== Common Conversions and Formulas -[cols="1, 8, 8"] +[cols="2, 8, 8"] |=============== | |Description | Formula From c9892766a85437d6ea88034741244f411a9def8e Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Wed, 4 Aug 2021 14:13:41 +0200 Subject: [PATCH 248/249] Remove special character in cos() and sin() --- appj.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appj.adoc b/appj.adoc index 06553dda..4e379e13 100644 --- a/appj.adoc +++ b/appj.adoc @@ -67,11 +67,11 @@ Note that, for simplicity of notation, the descriptions of the interpolation met |=============== | |Description | Formula -| `fll2v` | Conversion from geocentric `(latitude, longitude)` to three-dimensional cartesian vector `(x, y, z)` | `(x, y, z) = fll2v(ll) = (cos⁡(ll.lat)*cos⁡(ll.lon), cos⁡(ll.lat)*sin⁡(ll.lon), sin⁡(ll.lat))` + +| `fll2v` | Conversion from geocentric `(latitude, longitude)` to three-dimensional cartesian vector `(x, y, z)` | `(x, y, z) = fll2v(ll) = (cos(ll.lat)*cos(ll.lon), cos(ll.lat)*sin(ll.lon), sin(ll.lat))` + | `fv2ll` | Conversion from three-dimensional cartesian vector `(x, y, z)` to geocentric `(latitude, longitude)`| `(lat, lon) = fv2ll(v) = (atan2(v.y, v.x), atan2(z, sqrt(v.x * v.x + v.y * v.y))` + -| `faz2v` | Conversion from `(azimuth, zenith)` angles to three-dimensional cartesian vector `(x, y, z)` | `(x, y, z) = faz2v(az) = (sin⁡(az.zenith) * sin⁡(az.azimuth), sin⁡(az.zenith) * cos⁡(az.azimuth), cos⁡(az.zenith))` + +| `faz2v` | Conversion from `(azimuth, zenith)` angles to three-dimensional cartesian vector `(x, y, z)` | `(x, y, z) = faz2v(az) = (sin(az.zenith) * sin(az.azimuth), sin(az.zenith) * cos(az.azimuth), cos(az.zenith))` + | `fv2az` | Conversion from three-dimensional cartesian vector `(x, y, z)` to `(azimuth, zenith)` angles | `(azimuth, zenith) = fv2az(v) = (atan2(y, x), atan2(sqrt(x * x + y * y), z)` + From b10fb673c6289bfe7585b33b7c5056b2c43abc90 Mon Sep 17 00:00:00 2001 From: AndersMS <63056394+AndersMS@users.noreply.github.com> Date: Tue, 10 Aug 2021 14:57:38 +0200 Subject: [PATCH 249/249] Clarify conditions for bounds interpolation --- ch08.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ch08.adoc b/ch08.adoc index 14755120..ef705716 100644 --- a/ch08.adoc +++ b/ch08.adoc @@ -587,7 +587,7 @@ given by the **`tie_point_mapping`** attribute. [[compression-by-coordinate-subsampling-interpolation-of-cell-boundaries, Section 8.3.9, "Interpolation of Cell Boundaries"]] ==== Interpolation of Cell Boundaries -Coordinates may have cell bounds. Equivalently to the way coordinates can be stored as coordinate tie points and reconstituted through interpolation, contiguous cell bounds of interpolated dimensions can be stored as __bounds tie points__ and reconstituted through interpolation. In this process, the coordinate tie points are a prerequisite for the bounds tie points and the same interpolation method used for the coordinate interpolation is used for the bounds interpolation. +Coordinates may have cell bounds. For the case that the reconstituted cells are contiguous and have exactly two cell bounds along each interpolated dimension, cell bounds of interpolated dimensions can be stored as __bounds tie points__ and reconstituted through interpolation. In this process, the coordinate tie points are a prerequisite for the bounds tie points and the same interpolation method used for the coordinate interpolation is used for the bounds interpolation. For the reconstituted coordinates, cell bounds are stored separately for each coordinate point, as shown in the left part of <> for the example of 2D bounds. Since the cell bounds are contiguous, bounds points of adjacent cells will coincide and so the full set of bounds points may be represented as a grid, comparable to the coordinate points grid. In the middle part of <>