or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-extraction.mdfile-operations.mdindex-operations.mdindex.mdmessage-access.mdmessage-modification.mdutility-functions.md

message-modification.mddocs/

0

# Message Modification

1

2

Limited capabilities for modifying existing GRIB messages and writing them to new files. Supports changing metadata keys and data values, but cannot create GRIB files from scratch.

3

4

## Capabilities

5

6

### Modifying Message Keys

7

8

Change GRIB key values in existing messages.

9

10

```python { .api }

11

class gribmessage:

12

def __setitem__(self, key: str, value):

13

"""

14

Set GRIB key values.

15

16

Parameters:

17

- key: str, GRIB key name

18

- value: appropriate type for the key

19

Common types: int, float, str, numpy.ndarray (for 'values')

20

"""

21

22

def __setattr__(self, name: str, value):

23

"""Set GRIB keys as attributes (equivalent to __setitem__)"""

24

```

25

26

Usage example:

27

```python

28

grbs = pygrib.open('weather.grb')

29

grb = grbs.readline()

30

31

# Modify forecast time

32

grb['forecastTime'] = 120

33

# Or using attribute syntax

34

grb.forecastTime = 120

35

36

# Change parameter (e.g., to pressure tendency)

37

grb['parameterNumber'] = 2

38

grb['shortName'] = 'prate' # May change automatically

39

40

# Modify level information

41

grb['level'] = 850

42

grb['typeOfLevel'] = 'isobaricInhPa'

43

44

print(f"Modified message: {grb}")

45

```

46

47

### Modifying Data Values

48

49

Change the actual meteorological data array in GRIB messages.

50

51

```python { .api }

52

class gribmessage:

53

def __setitem__(self, key: str, value):

54

"""

55

For 'values' key, accepts numpy arrays to replace data.

56

57

Parameters:

58

- key: str, must be 'values' for data modification

59

- value: numpy.ndarray, new data array

60

Must be compatible with grid dimensions

61

"""

62

```

63

64

Usage example:

65

```python

66

grbs = pygrib.open('weather.grb')

67

grb = grbs.select(shortName='t', level=500)[0]

68

69

# Get original data

70

original_data = grb['values']

71

print(f"Original range: {original_data.min():.1f} to {original_data.max():.1f}")

72

73

# Apply transformations

74

# Convert from Kelvin to Celsius

75

celsius_data = original_data - 273.15

76

77

# Apply smoothing filter

78

from scipy import ndimage

79

smoothed_data = ndimage.gaussian_filter(original_data, sigma=1.0)

80

81

# Scale values

82

scaled_data = original_data * 1.1

83

84

# Set modified data back to message

85

grb['values'] = celsius_data

86

print(f"Modified range: {grb['values'].min():.1f} to {grb['values'].max():.1f}")

87

88

# Update metadata to reflect change

89

grb['units'] = 'C'

90

grb['name'] = 'Temperature (Celsius)'

91

```

92

93

### Writing Modified Messages

94

95

Convert modified messages to binary format and write to files.

96

97

```python { .api }

98

class gribmessage:

99

def tostring(self) -> bytes:

100

"""

101

Encode message as binary GRIB string.

102

103

Returns:

104

bytes, binary GRIB message data ready for writing

105

"""

106

```

107

108

Usage example:

109

```python

110

grbs = pygrib.open('input.grb')

111

grb = grbs.readline()

112

113

# Modify the message

114

grb['forecastTime'] = 168

115

grb['parameterNumber'] = 11 # Change to different parameter

116

data = grb['values']

117

grb['values'] = data * 0.95 # Scale data by 5%

118

119

# Convert to binary format

120

binary_msg = grb.tostring()

121

122

# Write to new file

123

with open('modified.grb', 'wb') as f:

124

f.write(binary_msg)

125

126

# Verify the written file

127

new_grbs = pygrib.open('modified.grb')

128

new_grb = new_grbs.readline()

129

print(f"Written message: {new_grb}")

130

print(f"Forecast time: {new_grb['forecastTime']}")

131

new_grbs.close()

132

```

133

134

### Processing Multiple Messages

135

136

Modify and write multiple messages to create new GRIB files.

137

138

