pygeomoptics package

A collection of optical properties of materials used in the LEGEND experiment.

Submodules

pygeomoptics.cli module

pygeomoptics.cli.optics_cli()
Return type:

None

pygeomoptics.copper module

Copper.

pygeomoptics.copper.copper_reflectivity()

Reflectivity of copper surfaces.

Measurements from [Wegmann2017] (data points above 300 nm) and [Salamanna2022] (data points between 120 and 220 nm, averaged and smoothed). The interpolation between both domains is linear, but arbitrary.

Returns:

../_images/pygeomoptics.copper.copper_reflectivity_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.copper.pyg4_copper_attach_reflectivity(mat, reg)

Attach the optical reflectivity to the given copper material instance.

Return type:

None

pygeomoptics.fibers module

Scinillating fibers BCF91-A from Saint Gobain.

[Bae2025] (1,2)

W. Bae et al. ”Further Fiber Studies for LEGEND. Fiber-Alpha measurement” (Feb 18, 2025; LEGEND-internal)

[Leverington2011]

B.D. Leverington et al. ”A 1 mm Scintillating Fibre Tracker Readout by a Multi-anode Photomultiplier” (2010), https://doi.org/10.48550/arXiv.1106.5649

pygeomoptics.fibers.fiber_absorption_length()

Absorption length of fiber [SaintGobainDataSheet]. Note this is a macroscopical value for a 1 mm fiber.

Returns:

constant value \(3.5\ \mathrm{m}\)

Return type:

Quantity

pygeomoptics.fibers.fiber_absorption_path_length()

Absorption length of fiber [SaintGobainDataSheet], corrected for the geometry of a 1 mm square fiber.

Multiplied by an empirical factor to account for the prolonged path length inside a square fiber with 1mm side length.

Returns:

constant value \(4.234999999999999\ \mathrm{m}\)

Return type:

Quantity

pygeomoptics.fibers.fiber_cladding1_refractive_index()

Refractive index of first fiber cladding material [SaintGobainDataSheet].

Returns:

constant value \(1.49\)

Return type:

float

pygeomoptics.fibers.fiber_cladding2_refractive_index()

Refractive index of second fiber cladding material [SaintGobainDataSheet].

Returns:

constant value \(1.42\)

Return type:

float

pygeomoptics.fibers.fiber_core_refractive_index()

Refractive index of fiber core material [SaintGobainDataSheet].

Returns:

constant value \(1.6\)

Return type:

float

pygeomoptics.fibers.fiber_core_scint_light_yield()

fiber scintillation yield for electrons, from [Bae2025].

Returns:

constant value \(1880\ \frac{1}{\mathrm{MeV}}\)

Return type:

Quantity

pygeomoptics.fibers.fiber_core_scintillation_params()

Get a ScintConfig object for fibers.

Light yield for different particle types (electrons, alphas) from [Bae2025].

The light yield for ions/nuclear recoils is set to zero. The light yield for protons is derived from the Birk’s constant similar as in [Leverington2011], assuming some common LET ranges. The quenching is not implemented in an energy-dependent way.

Return type:

ScintConfig

pygeomoptics.fibers.fiber_wls_absorption(abs_at_400nm=<Quantity(0.7, 'millimeter')>)

[SaintGobainDataSheet] reports the absorption spectrum for BCF-91A.

Knowing that the fibers are 1mm thick one can extract the absorption length: starting from the trivial relation:

\(1 - P(E) = \exp(-x/l(E))\)

where \(P(E)\) is the probability (thus proportional to the absorption spectrum) for a photon travelling a distance \(x\) to be absorbed in the material given the attenuation length \(l(E)\), one can extract \(l(E)\) from \(P(E)\). By integrating over the thickness of the material \(L\) one obtains:

\((1 - P(E)) \cdot L = l(E) \cdot (1 - \exp(-L/l(E)))\)

but the problem now is that \(l(E)\) cannot be extracted analytically (inhomogeneus expression). Luigi wrote a Mathematica script that solves it numerically. Remember that the units are arbitrary because the original absorption spectrum has arbitrary units.

Measured an absorption length of 0.7 mm at 400 nm, the spectrum has been rescaled by that.

Returns:

../_images/pygeomoptics.fibers.fiber_wls_absorption_0.png

Parameters:

abs_at_400nm (Quantity)

Return type:

tuple[Quantity, Quantity]

pygeomoptics.fibers.fiber_wls_emission()

[SaintGobainDataSheet] reports the emission spectrum for BCF-91A.

Returns:

../_images/pygeomoptics.fibers.fiber_wls_emission_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.fibers.fiber_wls_timeconstant()

WLS time constant [SaintGobainDataSheet].

Returns:

constant value \(12\ \mathrm{ns}\)

Return type:

Quantity

pygeomoptics.fibers.g4gps_fiber_emissions_spectrum(filename, output_macro)

Write a fiber emission energy spectrum for G4GeneralParticleSource.

See also

fiber_wls_emission, utils.g4gps_write_emission_spectrum

Parameters:
  • filename (str)

  • output_macro (bool)

Return type:

None

pygeomoptics.fibers.pyg4_fiber_cladding1_attach_rindex(mat, reg)

Attach the refractive index to the given fiber cladding 1 material instance.

Return type:

None

pygeomoptics.fibers.pyg4_fiber_cladding2_attach_rindex(mat, reg)

Attach the refractive index to the given fiber cladding 2 material instance.

Return type:

None

pygeomoptics.fibers.pyg4_fiber_core_attach_absorption(mat, reg, use_geometrical_absorption=True)

Attach absorption to the given material instance.

Parameters:

use_geometrical_absorption (bool) – switch between the absorption length as specified by the manufacturer and the length corrected for the geometry of a 1x1mm fiber.

Return type:

None

pygeomoptics.fibers.pyg4_fiber_core_attach_rindex(mat, reg)

Attach the refractive index to the given fiber core material instance.

Return type:

None

pygeomoptics.fibers.pyg4_fiber_core_attach_scintillation(mat, reg)

Attach Geant4 properties for fiber scintillation response to the given material instance.

Note

This currently only adds scintillation for energy deposited by electrons or alphas.

Return type:

None

pygeomoptics.fibers.pyg4_fiber_core_attach_wls(mat, reg, wls_abs_at_400nm=<Quantity(0.7, 'millimeter')>)

Attach wavelength shifting properties to the given material instance.

Parameters:

wls_abs_at_400nm (Quantity)

Return type:

None

pygeomoptics.germanium module

Germanium.

[Wegmann2017] (1,2)

A. Wegmann “Characterization of the liquid argon veto of the GERDA experiment and its application for the measurement of the 76Ge half-life” (PhD thesis). https://www.mpi-hd.mpg.de/gerda/public/2017/phd2017-anneWegmann.pdf

[Salamanna2022] (1,2)

Measurements by E. Bernieri, G. Salamanna, D. Tagnani (Roma Tre & INFN), unpublished.

pygeomoptics.germanium.germanium_reflectivity()

Reflectivity of germanium surfaces.

Measurements from [Wegmann2017] (with GERDA dead-layer Li-doped germanium, at room temperature; data-points above 300nm). Data points between 220 and 120 nm from [Salamanna2022] (averaged and smoothed). The interpolation between both domains is linear, but arbitrary.

Returns:

