legendoptics package

Submodules

legendoptics.cli module

legendoptics.cli.optics_cli()
Return type:

None

legendoptics.copper module

Copper.

legendoptics.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/legendoptics.copper.copper_reflectivity_0.png

Return type:

tuple[Quantity, Quantity]

legendoptics.copper.pyg4_copper_attach_reflectivity(mat, reg)

Attach the optical reflectivity to the given copper material instance.

Return type:

None

legendoptics.fibers module

Scinillating fibers BCF91-A from Saint Gobain.

legendoptics.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

legendoptics.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

legendoptics.fibers.fiber_cladding1_refractive_index()

Refractive index of first fiber cladding material [SaintGobainDataSheet].

Returns:

constant value \(1.49\)

Return type:

float

legendoptics.fibers.fiber_cladding2_refractive_index()

Refractive index of second fiber cladding material [SaintGobainDataSheet].

Returns:

constant value \(1.42\)

Return type:

float

legendoptics.fibers.fiber_core_refractive_index()

Refractive index of fiber core material [SaintGobainDataSheet].

Returns:

constant value \(1.6\)

Return type:

float

legendoptics.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/legendoptics.fibers.fiber_wls_absorption_0.png

Parameters:

abs_at_400nm (Quantity)

Return type:

tuple[Quantity, Quantity]

legendoptics.fibers.fiber_wls_emission()

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

Returns:

../_images/legendoptics.fibers.fiber_wls_emission_0.png

Return type:

tuple[Quantity, Quantity]

legendoptics.fibers.fiber_wls_timeconstant()

WLS time constant [SaintGobainDataSheet].

Returns:

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

Return type:

Quantity

legendoptics.fibers.pyg4_fiber_cladding1_attach_rindex(mat, reg)

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

Return type:

None

legendoptics.fibers.pyg4_fiber_cladding2_attach_rindex(mat, reg)

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

Return type:

None

legendoptics.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

legendoptics.fibers.pyg4_fiber_core_attach_rindex(mat, reg)

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

Return type:

None

legendoptics.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

legendoptics.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.

legendoptics.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/legendoptics.germanium.germanium_reflectivity_0.png

Return type:

tuple[Quantity, Quantity]

legendoptics.germanium.pyg4_germanium_attach_reflectivity(mat, reg)

Attach the optical reflectivity to the given germanium material instance.

Return type:

None

legendoptics.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)

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 legendoptics.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

legendoptics.lar.g4gps_lar_emissions_spectrum(filename, output_macro)

Write a LAr emission energy spectrum for G4GeneralParticleSource.

See also

lar_emission_spectrum, utils.g4gps_write_emission_spectrum

Parameters:
  • filename (str)

  • output_macro (bool)

Return type:

None

legendoptics.lar.lar_abs_length(λ)

Absorption length (not correctly scaled).

We don’t know how the attenuation length actually varies with the wavelength, so here 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. This function has to be re-scaled with the intended attenuation length at the VUV emission peak.

Returns:

../_images/legendoptics.lar.lar_abs_length_0.png

Parameters:

λ (Quantity)

Return type:

Quantity

legendoptics.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 (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)

  • sampled wavelengths λ

  • rayleigh length at all points in λ

  • absorption length at all points in λ

  • attenuation length at all points in λ

Return type:

tuple[Quantity, Quantity, Quantity, 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!

Notes

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

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

Parameters:
Return type:

Quantity

legendoptics.lar.lar_dielectric_constant_bideau_mehu(λ)

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/legendoptics.lar.lar_dielectric_constant_bideau_mehu_0.png

Parameters:

λ (Quantity)

Return type:

Quantity

legendoptics.lar.lar_dielectric_constant_cern2020(λ)

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

From [Babicz2020] (measurements in LAr).

Returns:

../_images/legendoptics.lar.lar_dielectric_constant_cern2020_0.png

Parameters:

λ (Quantity)

Return type:

Quantity

legendoptics.lar.lar_emission_spectrum(λ)

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

Returns:

../_images/legendoptics.lar.lar_emission_spectrum_0.png

Parameters:

λ (Quantity)

Return type:

Quantity

legendoptics.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

legendoptics.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).

Parameters:

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

Return type:

ArScintLiftime

legendoptics.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

legendoptics.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/legendoptics.lar.lar_rayleigh_0.png

Parameters:
Return type:

Quantity

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

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

Returns:

../_images/legendoptics.lar.lar_refractive_index_0.png

Parameters:
Return type:

Quantity

legendoptics.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\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)

See also

lar_fano_factor

Parameters:

flat_top_yield (Quantity)

Return type:

ScintConfig

legendoptics.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!

legendoptics.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

legendoptics.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

legendoptics.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

legendoptics.nylon.nylon_absorption()

Values reported in [Agostini2018].

Returns:

../_images/legendoptics.nylon.nylon_absorption_0.png

Return type:

tuple[Quantity, Quantity]

legendoptics.nylon.nylon_refractive_index()

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

Returns:

constant value \(1.53\)

Return type:

float

legendoptics.nylon.pyg4_nylon_attach_absorption(mat, reg)

Attach absorption to the given nylon material instance.

See also

nylon_absorption

Return type:

None

legendoptics.nylon.pyg4_nylon_attach_rindex(mat, reg)

Attach the refractive index to the given nylon material instance.

Return type:

None

legendoptics.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

legendoptics.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

legendoptics.pen.pen_absorption()

Bulk absorption reported in [Manzanillas2022].

Returns:

