## Tutorial: The Grid Feature Type

### Scientific Feature Types

The Common Data Model (CDM) Scientific Feature Type layer adds another layer of functionality on top of `NetcdfDataset`

, by specializing in various kinds of data that are common in Earth science.
The abstract concepts and concrete classes are continually evolving, and we have concentrated on, for obvious reasons, the types of datasets and data that Unidata is most familiar with, mainly from the atmospheric and ocean sciences.

All Scientific Feature Types have georeferencing coordinate systems, from which a location in real physical space and time can be found, usually with reference to the Earth.
Each adds special data subsetting methods which cannot be done efficiently or at all in the general case of `NetcdfDataset`

objects.

The Scientific Feature Type interface is currently undergoing significant change; this page serves as an overview of a conceptual goal, rather than documentation. For more information see the overview of Scientific Feature Types.

### The Grid Feature Type

A `GridCoordSystem`

at a minimum has a `Lat`

and `Lon`

coordinate axis, or a `GeoX`

and `GeoY`

coordinate axis plus a `Projection`

that maps x, y to lat, lon.
It usually has a time coordinate axis. It may optionally have a vertical coordinate axis, classified as `Height`

, `Pressure`

, or `GeoZ`

.
If it is a `GeoZ`

axis, it may have a vertical transform that maps `GeoZ`

to height or pressure. A `Grid`

may also optionally have a `Runtime`

and/or `Ensemble`

coordinate axis.

A `GridDataset`

(aka Grid) has a `GridCoordSystem`

, whose dimensions are all connected, meaning that neighbors in index space are connected neighbors in coordinate space.
This means that data values that are close to each other in the real world (coordinate space) are close to each other in the data array, and are usually stored close to each other on disk, making coordinate subsetting easy and efficient.

A `GridDataset`

has `Grids`

that can be grouped based on common attributes and `GridCoordSystems`

. Below is the UML for the Grid interface classes, found in the ucar.nc2.dt package:

### Opening a GridDataset

The most general way to open a `GridDataset`

is to use the `FeatureDatasetFactoryManager`

class. This allows third parties to plug-in alternative implementations of `GridDataset`

at runtime.
For example:

```
Formatter errlog = new Formatter();
FeatureDataset fd =
FeatureDatasetFactoryManager.open(wantFeatureType, yourLocationAsString, task, errlog);
if (fd == null) {
throw new NoFactoryFoundException(errlog.toString());
} else {
return fd;
}
```

If you know that the file you are opening is a `GridDataset`

, you can call directly:

```
GridDataset gds = ucar.nc2.dt.grid.GridDataset.open(yourLocationAsString);
```

### Using a GridDataset

Once you have a `GridDataset`

, you can get the grids and their associated coordinate systems:

```
GridDatatype grid = yourGridDataset.findGridDatatype(gridNameAsString);
GridCoordSystem yourGridCoordSystem = grid.getCoordinateSystem();
CoordinateAxis xAxis = yourGridCoordSystem.getXHorizAxis();
CoordinateAxis yAxis = yourGridCoordSystem.getYHorizAxis();
CoordinateAxis1D zAxis = yourGridCoordSystem.getVerticalAxis(); // may be null
if (yourGridCoordSystem.hasTimeAxis1D()) {
CoordinateAxis1DTime tAxis1D = yourGridCoordSystem.getTimeAxis1D();
List<CalendarDate> dates = tAxis1D.getCalendarDates();
} else if (yourGridCoordSystem.hasTimeAxis()) {
CoordinateAxis tAxis = yourGridCoordSystem.getTimeAxis();
}
```

A `GridCoordSystem`

wraps a georeferencing coordinate system. It always has 1D or 2D `XHoriz`

and `YHoriz`

axes, and optionally 1D vertical and 1D or 2D time axes.
The `XHoriz/YHoriz`

axes will be lat/lon if `isLatLon()`

is true, otherwise they will be `GeoX,GeoY`

with an appropriate `Projection`

.
The `getBoundingBox()`

method returns a bounding box from the `XHoriz/YHoriz`

corner points. The `getLatLonBoundingBox()`

method returns the smallest lat/lon bounding box that contains `getBoundingBox()`

.

You can use the `GridCoordSystem`

to find the indices and coordinates of the 2D grid from the (x,y) projection point:

```
// open the dataset, find the variable and its coordinate system
GridDataset gds = ucar.nc2.dt.grid.GridDataset.open(yourLocationAsString);
GridDatatype grid = gds.findGridDatatype("myVariableName");
GridCoordSystem gcs = grid.getCoordinateSystem();
double lat = 8.0;
double lon = 21.0;
// find the x,y index for a specific lat/lon position
int[] xy = gcs.findXYindexFromLatLon(lat, lon, null); // xy[0] = x, xy[1] = y
// read the data at that lat, lon and the first time and z level (if any)
Array data = grid.readDataSlice(0, 0, xy[1], xy[0]); // note order is t, z, y, x
double val = data.getDouble(0); // we know its a scalar
System.out.printf("Value at %f %f == %f%n", lat, lon, val);
```

Most `GridCoordSystems`

have a `CoordinateAxis1DTime`

time coordinate. If so, you can get the list of dates from it.

A `GridDatatype`

is like a specialized `Variable`

that explicitly handles X,Y,Z,T dimensions, which are put into canonical order: (t, z, y, x).
It has various convenience routines that expose methods from the `GridCoordSystem`

and `VariableDS`

objects.
The main data access method is `readDataSlice()`

, where you can fix an index on any `Dimension`

, or use a -1 to get all the data in that `Dimension`

.

```
// get 2D data at timeIndex, levelIndex
Array data = yourGridDatatype.readDataSlice(time_index, z_index, x_index, y_index);
```

The subset method allows you to create a logical subset of a `GeoGrid`

using index `Ranges`

.

```
GridDatatype subset =
yourGridDatatype.makeSubset(rt_range, ens_range, t_range, z_range, y_range, x_range);
```

### Writing a GridDataset to a Netcdf-3 file using CF-1.0 Conventions

Once you have a `GridDataset`

, you can write it as a Netcdf-3 file using the CF Conventions, using `ucar.nc2.write.NetcdfFormatWriter`

.
See the Writing CDM page for a detailed explanation of writing netCDF-3 and netCDF-4 files.

### Using ToolsUI to look at Grids

You can use ToolsUI **FeatureTypes/Grids** Tab to view `GridDatasets`

. This consists of 3 tables that show the `Grid`

datatypes, the `GridCoordSystems`

, and the coordinate axes:

Use the button to display the grids in the grid viewer window: