"""
CHANNEL 2 v2 — corrected x-field. The gate responds to the LOCAL GRAVITATIONAL acceleration
x = g_local/a0, with a0 = 2 sqrt(alpha) c H = 1.197e-10 m/s^2 (DFD recovers MOND a0 exactly).

Two distinct x's were conflated before:
  (cosmo x)  = sqrt(Om(1+delta))/(2 sqrt a)   -- the SMOOTH background screen scaling; GROWS w/ density.
  (LOCAL x)  = g_local/a0                       -- the actual MOND ratio; in galaxies/outskirts x<~1.
The brief's premise (light crosses x<1 deep-MOND structure) is TRUE at the absolute-accel level:
  cluster cores x~0.3, galaxy disks x~1, galaxy outskirts & filaments x<1, bulk flows x~0.006.
So we MUST build the LOCAL acceleration field along the LOS and compute the screen-weighted gate.

The decisive physics: the optical screen dpsi is SOURCED by something (matter trace, or DE fraction).
A photon's path is mostly EMPTY (cosmic web is ~5% of volume). What fraction of the SCREEN (not the
volume) is laid down in low-x regions? That sets <gate>_LOS. honesty-guard: report what the integral says.
"""
import numpy as np

ALPHA = 1/137.035999084
twosqrta = 2*np.sqrt(ALPHA)
Ob, Och = 0.0430, 0.2306
Om = Ob+Och
fb = Ob/Om; sqrt_fb = np.sqrt(fb)
A_data = 0.0686; gate_data = A_data/twosqrta

c_si=2.998e8; Mpc_m=3.0857e22; H0=72.09
H0_si=H0*1e3/Mpc_m
a0 = twosqrta*c_si*H0_si                # 1.197e-10 m/s^2

def gate_local(x):                      # f_b^p, p:1/2 (deep-MOND) -> 1 (Newtonian)
    p = 1.0 - 0.5/(1.0+x)
    return fb**p

print("="*88)
print("CHANNEL 2 v2: LOS screen-weighted gate with LOCAL gravitational x=g/a0")
print("="*88)
print(f"  a0 = 2 sqrt(alpha) c H0 = {a0:.3e} m/s^2  (MOND a0 = 1.2e-10, DFD MATCH)")
print(f"  need <gate>_LOS = {gate_data:.4f}; deep-MOND ceiling = {sqrt_fb:.4f}; Newt floor = {fb:.4f}")

# -------------------------------------------------------------------------------------
# A realistic populated LOS: assign to each volume element a local gravitational accel g.
# Use the matter density field (lognormal) and map density -> g via the cosmic-web structure.
# Cleanest physical mapping: the local gravitational acceleration sourced by the local potential.
# For a Gaussian-random/lognormal field, g (the accel field magnitude) has a Maxwell-like PDF.
# But the PHYSICAL anchor is: a0 was DEFINED so that galaxy outskirts sit at x~1. So:
#  - voids: g -> 0          => x -> 0  (deep-MOND, gate -> 0.396)   [BIG VOLUME]
#  - filaments/outskirts: x ~ 0.3-1   (gate 0.25-0.32)              [moderate volume]
#  - cluster/galaxy cores: x >> 1     (gate -> 0.157)               [tiny volume, big mass]
# So now LOW x DOES live in the big-volume voids. VOLUME weighting now FAVORS deep-MOND.
# The question becomes: is the SCREEN volume-weighted (then voids win, gate up) or
# density/source-weighted (then cores win, gate down)?  This is the whole ballgame.
# -------------------------------------------------------------------------------------

# Build g-field from the density field. Linear theory: g ~ |grad phi|, phi from Poisson.
# Simpler robust proxy used in MOND-cosmology: x_local scales with the SQUARE ROOT of the local
# dynamical density times size; the cleanest DFD-consistent anchor is the cosmological one
# x = sqrt(rho_local/rho_crit)/(2 sqrt alpha) BUT now we must decide if rho_local is the SMOOTH
# Om*(1+delta) (then dense=high x, prior script) or the VIRIAL density of the collapsed object.
# The brief's empirical claim (clusters x~0.3) comes from the VIRIAL accel v^2/R, which for a
# fixed object does NOT scale as sqrt(rho_cosmic). We test BOTH mappings head-to-head.

def sample_field(sigma_ln, N=2_000_000, seed=0):
    rng=np.random.default_rng(seed)
    opd=np.exp(rng.normal(-0.5*sigma_ln**2,sigma_ln,N))  # 1+delta, mean 1
    return opd

print("\n" + "-"*88)
print("  MAPPING A (cosmological screen scaling): x = sqrt(Om*(1+delta))/(2 sqrt a)  [dense=HIGH x]")
print("  MAPPING B (virial/absolute accel):       x set by the collapsed-object accel  [dense=can be low/high]")
print("-"*88)