../_images/legendoptics.pen.pen_absorption_0.png

Return type:

tuple[Quantity, Quantity]

legendoptics.pen.pen_quantum_efficiency()

Quantum efficiency, from [Araujo2022] at LAr temperature.

Returns:

constant value \(0.69\)

Return type:

float

legendoptics.pen.pen_refractive_index()

Refractive index from [Hong2017].

Returns:

constant value \(1.51\)

Return type:

float

legendoptics.pen.pen_scint_light_yield()

PEN scintillation yield for electrons, from [Manzanillas2022].

Returns:

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

Return type:

Quantity

legendoptics.pen.pen_scint_timeconstant()

Time constant, from [Manzanillas2022].

Returns:

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

Return type:

Quantity

legendoptics.pen.pen_scintillation_params()

Get a ScintConfig object for PEN.

Return type:

ScintConfig

legendoptics.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/legendoptics.pen.pen_wls_absorption_0.png

Return type:

tuple[Quantity, Quantity]

legendoptics.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/legendoptics.pen.pen_wls_emission_0.png

Return type:

tuple[Quantity, Quantity]

legendoptics.pen.pyg4_pen_attach_attenuation(mat, reg)

Attach bulk absorption properties to the given PEN material instance.

See also

pen_absorption

Return type:

None

legendoptics.pen.pyg4_pen_attach_rindex(mat, reg)

Attach the refractive index to the given PEN material instance.

Return type:

None

legendoptics.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

legendoptics.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

legendoptics.plot module

legendoptics.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().

legendoptics.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().

legendoptics.pyg4utils module

legendoptics.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

legendoptics.pyg4utils._gdml_unit(u)
Parameters:

u (str)

Return type:

str

legendoptics.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)

legendoptics.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

legendoptics.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

legendoptics.pyg4utils.pyg4_sample_λ(start_lambda, end_lambda, sample_count=200)

Sample equally-spaced energies between the two specified wavelengths.

Parameters:
Return type:

Quantity

legendoptics.scintillate module

class legendoptics.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 legendoptics.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'])

  • yield_factor (float)

  • exc_ratio (float | None)

exc_ratio: float | None

Alias for field number 2

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

Alias for field number 0

valid_geant_particle()
Return type:

bool

yield_factor: float

Alias for field number 1

legendoptics.scintillate.particle_to_index(particle)

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

Parameters:

particle (str)

Return type:

ParticleIndex

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

ComputedScintParams

legendoptics.scintillate.scintillate(params, x0_m, x1_m, v0_mpns, v1_mpns, t0_ns, particle, particle_charge, edep_keV, rng)

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.

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

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

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

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

  • v1_mpns (float) – 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.

  • rng (np.random.Generator)

Returns:

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

legendoptics.scintillate.scintillate_local(params, particle, edep_keV, rng)

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.

  • rng (np.random.Generator)

Returns:

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

Return type:

np.ndarray

legendoptics.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

legendoptics.silicon.pyg4_silicon_attach_complex_rindex(mat, reg)

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

Return type:

None

legendoptics.silicon.silicon_complex_rindex()

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

Returns:

../_images/legendoptics.silicon.silicon_complex_rindex_0.png

Return type:

tuple[Quantity, Quantity, Quantity]

legendoptics.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.

legendoptics.store.get_replaced()

Get the names of all replaced pluggable material property functions.

Return type:

list[str]

legendoptics.store.is_all_original()

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

Return type:

bool

legendoptics.store.register_pluggable(fn)

Decorator that registers this function as a pluggable property function.

Parameters:

fn (Callable)

Return type:

Callable

legendoptics.store.reset_all_to_original()

Reset all pluggable material property functions to their original implementations.

Return type:

None

legendoptics.tetratex module

Tetratex reflector.

[Janacek2012]
  1. Janacek, “Reflectivity spectra for commonly used reflectors”, https://www.osti.gov/servlets/purl/1184400

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

Attach the optical reflectivity to the given germanium material instance.

Parameters:

reflectivity_scale (float) – Global scale for tetratex reflectivity.

Return type:

None

legendoptics.tetratex.tetratex_reflectivity()

Tetratex reflectivity from [Janacek2012].

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.

Returns:

../_images/legendoptics.tetratex.tetratex_reflectivity_0.png

Return type:

tuple[Quantity, Quantity]

legendoptics.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)

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

legendoptics.tpb.pyg4_tpb_attach_rindex(mat, reg)

Attach the refractive index to the given tpb material instance.

Return type:

None

legendoptics.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

legendoptics.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/legendoptics.tpb.tpb_polystyrene_wls_emission_0.png

Return type:

tuple[Quantity, Quantity]

legendoptics.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

legendoptics.tpb.tpb_refractive_index()

Refractive index from [MolbaseTPB].

Returns:

constant value \(1.635\)

Return type:

float

legendoptics.tpb.tpb_wls_absorption()

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

Returns:

../_images/legendoptics.tpb.tpb_wls_absorption_0.png

Return type:

tuple[Quantity, Quantity]

legendoptics.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/legendoptics.tpb.tpb_wls_emission_0.png

Return type:

tuple[Quantity, Quantity]

legendoptics.tpb.tpb_wls_timeconstant()

Time constant: arbitrary small.

Returns:

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

Return type:

Quantity

legendoptics.utils module

class legendoptics.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)

legendoptics.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

legendoptics.utils.readdatafile(filename, pkg='legendoptics.data')

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.

Return type:

tuple[Quantity, Quantity]