Example of component

[1]:
import os
from time import time

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import jax.numpy as jnp
import multihist as mh

import appletree as apt
from appletree.utils import get_file_path
Using Normal as an approximation of Binomial
Using aptext package from https://github.com/XENONnT/applefiles
[2]:
# constrain the GPU memory usage

apt.set_gpu_memory_usage(0.2)

Define component

ComponentSim

[3]:
# The components is associated with bins, so first we load bins
data = pd.read_csv(get_file_path("data_Rn220.csv"))
bins_cs1, bins_cs2 = apt.utils.get_equiprob_bins_2d(
    data[["cs1", "cs2"]].to_numpy(),
    [15, 15],
    order=[0, 1],
    x_clip=[0, 100],
    y_clip=[1e2, 1e4],
    which_np=jnp,
)
[4]:
# Initialize component
er = apt.ERBand(bins=[bins_cs1, bins_cs2], bins_type="irreg")
[5]:
# Deduce the workflow(datastructure)
er.deduce(data_names=["cs1", "cs2"], func_name="simulate")  # 'eff'(efficiency) is always simulated
er.rate_name = "er_rate"  # also we have to specify a normalization factor of the component

# Compile ER script
# This is meta-programing because  appletree can generate codes dynamically
er.compile()
[6]:
# For reference, this is the compiled code, the function is stored in appletree.share._cached_functions
print(er.code)
from functools import partial
from jax import jit
from appletree.plugins import PositionSpectra
from appletree.plugins import UniformEnergySpectra
from appletree.plugins import RecombFluct
from appletree.plugins import mTI
from appletree.plugins import Quanta
from appletree.plugins import TrueRecombER
from appletree.plugins import IonizationER
from appletree.plugins import DriftLoss
from appletree.plugins import RecombinationER
from appletree.plugins import ElectronDrifted
from appletree.plugins import PositionRecon
from appletree.plugins import S2Correction
from appletree.plugins import S2PE
from appletree.plugins import S2
from appletree.plugins import S1Correction
from appletree.plugins import PhotonDetection
from appletree.plugins import S1PE
from appletree.plugins import S1
from appletree.plugins import S2CutAccept
from appletree.plugins import S1CutAccept
from appletree.plugins import S1ReconEff
from appletree.plugins import S2Threshold
from appletree.plugins import Eff
from appletree.plugins import cS2
from appletree.plugins import cS1
PositionSpectra_ERBand = PositionSpectra('ERBand_llh')
UniformEnergySpectra_ERBand = UniformEnergySpectra('ERBand_llh')
RecombFluct_ERBand = RecombFluct('ERBand_llh')
mTI_ERBand = mTI('ERBand_llh')
Quanta_ERBand = Quanta('ERBand_llh')
TrueRecombER_ERBand = TrueRecombER('ERBand_llh')
IonizationER_ERBand = IonizationER('ERBand_llh')
DriftLoss_ERBand = DriftLoss('ERBand_llh')
RecombinationER_ERBand = RecombinationER('ERBand_llh')
ElectronDrifted_ERBand = ElectronDrifted('ERBand_llh')
PositionRecon_ERBand = PositionRecon('ERBand_llh')
S2Correction_ERBand = S2Correction('ERBand_llh')
S2PE_ERBand = S2PE('ERBand_llh')
S2_ERBand = S2('ERBand_llh')
S1Correction_ERBand = S1Correction('ERBand_llh')
PhotonDetection_ERBand = PhotonDetection('ERBand_llh')
S1PE_ERBand = S1PE('ERBand_llh')
S1_ERBand = S1('ERBand_llh')
S2CutAccept_ERBand = S2CutAccept('ERBand_llh')
S1CutAccept_ERBand = S1CutAccept('ERBand_llh')
S1ReconEff_ERBand = S1ReconEff('ERBand_llh')
S2Threshold_ERBand = S2Threshold('ERBand_llh')
Eff_ERBand = Eff('ERBand_llh')
cS2_ERBand = cS2('ERBand_llh')
cS1_ERBand = cS1('ERBand_llh')

