<jupyter_start><jupyter_text>The short ($L << \lambda/2$) dipole power in the farfield for an antenna of length L goes as$$P(\theta, \lambda) \propto \left(\frac{L}{\lambda}\right)^2 \sin^2{\theta} \iff P(\theta, \nu) \propto (L\nu)^2 \sin^2{\theta} $$In the equation above, $\theta$ is the angle to the current. In spherical coordinates, where $\theta$ is the polar angle, the power is given by:$$P(\theta, \nu) \propto (L\nu)^2 \cos^2{\theta} $$ In the language of [spherical harmonics](https://en.wikipedia.org/wiki/Table_of_spherical_harmonics), the power is completely described by the $\ell=0$ and $\ell=2$ modes:$$P(\theta, \nu) \propto (L\nu)^2 \left(\frac{3\sqrt{5}}{2}Y_0^0(\theta) + Y_2^0(\theta) \right)$$<jupyter_code>def dipole_map(frequency, ant_length=1, nside=16, lmax=2):
    """
    Get dipole power pattern in the far field for a single frequency.
    """    
    mmax = lmax
    size = int(mmax * (2 * lmax + 1 - mmax) / 2 + lmax + 1)
    
    l_eff_sq = (ant_length * frequency) ** 2 
    a00 = l_eff_sq * 3 * np.sqrt(5) / 2
    a20 = l_eff_sq
    
    alm = np.zeros(size, dtype=complex)
    alm[0] = a00
    alm[2] = a20
    
    hp_map = hp.alm2map(alm, nside)
    
    return hp_map

def dipole_maps(frequencies, **kwargs):
    """
    Get the maps for many frequencies
    """
    f0 = frequencies[0]
    ref_map = dipole_map(f0, **kwargs)
    ref_map.shape = (1, -1)
    frequencies = frequencies.reshape(-1, 1)
    maps = (frequencies/f0)**2 * ref_map
    return maps
freq = np.linspace(1, 50, 101)
beams = dipole_maps(freq, ant_length=1, nside=64)
# horizon cutoff
mask = np.ones_like(beams[0])
mask[len(mask)//2:] = 0

beams *= mask
hp.mollview(beams[0], title="1 MHz")
d = beams.T 
d -= d.mean(axis=0)
C = d.T @ d
U, S, V = np.linalg.svd(C)
eig_nr = np.arange(len(S))

plt.figure()
plt.scatter(eig_nr, S)
plt.yscale("log")
plt.show()
plt.figure(figsize=(15,7))
plt.plot(freq, V[0].T)
plt.xlim(freq.min(), freq.max())
plt.show()
t21 = T_DarkAges(freq) * 1e3
plt.figure()
plt.plot(freq, t21)
plt.xlabel("$\\nu$ [MHz]")
plt.ylabel("$T_{21}$ [mK]")
plt.title("Global Signal")
plt.xlim(0, freq.max())
plt.show()
proj_t21 = np.abs(V @ t21)


plt.figure()
plt.plot(eig_nr, proj_t21)
plt.xlabel("Eigenmode Number")
plt.ylabel("$T_{21}$ [mK]")
plt.title("Global Signal in Foreground Eigenmode Basis")
plt.xlim(eig_nr.min(), eig_nr.max())
plt.yscale("log")
plt.show()
f21 = V @ t21
f21[0] = 0  # remove brightest fg mode
rec_21 = np.linalg.inv(V) @ f21

plt.figure()
plt.plot(freq, t21, label="original")
plt.plot(freq, rec_21, label="filtered")
plt.xlabel("$\\nu$ [MHz]")
plt.ylabel("$T_{21}$ [mK]")
plt.title("Global Signal")
plt.xlim(0, freq.max())
plt.legend()
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.19105243857719106, 'fraction_numerical': 0.03813714704803814, 'mean_word_length': 3.9330922242314648, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '539977', 'license': 'MIT', 'n_tokens_mistral': 1233, 'n_tokens_neox': 1129, 'n_words': 261, 'path': 'eigenanalysis/short_dipole_analysis.ipynb', 'repo_name': 'lusee-night/notebooks', 'size': '2727'}