or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

file-operations.mdheader-operations.mdimage-operations.mdindex.mdtable-operations.md

image-operations.mddocs/

0

# Image Operations

1

2

FITS image data handling functionality providing efficient reading, writing, and manipulation of image HDUs with support for subsets, compression, various data types, and numpy-style array operations.

3

4

## Capabilities

5

6

### ImageHDU Class

7

8

Handler for FITS image extensions with support for reading, writing, compression, and array-like access patterns.

9

10

```python { .api }

11

class ImageHDU:

12

def read(self, **kwargs):

13

"""

14

Read image data.

15

16

Parameters:

17

- **kwargs: additional read options

18

19

Returns:

20

numpy array, image data

21

"""

22

23

def write(self, img, start=0):

24

"""

25

Write image data.

26

27

Parameters:

28

- img: array-like, image data to write

29

- start: int/tuple, starting position for writing subset

30

"""

31

32

def get_dims(self):

33

"""

34

Get image dimensions.

35

36

Returns:

37

tuple of int, image dimensions (NAXIS1, NAXIS2, ...)

38

"""

39

40

def reshape(self, dims):

41

"""

42

Change image dimensions on disk.

43

44

Parameters:

45

- dims: tuple of int, new dimensions

46

"""

47

48

def is_compressed(self):

49

"""

50

Check if image is tile-compressed.

51

52

Returns:

53

bool, True if tile-compressed

54

"""

55

56

def get_comptype(self):

57

"""

58

Get compression type.

59

60

Returns:

61

str, compression algorithm name

62

"""

63

64

def has_data(self):

65

"""

66

Check if HDU contains image data.

67

68

Returns:

69

bool, True if HDU has data

70

"""

71

72

def __getitem__(self, key):

73

"""

74

Access image data using numpy-style slicing.

75

76

Parameters:

77

- key: slice/tuple, numpy-style slice notation

78

79

Returns:

80

numpy array, image subset

81

"""

82

83

# Inherited from HDUBase

84

def get_info(self):

85

"""Get complete HDU information."""

86

87

def get_offsets(self):

88

"""Get byte offsets (header_start, data_start, data_end)."""

89

90

def get_extnum(self):

91

"""Get extension number."""

92

93

def get_extname(self):

94

"""Get extension name."""

95

96

def get_extver(self):

97

"""Get extension version."""

98

99

def get_exttype(self, num=False):

100

"""Get extension type."""

101

102

def read_header(self):

103

"""Read header as FITSHDR object."""

104

105

def write_key(self, name, value, comment=""):

106

"""Write single header keyword."""

107

108

def write_keys(self, records, clean=True):

109

"""Write multiple header keywords."""

110

111

def write_checksum(self):

112

"""Write DATASUM/CHECKSUM keywords."""

113

114

def verify_checksum(self):

115

"""Verify data integrity."""

116

```

117

118

### Image Writing with Compression

119

120

```python { .api }

121

def write(filename, data, compress=None, qlevel=None, qmethod=None,

122

hcomp_scale=None, **kwargs):

123

"""

124

Write image with compression options.

125

126

Parameters:

127

- filename: str, output file path

128

- data: array-like, image data

129

- compress: str, compression type ('rice', 'gzip', 'plio', 'hcompress')

130

- qlevel: float, quantization level (for lossy compression)

131

- qmethod: str, quantization method

132

- hcomp_scale: float, HCOMPRESS scale parameter

133

- **kwargs: additional options

134

"""

135

```

136

137

### Image Data Types

138

139

```python { .api }

140

# Supported numpy data types for images:

141

# - np.uint8, np.int8

142

# - np.uint16, np.int16

143

# - np.uint32, np.int32

144

# - np.uint64, np.int64

145

# - np.float32 (BITPIX = -32)

146

# - np.float64 (BITPIX = -64)

147

# - np.complex64, np.complex128

148

```

149