@partial(jit, static_argnums=(1, ))
def simulate(key, batch_size, parameters):
    key, x, y, z = PositionSpectra_ERBand(key, parameters, batch_size)
    key, energy = UniformEnergySpectra_ERBand(key, parameters, batch_size)
    key, recomb_std = RecombFluct_ERBand(key, parameters, energy)
    key, recomb_mean = mTI_ERBand(key, parameters, energy)
    key, num_quanta = Quanta_ERBand(key, parameters, energy)
    key, recomb = TrueRecombER_ERBand(key, parameters, recomb_mean, recomb_std)
    key, num_ion = IonizationER_ERBand(key, parameters, num_quanta)
    key, drift_survive_prob = DriftLoss_ERBand(key, parameters, z)
    key, num_photon, num_electron = RecombinationER_ERBand(key, parameters, num_quanta, num_ion, recomb)
    key, num_electron_drifted = ElectronDrifted_ERBand(key, parameters, num_electron, drift_survive_prob)
    key, rec_x, rec_y, rec_z, rec_r = PositionRecon_ERBand(key, parameters, x, y, z, num_electron_drifted)
    key, s2_correction = S2Correction_ERBand(key, parameters, rec_x, rec_y)
    key, num_s2_pe = S2PE_ERBand(key, parameters, num_electron_drifted, s2_correction)
    key, s2_area = S2_ERBand(key, parameters, num_s2_pe)
    key, s1_correction = S1Correction_ERBand(key, parameters, rec_x, rec_y, rec_z)
    key, num_s1_phd = PhotonDetection_ERBand(key, parameters, num_photon, s1_correction)
    key, num_s1_pe = S1PE_ERBand(key, parameters, num_s1_phd)
    key, s1_area = S1_ERBand(key, parameters, num_s1_phd, num_s1_pe)
    key, cut_acc_s2 = S2CutAccept_ERBand(key, parameters, s2_area)
    key, cut_acc_s1 = S1CutAccept_ERBand(key, parameters, s1_area)
    key, acc_s1_recon_eff = S1ReconEff_ERBand(key, parameters, num_s1_phd)
    key, acc_s2_threshold = S2Threshold_ERBand(key, parameters, s2_area)
    key, eff = Eff_ERBand(key, parameters, acc_s2_threshold, acc_s1_recon_eff, cut_acc_s1, cut_acc_s2)
    key, cs2 = cS2_ERBand(key, parameters, s2_area, s2_correction, drift_survive_prob)
    key, cs1 = cS1_ERBand(key, parameters, s1_area, s1_correction)
    return key, [cs1, cs2, eff]

ComponentFixed

[7]:
# Initialize component, not based on simulation, but the input template
ac = apt.AC(bins=[bins_cs1, bins_cs2], bins_type="irreg", file_name="AC_Rn220.pkl")
ac.rate_name = "ac_rate"

# Do not forget to deduce
ac.deduce()

# Of course these initialization process looks messy, but we will do the initialization automatically in context

Load parameters

[8]:
# Of course we have to load parameters(and their priors) in simulation

par_manager = apt.Parameter(get_file_path("er.json"))
par_manager.sample_init()
parameters = par_manager.get_all_parameter()

Simulation

[9]:
# Really do the simulation

batch_size = int(1e6)
key = apt.randgen.get_key(seed=137)

key, (cs1, cs2, eff) = er.simulate(key, batch_size, parameters)
[10]:
# Just to show the histogram

h, be = jnp.histogramdd(
    jnp.asarray([cs1, cs2]).T,
    bins=(jnp.linspace(0, 100, 101), jnp.logspace(2.5, 4.1, 81)),
    weights=eff,
)

h = mh.Histdd.from_histogram(np.array(h), be, axis_names=["cs1", "cs2"])
h.plot(norm=LogNorm())
plt.yscale("log")
plt.show()
../_images/notebooks_component_15_0.png

Simulation and make equiprob hist

[11]:
# Actually `simulate_hist` is just a wrapper of `simulate`

batch_size = int(1e6)
key = apt.randgen.get_key(seed=137)
key, h = er.simulate_hist(key, batch_size, parameters)
[12]:
apt.utils.plot_irreg_histogram_2d(bins_cs1, bins_cs2, h, density=False)
plt.yscale("log")
plt.ylim(5e2, 1e4)
plt.show()
../_images/notebooks_component_18_0.png
[13]:
h = ac.simulate_hist(parameters)
[14]:
apt.utils.plot_irreg_histogram_2d(bins_cs1, bins_cs2, h, density=False)
plt.yscale("log")
plt.ylim(5e2, 1e4)
plt.show()
../_images/notebooks_component_20_0.png

Speed test

[15]:
@apt.utils.timeit
def test(key, batch_size, parameters):
    return er.simulate_hist(key, batch_size, parameters)
[16]:
@apt.utils.timeit
def benchmark():
    key = apt.randgen.get_key()
    for _ in range(100):
        key, _ = test(key, int(1e6), parameters)
[17]:
benchmark()
 Function <benchmark> starts.
 Function <test> starts.
 Function <test> ends! Time cost = 8.48 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.53 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 8.02 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 7.70 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.23 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 7.32 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.84 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.98 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.15 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.27 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 6.68 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 3.86 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.78 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.54 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 8.88 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.76 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.54 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 3.63 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 3.32 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.68 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 7.80 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.42 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 6.34 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 7.96 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.27 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.65 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.82 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 8.28 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.91 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.11 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.19 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 8.61 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 7.04 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 3.81 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.02 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.60 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 6.13 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.87 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.91 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.58 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.89 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 6.54 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 8.76 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 7.29 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.63 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.72 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.47 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 3.44 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 6.00 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.77 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.67 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.90 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 6.52 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 7.54 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.80 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.01 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 8.54 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.54 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.44 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.75 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.30 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.66 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.84 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.30 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.73 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 6.04 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.72 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 8.51 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 6.50 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.19 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 3.97 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.05 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.44 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.41 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.43 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.71 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.42 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.94 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.54 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.88 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 7.84 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 8.60 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 8.21 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.22 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.73 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 3.78 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 3.65 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 3.48 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.77 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.53 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.89 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.75 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.65 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.67 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 6.39 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 8.08 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.54 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 9.05 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 5.62 msec.
 Function <test> starts.
 Function <test> ends! Time cost = 4.42 msec.
 Function <benchmark> ends! Time cost = 582.11 msec.