or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

attributes.mddimensions.mdfile-operations.mdgroups.mdindex.mdlegacy-api.mduser-types.mdvariables.md

dimensions.mddocs/

0

# Dimensions Management

1

2

Dimensions define the coordinate system and shape constraints for variables in netCDF4 files. They can be fixed-size or unlimited, and serve as the foundation for all variable definitions and data organization.

3

4

## Capabilities

5

6

### Dimension Creation and Access

7

8

Create and manage dimensions within groups.

9

10

```python { .api }

11

class Dimensions(MutableMapping):

12

def __getitem__(self, name: str) -> Dimension:

13

"""Get dimension by name."""

14

...

15

16

def __setitem__(self, name: str, size: int) -> None:

17

"""Create new dimension with specified size."""

18

...

19

20

def __delitem__(self, name: str) -> None:

21

"""Remove dimension (if not used by variables)."""

22

...

23

24

def __contains__(self, name: str) -> bool:

25

"""Check if dimension exists."""

26

...

27

28

def __iter__(self):

29

"""Iterate over dimension names."""

30

...

31

32

def __len__(self) -> int:

33

"""Number of dimensions in this group."""

34

...

35

```

36

37

### Dimension Objects

38

39

Individual dimension properties and methods.

40

41

```python { .api }

42

class Dimension:

43

def __init__(self, parent: Group, name: str, size: int = None,

44

create_h5ds: bool = False, phony: bool = False):

45

"""

46

Create or access a dimension.

47

48

Args:

49

parent (Group): Parent group containing this dimension

50

name (str): Dimension name

51

size (int): Dimension size (None for unlimited)

52

create_h5ds (bool): Create HDF5 dimension scale

53

phony (bool): Whether this is a phony dimension

54

"""

55

...

56

57

@property

58

def name(self) -> str:

59

"""Dimension name."""

60

...

61

62

@property

63

def size(self) -> int:

64

"""Current dimension size."""

65

...

66

67

def isunlimited(self) -> bool:

68

"""Check if dimension is unlimited."""

69

...

70

71

def group(self) -> Group:

72

"""Return parent group."""

73

...

74

```

75

76

### Dimension Management Operations

77

78

Advanced dimension operations and utilities.

79

80

```python { .api }

81

def add(self, name: str) -> None:

82

"""Add existing dimension from parent groups."""

83

...

84

85

def add_phony(self, name: str, size: int) -> None:

86

"""Add phony dimension for unlabeled axes."""

87

...

88

89

def resize_dimension(self, dim: str, size: int) -> None:

90

"""Resize unlimited dimension."""

91

...

92

```

93

94

## Usage Examples

95

96

### Basic Dimension Operations

97

98

```python

99

import h5netcdf

100

101

with h5netcdf.File('dimensions.nc', 'w') as f:

102

# Create fixed-size dimensions

103

f.dimensions['lat'] = 180

104

f.dimensions['lon'] = 360

105

f.dimensions['level'] = 50

106

107

# Create unlimited dimension

108

f.dimensions['time'] = None # None indicates unlimited

109

110

# Access dimension properties

111

lat_dim = f.dimensions['lat']

112

print(f"Latitude dimension size: {lat_dim.size}")

113

print(f"Is unlimited: {lat_dim.isunlimited()}")

114

115

# Check if dimension exists

116

if 'time' in f.dimensions:

117

time_dim = f.dimensions['time']

118

print(f"Time is unlimited: {time_dim.isunlimited()}")

119

120

# List all dimensions

121

print(f"Dimensions: {list(f.dimensions.keys())}")

122

print(f"Number of dimensions: {len(f.dimensions)}")

123

```

124

125

### Unlimited Dimensions

126

127

```python

128

with h5netcdf.File('unlimited.nc', 'w') as f:

129

# Create unlimited dimension

130

f.dimensions['time'] = None

131

f.dimensions['station'] = 100

132

133

# Create variable using unlimited dimension

134

temp = f.create_variable('temperature', ('time', 'station'), dtype='f4')

135

136

# Initially, unlimited dimension has size 0

137

print(f"Initial time size: {f.dimensions['time'].size}")

138

139

# Writing data extends the unlimited dimension

140

temp[0, :] = np.random.random(100)

141

print(f"After first write: {f.dimensions['time'].size}")

142

143

temp[1, :] = np.random.random(100)

144

print(f"After second write: {f.dimensions['time'].size}")

145

146

# Can explicitly resize unlimited dimensions

147

f.resize_dimension('time', 10)

148

print(f"After resize: {f.dimensions['time'].size}")

149

```

150

151

### Coordinate Variables and Dimensions

152

153

```python

154

with h5netcdf.File('coordinates.nc', 'w') as f:

155

# Create dimensions

156

f.dimensions['x'] = 100

157

f.dimensions['y'] = 50

158

f.dimensions['time'] = None

159

160

# Create coordinate variables (same name as dimension)

161

x_coord = f.create_variable('x', ('x',), dtype='f4')

162

x_coord[:] = np.linspace(0, 99, 100)

163

x_coord.attrs['units'] = 'm'

164

x_coord.attrs['long_name'] = 'X coordinate'

165

166

y_coord = f.create_variable('y', ('y',), dtype='f4')

167

y_coord[:] = np.linspace(0, 49, 50)

168

y_coord.attrs['units'] = 'm'

169

y_coord.attrs['long_name'] = 'Y coordinate'

170

171

# Time coordinate (unlimited)

172

time_coord = f.create_variable('time', ('time',), dtype='f8')

173

time_coord.attrs['units'] = 'days since 2023-01-01'

174

time_coord.attrs['calendar'] = 'standard'

175

176

# Data variable using these dimensions

177

data = f.create_variable('temperature', ('time', 'y', 'x'), dtype='f4')

178

179

# Write time series data

180

for t in range(5):

181

time_coord[t] = t

182

data[t, :, :] = np.random.random((50, 100)) * 30 + 273.15

183

```