150

## Compression Constants

151

152

```python { .api }

153

NOCOMPRESS = 0

154

RICE_1 = 11 # Rice compression

155

GZIP_1 = 21 # GZIP compression level 1

156

GZIP_2 = 22 # GZIP compression level 2

157

PLIO_1 = 31 # PLIO compression

158

HCOMPRESS_1 = 41 # HCOMPRESS compression

159

160

# Quantization methods for lossy compression

161

NO_DITHER = -1

162

SUBTRACTIVE_DITHER_1 = 1

163

SUBTRACTIVE_DITHER_2 = 2

164

165

# Default compression parameters

166

DEFAULT_QLEVEL = 4.0

167

DEFAULT_QMETHOD = 'SUBTRACTIVE_DITHER_1'

168

DEFAULT_HCOMP_SCALE = 0.0

169

```

170

171

## Usage Examples

172

173

### Reading Images

174

175

```python

176

import fitsio

177

import numpy as np

178

179

# Read entire image

180

image = fitsio.read('image.fits')

181

print(f"Image shape: {image.shape}")

182

183

# Read specific HDU

184

image = fitsio.read('multi.fits', ext=1)

185

186

# Read with FITS object for more control

187

with fitsio.FITS('image.fits') as fits:

188

# Get image information

189

hdu = fits[0]

190

dims = hdu.get_dims()

191

is_compressed = hdu.is_compressed()

192

193

print(f"Dimensions: {dims}")

194

print(f"Compressed: {is_compressed}")

195

196

# Read entire image

197

full_image = hdu.read()

198

199

# Read image subsets using slicing

200

subset = hdu[100:200, 50:150] # 100x100 subset

201

row = hdu[500, :] # Single row

202

column = hdu[:, 300] # Single column

203

204

# Advanced slicing

205

every_other = hdu[::2, ::2] # Every other pixel

206

flipped = hdu[::-1, :] # Vertically flipped

207

```

208

209

### Writing Images

210

211

```python

212

import fitsio

213

import numpy as np

214

215

# Create sample image

216

image = np.random.random((512, 512)).astype(np.float32)

217

218

# Write uncompressed image

219

fitsio.write('output.fits', image)

220

221

# Write with compression

222

fitsio.write('compressed.fits', image, compress='rice')

223

224

# Write with compression options

225

fitsio.write('lossy.fits', image, compress='rice',

226

qlevel=8.0, qmethod='SUBTRACTIVE_DITHER_2')

227

228

# Write integer data with GZIP

229

int_image = (image * 1000).astype(np.int16)

230

fitsio.write('int_compressed.fits', int_image, compress='gzip')

231

232

# Write to specific HDU

233

with fitsio.FITS('multi.fits', 'rw', clobber=True) as fits:

234

fits.write(image, extname='IMAGE1')

235

fits.write(image * 2, extname='IMAGE2', compress='plio')

236

```

237

238

### Working with Large Images

239

240

```python

241

import fitsio

242

import numpy as np

243

244

# Create large image file

245

large_image = np.random.random((4096, 4096)).astype(np.float32)

246

fitsio.write('large.fits', large_image)

247

248

with fitsio.FITS('large.fits', 'rw') as fits:

249

hdu = fits[0]

250

251

# Read small regions without loading entire image

252

corner = hdu[0:100, 0:100]

253

center = hdu[2000:2100, 2000:2100]

254

255

# Write to subset of existing image

256

new_data = np.ones((50, 50), dtype=np.float32)

257

hdu.write(new_data, start=[1000, 1000])

258

259

# Modify image dimensions

260

hdu.reshape([2048, 8192]) # Reshape to different aspect ratio

261

```

262

263

### Image Compression Examples

264

265

