Add MC generation codes

This commit is contained in:
xie_x1 committed 2025-10-08 08:36:06 +02:00
commit df661e255c
4 files changed
+395

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
*.npy
*.pyc
+179
View File
@@ -0,0 +1,179 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Welcome to JupyROOT 6.28/10\n"
]
}
],
"source": [
"import os\n",
"import numpy as np\n",
"from ROOT import *\n",
"from multiprocessing import Pool\n",
"from array import array\n",
"from scipy.stats import gennorm\n",
"import imp"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Processing Moench040 150V 15keV simu2 with 128 bins\n",
"Alpha fitting chi2/NDF = 1.9768728049976632\n",
"Beta fitting chi2/NDF = 1.3047556961613742\n",
" FCN=245.132 FROM MIGRAD STATUS=CONVERGED 96 CALLS 97 TOTAL\n",
" EDM=3.53827e-13 STRATEGY= 1 ERROR MATRIX ACCURATE \n",
" EXT PARAMETER STEP FIRST \n",
" NO. NAME VALUE ERROR SIZE DERIVATIVE \n",
" 1 p0 5.20982e-01 1.41176e-02 3.53269e-05 -1.23898e-06\n",
" 2 p1 2.73449e+00 1.50597e-02 1.01242e-05 -3.50997e-04\n",
" 3 p2 -9.48420e-02 3.32013e-03 1.69238e-06 -3.00452e-03\n",
" 4 p3 4.99907e-04 2.88035e-05 3.33069e-08 -1.76453e-01\n",
" FCN=160.485 FROM MIGRAD STATUS=CONVERGED 412 CALLS 413 TOTAL\n",
" EDM=3.93066e-07 STRATEGY= 1 ERROR MATRIX ACCURATE \n",
" EXT PARAMETER STEP FIRST \n",
" NO. NAME VALUE ERROR SIZE DERIVATIVE \n",
" 1 p0 8.57590e-01 1.20963e-01 5.07321e-05 -4.75170e-02\n",
" 2 p1 -2.47722e+00 1.29467e+00 1.23369e-03 -3.44551e-03\n",
" 3 p2 -3.91474e-01 3.56163e-02 1.94337e-05 -5.53030e-02\n",
" 4 p3 -3.36737e-01 1.31473e-01 3.89495e-04 -1.89786e-03\n",
" 5 p4 -2.81985e+00 1.71232e+00 3.71391e-03 7.06359e-04\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABjwAAAMECAIAAACE6hs7AAAABmJLR0QAAAAAAAD5Q7t/AAAgAElEQVR4nOzd3XKySBcG0OaruaN4rrkyzZWJ58k18R302NMCIv7SwFo1NZXXoEFDpH3YvbtqmiYAAAAAQEn+N/UOAAAAAECb0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4gitAAAAACiO0AoAAACA4vwz9Q6UqKqqqXcBAGagaZqpd2F16rqOX+x2uyn34x5GVgAwhpFV15Sh1eFw+Pn52W63h8OhtIGXYwUAhkkiPmy3251Op/yW4/FY2gjqGiMrABhmZNXrE9MDq6o6HA7d2w+HQxzBfH9/p8uGAABrttvtqrN0Y1VVrcQqGEEBAEv3oZ5WPz8/cezVTa+6IzAAgHVqlVPF3Cr+f7vdHo/H4/HYNM3xeNxu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 truncated
"text/plain": [
"<IPython.core.display.Image object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import McGenerator\n",
"imp.reload(McGenerator)\n",
"\n",
"attenuationLengthDict = { ### https://henke.lbl.gov/optical_constants/atten2.html\n",
" '5keV': 18.0101, '10keV':133.706, '15keV':442.607, '20keV':1037.80, '25keV':1991.45,\n",
"}\n",
"element = '15keV'\n",
"mcConfig = {\n",
" 'element': element,\n",
" 'energy': 15000, ### eV\n",
" 'attenuationLength': attenuationLengthDict[element],\n",
" 'sensorCode': 'Moench040',\n",
" 'nTotalIncident': 10000000,\n",
" 'nThread': 16,\n",
" 'Roi': [50, 350, 50, 350], \n",
" 'clusterWidth': 5, ### pixel\n",
" 'pixelSize': 25, ### um\n",
" 'noiseEneFrame': np.ones((400, 400)) * 0, \n",
" 'shotNoiseFactor': 0.0,\n",
" 'calibrationNoise': 0.0,\n",
" 'sensorThickness': 650, ### moench040: 650 um, 34.7 V\n",
" 'T': 273 + 20.0 + 14.8,\n",
" 'zBins': 128,\n",
" 'hv': 150,\n",
" 'depletionVoltage': 34.7,\n",
" 'simulationMethod': 'simu2', ### 'simu1' (cpu) or 'simu2' (gpu)\n",
" 'resultsPath': '/home/xie_x1/MLED/McSimulation/BatchResults',\n",
" 'sampleOutputPath': '/home/xie_x1/MLXID/McGeneration/Samples'\n",
"}\n",
"\n",
"McGenerator.init(mcConfig)\n",
"McGenerator.parameterization().Draw()\n",
"McGenerator.generateFromParameters()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(625000, 4)\n",
"2.96790016863627 2.287150706089626 15088.160000000002\n"
]
},
{
"data": {
"text/plain": [
"<matplotlib.collections.PathCollection at 0x7f2f39e45d00>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAZwAAAGiCAYAAADTMXDkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAVyklEQVR4nO3df4yVhbng8ecwwEH5MTIowiw/SrVq5Ye7grVjrFWx5HINkTS9qb3WsDV3E7poMSxpi95EydKOae6mMaElYhurtzXYpqJmtxLprUBNQxewrCy1Fi1bpnsRrnqZgUEOMLz7R6+zUkDnDDPPmRk+n+SNnuP7vufJkeGb9z3vvKdUFEURANDLBtV6AADODYIDQArBASCF4ACQQnAASCE4AKQQHABSCA4AKQQHgBSCA0CKqoLz4IMPRqlUOmkZN25cb80GwAAyuNoNpk6dGj//+c87H9fV1fXoQAAMTFUHZ/DgwY5qAKha1cHZtWtXNDY2RrlcjmuvvTa++c1vxkc/+tEzrl+pVKJSqXQ+PnHiRLzzzjsxZsyYKJVK3ZsagJooiiIOHjwYjY2NMWhQdZcBlKr5eoLnn38+Dh8+HJdddlns27cvVqxYEb/73e9i586dMWbMmNNu8+CDD8by5curGgqAvq2lpSUmTJhQ1TZVBecvtbe3xyWXXBJf/epXY8mSJadd5y+PcFpbW2PSpElxffx1DI4h3X1pAGrgeByLl+JnceDAgaivr69q26pPqb3f8OHDY/r06bFr164zrlMul6NcLp/mhYfE4JLgAPQr/3aI0p2PRM7q93AqlUq8+uqrMX78+LPZDQDngKqCs3Tp0ti4cWPs3r07fv3rX8fnPve5aGtriwULFvTWfAAMEFWdUvvTn/4UX/jCF+Ktt96Kiy66KD75yU/G5s2bY/Lkyb01HwADRFXBWbNmTW/NAcAA515qAKQQHABSCA4AKQQHgBSCA0AKwQEgheAAkEJwAEghOACkEBwAUggOACkEB4AUggNACsEBIIXgAJBCcABIITgApBAcAFIIDgApBAeAFIIDQArBASCF4ACQQnAASCE4AKQQHABSCA4AKQQHgBSCA0AKwQEgheAAkEJwAEghOACkEBwAUggOACkEB4AUggNACsEBIIXgAJBCcABIITgApBAcAFIIDgApBAeAFIIDQArBASCF4ACQQnAASCE4AKQQHABSCA4AKQQHgBSCA0AKwQEgheAAkEJwAEghOACkEBwAUggOACkEB4AUggNACsEBIIXgAJDirILT3NwcpVIp7r333h4aB4CBqtvB2bJlS6xevTpmzJjRk/MAMEB1KziHDh2KO+64Ix599NEYPXp0T88EwAA0uDsbLVq0KG699da45ZZbYsWKFR+4bqVSiUql0vm4ra2tOy8JZ1Q39fJaj9A/HD1W6wn6hY5df6j1CANW1cFZs2ZNvPzyy7Fly5Yurd/c3BzLly+vejAABpaqTqm1tLTE4sWL44c//GEMGzasS9ssW7YsWltbO5eWlpZuDQpA/1bVEc62bdti//79MXPmzM7nOjo6YtOmTbFy5cqoVCpRV1d30jblcjnK5XLPTAtAv1VVcGbPnh07duw46bkvfelLccUVV8TXvva1U2IDAO+pKjgjR46MadOmnfTc8OHDY8yYMac8DwDv504DAKTo1mXR77dhw4YeGAOAgc4RDgApBAeAFIIDQArBASCF4ACQQnAASCE4AKQQHABSCA4AKQQHgBSCA0AKwQEgheAAkEJwAEghOACkEBwAUggOACkEB4AUggNACsEBIIXgAJBCcABIITgApBAcAFIIDgApBAeAFIIDQArBASCF4ACQQnAASCE4AKQQHABSCA4AKQQHgBSCA0AKwQEgheAAkEJwAEghOACkEBwAUggOACkEB4AUggNACsEBIIXgAJBCcABIITgApBAcAFIIDgApBAeAFIIDQArBASCF4ACQQnAASCE4AKQQHABSCA4AKQQHgBSCA0AKwQEgheAAkEJwAEghOACkqCo4q1atihkzZsSoUaNi1KhR0dTUFM8//3xvzQbAAFJVcCZMmBAPPfRQbN26NbZu3Ro333xz3HbbbbFz587emg+AAWJwNSvPmzfvpMff+MY3YtWqVbF58+aYOnVqjw4GwMBSVXDer6OjI37yk59Ee3t7NDU1nXG9SqUSlUql83FbW1t3X/KcU3fhmFqP0C/8bP1TtR6hX3j16OFaj9AvLJn6mVqP0KcNKo5GtHdz22o32LFjR4wYMSLK5XIsXLgw1q5dG1deeeUZ129ubo76+vrOZeLEid2bFIB+rergXH755bF9+/bYvHlzfPnLX44FCxbEb3/72zOuv2zZsmhtbe1cWlpazmpgAPqnqk+pDR06NC699NKIiJg1a1Zs2bIl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 truncated
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"samples = np.load('/home/xie_x1/MLXID/McGeneration/Samples/15keV_Moench040_150V_0_samples.npy')\n",
"labels = np.load('/home/xie_x1/MLXID/McGeneration/Samples/15keV_Moench040_150V_0_labels.npy')\n",
"print(labels.shape)\n",
"import matplotlib.pyplot as plt\n",
"idx = 6\n",
"plt.imshow(samples[idx], origin='lower', extent = (0, samples.shape[1], 0, samples.shape[2]))\n",
"x,y,z,e = labels[idx]\n",
"print(x,y,e)\n",
"plt.scatter(x, y, s=200, facecolors='none', edgecolors='r')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "pytorch_nightly",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.18"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
+214
View File
@@ -0,0 +1,214 @@
import os
import numpy as np
from ROOT import *
from multiprocessing import Pool
from array import array
from scipy.stats import gennorm
EnergyPerPair = 3.62 # eV
FanoFactor = 0.13
pars_alpha, pars_beta = None, None
_cfg = {} ### global config
def init(cfg):
global _cfg
_cfg = cfg
def parameterization():
sensorCode = _cfg['sensorCode']
zBins = _cfg['zBins']
biasVoltage = _cfg['hv']
element = _cfg['element']
simulationMethod = _cfg['simulationMethod']
sensorThickness = _cfg['sensorThickness'] # cm
energy = _cfg['energy'] ### eV
reultsPath = _cfg['resultsPath']
print(f'Processing {sensorCode} {biasVoltage}V {element} {simulationMethod} with {zBins} bins')
xsFiles = [f'{reultsPath}/{sensorCode}_{biasVoltage}V_xs_{element}_{i}_of_{zBins}_{simulationMethod}.npy' for i in range(zBins)]
ysFiles = [f'{reultsPath}/{sensorCode}_{biasVoltage}V_ys_{element}_{i}_of_{zBins}_{simulationMethod}.npy' for i in range(zBins)]
ggdParList, ggdParUncertList = [], []
for i in range(zBins):
xs = np.load(xsFiles[i])
ys = np.load(ysFiles[i])
coords = np.concatenate((xs, ys))
_rms = np.std(coords)
_binWidth = _rms / 20
_nBin = int(100 / _binWidth)
_h1 = TH1F('_h1', '', _nBin, -_rms*5, _rms*5)
_h1.FillN(len(coords), array('d', coords), array('d', [1]*len(coords)))
def ggd(x, par):
beta = par[0]
alpha = par[1]
coef = beta / (2 * alpha * TMath.Gamma(1 / beta))
return coef * TMath.Exp(-TMath.Power((abs(x[0] - 0) / alpha), beta))
f1 = TF1('f1', ggd, -5 * _rms, 5 * _rms, 2) ### par[0]: beta, par[1]: alpha
f1.SetParLimits(0, 2, 5)
f1.SetParLimits(1, .5, 30)
f1.SetParameters(2., _rms*1.5)
_h1.Scale(_h1.GetNbinsX()/(10*_rms) /_h1.Integral())
_h1.Fit(f1, 'Q')
ggdParList.append((f1.GetParameter(0), f1.GetParameter(1)))
ggdParUncertList.append((f1.GetParError(0), f1.GetParError(1)))
del _h1
z0List = np.linspace(0, sensorThickness, zBins+1)
z0List = (z0List[:-1] + z0List[1:])/2
arr_beta = np.array([ggdParList[i][0] for i in range(len(ggdParList))])
arr_betaUncert = np.array([ggdParUncertList[i][0] for i in range(len(ggdParList))])
arr_alpha = np.array([ggdParList[i][1] for i in range(len(ggdParList))])
arr_alphaUncert = np.array([ggdParUncertList[i][1] for i in range(len(ggdParList))])
arr_z0 = np.array([z0List[i] for i in range(len(ggdParList))])
arr_t = np.array([getDriftTime_allpix2_8p23(z0) for z0 in z0List])
c = TCanvas()
c.SetCanvasSize(1600, 800)
c.Divide(2, 1)
# c.SetCanvasSize(800, 1375//2)
c.SetTopMargin(0.05)
c.SetRightMargin(0.05)
global gr_AlphaT, gr_BetaT
pad2 = c.cd(1)
gr_AlphaT = TGraphErrors(len(arr_z0), arr_t, arr_alpha, array('d', np.zeros(len(arr_z0))), arr_alphaUncert)
gr_AlphaT.SetTitle(';Approximated Drift Time [ns];#alpha')
func_alpha = TF1('func_alpha', '[0] + [1] * sqrt((x)) + [2] * x + [3] * x^2')
func_alpha.SetLineColor(kRed+1)
gr_AlphaT.Fit(func_alpha, '')
# set fit line color
gr_AlphaT.Draw()
print(f'Alpha fitting chi2/NDF = {func_alpha.GetChisquare()/func_alpha.GetNDF()}')
c.cd(2)
gr_BetaT = TGraphErrors(len(arr_z0), arr_t, arr_beta, array('d', np.zeros(len(arr_z0))), arr_betaUncert)
func_betaT = TF1('func_betaT', '[0]*(x-[1])^[2]+ [3]*exp([4]*x) + 2')
func_betaT.SetParameters(1.3, -4, -0.4, -0.6, -4.)
func_betaT.SetLineColor(kRed+1)
gr_BetaT.Fit(func_betaT, '')
gr_BetaT.SetTitle(';Approximated Drift Time [ns];#beta')
gr_BetaT.Draw()
print(f'Beta fitting chi2/NDF = {func_betaT.GetChisquare()/func_betaT.GetNDF()}')
### save parameters to file
global pars_alpha, pars_beta
pars_alpha = [func_alpha.GetParameter(i) for i in range(func_alpha.GetNpar())]
pars_beta = [func_betaT.GetParameter(i) for i in range(func_betaT.GetNpar())]
np.save(f'ggdPar_{sensorCode}_{biasVoltage}V_{element}.npy', pars_alpha + pars_beta)
return c.Clone()
def singleProcess(thredIdx):
energy = _cfg['energy'] ### eV
Roi = _cfg['Roi'] ### [x1, x2, y1, y2], for noise sampling from measured noise map
sensorThickness = _cfg['sensorThickness'] # cm
pixelSize = _cfg['pixelSize'] ### um
clusterWidth = _cfg['clusterWidth'] ### um
attenuationLength = _cfg['attenuationLength'] # cm
global pars_alpha, pars_beta
func_betaT = TF1('func_betaT', '[0]*(x-[1])^[2]+ [3]*exp([4]*x) + 2')
func_betaT.SetParameters(pars_beta[0], pars_beta[1], pars_beta[2], pars_beta[3], pars_beta[4])
func_alphaT = TF1('func_alpha', '[0] + [1] * sqrt((x)) + [2] * x + [3] * x^2')
func_alphaT.SetParameters(pars_alpha[0], pars_alpha[1], pars_alpha[2], pars_alpha[3])
_frameWidth = 9
nEvents = _cfg['nTotalIncident'] // _cfg['nThread']
samples = np.zeros((nEvents, clusterWidth, clusterWidth))
labels = np.zeros((nEvents, 4)) ### x, y, z, energy
### set random seed
np.random.seed(thredIdx)
for i in range(nEvents):
### z0 from 0 to sensorThickness
while True:
z0 = np.random.exponential(attenuationLength)
if 0 < z0 < sensorThickness:
break
### drift time, alpha, beta
t = getDriftTime_allpix2_8p23(z0)
alpha, beta = func_alphaT.Eval(t), func_betaT.Eval(t)
### nChargeCarrierPairs
nExpectedPair = round(energy / EnergyPerPair)
nPair = np.random.normal(nExpectedPair, np.sqrt(energy * FanoFactor / EnergyPerPair))
nPair = round(nPair)
### sample the incident position
x_center = np.random.uniform(pixelSize*_frameWidth//2, pixelSize*_frameWidth//2 + pixelSize)
y_center = np.random.uniform(pixelSize*_frameWidth//2, pixelSize*_frameWidth//2 + pixelSize)
### sample pair positions
try:
x_pairs = gennorm.rvs(beta = beta, loc = x_center, scale = alpha, size = nPair)
y_pairs = gennorm.rvs(beta = beta, loc = y_center, scale = alpha, size = nPair)
except Exception as e:
print(f't = {t:.3f} beta = {beta:.3f}, alpha = {alpha:.3f}')
continue
x_pairs = x_pairs//pixelSize
y_pairs = y_pairs//pixelSize
### put the pairs into the frame
_carrierArray = np.zeros((_frameWidth, _frameWidth))
np.add.at(_carrierArray, (y_pairs.astype(np.int32), x_pairs.astype(np.int32)), 1)
_energyArray = _carrierArray * EnergyPerPair
### spread noise
x_pedetal = np.random.randint(Roi[0], Roi[1] - _frameWidth)
y_pedetal = np.random.randint(Roi[2], Roi[3] - _frameWidth)
_pedestalNoiseFrame = _cfg['noiseEneFrame'][y_pedetal:y_pedetal + _frameWidth, x_pedetal:x_pedetal + _frameWidth]
shotNoiseFactor = _cfg['shotNoiseFactor']
_shotNoiseFrame = np.sqrt(_energyArray * shotNoiseFactor)
_calibrationNoiseFrame = np.ones_like(_energyArray) * _cfg['calibrationNoise']
_noiseFrame = np.random.normal(0, np.sqrt(_pedestalNoiseFrame**2 + _shotNoiseFrame**2 + _calibrationNoiseFrame**2), size = _energyArray.shape)
_energyArray += _noiseFrame
### truncate to desired cluster width
### odd width: highest pixel in the center
### even width: highest pixel in the center 2x2 is selected to maximize the cluster energy
highestPixel = (np.argmax(_energyArray)//_frameWidth, np.argmax(_energyArray)%_frameWidth)
if clusterWidth%2 == 1:
pixelArray = _energyArray[highestPixel[0]-clusterWidth//2:highestPixel[0]+clusterWidth//2+1, highestPixel[1]-clusterWidth//2:highestPixel[1]+clusterWidth//2+1]
carrierArray = _carrierArray[highestPixel[0]-clusterWidth//2:highestPixel[0]+clusterWidth//2+1, highestPixel[1]-clusterWidth//2:highestPixel[1]+clusterWidth//2+1]
x_center -= (highestPixel[1]-clusterWidth//2) * pixelSize
y_center -= (highestPixel[0]-clusterWidth//2) * pixelSize
else:
clusterEnergy = 0
for i in range(2):
for j in range(2):
_pixelArray = _energyArray[highestPixel[0]-clusterWidth//2+i:highestPixel[0]+clusterWidth//2+i, highestPixel[1]-clusterWidth//2+j:highestPixel[1]+clusterWidth//2+j]
_carrierArray = _carrierArray[highestPixel[0]-clusterWidth//2+i:highestPixel[0]+clusterWidth//2+i, highestPixel[1]-clusterWidth//2+j:highestPixel[1]+clusterWidth//2+j]
if np.sum(_pixelArray) > clusterEnergy:
clusterEnergy = np.sum(_pixelArray)
pixelArray = _pixelArray
carrierArray = _carrierArray
x_center = x_center - (highestPixel[1] - _frameWidth//2 + j) * pixelSize
y_center = y_center - (highestPixel[0] - _frameWidth//2 + i) * pixelSize
samples[i] = pixelArray
labels[i] = np.array([x_center/pixelSize, y_center/pixelSize, z0, np.sum(_energyArray)])
sampleOutputPath = _cfg['sampleOutputPath']
element = _cfg['element']
np.save(f'{sampleOutputPath}/{element}_{_cfg["sensorCode"]}_{_cfg["hv"]}V_{thredIdx}_samples.npy', samples)
np.save(f'{sampleOutputPath}/{element}_{_cfg["sensorCode"]}_{_cfg["hv"]}V_{thredIdx}_labels.npy', labels)
### save samples and labels into one npy file
np.save(f'{sampleOutputPath}/{element}_{_cfg["sensorCode"]}_{_cfg["hv"]}V_{thredIdx}_samples_labels.npy', (samples, labels))
def getDriftTime_allpix2_8p23(z0):
### unit: V, cm, ns, K
sensorThickness = _cfg['sensorThickness'] # cm
depletionVoltage = _cfg['depletionVoltage']
T = _cfg['T']
hv = _cfg['hv']
def getEz(z):
return (hv - depletionVoltage) / sensorThickness + 2 * depletionVoltage / sensorThickness**2 * z
v_m = 1.62e8 * T**(-0.52) # cm/s
E_c = 1.24 * T**1.68 # V/cm
u0 = v_m / E_c # cm^2/V/s
k = depletionVoltage * 2 / (sensorThickness * 1e-4)**2 ### um to cm
t = 1 / u0 * ((sensorThickness - z0)*1e-4/E_c + np.log(getEz(sensorThickness)/getEz(z0)) /k)
t *= 1e9 # convert to ns
return t
def generateFromParameters():
global pars_alpha, pars_beta
with Pool(processes = _cfg['nThread']) as pool:
results = pool.map(singleProcess, range(_cfg['nThread']))
return
Binary file not shown.