../_images/pygeomoptics.germanium.germanium_reflectivity_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.germanium.pyg4_germanium_attach_reflectivity(mat, reg)

Attach the optical reflectivity to the given germanium material instance.

Return type:

None

pygeomoptics.lar module

Liquid Argon (LAr).

[Heindl2010]

T. Heindl et al. “The scintillation of liquid argon.” In: EPL 91.6 (Sept. 2010). https://doi.org/10.1209/0295-5075/91/62002

[Doke1976]

Doke et al. “Estimation of Fano factors in liquid argon, krypton, xenon and xenon-doped liquid argon.” NIM 134 (1976)353, https://doi.org/10.1016/0029-554X(76)90292-5

[Bideau-Mehu1980]

Bideau-Mehu et al. “Measurement of refractive indices of neon, argon, krypton and xenon in the 253.7-140.4 nm wavelength range. Dispersion relations and estimated oscillator strengths of the resonance lines.” In: Journal of Quantitative Spectroscopy and Radiative Transfer 25.5 (1981)). https://doi.org/10.1016/0022-4073(81)90057-1

[Seidel2002]

G. M. Seidel at al. “Rayleigh scattering in rare-gas liquids.” In: Nuclear Instruments and Methods in Physics Research Section A: Accelerators, Spectrometers Detectors and Associated Equipment 489.1-3 (Aug. 2002). https://doi.org/10.1016/s0168-9002(02)00890-2

[Babicz2020]

M. Babicz et al. “A measurement of the group velocity of scintillation light in liquid argon.” In: Journal of Instrumentation 15.09 (Sept. 2020). https://doi.org/10.1088/1748-0221/15/09/P09009

[Doke2002]

T. Doke et al. “Absolute Scintillation Yields in Liquid Argon and Xenon for Various Particles” Jpn. J. Appl. Phys. 41 1538, https://doi.org/10.1143/JJAP.41.1538

[Hitachi1983]

A. Hitachi et al. “Effect of ionization density on the time dependence of luminescence from liquid argon and xenon.” In: Phys. Rev. B 27 (9 May 1983), pp. 5279-5285, https://doi.org/10.1103/PhysRevB.27.5279

[Schwarz2024] (1,2,3)

M. Schwarz “Tracing impurities and illuminating their impact: Surveying and characterizing liquid argon with LLAMA for LEGEND and beyond” (PhD thesis). https://mediatum.ub.tum.de/?id=1741523

class pygeomoptics.lar.ArAttenuation(peak_rayleigh_length, peak_abs_length, λ, rayleigh, abslength, attenuation)

Bases: NamedTuple

Create new instance of ArAttenuation(peak_rayleigh_length, peak_abs_length, λ, rayleigh, abslength, attenuation)

Parameters:
abslength: Quantity | None

absorption length at all points in λ.

attenuation: Quantity

attenuation length at all points in λ.

peak_abs_length: Quantity

calculated absorption length at the scintillation peak (λ = 126.8 nm).

peak_rayleigh_length: Quantity

calculated rayleigh scattering length at the scintillation peak (λ = 126.8 nm).

rayleigh: Quantity | None

rayleigh length at all points in λ.

λ: Quantity

sampled wavelengths λ.

class pygeomoptics.lar.ArScintLiftime(singlet, triplet)

Bases: NamedTuple

Create new instance of ArScintLiftime(singlet, triplet)

Parameters:
as_tuple()
Return type:

tuple[Quantity, Quantity]

singlet: Quantity

Alias for field number 0

triplet: Quantity

Alias for field number 1

pygeomoptics.lar.g4gps_lar_emissions_spectrum(filename, output_macro)

Write a LAr emission energy spectrum for G4GeneralParticleSource.

See also

lar_emission_spectrum, lar_emission_peak_range, utils.g4gps_write_emission_spectrum

Parameters:
  • filename (str)

  • output_macro (bool)

Return type:

None

pygeomoptics.lar.gar_refractive_index(λ)

Calculate the refractive index of gaseous argon (GAr) for a given photon wavelength.

Returns:

../_images/pygeomoptics.lar.gar_refractive_index_0.png

Parameters:

λ (Quantity)

Return type:

Quantity

pygeomoptics.lar.lar_abs_length(λ, method='default')

Absorption length (not correctly scaled).

We don’t know how the attenuation length actually varies with the wavelength. With the default model, we use a custom exponential function connecting the LAr Scintillation peak and the VIS range just to avoid a step-like function. Still is a guess.

Parameters:
  • λ (Quantity) – Photon wavelength

  • method (Literal['default', 'legend200-llama-two-components']) –

    Choose the absorption curve model:

    • default: Standard exponential model

    • legend200-llama-two-components: Attenuation in the LEGEND-argon, as measured with LLAMA, can be described with a two-component absorption length model, see [Schwarz2024] (p. 137).

Return type:

Quantity

Notes

For mode="default", the return value of this function has to be re-scaled with the intended attenuation length at the VUV emission peak.

Returns:

../_images/pygeomoptics.lar.lar_abs_length_0.png../_images/pygeomoptics.lar.lar_abs_length_1.png

Parameters:
  • λ (Quantity)

  • method (Literal['default', 'legend200-llama-two-components'])

Return type:

Quantity

pygeomoptics.lar.lar_calculate_attenuation(lar_temperature=<Quantity(88.8, 'kelvin')>, lar_dielectric_method='cern2020', attenuation_method_or_length='legend200-llama', rayleigh_enabled_or_length=True, absorption_enabled_or_length=True)

Calculate all attenuation-related optical properties to the given LAr material instance.

Parameters:
  • lar_temperature (Quantity) – liquid phase temperature for rayleigh scattering length calculation.

  • lar_dielectric_method (Literal['cern2020', 'bideau-mehu']) – Choose which calculation method is used for calculation of the dielectric function, which is used for deriving the rayleigh scattering length.

  • attenuation_method_or_length (Literal['legend200-llama'] | ~pint.registry.Quantity) – Change the method/measurement used to define the LAr attenuation length. If set to a length-Quantity, this value is used directly as attenuation length at the scintillation peak.

  • rayleigh_enabled_or_length (bool | Quantity) –

    If set to a boolean value, it enables or disables the default rayleigh scattering.

    If set to a length-Quantity, the given value will be used as the scattering length at the scintillation peak.

  • absorption_enabled_or_length (Literal['default', 'legend200-llama-two-components'] | bool | ~pint.registry.Quantity) –

    If set to a boolean value, the default absorption length is used (i.e. it is derived from the scattering length and the total attenuation length).

    If set to a length-Quantity, the given value will be used as the absorption length at the scintillation peak.

Return type:

ArAttenuation

Important

If all three of rayleigh length, absorption length and attenuation length are set via the function parameters, the parameter defining the total attenuation length will be ignored!

Notes

This functions calculates and returns output similar to this (here for 88.8 K LAr temperature):
../_images/pygeomoptics.lar.lar_calculate_attenuation_0.png ../_images/pygeomoptics.lar.lar_calculate_attenuation_1.png
pygeomoptics.lar.lar_dielectric_constant(λ, method='cern2020')

Calculate the dielectric constant of LAr for a given photon wavelength.

Parameters:
Return type:

Quantity

pygeomoptics.lar.lar_dielectric_constant_bideau_mehu(λ, *, is_liquid=True)

Calculate the dielectric constant of LAr for a given photon wavelength.