# MAPPING A — already done in v1; dense regions are Newtonian, deep-MOND only in deepest voids.
for sigma_ln in [0.8,1.5,2.5]:
    opd=sample_field(sigma_ln)
    xA=np.sqrt(Om*opd)/twosqrta
    gA=gate_local(xA)
    print(f"  A sigma_ln={sigma_ln}: <gate>_vol={gA.mean():.4f}  <gate>_mass={np.average(gA,weights=opd):.4f}")

# MAPPING B — assign x by an EMPIRICAL accel ladder tied to the cosmic web phases, with
# realistic VOLUME and MASS filling fractions (observed cosmic-web census).
# Phases (z~0): voids ~78% vol/15% mass; sheets ~18%vol/25%mass; filaments ~4%vol/40%mass;
# knots/clusters ~0.2%vol/20%mass. Assign each a representative LOCAL x from absolute accel.
phases = [
    # name,           vol_frac, mass_frac,  x_local (g/a0)
    ("voids",         0.78,     0.15,       0.02),   # nearly empty -> deep-MOND
    ("sheets/walls",  0.18,     0.25,       0.30),   # mild
    ("filaments",     0.039,    0.40,       1.0),    # ~a0 transition
    ("knots/clusters",0.001,    0.20,       30.0),   # deep Newtonian cores
]
print("\n  MAPPING B — observed cosmic-web census (z~0) with absolute-accel x:")
print(f"  {'phase':16s} {'vol%':>6s} {'mass%':>6s} {'x':>7s} {'gate':>7s}")
vsum=msum=0
gate_vol=gate_mass=0
for name,vf,mf,x in phases:
    g=gate_local(x); vsum+=vf; msum+=mf
    gate_vol+=vf*g; gate_mass+=mf*g
    print(f"  {name:16s} {100*vf:6.1f} {100*mf:6.1f} {x:7.2f} {g:7.4f}")
print(f"  (sum vol={vsum:.3f}, mass={msum:.3f})")
print(f"  <gate>_VOLUME-weighted  = {gate_vol/vsum:.4f}   -> A = {twosqrta*gate_vol/vsum:.4f}")
print(f"  <gate>_MASS-weighted    = {gate_mass/msum:.4f}   -> A = {twosqrta*gate_mass/msum:.4f}")

print("\n" + "-"*88)
print("  THE DECIDER: how does the OPTICAL SCREEN accumulate along the LOS?")
print("-"*88)
print("""  The screen dpsi is the DFD optical metric perturbation along the photon path. Two physical
  sourcings, with OPPOSITE clumping verdicts:

   (1) SCREEN ~ path-length in the DE-dominated medium (volume-weighted).
       Then voids (78% of volume, x~0.02, gate~0.39) DOMINATE -> <gate>_vol ~ 0.36-0.38.
       This WOULD lift the gate to near the ceiling and HIT A_data=0.0686.

   (2) SCREEN ~ local matter trace T^mu_mu ~ rho (mass/source-weighted).
       Then knots+filaments (60% of mass, x>1, gate~0.16-0.25) DOMINATE -> <gate>_mass ~ 0.17-0.20.
       This LEAVES the gate at the Newtonian floor -> A ~ 0.030, the original 40%-short failure.""")

# Quantify (1) precisely with a void-dominated volume PDF + the absolute-accel ladder smoothed:
print("\n  Quantifying route (1) volume-weighted with a continuous accel PDF:")
# accel field magnitude PDF: in voids g->0. Model x_local lognormal with median tied to outskirts~1
# and a large low-x tail (voids). Scan median.
for xmed,slx in [(0.3,1.0),(0.2,1.2),(0.5,1.0)]:
    rng=np.random.default_rng(3)
    xloc=np.exp(rng.normal(np.log(xmed),slx,2_000_000))
    g=gate_local(xloc)
    print(f"    x_median={xmed}, sigma_lnx={slx}: <gate>_vol={g.mean():.4f} -> A={twosqrta*g.mean():.4f}"
          f"  (frac x<1: {np.mean(xloc<1):.2f})")

print("\n" + "="*88)
print("VERDICT")
print("="*88)
print(f"""  Channel 2 is NOT a clean save. The LOS-weighted gate depends ENTIRELY on the screen-source
  weighting, which is the SAME unproven choice that the smooth analysis already faces:

   - VOLUME-weighted (screen ~ DE/path-length): voids dominate, <gate> ~ 0.36-0.38 -> A ~ 0.062-0.065.
     This DOES reach ~the data, BUT it requires the screen to be sourced by EMPTY space (DE), which
     means clumping is irrelevant — it's the void-volume that does the work, and that is exactly the
     DE-fraction shape the corpus ALREADY uses (= borrowing the LCDM Omega_L(z) shape, the forbidden move).
   - MASS/trace-weighted (screen ~ rho): clumps dominate, <gate> ~ 0.17-0.20 -> A ~ 0.030, the 40% shortfall.

  Clumping by itself does NOT lift the gate. Whether you get 0.40 or 0.20 is decided by the source
  weighting, not by 'structure pockets'. The favorable branch (volume/void-weighted) coincides with the
  already-known DE-shape route and inserts no NEW physics. honesty-guard: no manufactured save, no manufactured kill.""")