```python

266

import fitsio

267

import numpy as np

268

269

# Test different compression methods

270

image = np.random.random((1024, 1024)).astype(np.float32)

271

272

# Lossless compression

273

fitsio.write('lossless_rice.fits', image, compress='rice', qlevel=None)

274

fitsio.write('lossless_gzip.fits', image, compress='gzip', qlevel=None)

275

276

# Lossy compression with quality control

277

fitsio.write('lossy_rice.fits', image, compress='rice',

278

qlevel=4.0, qmethod='SUBTRACTIVE_DITHER_1')

279

280

# HCOMPRESS for smooth images

281

smooth = np.outer(np.linspace(0, 1, 1024), np.linspace(0, 1, 1024))

282

fitsio.write('hcompress.fits', smooth, compress='hcompress',

283

hcomp_scale=2.0)

284

285

# Check compression ratios

286

import os

287

original_size = os.path.getsize('uncompressed.fits')

288

compressed_size = os.path.getsize('lossless_rice.fits')

289

ratio = original_size / compressed_size

290

print(f"Compression ratio: {ratio:.2f}")

291

```

292

293

### Data Type Handling

294

295

```python

296

import fitsio

297

import numpy as np

298

299

# Different data types

300

uint8_data = np.random.randint(0, 256, (100, 100), dtype=np.uint8)

301

int16_data = np.random.randint(-32768, 32767, (100, 100), dtype=np.int16)

302

float32_data = np.random.random((100, 100)).astype(np.float32)

303

float64_data = np.random.random((100, 100)).astype(np.float64)

304

305

# Write each type

306

fitsio.write('uint8.fits', uint8_data)

307

fitsio.write('int16.fits', int16_data)

308

fitsio.write('float32.fits', float32_data)

309

fitsio.write('float64.fits', float64_data)

310

311

# Read back and check types

312

data = fitsio.read('uint8.fits')

313

print(f"Data type: {data.dtype}") # Should be uint8

314

315

# Handle scaling (BSCALE/BZERO)

316

with fitsio.FITS('scaled.fits') as fits:

317

# Check for scaling keywords

318

header = fits[0].read_header()

319

if 'BSCALE' in header:

320

print(f"BSCALE: {header['BSCALE']}")

321

print(f"BZERO: {header.get('BZERO', 0.0)}")

322

323

# Data is automatically scaled on read

324

scaled_data = fits[0].read()

325

```

326

327

### Working with Multi-dimensional Images

328

329

```python

330

import fitsio

331

import numpy as np

332

333

# 3D data cube

334

cube = np.random.random((50, 256, 256)).astype(np.float32)

335

fitsio.write('cube.fits', cube)

336

337

with fitsio.FITS('cube.fits') as fits:

338

hdu = fits[0]

339

dims = hdu.get_dims()

340

print(f"Cube dimensions: {dims}") # (256, 256, 50) - FITS order

341

342

# Access slices

343

first_plane = hdu[:, :, 0] # First image plane

344

middle_plane = hdu[:, :, 25] # Middle plane

345

spectrum = hdu[128, 128, :] # Spectrum at center pixel

346

347

# 4D hypercube

348

hypercube = np.random.random((10, 20, 100, 100)).astype(np.float32)

349

fitsio.write('hypercube.fits', hypercube)

350

```

351

352

### Image Metadata and Information

353

354

```python

355

import fitsio

356

357

with fitsio.FITS('image.fits') as fits:

358

hdu = fits[0]

359

360

# Get complete HDU information

361

info = hdu.get_info()

362

print(f"HDU info: {info}")

363

364

# Check basic properties

365

has_data = hdu.has_data()

366

is_compressed = hdu.is_compressed()

367

comp_type = hdu.get_comptype() if is_compressed else None

368

369

# Get file offsets

370

offsets = hdu.get_offsets()

371

header_start, data_start, data_end = offsets

372

373

print(f"Header starts at byte: {header_start}")

374

print(f"Data starts at byte: {data_start}")

375

print(f"Data ends at byte: {data_end}")

376

```