Source code for flamedisx.lxe_sources

import tensorflow as tf

import flamedisx as fd
export, __all__ = fd.exporter()


[docs]@export class ERSource(fd.BlockModelSource): model_blocks = ( fd.FixedShapeEnergySpectrum, fd.MakeERQuanta, fd.MakePhotonsElectronsBetaBinomial, fd.DetectPhotons, fd.MakeS1Photoelectrons, fd.MakeS1, fd.DetectElectrons, fd.MakeS2)
[docs] @staticmethod def p_electron(nq, *, er_pel_a=15, er_pel_b=-27.7, er_pel_c=32.5, er_pel_e0=5.): """Fraction of ER quanta that become electrons Simplified form from Jelle's thesis """ # The original model depended on energy, but in flamedisx # it has to be a direct function of nq. e_kev_sortof = nq * 13.7e-3 eps = fd.tf_log10(e_kev_sortof / er_pel_e0 + 1e-9) qy = ( er_pel_a * eps ** 2 + er_pel_b * eps + er_pel_c) return fd.safe_p(qy * 13.7e-3)
final_dimensions = ('s1', 's2') no_step_dimensions = ()
[docs]@export class NRSource(fd.BlockModelSource): model_blocks = ( fd.FixedShapeEnergySpectrum, fd.MakeNRQuanta, fd.MakePhotonsElectronsBinomial, fd.DetectPhotons, fd.MakeS1Photoelectrons, fd.MakeS1, fd.DetectElectrons, fd.MakeS2) final_dimensions = ('s1', 's2') no_step_dimensions = () # Use a larger default energy range, since most energy is lost # to heat. energies = tf.cast(tf.linspace(0.7, 150., 100), fd.float_type()) rates_vs_energy = tf.ones(100, fd.float_type())
[docs] @staticmethod def p_electron(nq, *, alpha=1.280, zeta=0.045, beta=273 * .9e-4, gamma=0.0141, delta=0.062, drift_field=120): """Fraction of detectable NR quanta that become electrons, slightly adjusted from Lenardo et al.'s global fit (https://arxiv.org/abs/1412.4417). Penning quenching is accounted in the photon detection efficiency. """ # TODO: so to make field pos-dependent, override this entire f? # could be made easier... # prevent /0 # TODO can do better than this nq = nq + 1e-9 # Note: final term depends on nq now, not energy # this means beta is different from lenardo et al nexni = alpha * drift_field ** -zeta * (1 - tf.exp(-beta * nq)) ni = nq * 1 / (1 + nexni) # Fraction of ions NOT participating in recombination squiggle = gamma * drift_field ** -delta fnotr = tf.math.log(1 + ni * squiggle) / (ni * squiggle) # Finally, number of electrons produced.. n_el = ni * fnotr return fd.safe_p(n_el / nq)
[docs]@export class SpatialRateERSource(ERSource): model_blocks = (fd.SpatialRateEnergySpectrum,) + ERSource.model_blocks[1:]
[docs]@export class SpatialRateNRSource(NRSource): model_blocks = (fd.SpatialRateEnergySpectrum,) + NRSource.model_blocks[1:]
[docs]@export class WIMPSource(NRSource): model_blocks = (fd.WIMPEnergySpectrum,) + NRSource.model_blocks[1:]