From the Bideau-Sellmeier formula [Bideau-Mehu1980] in gaseous argon, density-corrected for liquid argon.

Returns:

../_images/pygeomoptics.lar.lar_dielectric_constant_bideau_mehu_0.png

Parameters:
Return type:

Quantity

pygeomoptics.lar.lar_dielectric_constant_cern2020(λ)

Calculate the dielectric constant of LAr for a given photon wavelength.

From [Babicz2020] (measurements in LAr).

Returns:

../_images/pygeomoptics.lar.lar_dielectric_constant_cern2020_0.png

Parameters:

λ (Quantity)

Return type:

Quantity

pygeomoptics.lar.lar_emission_peak_range()

Return the range of the main argon emission peak.

This can be swapped to simulate different argon physics.

Return type:

tuple[Quantity, Quantity]

pygeomoptics.lar.lar_emission_spectrum(λ)

Return the LAr emission spectrum, adapted from [Heindl2010].

Returns:

../_images/pygeomoptics.lar.lar_emission_spectrum_0.png

Parameters:

λ (Quantity)

Return type:

Quantity

pygeomoptics.lar.lar_fano_factor()

Fano factor.

Statistical yield fluctuation can be broadened or narrower (impurities, fano factor). Value from [Doke1976].

Returns:

constant value \(0.11\)

Return type:

float

pygeomoptics.lar.lar_lifetimes(triplet_lifetime_method='legend200-llama')

Singlet and triplet lifetimes of liquid argon.

Singlet time from [Hitachi1983] and triplet time as measured by LLAMA in LEGEND-200, see [Schwarz2024] (p. 117).

Returns:

constant value | singlet: \(5.95\ \mathrm{ns}\) triplet: \(1.16\ \mathrm{µs}\)

Parameters:

triplet_lifetime_method (float | Literal['legend200-llama'])

Return type:

ArScintLiftime

pygeomoptics.lar.lar_peak_attenuation_length(attenuation_method='legend200-llama')

Attenuation length in the LEGEND-argon, as measured with LLAMA, see [Schwarz2024] (p. 124).

Parameters:

attenuation_method (Literal['legend200-llama'] | ~pint.registry.Quantity)

Return type:

Quantity

pygeomoptics.lar.lar_rayleigh(λ, temperature=<Quantity(90, 'kelvin')>, method='cern2020')

Calculate the Rayleigh scattering length using the equations given in [Seidel2002].

This uses the dielectric constant created using the specified method. This calculation leads to about 90cm length at 128nm (using cern2020), but keep in mind that the value changes drastically out the scintillation peak.

Returns:

../_images/pygeomoptics.lar.lar_rayleigh_0.png

Parameters:
Return type:

Quantity

pygeomoptics.lar.lar_refractive_index(λ, method='cern2020')

Calculate the refractive index of LAr for a given photon wavelength.

Returns:

../_images/pygeomoptics.lar.lar_refractive_index_0.png

Parameters:
Return type:

Quantity

pygeomoptics.lar.lar_scintillation_params(flat_top_yield=<Quantity(31250, '1 / megaelectron_volt')>)

Scintillation yield (approx. inverse of the mean energy to produce a UV photon).

This depends on the nature of the impinging particles, the field configuration and the quencher impurities. We set here just a reference value that is lower than the value provided by [Doke2002], that probably does not represent experimental reality.

For flat-top response particles the mean energy to produce a photon is 19.5 eV

\[Y = 1/(19.5 \mathrm{eV}) = 0.051 \mathrm{eV}^{-1}\]

At zero electric field, for not-flat-top particles, the scintillation yield, relative to the one of flat top particles is:

\[ \begin{align}\begin{aligned}Y_\textrm{e} &= 0.8 Y\\Y_\textrm{alpha} &= 0.7 Y\\Y_\textrm{recoils} &= 0.2\textrm{--}0.4\\Y_\textrm{proton} &= 0.8 Y\end{aligned}\end{align} \]

Excitation ratio:

  • For example, for nuclear recoils it should be 0.75

  • nominal value for electrons and gammas: 0.23 (WArP data)

  • for protons, the excitation ratio is unknown.

Returns:

constant value

  • flat-top: \(31250\ \frac{1}{\mathrm{MeV}}\)

  • fano factor: \(0.11\))

  • electron: \(Y_\textrm{electron}=Y\times0.8\), excitation ratio: 0.23

  • alpha: \(Y_\textrm{alpha}=Y\times0.7\), excitation ratio: 1

  • ion: \(Y_\textrm{ion}=Y\times0.3\), excitation ratio: 0.75

  • proton: \(Y_\textrm{proton}=Y\times0.8\), excitation ratio: 0.23

Parameters:

flat_top_yield (Quantity)

Return type:

ScintConfig

See also

lar_fano_factor

pygeomoptics.lar.pyg4_gar_attach_rindex(lar_mat, reg)

Attach the refractive index to the given gaseous argon (GAr) material instance.

Return type:

None

pygeomoptics.lar.pyg4_lar_attach_attenuation(lar_mat, reg, lar_temperature, lar_dielectric_method='cern2020', attenuation_method_or_length='legend200-llama', rayleigh_enabled_or_length=True, absorption_enabled_or_length=True)

Attach all attenuation-related optical properties to the given LAr material instance.

Parameters:
  • lar_temperature (Quantity) – liquid phase temperature for rayleigh scattering length calculation.

  • lar_dielectric_method (Literal['cern2020', 'bideau-mehu']) – Choose which calculation method is used for calculation of the dielectric function, which is used for deriving the rayleigh scattering length.

  • attenuation_method_or_length (Literal['legend200-llama'] | ~pint.registry.Quantity) – Change the method/measurement used to define the LAr attenuation length. If set to a length-Quantity, this value is used directly as attenuation length at the scintillation peak.

  • rayleigh_enabled_or_length (bool | Quantity) –

    If set to a boolean value, it enables or disables the default rayleigh scattering.

    If set to a length-Quantity, the given value will be used as the scattering length at the scintillation peak.

  • absorption_enabled_or_length (bool | Quantity) –

    If set to a boolean value, the default absorption length is used (i.e. it is derived from the scattering length and the total attenuation length).

    If set to a length-Quantity, the given value will be used as the absorption length at the scintillation peak.

Returns:

  • calculated rayleigh scattering length at the scintillation peak (λ = 126.8 nm)

  • calculated absorption length at the scintillation peak (λ = 126.8 nm)

Return type:

tuple[Quantity, Quantity]

Important

If all three of rayleigh length, absorption length and attenuation length are set via the function parameters, the parameter defining the total attenuation length will be ignored!

pygeomoptics.lar.pyg4_lar_attach_rindex(lar_mat, reg, lar_dielectric_method='cern2020')

Attach the refractive index to the given LAr material instance.

Parameters:

lar_dielectric_method (Literal['cern2020', 'bideau-mehu']) – Choose which calculation method is used for calculation of the refractive index.

Return type:

None

pygeomoptics.lar.pyg4_lar_attach_scintillation(lar_mat, reg, flat_top_yield=<Quantity(31250, '1 / megaelectron_volt')>, triplet_lifetime_method='legend200-llama')

Attach all properties for LAr scintillation response to the given LAr material instance.