```python

139

input_grbs = pygrib.open('input.grb')

140

141

# Open output file for writing

142

with open('processed.grb', 'wb') as output_file:

143

144

# Process each message

145

for grb in input_grbs:

146

147

# Apply modifications based on parameter type

148

if grb['shortName'] == 't': # Temperature

149

# Convert K to C

150

data = grb['values'] - 273.15

151

grb['values'] = data

152

grb['units'] = 'C'

153

154

elif grb['shortName'] in ['u', 'v']: # Wind components

155

# Scale wind speeds

156

data = grb['values'] * 1.05

157

grb['values'] = data

158

159

# Extend forecast time by 6 hours

160

grb['forecastTime'] = grb['forecastTime'] + 6

161

162

# Write modified message

163

binary_msg = grb.tostring()

164

output_file.write(binary_msg)

165

166

input_grbs.close()

167

168

# Verify processed file

169

processed_grbs = pygrib.open('processed.grb')

170

print(f"Processed file contains {len(processed_grbs)} messages")

171

processed_grbs.close()

172

```

173

174

### Message Reloading

175

176

Reload original message data from file after modifications.

177

178

```python { .api }

179

def reload(grb):

180

"""

181

Reload gribmessage from file to refresh data.

182

Creates new message object with original file data.

183

184

Parameters:

185

- grb: gribmessage, message to reload

186

187

Returns:

188

New gribmessage object with original data from file

189

"""

190

```

191

192

Usage example:

193

```python

194

grbs = pygrib.open('weather.grb')

195

grb = grbs.readline()

196

197

# Store original values for comparison

198

original_forecast_time = grb['forecastTime']

199

original_data = grb['values'].copy()

200

201

# Make modifications

202

grb['forecastTime'] = 240

203

grb['values'] = grb['values'] * 2.0

204

205

print(f"Modified forecast time: {grb['forecastTime']}")

206

print(f"Modified data range: {grb['values'].min():.1f} to {grb['values'].max():.1f}")

207

208

# Reload original data

209

original_grb = pygrib.reload(grb)

210

print(f"Reloaded forecast time: {original_grb['forecastTime']}")

211

print(f"Reloaded data range: {original_grb['values'].min():.1f} to {original_grb['values'].max():.1f}")

212

```

213

214

## Modification Limitations

215

216

### Cannot Create New Files

217

218

pygrib cannot create GRIB files from scratch - it can only modify existing messages.

219

220

```python

221

# NOT SUPPORTED: Creating new GRIB files from scratch

222

# This will not work:

223

# new_grb = pygrib.gribmessage() # Cannot instantiate directly

224

# pygrib.create_grib_file() # No such function

225

226

# SUPPORTED: Modify existing messages

227

grbs = pygrib.open('existing.grb')

228

grb = grbs.readline()

229

# ... modify grb ...

230

binary_data = grb.tostring() # Convert to binary for writing

231

```

232

233

### Key Modification Constraints

234

235

Not all GRIB keys can be modified safely:

236

237

```python

238

grb = grbs.readline()

239

240

# Safe modifications (common use cases)

241

grb['forecastTime'] = 120 # Change forecast hour

242

grb['level'] = 850 # Change level

243

grb['values'] = new_data # Replace data array

244

grb['units'] = 'new_unit' # Change units

245

246

# Potentially problematic modifications

247

# grb['Ni'] = 360 # Don't change grid dimensions

248

# grb['Nj'] = 181 # without corresponding data changes

249

# grb['gridType'] = 'lambert' # Don't change grid type

250

251

# Always verify modifications work by testing the output

252

try:

253

binary_data = grb.tostring()

254

print("Modification successful")

255

except Exception as e:

256

print(f"Modification failed: {e}")

257

```

258

259

### Data Array Compatibility

260

261

When modifying data arrays, ensure compatibility with grid structure:

262

263

```python

264

grb = grbs.select(shortName='t', level=500)[0]

265

original_data = grb['values']

266

267

print(f"Original data shape: {original_data.shape}")

268

print(f"Grid info: Ni={grb['Ni']}, Nj={grb['Nj']}")

269

270

# New data must match grid dimensions

271

if grb.expand_reduced:

272

# For expanded grids, data shape should match (Nj, Ni)

273

expected_shape = (grb['Nj'], grb['Ni'])

274

else:

275

# For reduced grids, data is 1D

276

expected_shape = (grb['numberOfValues'],)

277

278

# Create compatible new data

279

new_data = original_data * 1.1 # Simple scaling preserves shape

280

grb['values'] = new_data

281

282

# Verify compatibility

283

assert grb['values'].shape == original_data.shape

284

```