# Utility functions

## Plotting and reshaping

Cross-sections returned by the high-level functions dispersion_spectrum and oa_spectrum can be reshaped into long format with the helper functions dispersion_df and oa_df, respectively.

CoupledDipole.dispersion_dfFunction
dispersion_df(x, wavelength)

Long format dataframe for dispersion spectra

• x: CrossSection structure with 3 arrays (extinction, absorption, scattering)
• wavelength: vector of wavelengths
source
CoupledDipole.oa_dfFunction
oa_df(x, wavelength)

Long format dataframe for orientation-averaged spectra

• x: Tuple with 2 CrossSection structures (average and dichroism), each containing 3 arrays (extinction, absorption, scattering)
• wavelength: vector of wavelengths
source

## Euler rotations

CoupledDipole.euler_activeFunction
euler_active(φ::Real, θ::Real, ψ::Real)

3D rotation matrix

• φ: Euler angle (longitude, in [0,2π])
• θ: Euler angle (colatitude, in [0,2π])
• ψ: Euler angle (rotation around z", in [0,2π])

Examples

julia> round.(euler_active(π/2,0,0), digits=5)
3×3 SMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
0.0  -1.0  0.0
1.0   0.0  0.0
-0.0   0.0  1.0
source
CoupledDipole.euler_passiveFunction
euler_passive(φ::Real, θ::Real, ψ::Real)

3D rotation matrix

• φ: Euler angle (longitude, in [0,2π])
• θ: Euler angle (colatitude, in [0,2π])
• ψ: Euler angle (rotation around z", in [0,2π])

Examples

julia> round.(euler_passive(π/2,0,0), digits=5)
3×3 SMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
0.0  1.0  -0.0
-1.0  0.0   0.0
0.0  0.0   1.0
source
CoupledDipole.axis_angleFunction
axis_angle(v = SVector(0, 1, 0), θ)

3D rotation matrix from axis-angle representation

• v: SVector
• θ: rotation angle

Examples

julia> axis_angle(SVector(0, 1, 0), π/4)
3×3 SMatrix{3, 3, Float64, 9} with indices SOneTo(3)×SOneTo(3):
0.707107  0.0  0.707107
0.0       1.0  0.0
-0.707107  0.0  0.707107
source
CoupledDipole.euler_unitvectorFunction
euler_unitvector(φ::Real, θ::Real)

Unit vector along direction φ, θ

• φ: Euler angle (longitude, in [0,2π])
• θ: Euler angle (colatitude, in [0,2π])

Examples

julia> euler_unitvector(π/2, 0)
3-element SVector{3, Float64} with indices SOneTo(3):
0.0
0.0
1.0
source

## Spherical cubature

CoupledDipole.quadrature_lgwtFunction
quadrature_lgwt(N::Int, a::Real, b::Real)

N-point Gauss-Legendre quadrature over [a,b] interval

• N: number of nodes
• a,b: bounds
$$$\int_a^b f(x)\,dx=\frac{b-a}{2}\int_{-1}^{1}f\left(\frac{b-a}{2} x + \frac{a+b}{2}\right)\,dx.$$$

Examples

julia> quadrature_lgwt(6,0,3)
(nodes = [0.10129572869527204, 0.5081859203006033, 1.1420712208752046, 1.8579287791247954, 2.4918140796993966, 2.898704271304728], weights = [0.25698673856875537, 0.5411423595722078, 0.7018709018590369, 0.7018709018590369, 0.5411423595722078, 0.25698673856875537])
source
CoupledDipole.cubature_sphereFunction
cubature_sphere(N::Int, method::String)

N-point cubature on the sphere

• N: number of nodes
• method: cubature method (only 'gl' currently implemented)

Returns a Cubature object containing 2 arrays (N'x3 nodes and N'x1 weights), N'≈N Note: using array instead of tuple for weights because we'll use them in a scalar product in orientation-averaging For nodes there is less of a reason, but it can be convenient to visualise the nodes.

The cubature is normalised by 4π such that a unit integrand approximates 1.

Examples

julia> cubature_sphere(6)
(nodes = SVector{3, Float64}[[0.43625314334650644, 2.1862760354652844, 0.0], [0.43625314334650644, 0.9553166181245093, 0.0], [2.0735107047038173, 2.1862760354652844, 0.0], [2.0735107047038173, 0.9553166181245093, 0.0], [4.2096746024757685, 2.1862760354652844, 0.0], [4.2096746024757685, 0.9553166181245093, 0.0], [5.846932163833079, 2.1862760354652844, 0.0], [5.846932163833079, 0.9553166181245093, 0.0]], weights = [0.08696371128436346, 0.08696371128436346, 0.16303628871563655, 0.16303628871563655, 0.16303628871563655, 0.16303628871563655, 0.08696371128436346, 0.08696371128436346])
source