Parameters:
  • flat_top_yield (Quantity) – Change the flat-top light yield of the scintillation response. Note that for different particle types, the value might be lower (see lar_scintillation_params()).

  • triplet_lifetime_method (float | Literal['legend200-llama']) – Change the method/measurement used to define the LAr triplet state lifetime. If set to a number, this value is used directly as lifetime in µs.

Return type:

None

pygeomoptics.nylon module

Nylon from Borexino tank, as described in [Agostini2018].

[Agostini2018] (1,2)

M. Agostini et al. “The Monte Carlo simulation of the Borexino detector” In: Astroparticle Physics 97 (2018). https://doi.org/10.1016/j.astropartphys.2017.10.003

[Benziger2007]

J. Benziger et al. “The Nylon Scintillator Containment Vessels for the Borexino Solar Neutrino Experiment” In: International Journal of Modern Physics A, 29(16) (2014). https://doi.org/10.1016/j.nima.2007.08.176

pygeomoptics.nylon.nylon_absorption()

Values reported in [Agostini2018].

Returns:

../_images/pygeomoptics.nylon.nylon_absorption_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.nylon.nylon_refractive_index()

Refractive index in near-UV range, from [Benziger2007].

Returns:

constant value \(1.53\)

Return type:

float

pygeomoptics.nylon.pyg4_nylon_attach_absorption(mat, reg)

Attach absorption to the given nylon material instance.

See also

nylon_absorption

Return type:

None

pygeomoptics.nylon.pyg4_nylon_attach_rindex(mat, reg)

Attach the refractive index to the given nylon material instance.

Return type:

None

pygeomoptics.pen module

Polyethylene Naphthalate (PEN) plastic scintillator and wavelength shifter.

[Manzanillas2022] (1,2,3)

L. Manzanillas et al. “Optical properties of low background PEN structural components for the LEGEND-200 experiment”. In: JINST 17 P09007 (2022), https://doi.org/10.1088/1748-0221/17/09/P09007

[Hong2017]

N. Hong et al. “Mueller matrix characterization of flexible plastic substrates”. In: Applied Surface Science, 421:518-528 (2017), https://doi.org/10.1016/j.apsusc.2017.01.276

[Ouchi2006]

I. Ouchi et al. “Features of Fluorescence Spectra of Polyethylene 2,6-Naphthalate Films” In: Journal of Applied Polymer Science, Vol. 105, 114-121 (2007), https://doi.org/10.1002/app.26085

[Hackett2024]

B. Hackett et al. “Light response of poly(ethylene 2,6-naphthalate) to neutrons”. In: Nuclear Inst. and Methods in Physics Research, A (2024), https://doi.org/10.1016/j.nima.2024.169900

pygeomoptics.pen.g4gps_pen_emissions_spectrum(filename, output_macro)

Write a PEN emission energy spectrum for G4GeneralParticleSource.

See also

pen_wls_emission, utils.g4gps_write_emission_spectrum

Parameters:
  • filename (str)

  • output_macro (bool)

Return type:

None

pygeomoptics.pen.pen_absorption()

Bulk absorption reported in [Manzanillas2022].

Returns:

../_images/pygeomoptics.pen.pen_absorption_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.pen.pen_quantum_efficiency()

Quantum efficiency, from [Araujo2022] at LAr temperature.

Returns:

constant value \(0.69\)

Return type:

float

pygeomoptics.pen.pen_refractive_index()

Refractive index from [Hong2017].

Returns:

constant value \(1.51\)

Return type:

float

pygeomoptics.pen.pen_scint_light_yield()

PEN scintillation yield for electrons, from [Manzanillas2022].

Returns:

constant value \(5440\ \frac{1}{\mathrm{MeV}}\)

Return type:

Quantity

pygeomoptics.pen.pen_scint_timeconstant()

Time constant, from [Manzanillas2022].

Returns:

constant value \(25.3\ \mathrm{ns}\)

Return type:

Quantity

pygeomoptics.pen.pen_scintillation_params()

Get a ScintConfig object for PEN.

This implements the measured electron light yield. The light yield for other particle types (protons, alphas, ions) is derived from the Birk’s constant in [Hackett2024] assuming some common LET ranges. The quenching is not implemented in an energy-dependent way.

Returns:

constant value

  • flat-top: \(5440\ \frac{1}{\mathrm{MeV}}\)

  • electron: \(Y_\textrm{electron}=Y\times1\)

  • proton: \(Y_\textrm{proton}=Y\times0.5\)

  • alpha: \(Y_\textrm{alpha}=Y\times0.1\)

  • ion: \(Y_\textrm{ion}=Y\times0.05\)

Return type:

ScintConfig

pygeomoptics.pen.pen_wls_absorption()

WLS absorption of PEN.

Warning

There is no measurement of PEN similar to ours available, so this step-function is improvised. For geometries with thick PEN objects, the absorption length should not matter too much—in a certain range, all light will be absorbed anyway.

The absorbing range and approximate magnitude have been extracted from [Ouchi2006], figure 1.

Returns:

../_images/pygeomoptics.pen.pen_wls_absorption_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.pen.pen_wls_emission()

WLS Emission spectrum.

[Leonhardt2024] measure the emission spectrum of a PEN sample made from the same pellets as in LEGEND-200 sample at an excitation wavelength of 128nm and at 87K, so exactly in our experimental conditions.

Note

Data points below 375 nm are an ad-hoc continuation of the measured data to zero, avoiding a steep step. They are not based on actual measurements.

Returns:

../_images/pygeomoptics.pen.pen_wls_emission_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.pen.pyg4_pen_attach_attenuation(mat, reg)

Attach bulk absorption properties to the given PEN material instance.

See also

pen_absorption

Return type:

None

pygeomoptics.pen.pyg4_pen_attach_rindex(mat, reg)

Attach the refractive index to the given PEN material instance.

Return type:

None

pygeomoptics.pen.pyg4_pen_attach_scintillation(mat, reg)

Attach Geant4 properties for PEN scintillation response to the given material instance.

Note

This currently only adds scintillation for energy deposited by electrons.

Return type:

None

pygeomoptics.pen.pyg4_pen_attach_wls(mat, reg, quantum_efficiency=True)

Attach wavelength shifting properties to the given PEN material instance.

Parameters:

quantum_efficiency (bool | float) – If False, disable attaching any photon number information. If True, use the values from .pen_quantum_efficiency. If specified as a number, directly attach this number as mean number of emitted photons.

Return type:

None

pygeomoptics.plot module

pygeomoptics.plot.plot_callable(obj, plot_file, options, *, ax=None, plotoptions=None)

Create a plot from the given optical property function.

By default, it will call obj() and unpack the result into an x-vector, and multiple y-vectors. All y-vectors will pe plotted together into one output file.

Parameters:
  • options (dict[str, Any]) –

    Change the behaviour of the plot.

    xlim

    Set the plot’s x axis limits, see matplotlib.pyplot.xlim()

    ylim

    Set the plot’s y axis limits, see matplotlib.pyplot.ylim()

    xscale

    Set the plot’s x axis scaling, see matplotlib.pyplot.xscale()

    yscale

    Set the plot’s y axis scaling, see matplotlib.pyplot.yscale()

    labels

    Tuple of labels that will be applied if more than one y vector is returned.

    call_x

    Differing from the default behavior above, the function will be called with an x vector of wavelengths in the optical range (as pint.Quantity). All return values are interpreted as y vectors.

    ret_offset

    use the argument numbered by this (default: 0) as the first argument that will be treated as an x or y vector.

    extra_kwargs

    add more kwargs to the obj() call.

  • obj (Callable)

  • plot_file (Path)

  • plotoptions (dict | None)