184

185

### Dimension Inheritance in Groups

186

187

```python

188

with h5netcdf.File('groups_dims.nc', 'w') as f:

189

# Create dimensions in root group

190

f.dimensions['time'] = None

191

f.dimensions['lat'] = 180

192

f.dimensions['lon'] = 360

193

194

# Create child group

195

surface = f.create_group('surface')

196

197

# Child group can use parent dimensions

198

surface.dimensions.add('time') # Reference parent's time dimension

199

surface.dimensions.add('lat') # Reference parent's lat dimension

200

surface.dimensions.add('lon') # Reference parent's lon dimension

201

202

# Or create group-specific dimensions

203

surface.dimensions['height'] = 10

204

205

# Create variable using mixed dimensions

206

temp = surface.create_variable(

207

'temperature',

208

('time', 'height', 'lat', 'lon'),

209

dtype='f4'

210

)

211

212

print(f"Root dimensions: {list(f.dimensions.keys())}")

213

print(f"Surface dimensions: {list(surface.dimensions.keys())}")

214

```

215

216

### Checking Dimension Usage

217

218

```python

219

with h5netcdf.File('check_usage.nc', 'r') as f:

220

for dim_name, dimension in f.dimensions.items():

221

print(f"Dimension: {dim_name}")

222

print(f" Size: {dimension.size}")

223

print(f" Unlimited: {dimension.isunlimited()}")

224

225

# Find variables using this dimension

226

using_vars = []

227

for var_name, variable in f.variables.items():

228

if dim_name in variable.dimensions:

229

using_vars.append(var_name)

230

231

print(f" Used by variables: {using_vars}")

232

233

# Check if coordinate variable exists

234

if dim_name in f.variables:

235

coord_var = f.variables[dim_name]

236

print(f" Has coordinate variable: {coord_var.dtype}")

237

else:

238

print(f" No coordinate variable")

239

```

240

241

### Phony Dimensions

242

243

```python

244

# Phony dimensions handle unlabeled axes in HDF5 files

245

with h5netcdf.File('unlabeled.nc', 'r', phony_dims='sort') as f:

246

# If file has unlabeled dimensions, they get phony names

247

for dim_name, dimension in f.dimensions.items():

248

if hasattr(dimension, 'phony') and dimension.phony:

249

print(f"Phony dimension: {dim_name} (size: {dimension.size})")

250

```

251

252

### Dimension Validation

253

254

```python

255

with h5netcdf.File('validate.nc', 'w') as f:

256

try:

257

# This will work

258

f.dimensions['valid_name'] = 100

259

260

# This might cause issues depending on backend

261

# f.dimensions[''] = 50 # Empty name

262

263

# Creating variable with non-existent dimension will fail

264

# f.create_variable('test', ('nonexistent',), dtype='f4')

265

266

except Exception as e:

267

print(f"Validation error: {e}")

268

```

269

270

### Multiple Unlimited Dimensions

271

272

```python

273

# Note: NetCDF4 format supports multiple unlimited dimensions

274

with h5netcdf.File('multi_unlimited.nc', 'w') as f:

275

# Multiple unlimited dimensions (netCDF4 feature)

276

f.dimensions['time'] = None

277

f.dimensions['ensemble'] = None

278

f.dimensions['lat'] = 90

279

f.dimensions['lon'] = 180

280

281

# Variable with multiple unlimited dimensions

282

temp = f.create_variable(

283

'temperature',

284

('time', 'ensemble', 'lat', 'lon'),

285

dtype='f4'

286

)

287

288

# Write data to extend both unlimited dimensions

289

temp[0, 0, :, :] = np.random.random((90, 180))

290

temp[1, 2, :, :] = np.random.random((90, 180))

291

292

print(f"Time size: {f.dimensions['time'].size}")

293

print(f"Ensemble size: {f.dimensions['ensemble'].size}")

294

```

295

296

## Dimension Naming Conventions

297

298

### Standard Names

299

- **time**: Temporal coordinate

300

- **lat**, **latitude**: Latitude coordinate

301

- **lon**, **longitude**: Longitude coordinate

302

- **level**, **lev**: Vertical levels

303

- **height**, **depth**: Vertical distance coordinates

304

305

### Best Practices

306

- Use descriptive names that indicate the coordinate type

307

- Avoid spaces and special characters

308

- Be consistent within and across files

309

- Consider CF (Climate and Forecast) conventions for geophysical data

310

311

## Dimension Constraints

312

313

- Dimension names must be unique within a group

314

- Cannot delete dimensions that are used by variables

315

- Unlimited dimensions can only grow, not shrink (use resize_dimension)

316

- Fixed dimensions cannot be resized after creation

317

- Each variable can reference dimensions from its group or parent groups