import numpy as np
import os, sys
import h5py
#possibly multiple wavelengths
= np.arange(400,850, 50)
wavelength = len(wavelength)
Nl = 3
lmax = 2*(lmax*(lmax+1)+lmax)
qmax # dummy 30x30 matrix values repeated for each wavelength
= np.reshape(np.arange(1,901,1) + 1j*np.arange(1,901,1), (qmax,qmax))
tdata = np.zeros((Nl,qmax,qmax), dtype="complex")
tmatrix for i in range(Nl):
= tdata
tmatrix[i,:,:]
print(tmatrix[0,0:3,0:3])
= np.zeros(qmax)
l = np.zeros(qmax)
m = np.array([b'xxxxxxic']*len(l))
s =0
ifor li in range(1,lmax+1):
for mi in range(-li, li+1):
for si in [b'electric', b'magnetic']:
= li
l[i] = mi
m[i] = si
s[i] = i+1 i
Export to ‘.tmat.h5’ format with Python
This document showcases a basic Matlab script to export T-matrices in the .tmat.h5
HDF5 format. For illustration, we start by producing a dummy dataset. This minimal reproducible example file is available for download as a standalone script: export_python.py.
Mockup input data
Consistent with the other examples, we generate a 50x30x30
array of dummy data, which repeats 50 times (50 wavelengths) a matrix of 900 entries ranging from \(1+1i\) (first element, top left) to \(900 + 900i\) (last element, bottom right). Note the expectation of row-major ordering in HDF5. The 3x3
top-left block is
1.0000 + 1.0000i 2.0000 + 2.0000i 3.0000 + 3.0000i ...
31.0000 +31.0000i 32.0000 +32.0000i 33.0000 +33.0000i ...
61.0000 +61.0000i 62.0000 +62.0000i 63.0000 +63.0000i ...
... ... ... ...
The Python library h5py
provides a convenient object-oriented interface to save python objects in the required HDF5 structure, so we don’t need particular care to organise them on the Python side.
Saving to HDF5
The Python library h5py
provides a convenient interface to generate groups, datasets, and attributes with simple assigments:
# Saving to HDF5
= 'ap.tmat.h5';
f with h5py.File(f, "w") as f:
"vacuum_wavelength"] = np.asarray(wavelength)
f["vacuum_wavelength"].attrs["unit"] = "nm"
f["tmatrix"] = tmatrix
f['modes/l'] = l
f['modes/m'] = m
f['modes/polarization'] = s
f[= f.create_group(f"embedding")
emb "relative_permittivity"] = 1.33**2
emb["relative_permeability"] = 1.0
emb["name"] = "H2O, Water"
emb.attrs["keywords"] = "non-dispersive"
emb.attrs[= f.create_group("scatterer/material")
sca_mat "name"] = 'Au, Gold'
sca_mat.attrs["keywords"] = "dispersive, plasmonic"
sca_mat.attrs["reference"] = "Au from Raschke et al 10.1103/PhysRevB.86.235147"
sca_mat.attrs["relative_permittivity"] = np.ones(len(wavelength), dtype = complex)*(-11.4+1.181j)
sca_mat["relative_permeability"] = 1.0
sca_mat[= f.create_group("scatterer/geometry")
sca_gr "radiusxy"] = 20.0
sca_gr["radiusz"] = 40.0
sca_gr['unit'] = 'nm'
sca_gr.attrs['shape'] = 'spheroid'
sca_gr.attrs['name'] = 'homogeneous spheroid with symmetry axis z'
sca_gr.attrs[= f.create_group("computation/method_parameters")
mpar #f["computation/analytical_zeros"] = analytical_zeros # not needed in this example
"Lmax"] = lmax
mpar["Ntheta"] = 100
mpar["computation/files")
f.create_group(with open(__file__, "r") as scriptfile:
f"computation/files/{os.path.basename(__file__)}"] = scriptfile.read()
f["computation"].attrs["method"] = "EBCM, Extended Boundary Condition Method"
f["computation"].attrs["description"] = "Computation using SMARTIES, a numerically robust EBCM implementation for spheroids"
f["computation"].attrs["software"] = f"SMARTIES=1.1, python={sys.version.split()[0]}, h5py={h5py.__version__}"
f["computation"].attrs["name"] = "SMARTIES"
f['name'] = 'Au prolate spheroid in water'
f.attrs['keywords'] = 'gold, spheroid, ebcm, passive, reciprocal, czinfinity, mirrorxyz'
f.attrs['description'] = 'Computation using SMARTIES, a numerically robust EBCM implementation for spheroids'
f.attrs['storage_format_version'] = 'v0.01' f.attrs[
Summary of the file:
<list>
├─data: <list>
│ ├─computation: <list>
│ │ ├─files: <list>
│ │ │ └─export_python.py: "import numpy as np↵import os, sy..."
│ │ └─method_parameters: <list>
│ │ ├─Lmax: 3
│ │ └─Ntheta: 100
│ ├─embedding: <list>
│ │ ├─relative_permeability: 1
│ │ └─relative_permittivity: 1.7689
│ ├─modes: <list>
│ │ ├─l<dbl [30]>: 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, ...
│ │ ├─m<dbl [30]>: -1, -1, 0, 0, 1, 1, -2, -2, -1, -1, ...
│ │ └─polarization<chr [30]>: "electric", "magnetic", "electric", "magnetic", "electric", "magnetic", "electric", "magnetic", "electric", "magnetic", ...
│ ├─scatterer: <list>
│ │ ├─geometry: <list>
│ │ │ ├─radiusxy: 20
│ │ │ └─radiusz: 40
│ │ └─material: <list>
│ │ ├─relative_permeability: 1
│ │ └─relative_permittivity<cpl [9]>: -11.4+1.181i, -11.4+1.181i, -11.4+1.181i, -11.4+1.181i, -11.4+1.181i, -11.4+1.181i, -11.4+1.181i, -11.4+1.181i, -11.4+1.181i
│ ├─tmatrix<cpl [8,100]>: 1+1i, 1+1i, 1+1i, 1+1i, 1+1i, 1+1i, 1+1i, 1+1i, 1+1i, 31+31i, ...
│ └─vacuum_wavelength<int [9]>: 400, 450, 500, 550, 600, 650, 700, 750, 800
└─attributes: <list>
├─root: <list>
│ ├─description: "Computation using SMARTIES, a nu..."
│ ├─keywords: "gold, spheroid, ebcm, passive, r..."
│ ├─name: "Au prolate spheroid in water"
│ └─storage_format_version: "v0.01"
├─vacuum_wavelength: <list>
│ └─unit: "nm"
├─computation: <list>
│ ├─description: "Computation using SMARTIES, a nu..."
│ ├─method: "EBCM, Extended Boundary Conditio..."
│ ├─name: "SMARTIES"
│ └─software: "SMARTIES=1.1, python=3.11.7, h5p..."
├─embedding: <list>
│ ├─keywords: "non-dispersive"
│ └─name: "H2O, Water"
├─material: <list>
│ ├─keywords: "dispersive, plasmonic"
│ ├─name: "Au, Gold"
│ └─reference: "Au from Raschke et al 10.1103/Ph..."
└─geometry: <list>
├─name: "homogeneous spheroid with symmet..."
├─shape: "spheroid"
└─unit: "nm"