Return type:

None

pygeomoptics.plot.plot_continuous_prop(ax, prop, x, param_dict=None)

Plot continuous property.

Plots the prop function on values x with matplotlib’s plot().

Parameters:
  • ax (Axes) – axes instance.

  • prop (Callable) – function defining continuous property, such as for example lar.lar_refractive_index().

  • x (Quantity) – array of domain values for which prop is shown.

  • param_dict – dictionary defining custom matplotlib settings to be passed to plot().

pygeomoptics.plot.plot_discrete_prop(ax, prop, param_dict=None)

Plot discrete property.

Unpacks what returned by the prop function and feeds it to matplotlib’s plot().

Parameters:
  • ax (Axes) – axes instance.

  • prop (Callable) – function defining discrete properties, such as for example lar.lar_emission_spectrum().

  • param_dict – dictionary defining custom matplotlib settings to be passed to plot().

pygeomoptics.pmts module

PMT components incorporating data for different PMT models.

Common parameters applicable to both models are included where relevant, like refractive index of borosilicate glass. Currently the photocathode efficiencies for the ETL9354KB [ETEL2010] and R7081 [HAMAMATSU2019] PMT models are included.

[ETEL2010]

ET Enterprises Limited 2010 “200 mm (8”) photomultiplier 9354KB series data sheet”, 2010, http://lampes-et-tubes.info/pm/9354KB.pdf

pygeomoptics.pmts.pmt_acryl_absorption_length()

Absorption length.

Returns:

../_images/pygeomoptics.pmts.pmt_acryl_absorption_length_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.pmts.pmt_acryl_refractive_index()

Refractive index.

Returns:

constant value \(1.489\)

Return type:

float

pygeomoptics.pmts.pmt_air_absorption_length()

Absorption length.

Returns:

constant value \(100\ \mathrm{m}\)

Return type:

Quantity

pygeomoptics.pmts.pmt_air_refractive_index()

Refractive index.

Returns:

constant value \(1.0\)

Return type:

float

pygeomoptics.pmts.pmt_borosilicate_absorption_length()

Absorption length.

Returns:

../_images/pygeomoptics.pmts.pmt_borosilicate_absorption_length_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.pmts.pmt_borosilicate_refractive_index()

Refractive index.

Returns:

constant value \(1.49\)

Return type:

float

pygeomoptics.pmts.pmt_etl9354kb_photocathode_collection_efficiency()

Collection efficiency photocathode for ETL9354KB.

Returns:

constant value \(0.85\)

Return type:

float

pygeomoptics.pmts.pmt_etl9354kb_photocathode_efficiency()

Efficiency for ETL9354KB.

Returns:

../_images/pygeomoptics.pmts.pmt_etl9354kb_photocathode_efficiency_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.pmts.pmt_photocathode_reflectivity()

Efficiency.

Returns:

../_images/pygeomoptics.pmts.pmt_photocathode_reflectivity_0.png

Return type:

tuple[Quantity, Quantity]

See also

borosilicate_refractive_index

pygeomoptics.pmts.pmt_r7081_photocathode_collection_efficiency()

Collection efficiency photocathode for Hamamatsu R7081.

Returns:

constant value \(0.9\)

Return type:

float

pygeomoptics.pmts.pmt_r7081_photocathode_efficiency()

Efficiency for Hamamatsu R7081.

Returns:

../_images/pygeomoptics.pmts.pmt_r7081_photocathode_efficiency_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.pmts.pmt_steel_efficiency()

Efficiency.

Deprecated since version 0.17: steel should not have a detection efficiency.

Return type:

float

pygeomoptics.pmts.pmt_steel_reflectivity()

Reflectivity. Modeled after [STEEL1982].

Returns:

../_images/pygeomoptics.pmts.pmt_steel_reflectivity_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.pmts.pyg4_pmt_attach_acryl_absorption_length(mat, reg)

Attach the absorption length to the given acryl material instance of the PMT cap.

Return type:

None

pygeomoptics.pmts.pyg4_pmt_attach_acryl_rindex(mat, reg)

Attach the refractive index to the given acryl material instance of the PMT cap.

Return type:

None

pygeomoptics.pmts.pyg4_pmt_attach_air_absorption_length(mat, reg)

Attach the absorption length to the given air material instance of the PMT cap.

Return type:

None

pygeomoptics.pmts.pyg4_pmt_attach_air_rindex(mat, reg)

Attach the refractive index to the given air material instance of the PMT cap.

Return type:

None

pygeomoptics.pmts.pyg4_pmt_attach_borosilicate_absorption_length(mat, reg)

Attach the absorption length to the given borosilicate material instance of the PMT cap.

Return type:

None

pygeomoptics.pmts.pyg4_pmt_attach_borosilicate_rindex(mat, reg)

Attach the refractive index to the given borosilicate material instance of the PMT cap.

Return type:

None

pygeomoptics.pmts.pyg4_pmt_attach_photocathode_efficiency(mat, reg, name='etl9354')

Attach the efficiency to the given PMT photocathode material instance.

See also

pmt_photocathode_efficiency, pmt_photocathode_collection_efficiency

Parameters:

name (Literal['etl9354', 'gerda', 'r7081', 'l1000'])

Return type:

None

pygeomoptics.pmts.pyg4_pmt_attach_photocathode_reflectivity(mat, reg)

Attach the reflectivity to the given PMT photocathode material instance.

Return type:

None

pygeomoptics.pmts.pyg4_pmt_attach_steel_efficiency(mat, reg)

Attach the efficiency to the given PMT steel material instance.

Deprecated since version 0.17: steel should not have a detection efficiency.

Return type:

None

pygeomoptics.pmts.pyg4_pmt_attach_steel_reflectivity(mat, reg)

Attach the reflectivity to the given PMT steel material instance.

Return type:

None

pygeomoptics.pyg4utils module

pygeomoptics.pyg4utils._def_scint_particle(mat, particle, y, yield_factor, exc_ratio)

Define a single particle type used by Geant4’s ScintillationByParticleType.

Parameters:
Return type:

None

pygeomoptics.pyg4utils._gdml_unit(u)
Parameters:

u (str)

Return type:

str

pygeomoptics.pyg4utils._get_scint_yield_vector(yield_per_mev)

In Geant4 11.0+, ScintillationByParticleType takes some sort of integrated scintillation yield.

To fulfill this we use a simple linear function.

Parameters:

yield_per_mev (Quantity)

pygeomoptics.pyg4utils._patch_g4_pint_unit_support()

pyg4ometry does currently not support code::pint unit that we use extensively here.

This function adds some helper functions to pyg4ometry.geant4.Material and pyg4ometry.geant4.solid.OpticalSurface in order to make adding material properties nicer. The new functions also check for some common properties to be used with the correct units.

Return type:

None

pygeomoptics.pyg4utils.pint_to_gdml(v)

Convert a pint Quantity or ArrayLike (scalar/vector) object to a unit usable in GDML and the suitable value.

Parameters:

v (Quantity | TypeAliasForwardRef('ArrayLike'))

Return type:

tuple[str, TypeAliasForwardRef(‘ArrayLike’)]

