Rename the Rosenblatt method; add the double CDF method. Add a simple example in notebook.

This commit is contained in:
2025-10-09 16:10:27 +02:00
parent 0d5202cbfa
commit d6caa48425
2 changed files with 136 additions and 15 deletions

View File

@@ -5,7 +5,7 @@ Functions for eta interpolation
2. bilinear_xy_lookup(etaX, etaY, X_tab, Y_tab, x_centers, y_centers)
3. map_xy_no_interp(etaX, etaY, X_tab, Y_tab, x_edges, y_edges)
'''
def build_xy_lut_from_hist(H):
def build_xy_lut_Rosenblatt(H):
"""
Generate two 2D tables X_tab, Y_tab from a 2D histogram H
such that (X_tab[i,j], Y_tab[i,j]) is the (x,y) value at the center of bin (i,j).
@@ -44,6 +44,44 @@ def build_xy_lut_from_hist(H):
return (X_tab, Y_tab)
def build_xy_lut_DoubleCDF(H):
"""
Generate two 2D tables X_tab, Y_tab from a 2D histogram H
such that (X_tab[i,j], Y_tab[i,j]) is the (x,y) value at the center of bin (i,j).
Input:
H: 2D histogram of charge centroid (eta_x, eta_y) distribution, shape (nBinX, nBinY), ranging from 0 to 1.
Output:
X_tab, Y_tab: two 2D tables of interpolated (x,y) values in position space, shape (nBinX, nBinY), ranging from 0 to 1.
"""
H = np.asarray(H, dtype=float)
nBinX, nBinY = H.shape
etaX_edges = np.linspace(0, 1, nBinX+1)
etaY_edges = np.linspace(0, 1, nBinY+1)
# slight smoothing to avoid zero-count rows/columns causing flat CDF
eps=1e-9
alpha = max(eps, 1e-12 * max(1.0, H.sum()))
Hs = H + alpha
# marginal 1D CDF F_EtaX
pEtaX = Hs.sum(axis=1) # Marginal PDF (nBinX,)
F_EtaX_edges = np.concatenate([[0.0], np.cumsum(pEtaX)])# CDF at bin edges (nBinX+1,)
F_EtaX_edges = F_EtaX_edges / F_EtaX_edges[-1]
# marginal 1D CDF F_EtaY
pEtaY = Hs.sum(axis=0) # Marginal PDF (nBinY,)
F_EtaY_edges = np.concatenate([[0.0], np.cumsum(pEtaY)])# CDF at bin edges (nBinY+1,)
F_EtaY_edges = F_EtaY_edges / F_EtaY_edges[-1]
# calculate (u,v) at the center of each original bin
Xc_1d = 0.5 * (F_EtaX_edges[:-1] + F_EtaX_edges[1:])
Yc_1d = 0.5 * (F_EtaY_edges[:-1] + F_EtaY_edges[1:])
X_tab = np.repeat(Xc_1d[:, None], nBinY, axis=1) # (nBinX, nBinY)
Y_tab = np.repeat(Yc_1d[None, :], nBinX, axis=0) # (nBinX, nBinY)
return (X_tab, Y_tab)
def bilinear_xy_lookup(etaX, etaY, X_tab, Y_tab):
"""
bilinear interpolation, from (eta_x, eta_y) to (u,v):

File diff suppressed because one or more lines are too long