pygeomoptics.pyg4utils.pyg4_def_scint_by_particle_type(mat, scint_cfg)

Define a full set of particles for scintillation.

Parameters:

scint_cfg (ScintConfig)

Return type:

None

pygeomoptics.pyg4utils.pyg4_sample_λ(λ_start, λ_end, sample_count=200)

Sample equally-spaced energies between the two specified wavelengths.

Parameters:
Return type:

Quantity

pygeomoptics.pyg4utils.pyg4_scale_spectral_density(λ)

Calculate a correction factor for emission spectra expressed as spectral density.

Geant4 samples the emission from the spectrum in energy representation. This requires an additional scaling factor according to the integral substitution:

\[\mathrm{d}\lambda \propto \lambda(E)^2 \mathrm{d}E\]
Parameters:

λ (Quantity)

Return type:

NDArray

pygeomoptics.pyg4utils.pyg4_spectral_density(λ, s_λ)

Convert an emission spectra expressed as spectral density in wavelength to vectors for Geant4.

Parameters:
  • λ (Quantity) – wavelength vector.

  • s_λ (Quantity) – spectral density expressed in wavelength.

Return type:

tuple[Quantity, Quantity]

pygeomoptics.scintillate module

class pygeomoptics.scintillate.ScintConfig(flat_top, fano_factor, particles)

Bases: NamedTuple

Scintillation yield parameters, depending on the particle types.

Create new instance of ScintConfig(flat_top, fano_factor, particles)

Parameters:
fano_factor: float | None

Alias for field number 1

flat_top: Quantity

Alias for field number 0

get_particle(name)
Parameters:

name (str)

Return type:

ScintParticle | None

particles: list[ScintParticle]

Alias for field number 2

class pygeomoptics.scintillate.ScintParticle(name, yield_factor, exc_ratio)

Bases: NamedTuple

Configuration for the scintillation yield relative to the flat-top yield.

Create new instance of ScintParticle(name, yield_factor, exc_ratio)

Parameters:
  • name (Literal['deuteron', 'triton', 'alpha', 'ion', 'electron', 'proton'])

  • yield_factor (float)

  • exc_ratio (float | None)

exc_ratio: float | None

Alias for field number 2

name: Literal['deuteron', 'triton', 'alpha', 'ion', 'electron', 'proton']

Alias for field number 0

valid_geant_particle()
Return type:

bool

yield_factor: float

Alias for field number 1

pygeomoptics.scintillate.particle_to_index(particle)

Converts the given G4 scintillation particle name to a module-internal index.

Parameters:

particle (str)

Return type:

ParticleIndex

pygeomoptics.scintillate.precompute_scintillation_params(scint_config, time_components)
Parameters:
Return type:

ComputedScintParams

pygeomoptics.scintillate.scintillate(params, x0_m, x1_m, v0_mpns, v1_mpns, t0_ns, particle, particle_charge, edep_keV, rng, emission_term_model='normal_fano')

Generates a Poisson/Gauss-distributed number of photons according to the scintillation yield formula, as implemented in Geant4, along the line segment between x0 and x1.

In case x1 is not supplied the position along the step and the time offsets are not considered.

Parameters:
  • params (ComputedScintParams) – scintillation parameter tuple, as created by precompute_scintillation_params().

  • x0_m (ndarray) – three-vector of pre step point position (in units of meter).

  • x1_m (ndarray | None) – three-vector of post step point position (in units of meter).

  • v0_mpns (float | None) – velocity of particle before step (in units of meter per nanosecond).

  • v1_mpns (float | None) – velocity of particle after step (in units of meter per nanosecond).

  • t0_ns (float) – global time offset of step start in scintillator, in nanoseconds.

  • particle (ParticleIndex) – module-internal particle index, see particle_to_index().

  • particle_charge (int) – charge of the particle, in units of the elementary charge.

  • edep_keV (float) – energy deposition along this step, in units pf keV.

  • emission_term_model (Literal['poisson', 'normal_fano']) – switch between a Geant4-like photon number term (normal distribution with fano factor) and a simplified model using a Poisson distribution.

  • rng (Generator)

Returns:

array of four-vectors containing time stamps (in nanoseconds) and global scintillation positions (in meter).

The emitted photons are distributed uniformly in space along the path and not ordered.

pygeomoptics.scintillate.scintillate_local(params, particle, edep_keV, rng, emission_term_model='normal_fano')

Generates a Poisson/Gauss-distributed number of photons according to the scintillation yield formula, as implemented in Geant4.

This function only calculates the local part of scintillation.

Parameters:
  • params (ComputedScintParams) – scintillation parameter tuple, as created by precompute_scintillation_params().

  • particle (ParticleIndex) – module-internal particle index, see particle_to_index().

  • edep_keV (float) – energy deposition along this step, in units pf keV.

  • emission_term_model (Literal['poisson', 'normal_fano']) – switch between a Geant4-like photon number term (normal distribution with fano factor) and a simplified model using a Poisson distribution.

  • rng (Generator)

Returns:

array of scintillation time stamps in nanoseconds, relative to the point in time of energy deposition.

Return type:

ndarray

pygeomoptics.scintillate.scintillate_numphot(params, particle, edep_keV, rng, emission_term_model='normal_fano')

Generates a Poisson/Gauss-distributed number of photons according to the scintillation yield formula, as implemented in Geant4.

This function only calculates the number of emitted photons.

Parameters:
  • params (ComputedScintParams) – scintillation parameter tuple, as created by precompute_scintillation_params().

  • particle (ParticleIndex) – module-internal particle index, see particle_to_index().

  • edep_keV (float) – energy deposition along this step, in units pf keV.

  • emission_term_model (Literal['poisson', 'normal_fano']) – switch between a Geant4-like photon number term (normal distribution with fano factor) and a simplified model using a Poisson distribution.

  • rng (Generator)

Returns:

number of emitted scintillation photons.

Return type:

int

pygeomoptics.scintillate.scintillate_times(params, particle, num_photons, rng)

Generates the scintillation emission time profile.

Parameters:
Returns:

array of scintillation time stamps in nanoseconds, relative to the point in time of energy deposition.

Return type:

ndarray

pygeomoptics.silica module

Fused silica (SiO₂) (e.g., Suprasil, …)

[Malitson1965]

I.H. Malitson “Interspecimen Comparison of the Refractive Index of Fused Silica”. In: J. Opt. Soc. Am. 55, 1205-1209 (1965), https://doi.org/10.1364/JOSA.55.001205

pygeomoptics.silica.pyg4_silica_attach_rindex(mat, reg)

Attach the refractive index to the given silica material instance.

Return type:

None

pygeomoptics.silica.silica_refractive_index(λ)

Refractive index reported in [Malitson1965].

Returns:

../_images/pygeomoptics.silica.silica_refractive_index_0.png

Parameters:

λ (Quantity)

Return type:

Quantity

pygeomoptics.silicon module

Silicon.

[Phillip1960]

H. R. Phillip and E. A. Taft “Optical Constants of Silicon in the Region 1 to 10 eV”. In: Phys. Rev. 120 (1 Oct. 1960) https://doi.org/10.1103/PhysRev.120.37

pygeomoptics.silicon.pyg4_silicon_attach_complex_rindex(mat, reg)

Attach the complex refractive index to the given silicon material instance.

Return type:

None

pygeomoptics.silicon.silicon_complex_rindex()

Real and imaginary parts as tuple(wavelength, Re, Im). Measurements from [Phillip1960].

Returns:

../_images/pygeomoptics.silicon.silicon_complex_rindex_0.png

Return type:

tuple[Quantity, Quantity, Quantity]

pygeomoptics.steel module

Steel.

Optical properties of steel are expected to vary depending on surface finish, oxidation, … The properties here can only be a guess toward any given special material (i.e. the GERDA/LEGEND cryostat) until we have a dedicated measurement available.

[STEEL1982] (1,2)

Optical constants and spectral selectivity of stainless steel and its oxides https://doi.org/10.1063/1.331503

pygeomoptics.steel.pyg4_steel_attach_reflectivity(mat, reg)

Attach the optical reflectivity to the given steel material instance.

Return type:

None

pygeomoptics.steel.steel_reflectivity()

Reflectivity of steel surfaces, modeled after [STEEL1982].

For the value below 200 nm, we just assume a lower reflectivity. This seems to follow the general trend of metals. See also [Soto-Oton2026], which also measures the overall reflectivity over the whole spectrum to be lower. The 20% at 110 nm is a conservative (upper) guess.

Returns:

../_images/pygeomoptics.steel.steel_reflectivity_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.store module

A store that allows to manipulate and swap individual material properties with custom implementations.

register_pluggable() is a decorator to use above all functions defining material properties.

Users can then replace the original implementation by their own implementations using replace_implementation(new_impl: Callable), and also switch back to the original implementation using reset_implementation() on the decorated function object. The original implementation is always available as original_impl().

Apart from the decorator, this store provides functions to get and reset the status of all registered pluggable functions.

class pygeomoptics.store.PluggableFunction(fn)

Bases: Generic[P, R]

A wrapper around a function that allows replacing its implementation at runtime.

Parameters:

fn (Callable[P, R])

is_original()

Is the underlying function the original implementation.

Return type:

bool

original_impl()

The original function implementation.

Return type:

Callable[[~P], R]

replace_implementation(new_impl)

Replace the underlying function implementation.

Parameters:

new_impl (Callable[[~P], R])

Return type:

None

reset_implementation()

Reset to the original function implementation.

Return type:

None

pygeomoptics.store.get_replaced()

Get the names of all replaced pluggable material property functions.

Return type:

list[str]

pygeomoptics.store.is_all_original()

Get whether all pluggable material property functions use their original implementation.

Return type:

bool

pygeomoptics.store.load_user_material_code(python_file)

Load a python file as a module for customizations to the material store.

Warning

this is potentially dangerous (i.e. against security best practices), as it loads “untrusted” code form the user - but this should be fine in the context of a CLI tool. We cannot restrict what this module can do, as it might require loading spectra or other files.

Note

This should only be used in CLI tools. In user code, a proper way to import python modules should be preferred.

Parameters:

python_file (str)

Return type:

None

pygeomoptics.store.register_pluggable(fn)

Decorator that registers this function as a pluggable property function.

Parameters:

fn (Callable[[~P], R])

Return type:

PluggableFunction[~P, R]

pygeomoptics.store.reset_all_to_original()

Reset all pluggable material property functions to their original implementations.

Return type:

None

pygeomoptics.tetratex module

Tetratex reflector.

[Janecek2012] (1,2)

M. Janecek, “Reflectivity spectra for commonly used reflectors”, https://www.osti.gov/servlets/purl/1184400

pygeomoptics.tetratex.pyg4_tetratex_attach_reflectivity(mat, reg, reflectivity_scale=1)

Attach the optical reflectivity to the given tetratex material instance.

Parameters:

reflectivity_scale (float) – Global scale for tetratex reflectivity.

Return type:

None

pygeomoptics.tetratex.tetratex_reflectivity()

Tetratex reflectivity from [Janecek2012].

He measures the reflectivity of 2 and 4 superimposed layers of 160um thick Tetratex. As our layer in GERDA/LEGEND is 254um thick I’m taking here his results for the two superimposed foils (= 320um). So, in reality, the reflectivity of our foil should be (negligibly) smaller.

The measured spectrum only has data points above 250 nm. Below that, the reflectivity is expected to drop; however, the value is unknown ([Araujo2022] finds an 90 %-CL upper limit of ~ 17 %). We set an arbitrary reflectivity of 10 % here.

Returns:

../_images/pygeomoptics.tetratex.tetratex_reflectivity_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.tpb module

Tetraphenyl-Butadiene wavelength shifter.

[Francini2013]

R. Francini et al. “VUV-Vis optical characterization of Tetraphenyl-butadiene films on glass and specular reflector substrates from room to liquid Argon temperature.” In: Journal of Instrumentation 8.09 (Sept. 2013). https://doi.org/10.1088/1748-0221/8/09/p09006.

[Benson2018] (1,2)

C. Benson et al. “Measurements of the intrinsic quantum efficiency and absorption length of tetraphenyl butadiene thin films in the vacuum ultraviolet regime.” In: The European Physical Journal C 78.4 (Apr. 2018). https://doi.org/10.1140/epjc/s10052-018-5807-z

[Araujo2022] (1,2,3)

G. R. Araujo et al. “R&D of wavelength-shifting reflectors and characterization of the quantum efficiency of tetraphenyl butadiene and polyethylene naphthalate in liquid argon.” In: The European Physical Journal C 82.5 (May 2022). https://doi.org/10.1140/epjc/s10052-022-10383-0

[Leonhardt2024] (1,2)

A. Leonhardt et al. “A novel cryogenic VUV spectrofluorometer for the characterization of wavelength shifters”. In: JINST 19 C05020 (2024). https://doi.org/10.1088/1748-0221/19/05/C05020

pygeomoptics.tpb.pyg4_tpb_attach_rindex(mat, reg)

Attach the refractive index to the given tpb material instance.

Return type:

None

pygeomoptics.tpb.pyg4_tpb_attach_wls(mat, reg, quantum_efficiency=True, emission_spectrum='default')

Attach wavelength shifting properties to the given tpb material instance.

Parameters:
  • quantum_efficiency (bool | float) – If False, disable attaching any photon number information. If True, use the values from .tpb_quantum_efficiency. If specified as a number, directly attach this number as mean number of emitted photons.

  • emission_spectrum (str) – either default or polystyrene_matrix

Return type:

None

pygeomoptics.tpb.tpb_polystyrene_wls_emission()

WLS Emission spectrum for TPB in a polystyrene matrix.

[Francini2013] measure the emission spectrum of TPB in a polystyrene matrix at an excitation wavelength of 128nm and at 87K, so exactly in our experimental conditions. The major differences brougth by the embedding in the PS matrix is the shift of the main emission peak and a loss of vibronic structures.

Returns:

../_images/pygeomoptics.tpb.tpb_polystyrene_wls_emission_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.tpb.tpb_quantum_efficiency()

Quantum efficiency.

  • Current literature value of 0.85 from [Araujo2022] at LAr Temperature.

  • Other measurement from [Benson2018] reports ~0.6 at room temperature

Returns:

constant value \(0.85\)

Return type:

float

pygeomoptics.tpb.tpb_refractive_index()

Refractive index from [MolbaseTPB].

Returns:

constant value \(1.635\)

Return type:

float

pygeomoptics.tpb.tpb_wls_absorption()

Values reported in [Benson2018] for TPB evaporated on utraviolet-transmitting acrylic substrate.

Returns:

../_images/pygeomoptics.tpb.tpb_wls_absorption_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.tpb.tpb_wls_emission()

WLS Emission spectrum.

[Leonhardt2024] measure the emission spectrum of TPB on a LEGEND-200 WLSR sample at an excitation wavelength of 128nm and at 87K, so exactly in our experimental conditions.

Returns:

../_images/pygeomoptics.tpb.tpb_wls_emission_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.tpb.tpb_wls_timeconstant()

Time constant: arbitrary small.

Returns:

constant value \(0.01\ \mathrm{ns}\)

Return type:

Quantity

pygeomoptics.tyvek module

Tyvek reflector.

pygeomoptics.tyvek.pyg4_tyvek_attach_reflectivity(mat, reg, reflectivity_scale=1)

Attach the optical reflectivity to the given material instance.

Parameters:

reflectivity_scale (float) – Global scale for tyvek reflectivity.

Return type:

None

pygeomoptics.tyvek.tyvek_reflectivity()

Tyvek reflectivity from [Janecek2012].

A little bit more conservative than in the paper (-1% reflectivity compared to the values in the paper).

Returns:

../_images/pygeomoptics.tyvek.tyvek_reflectivity_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.ultem module

Ultem (polyetherimide, PEI) structural components

[Zhang2020] (1,2)

X. Zhang et al. “Complex refractive indices measurements of polymers in visible and near-infrared bands”. In: Appl. Opt. 59, 2337-2344 (2020), https://doi.org/10.1364/AO.383831

pygeomoptics.ultem.pyg4_ultem_attach_absorption(mat, reg)

Attach the absorption length to the given Ultem/PEI material instance.

See also

ultem_absorption

Return type:

None

pygeomoptics.ultem.pyg4_ultem_attach_rindex(mat, reg)

Attach the refractive index to the given Ultem/PEI material instance.

Return type:

None

pygeomoptics.ultem.ultem_absorption()

Absorption length, based on the complex refractive index reported for PEI in [Zhang2020].

The data points below 400 nm are an ad-hoc extension.

Returns:

../_images/pygeomoptics.ultem.ultem_absorption_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.ultem.ultem_refractive_index()

Real refractive index reported for PEI in [Zhang2020], smoothed.

The data points below 400 nm are an ad-hoc extension.

Returns:

../_images/pygeomoptics.ultem.ultem_refractive_index_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.utils module

class pygeomoptics.utils.InterpolatingGraph(idx, vals, min_idx=None, max_idx=None, zero_outside=False)

Bases: object

Linear interpolation between data points, similar to Geant4 default interpolation.

The data points are given as two 1-dimensional NDArrays with units.

Parameters:
  • idx (Quantity)

  • vals (Quantity)

  • min_idx (Quantity | None)

  • max_idx (Quantity | None)

  • zero_outside (bool)

pygeomoptics.utils.g4gps_write_emission_spectrum(filename, output_macro, λ_peak, scint_em, quantity_name)

Write a energy spectrum for use with G4GeneralParticleSource.

It can be used like this in a Geant4 macro:

/gps/ene/type     Arb
/gps/ene/diffspec true
/gps/hist/type    arb
/gps/hist/file    <filename>
/gps/hist/inter   Lin
Parameters:
Return type:

None

pygeomoptics.utils.readdatafile(filename, pkg='pygeomoptics.data', ncols=2)

Read (x, y) data points from filename with units.

Accepted file format

# unit1 unit2
0.23453 2.3456
0.49678 3.6841
...

After the first line, comments are also allowed after a # character.

Units in the header must be parseable as pint units.

Parameters:
  • filename (str) – (relative) file name of the data file, including extension.

  • pkg (str) – python package name used to access data files. Only needs to be set to access data files in other packages.

  • ncols (int) – number of columns to read.

Return type:

tuple[Quantity, Quantity]

pygeomoptics.vm2000 module

VM2000 reflective film inside water tank, mainly based on [Geis2017].

[Geis2017]

Ch. Geis et al. 2017 “Optical response of highly reflective film used in the water Cherenkov muon veto of the XENON1T dark matter experiment” In: Journal of Instrumentation, Vol. 12, 2017, https://doi.org/10.1088/1748-0221/12/06/P06017

WLS properties taken from MaGe.

pygeomoptics.vm2000.pyg4_vm2000_attach_absorption_length(mat, reg)

Attach the refractive index to the given VM2000 material instance.

Return type:

None

pygeomoptics.vm2000.pyg4_vm2000_attach_border_params(mat, reg)

Attach border parameters between water and the given VM2000 material instance.

Return type:

None

pygeomoptics.vm2000.pyg4_vm2000_attach_efficiency(mat, reg)

Attach the efficiency to the given VM2000 material instance.

Return type:

None

pygeomoptics.vm2000.pyg4_vm2000_attach_particle_scintillationyields(mat, reg)

Attach the scintillation yiels (except of electron yield) to the given VM2000 material instance.

Return type:

None

pygeomoptics.vm2000.pyg4_vm2000_attach_reflectivity(mat, reg)

Attach the reflectivity to the given VM2000 material instance.

Return type:

None

pygeomoptics.vm2000.pyg4_vm2000_attach_rindex(mat, reg)

Attach the refractive index to the given VM2000 material instance.

Return type:

None

pygeomoptics.vm2000.pyg4_vm2000_attach_wls(mat, reg)

Attach wavelength shifting properties to the given VM2000 material instance.

Return type:

None

pygeomoptics.vm2000.vm2000_absorption_length()

Absorption length.

Returns:

constant value \(50.0\ \mathrm{m}\)

Return type:

Quantity

pygeomoptics.vm2000.vm2000_calculate_wls_mfp(yield_value)
pygeomoptics.vm2000.vm2000_parameters()

Wavelength-shifting parameters for the reflective foil VM2000.

Return type:

tuple[Quantity, NDArray[np.float64], NDArray[np.float64], Quantity, Quantity]

pygeomoptics.vm2000.vm2000_refractive_index()

Refractive index.

Returns:

constant value \(1.15\)

Return type:

float

pygeomoptics.vm2000.vm2000_scint_timeconstant()

Time constant, from MaGe.

Returns:

constant value \(0.5\ \mathrm{ns}\)

Return type:

Quantity

pygeomoptics.water module

High puritiy water for LEGEND-200 watertank.

[Mason2016]

John D. Mason, Michael T. Cone, and Edward S. Fry, “Ultraviolet (250-550 nm) absorption spectrum of pure water”. In: Appl. Opt. 55, 7163-7172 (2016). https://doi.org/10.1364/AO.55.007163

pygeomoptics.water.pyg4_water_attach_absorption(mat, reg)

Attach absorption to the given water material instance.

See also

water_absorption

Return type:

None

pygeomoptics.water.pyg4_water_attach_rindex(mat, reg)

Attach the refractive index to the given water material instance.

Return type:

None

pygeomoptics.water.water_absorption()

Ultra pure water absorption lengths, from [Mason2016].

Returns:

../_images/pygeomoptics.water.water_absorption_0.png

Return type:

tuple[Quantity, Quantity]

pygeomoptics.water.water_refractive_index()

Refractive index.

Returns:

constant value \(1.33\)

Return type:

float