"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Latex(r\"$\\sigma_t = $ %.1f ps, while $\\gamma\\tau_0 = $ %.1f ps.\" % (pulse.sigma_t*1e12, gamma_0*tau_0*1e12))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we can calculate the excitation probability for every ion in the bunch."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We define Doppler factor $f_D = \\gamma (1 + \\beta \\cos\\theta)$."
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [],
"source": [
"f_D = gamma_0*(1+dp)*(1+beta_0*np.cos(theta_l))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then $\\omega_l'$ "
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
"omega_l = 2*np.pi/(lambda_l/c)*f_D"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [],
"source": [
"sigma_average = sigma_0*pulse.sigma_t/(tau_0*f_D) * \\\n",
" np.sqrt(2*np.pi)/4 * \\\n",
" np.exp(-np.power( (omega_0 - omega_l)/(sigma_w*f_D) , 2)/2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Position of the laser center at the time of collision $\\boldsymbol{r}_l = \\boldsymbol{a} + c(t_{\\mathrm{col}}-t_a)\\boldsymbol{n}$:"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [],
"source": [
"x_l = ax + c*(t_col-t_a)*nx\n",
"y_l = ay + c*(t_col-t_a)*ny\n",
"z_l = az + c*(t_col-t_a)*nz"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Distance to the laser center r2 = $(\\boldsymbol{r} - \\boldsymbol{r}_l)^2$"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [],
"source": [
"r2 = (x_col-x_l)*(x_col-x_l) + (y_col-y_l)*(y_col-y_l) + (z_col-z_l)*(z_col-z_l)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's find the laser pulse width\n",
"\n",
"$$\n",
"w = w_0 \\sqrt{1 + \\left(\\frac{\\boldsymbol{r}_l - \\boldsymbol{a}}{z_R}\\right)^2}.\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [],
"source": [
"w = pulse.w_0*np.sqrt( 1 + ((x_l-ax)*(x_l-ax) + (y_l-ay)*(y_l-ay) + (z_l-az)*(z_l-az))/(z_R*z_R) )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And finally number of excitation events for every ion can be found as\n",
"\n",
"$$\n",
"\\frac{dN_{\\hbar \\omega}}{dS} \\bar\\sigma = \\frac{2N_{\\hbar\\omega}}{\\pi w^2} \\exp \\left(-\\frac{2(\\boldsymbol{r} - \\boldsymbol{r}_l)^2}{w^2}\\right) \\bar\\sigma,\n",
"$$\n",
"\n",
"$$\n",
"N_{exc} = \\frac{1 - \\exp\\left[-(1+B)\\frac{dN_{\\hbar \\omega}}{dS} \\bar\\sigma \\right]}{1+B}.\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [],
"source": [
"N_exc = 2*N_hw/(np.pi*w*w)*np.exp(-2*r2/w/w)*sigma_average\n",
"N_exc = (1 - np.exp(-1*(1+g1/g2)*N_exc))/(1+g1/g2)"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":Points [z,N_exc]"
]
},
"execution_count": 54,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"#%output backend='matplotlib' fig='png' size=250\n",
"#%opts Points [aspect=3]\n",
"\n",
"hv.Points((z/mm, N_exc), [dim_z,\"N_exc\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Since we treat $N_{exc}$ as the probability of ion excitation, let's randomply select excited atoms according to their $N_{exc}$ value:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For every ion select a random number from 0 to 1:"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [],
"source": [
"rnd = np.random.uniform(size=Np)"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":Points [z,rnd]"
]
},
"execution_count": 56,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"hv.Points((z/mm, rnd), [dim_z,\"rnd\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And we count the ion as excited if its N_exc value is larger than the rnd value:"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [],
"source": [
"Excited = N_exc > rnd"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Plot excited ions:"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [],
"source": [
"%opts Points.Excited (alpha=0.8, color='black')\n",
"%opts Points.Still (alpha=0.3)"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":Overlay\n",
" .Still.I :Points [z,y]\n",
" .Excited.I :Points [z,y]"
]
},
"execution_count": 59,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"hv.Points((z/mm, y/mm), [dim_z,dim_y], group='Still') * \\\n",
"hv.Points((z[Excited]/mm, y[Excited]/mm), [dim_z,dim_y], group='Excited')"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [],
"source": [
"%opts Histogram (alpha=0.5 linewidth=0.1)\n",
"%opts Histogram.Excited (facecolor='black')"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":AdjointLayout\n",
" :Overlay\n",
" .Still.I :Points [z,x]\n",
" .Excited.I :Points [z,x]\n",
" :Overlay\n",
" .Still.I :Histogram [x] (x_count)\n",
" .Excited.I :Histogram [x] (x_count)"
]
},
"execution_count": 61,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"hv.Points((z/mm, x/mm), [dim_z,dim_x], group='Still').hist(dimension=dim_x, num_bins=50, normed=False) * \\\n",
"hv.Points((z[Excited]/mm, x[Excited]/mm), [dim_z,dim_x], group='Excited').hist(dimension=dim_x, num_bins=50, normed=False, group='Excited')"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":AdjointLayout\n",
" :Overlay\n",
" .Still.I :Points [z,dp]\n",
" .Excited.I :Points [z,dp]\n",
" :Overlay\n",
" .Still.I :Histogram [dp] (dp_count)\n",
" .Excited.I :Histogram [dp] (dp_count)"
]
},
"execution_count": 62,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"hv.Points((z/mm, dp*100), [dim_z,dim_dp], group='Still').hist(dimension=dim_dp, num_bins=50, normed=False) * \\\n",
"hv.Points((z[Excited]/mm, dp[Excited]*100), [dim_z,dim_dp], group='Excited').hist(dimension=dim_dp, num_bins=50, normed=False, group='Excited')"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"17.0% of all ions are excited.\n"
]
}
],
"source": [
"print(\"%.1f%% of all ions are excited.\" % (100*len(z[Excited])/len(z)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Photon emissions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The effect of photon absorption on the ion momentum in the lab frame can be neglected. We should take into account only the emitted photon. On every turn we will select a random direction of photon emission in the ion's frame of reference. The random polar angle $\\theta_1'$ can be obtained as arccos of uniformly distributed random number from $-1$ to $+1$. Then using the above expressions we can find the frequency of the scattered photon as well as $\\theta_1$ angle between the initial ion momentum and the direction of photon emission in the lab frame. Finally a random azimuthal angle (from $0$ to $2\\pi$) is needed to get the direction of photon scattering in the plane which is perpendicular to the initial ion momentum."
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [],
"source": [
"# random polar angle in the ion's frame:\n",
"costheta = np.random.uniform(-1,+1, size=Np)\n",
"theta1p = np.arccos(costheta)\n",
"\n",
"# emitted photon energy in the lab frame:\n",
"hw1_emitted = gamma_0*(1+dp) * ( 1 + beta_0*np.cos(theta1p) )*hw0 # eV\n",
"# only excited atoms are emitting of course:\n",
"hw1_emitted = hw1_emitted*Excited\n",
"\n",
"dp = dp - hw1_emitted/(gamma_0*mc)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's summarize the above theory into the python function to simulate the process of ion excitations and photon emissions in a turn-by-turn simulation."
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [],
"source": [
"X = np.matrix([\n",
" x ,\n",
" xp,\n",
" y ,\n",
" yp,\n",
" z ,\n",
" dp\n",
"])"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [],
"source": [
"def ExciteIons(X, pulse):\n",
" # Returns a vector of ion states after interaction with the laser: Excited / Not excited.\n",
"\n",
" x = X[0].A1; xp = X[1].A1; y = X[2].A1; yp = X[3].A1; z = X[4].A1; dp = X[5].A1\n",
" \n",
" t_a = pulse.t_a\n",
" w_0 = pulse.w_0\n",
" ax = pulse.ax; ay = pulse.ay; az= pulse.az\n",
" nx = pulse.nx; ny = pulse.ny; nz= pulse.nz\n",
" cos_theta_l = -pulse.nz\n",
" \n",
" sigma_t = pulse.sigma_t\n",
" sigma_w = 1/sigma_t\n",
" lambda_l = pulse.wavelength\n",
" N_hw = pulse.J/(hw*1.602e-19)\n",
" \n",
" vz = c*beta_0\n",
"\n",
" vx = vz*xp\n",
" vy = vz*yp\n",
" \n",
" t_col = ((x-ax)*nx + (y-ay)*ny + (z-az)*nz + c*t_a) / (c - (vx*nx+vy*ny+vz*nz)) # sec\n",
" \n",
" x_col = x + vx*t_col # m\n",
" y_col = y + vy*t_col # m\n",
" z_col = z + vz*t_col # m\n",
" \n",
" f_D = gamma_0*(1+dp)*(1+beta_0*cos_theta_l)\n",
" omega_l = 2*np.pi/(lambda_l/c)*f_D\n",
" sigma_average = sigma_0*sigma_t/(tau_0*f_D) * \\\n",
" np.sqrt(2*np.pi)/4 * \\\n",
" np.exp(-np.power( (omega_0 - omega_l)/(sigma_w*f_D) , 2)/2)\n",
" \n",
" x_l = ax + c*(t_col-t_a)*nx\n",
" y_l = ay + c*(t_col-t_a)*ny\n",
" z_l = az + c*(t_col-t_a)*nz\n",
" \n",
" r2 = (x_col-x_l)*(x_col-x_l) + (y_col-y_l)*(y_col-y_l) + (z_col-z_l)*(z_col-z_l)\n",
" \n",
" w = w_0*np.sqrt( 1 + ((x_l-ax)*(x_l-ax) + (y_l-ay)*(y_l-ay) + (z_l-az)*(z_l-az))/(z_R*z_R) )\n",
" \n",
" N_exc = 2*N_hw/(np.pi*w*w)*np.exp(-2*r2/w/w)*sigma_average\n",
" N_exc = (1 - np.exp(-1*(1+g1/g2)*N_exc))/(1+g1/g2)\n",
" \n",
" rnd = np.random.uniform(size=Np)\n",
" \n",
" Excited = N_exc > rnd\n",
" \n",
" return Excited"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":AdjointLayout\n",
" :Overlay\n",
" .Still.I :Points [z,dp]\n",
" .Excited.I :Points [z,dp]\n",
" :Overlay\n",
" .Still.I :Histogram [dp] (dp_count)\n",
" .Excited.I :Histogram [dp] (dp_count)"
]
},
"execution_count": 67,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"Excited = ExciteIons(X, pulse)\n",
"\n",
"hv.Points((z/mm, dp*100), [dim_z,dim_dp], group='Still').hist(dimension=dim_dp, num_bins=50, normed=False) * \\\n",
"hv.Points((z[Excited]/mm, dp[Excited]*100), [dim_z,dim_dp], group='Excited').hist(dimension=dim_dp, num_bins=50, normed=False, group='Excited')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As we can see the number of ions excited at $\\Delta p < 0$ is slightly more than the number of ions excited at $\\Delta p > 0$. This will lead to the longitudinal emittance blow-up unless we correct it with another laser pulse centered on the beam transversely but slightly shifted in the wavelength (or angle). This additional laser pulse will provide an additional longitudinal cooling required to conteract the transverse-cooling induced longitudinal emittance blow-up."
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [],
"source": [
"import copy"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [],
"source": [
"# to avoid reentering the parameters let's copy the laser pulse object:\n",
"pulse2 = copy.copy(pulse)"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [],
"source": [
"pulse2.ax = 0\n",
"pulse2.J = pulse.J/2.0\n",
"pulse2.wavelength = pulse.wavelength * (1 + 1.5*sigma_dp)"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":AdjointLayout\n",
" :Overlay\n",
" .Still.I :Points [z,dp]\n",
" .Excited.I :Points [z,dp]\n",
" :Overlay\n",
" .Still.I :Histogram [dp] (dp_count)\n",
" .Excited.I :Histogram [dp] (dp_count)"
]
},
"execution_count": 71,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"Excited = ExciteIons(X, pulse2)\n",
"\n",
"hv.Points((z/mm, dp*100), [dim_z,dim_dp], group='Still').hist(dimension=dim_dp, num_bins=50, normed=False) * \\\n",
"hv.Points((z[Excited]/mm, dp[Excited]*100), [dim_z,dim_dp], group='Excited').hist(dimension=dim_dp, num_bins=50, normed=False, group='Excited')"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"20.1% of all ions are excited.\n"
]
}
],
"source": [
"print(\"%.1f%% of all ions are excited.\" % (100*len(z[Excited])/len(z)))"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":AdjointLayout\n",
" :Overlay\n",
" .Still.I :Points [z,x]\n",
" .Excited.I :Points [z,x]\n",
" :Overlay\n",
" .Still.I :Histogram [x] (x_count)\n",
" .Excited.I :Histogram [x] (x_count)"
]
},
"execution_count": 73,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"hv.Points((z/mm, x/mm), [dim_z,dim_x], group='Still').hist(dimension=dim_x, num_bins=50, normed=False) * \\\n",
"hv.Points((z[Excited]/mm, x[Excited]/mm), [dim_z,dim_x], group='Excited').hist(dimension=dim_x, num_bins=50, normed=False, group='Excited')"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":AdjointLayout\n",
" :Overlay\n",
" .Still.I :Points [z,y]\n",
" .Excited.I :Points [z,y]\n",
" :Overlay\n",
" .Still.I :Histogram [y] (y_count)\n",
" .Excited.I :Histogram [y] (y_count)"
]
},
"execution_count": 74,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"hv.Points((z/mm, y/mm), [dim_z,dim_y], group='Still').hist(dimension=dim_y, num_bins=50, normed=False) * \\\n",
"hv.Points((z[Excited]/mm, y[Excited]/mm), [dim_z,dim_y], group='Excited').hist(dimension=dim_y, num_bins=50, normed=False, group='Excited')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The function to emit photons:"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [],
"source": [
"def EmitPhotons(X, Excited):\n",
" # Returns vector of emitted photons and vector X after photon emissions\n",
" \n",
" x = X[0].A1; xp = X[1].A1; y = X[2].A1; yp = X[3].A1; z = X[4].A1; dp = X[5].A1\n",
" \n",
" Np_Excited = len(x[Excited])\n",
" \n",
" # random polar angle in the ion's frame:\n",
" cos_theta1p = np.random.uniform(-1,+1, size=Np_Excited)\n",
" theta1p = np.arccos(cos_theta1p)\n",
" \n",
" # emission angle in the lab frame:\n",
" sin_theta1 = np.sin(theta1p)/(gamma_0 * (1+dp[Excited]) * ( 1 + beta_0*np.cos(theta1p) ))\n",
" theta1 = np.arcsin(sin_theta1)\n",
" \n",
" # azimuthal angle of emission:\n",
" phi1 = np.random.uniform(0,2*np.pi, size=Np_Excited)\n",
"\n",
" # emitted photon energy in the lab frame:\n",
" hw1_emitted = gamma_0*(1+dp[Excited]) * ( 1 + beta_0*np.cos(theta1p) )*hw0 # eV\n",
"\n",
"\n",
" # duration of time between the ion excitation and photon emission (in the lab frame):\n",
" dt_excited = gamma_0*np.random.exponential(scale=tau_0, size=Np_Excited) # seconds\n",
"\n",
" # distance travelled by the ion between its excitation and photon emission:\n",
" ds = dt_excited*c # meters\n",
"\n",
" # emitted photon location:\n",
" s_photon = z[Excited] + ds\n",
" x_photon = x[Excited] + ds*xp[Excited]\n",
" y_photon = y[Excited] + ds*yp[Excited]\n",
"\n",
" p_photon = hw1_emitted # eV/c\n",
" pz_photon = p_photon*np.cos(theta1)\n",
" pt_photon = p_photon*np.sin(theta1) # photon transverse momentum\n",
" px_photon = pt_photon*np.cos(phi1)\n",
" py_photon = pt_photon*np.sin(phi1)\n",
" \n",
" xp_photon = px_photon/pz_photon # rad\n",
" yp_photon = py_photon/pz_photon # rad\n",
" \n",
" # The effect of photon emission on ion is noticeble only in the dp value (see earlier explanation):\n",
" dp[Excited] = dp[Excited] - hw1_emitted/(gamma_0*mc)\n",
" \n",
" Photons = np.matrix([\n",
" x_photon,\n",
" xp_photon,\n",
" y_photon,\n",
" yp_photon,\n",
" s_photon,\n",
" p_photon\n",
" ])\n",
" \n",
" X1 = np.matrix([\n",
" x ,\n",
" xp,\n",
" y ,\n",
" yp,\n",
" z ,\n",
" dp\n",
" ])\n",
" \n",
" return X1, Photons"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [],
"source": [
"Excited = ExciteIons(X, pulse)"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [],
"source": [
"X1, Photons = EmitPhotons(X, Excited)"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":Layout\n",
" .Points.I :Points [s,x]\n",
" .Points.II :Points [xp_photon,x]"
]
},
"execution_count": 78,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"#%output backend='matplotlib' fig='png' size=150\n",
"#%opts Points [aspect=2]\n",
"\n",
"x_photon = Photons[0].A1\n",
"xp_photon = Photons[1].A1\n",
"s_photon = Photons[4].A1\n",
"p_photon = Photons[5].A1\n",
"\n",
"dim_s = hv.Dimension('s', unit='m')# , range=(-600.0,+600.0))\n",
"dim_xp_photon = hv.Dimension('xp_photon', unit='mrad', label=\"x'\", range=(-100,+100))\n",
"\n",
"hv.Points((s_photon,x_photon/mm), [dim_s,dim_x]) + \\\n",
"hv.Points((xp_photon/mm,x_photon/mm), [dim_xp_photon,dim_x])"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":Layout\n",
" .Points.I :Points [s,p_photon]\n",
" .Points.II :Points [xp_photon,p_photon]"
]
},
"execution_count": 79,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"dim_p_photon = hv.Dimension('p_photon', unit='keV', label=\"Photon energy\") #, range=(0,None))\n",
"\n",
"hv.Points((s_photon,p_photon/keV), [dim_s,dim_p_photon]) + \\\n",
"hv.Points((xp_photon/mrad,p_photon/keV), [dim_xp_photon,dim_p_photon])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And now we can do the full 1-turn tracking of the ion beam."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Transverse 1-turn matrix\n",
"\n",
"The expressions will be written for the general coupled case (in x-y) but with matrix elements simplified for the uncoupled case. 1-turn matrix in the uncoupled case can be expressed in the Twiss parametrization."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Full 1-turn matrix (excluding RF-effects) can be written as\n",
"\n",
"$$\n",
"\\begin{pmatrix}\n",
"x \\\\\n",
"x' \\\\\n",
"y \\\\\n",
"y' \\\\\n",
"\\Delta l \\\\\n",
"\\Delta p/p\n",
"\\end{pmatrix}_{n+1} =\n",
"\\begin{pmatrix}\n",
"R_{11} & R_{12} & R_{13} & R_{14} & 0 & R_{16} \\\\\n",
"R_{21} & R_{22} & R_{23} & R_{24} & 0 & R_{26} \\\\\n",
"R_{31} & R_{32} & R_{33} & R_{34} & 0 & R_{36} \\\\\n",
"R_{41} & R_{42} & R_{43} & R_{44} & 0 & R_{46} \\\\\n",
"R_{51} & R_{52} & R_{53} & R_{54} & 1 & R_{56} \\\\\n",
"0 & 0 & 0 & 0 & 0 & 1\n",
"\\end{pmatrix}\n",
"\\begin{pmatrix}\n",
"x \\\\\n",
"x' \\\\\n",
"y \\\\\n",
"y' \\\\\n",
"0 \\\\\n",
"\\Delta p/p\n",
"\\end{pmatrix}_n,\n",
"$$\n",
"$n$ is the turn number."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"According to the usual accelerator physics notation here $\\Delta l$ is the path length difference between the trajectory of the particle with these particular coordinates and the central particle. $\\Delta l$ can be used to find the longitudinal particle coordinate along the bunch $z$ (used earlier). Since particles with different momentum move with different velocity\n",
"\n",
"$$\n",
"z_{n+1} = z_n - \\Delta l_{n+1} + T_s \\Delta \\upsilon,\n",
"$$\n",
"\n",
"where $T_s$ is the revolution period and\n",
"\n",
"$$\n",
"\\Delta \\upsilon = \\upsilon_s \\frac{1}{\\gamma^2}\\frac{\\Delta p}{p},\n",
"$$\n",
"\n",
"where $\\upsilon_s$ is the reference ion velocity. Therefore \n",
"\n",
"$$\n",
"z_{n+1} = z_n - \\Delta l_{n+1} + T_s \\upsilon_s \\frac{1}{\\gamma^2}\\frac{\\Delta p}{p} = z_n - \\Delta l_{n+1} + \\frac{L}{\\gamma^2}\\frac{\\Delta p}{p},\n",
"$$\n",
"\n",
"where $T_s \\upsilon_s = L$ is the ring circumference."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So we can replace $\\Delta l$ with $z$ in the above matrix 1-turn expression:\n",
"\n",
"$$\n",
"\\begin{pmatrix}\n",
"x \\\\\n",
"x' \\\\\n",
"y \\\\\n",
"y' \\\\\n",
"z \\\\\n",
"\\Delta p/p\n",
"\\end{pmatrix}_{n+1} =\n",
"\\begin{pmatrix}\n",
"R_{11} & R_{12} & R_{13} & R_{14} & 0 & R_{16} \\\\\n",
"R_{21} & R_{22} & R_{23} & R_{24} & 0 & R_{26} \\\\\n",
"R_{31} & R_{32} & R_{33} & R_{34} & 0 & R_{36} \\\\\n",
"R_{41} & R_{42} & R_{43} & R_{44} & 0 & R_{46} \\\\\n",
"-R_{51} & -R_{52} & -R_{53} & -R_{54} & 1 & -R_{56} + L\\gamma^{-2} \\\\\n",
"0 & 0 & 0 & 0 & 0 & 1\n",
"\\end{pmatrix}\n",
"\\begin{pmatrix}\n",
"x \\\\\n",
"x' \\\\\n",
"y \\\\\n",
"y' \\\\\n",
"z \\\\\n",
"\\Delta p/p\n",
"\\end{pmatrix}_n.\n",
"$$ "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Effects of RF-resonators should be included separately because in our case the longitudinal nonlinearity of RF is often important."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The expression looks more simple in the uncoupled case:\n",
"\n",
"$$\n",
"\\begin{pmatrix}\n",
"x \\\\\n",
"x' \\\\\n",
"y \\\\\n",
"y' \\\\\n",
"z \\\\\n",
"\\Delta p/p\n",
"\\end{pmatrix}_{n+1} =\n",
"\\begin{pmatrix}\n",
"R_{11} & R_{12} & 0 & 0 & 0 & R_{16} \\\\\n",
"R_{21} & R_{22} & 0 & 0 & 0 & R_{26} \\\\\n",
"0 & 0 & R_{33} & R_{34} & 0 & 0 \\\\\n",
"0 & 0 & R_{43} & R_{44} & 0 & 0 \\\\\n",
"-R_{51} & -R_{52} & 0 & 0 & 1 & -R_{56} + L\\gamma^{-2} \\\\\n",
"0 & 0 & 0 & 0 & 0 & 1\n",
"\\end{pmatrix}\n",
"\\begin{pmatrix}\n",
"x \\\\\n",
"x' \\\\\n",
"y \\\\\n",
"y' \\\\\n",
"z \\\\\n",
"\\Delta p/p\n",
"\\end{pmatrix}_n.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Since the closed orbit with some momentum offset is given by\n",
"\n",
"$$\n",
"\\begin{pmatrix}\n",
"x \\\\\n",
"x'\n",
"\\end{pmatrix} =\n",
"\\begin{pmatrix}\n",
"D_x \\\\\n",
"D'_x\n",
"\\end{pmatrix}\n",
"\\frac{\\Delta p}{p},\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"we can find the $R_{16}$ and $R_{26}$ matrix elements from the vales of dispersion functions defined earlier\n",
"\n",
"$$\n",
"\\begin{pmatrix}\n",
"D_x \\\\\n",
"D'_x\n",
"\\end{pmatrix}\n",
"\\frac{\\Delta p}{p} =\n",
"\\begin{pmatrix}\n",
"R_{11} & R_{12} \\\\\n",
"R_{21} & R_{22}\n",
"\\end{pmatrix}\n",
"\\begin{pmatrix}\n",
"D_x \\\\\n",
"D'_x\n",
"\\end{pmatrix}\n",
"\\frac{\\Delta p}{p} +\n",
"\\begin{pmatrix}\n",
"R_{16} \\\\\n",
"R_{26} \\\\\n",
"\\end{pmatrix}\n",
"\\frac{\\Delta p}{p}.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"therefore\n",
"\n",
"$$\n",
"\\begin{pmatrix}\n",
"R_{16} \\\\\n",
"R_{26}\n",
"\\end{pmatrix} = \n",
"\\begin{pmatrix}\n",
"D_x \\\\\n",
"D'_x\n",
"\\end{pmatrix} -\n",
"\\begin{pmatrix}\n",
"R_{11} & R_{12} \\\\\n",
"R_{21} & R_{22}\n",
"\\end{pmatrix}\n",
"\\begin{pmatrix}\n",
"D_x \\\\\n",
"D'_x\n",
"\\end{pmatrix}.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the uncoupled case the 1-turn matrix can be written in Twiss as\n",
"\n",
"$$\n",
"\\begin{pmatrix}\n",
"R_{11} & R_{12} \\\\\n",
"R_{21} & R_{22} \\\\\n",
"\\end{pmatrix} = \n",
"\\begin{pmatrix}\n",
"\\cos\\mu_x + \\alpha_x\\sin\\mu_x & \\beta_x \\sin\\mu_x \\\\\n",
"-\\gamma_x \\sin\\mu_x & \\cos\\mu_x - \\alpha_x \\sin\\mu_x \\\\\n",
"\\end{pmatrix},\n",
"$$\n",
"\n",
"where $\\mu_x = 2\\pi\\nu_x$ ($\\nu_x$ -- betatron tune), $\\alpha_x = -\\beta'_x / 2$, $\\gamma_x = (1 + \\alpha_x^2)/\\beta_x$.\n",
"\n",
"And the same for the y-plane."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The matrix elements $R_{51}$ and $R_{52}$ can be found from the symplecticity of the full-turn matrix $M$ as described in Analytical Tools in Accelerator Physics by V. Litvinenko (page 43, equation L3-53):\n",
"\n",
"$$\n",
"-R_{51} = R_{16}R_{21} - R_{26}R_{11}, \\\\\n",
"-R_{52} = R_{16}R_{22} - R_{26}R_{12}.\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [],
"source": [
"# For the SPS Q26 optics the betatron tunes are:\n",
"\n",
"nux = 26.12999969\n",
"#nuy = 26.17999991\n",
"nuy = nux # to study fully coupled betatron oscillations\n",
"\n",
"mux = 2*np.pi*nux\n",
"muy = 2*np.pi*nuy\n",
"\n",
"R11 = np.cos(mux) + alpha_x*np.sin(mux); R12 = beta_x*np.sin(mux)\n",
"R21 = -(1+alpha_x*alpha_x)*np.sin(mux)/beta_x; R22 = np.cos(mux) - alpha_x*np.sin(mux)\n",
"\n",
"R33 = np.cos(muy) + alpha_y*np.sin(muy); R34 = beta_y*np.sin(muy)\n",
"R43 = -(1+alpha_y*alpha_y)*np.sin(muy)/beta_y; R44 = np.cos(muy) - alpha_y*np.sin(muy)\n",
"\n",
"R16 = Dx - (Dx*R11 + Dpx*R12)\n",
"R26 = Dpx - (Dx*R21 + Dpx*R22)\n",
"\n",
"R51 = R26*R11 - R16*R21\n",
"R52 = R26*R12 - R16*R22\n",
"\n",
"gamma_t = 22.77422909 # gamma transition in the ring\n",
"\n",
"R56 = L/(gamma_t*gamma_t)"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [],
"source": [
"M = np.matrix([\n",
" [ R11, R12, 0 , 0 , 0 , R16],\n",
" [ R21, R22, 0 , 0 , 0 , R26],\n",
" [ 0 , 0 , R33, R34, 0 , 0 ],\n",
" [ 0 , 0 , R43, R44, 0 , 0 ],\n",
" [-R51, -R52, 0 , 0 , 1 , -R56+L/(gamma_0*gamma_0)],\n",
" [ 0 , 0 , 0 , 0 , 0 , 1 ]\n",
"])"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [],
"source": [
"def print_matrix(M, format='%+.3e'):\n",
" for row in M:\n",
" for itm in row.A1:\n",
" print(format % itm, end=\" \")\n",
" print(\"\\n\")"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"-4.346e-01 +3.981e+01 +0.000e+00 +0.000e+00 +0.000e+00 -3.754e-01 \n",
"\n",
"-4.481e-02 +1.804e+00 +0.000e+00 +0.000e+00 +0.000e+00 +3.116e-02 \n",
"\n",
"+0.000e+00 +0.000e+00 +1.642e+00 +3.232e+01 +0.000e+00 +0.000e+00 \n",
"\n",
"+0.000e+00 +0.000e+00 -4.484e-02 -2.734e-01 +0.000e+00 +0.000e+00 \n",
"\n",
"+3.036e-02 -1.918e+00 +0.000e+00 +0.000e+00 +1.000e+00 -1.316e+01 \n",
"\n",
"+0.000e+00 +0.000e+00 +0.000e+00 +0.000e+00 +0.000e+00 +1.000e+00 \n",
"\n"
]
}
],
"source": [
"print_matrix(M)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" From SPS_optics:\n",
"\n",
"\n",
"\n",
"-4.346e-01 +3.981e+01 +0.000e+00 +0.000e+00 +0.000e+00 -3.754e-01 \n",
"\n",
"-4.481e-02 +1.804e+00 +0.000e+00 +0.000e+00 +0.000e+00 +3.116e-02 \n",
"\n",
"+0.000e+00 +0.000e+00 +1.615e+00 +4.011e+01 +0.000e+00 +0.000e+00 \n",
"\n",
"+0.000e+00 +0.000e+00 -5.566e-02 -7.633e-01 +0.000e+00 +0.000e+00 \n",
"\n",
"+3.036e-02 -1.918e+00 +0.000e+00 +0.000e+00 +1.000e+00 -1.318e+01 \n",
"\n",
"+0.000e+00 +0.000e+00 +0.000e+00 +0.000e+00 +0.000e+00 +1.000e+00 \n",
"\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can quickly test that the 1-turn transformation is not changing the beam distribution:\n",
"\n",
"Initial distribution:"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {},
"outputs": [],
"source": [
"def plot_xxp_yyp(X):\n",
" x = X[0].A1 # .A1 converts matrix into 1D-array\n",
" xp = X[1].A1\n",
" y = X[2].A1\n",
" yp = X[3].A1\n",
" \n",
" return hv.Points((x*1e3,xp*1e3), kdims=[dim_x,dim_xp]) + hv.Points((y*1e3,yp*1e3), kdims=[dim_y,dim_yp])"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":Layout\n",
" .Points.I :Points [x,xp]\n",
" .Points.II :Points [y,yp]"
]
},
"execution_count": 85,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"plot_xxp_yyp(X)"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":Layout\n",
" .Points.I :Points [x,xp]\n",
" .Points.II :Points [y,yp]"
]
},
"execution_count": 86,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"# test one turn:\n",
"X1 = M*X\n",
"# test many turns\n",
"#X1 = M*M*M*M*M*M*M*M*M*M*M*M*M*M*M*M*M*M*M*X\n",
"\n",
"plot_xxp_yyp(X1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Betatron x-y coupling"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In order to introduce betatron coupling into our model let's assume there is a skew-quadrupole located right after the IP. The quadrupole matrix acting on $(x,x')^T$ or $(y,y')^T$ can be written as\n",
"\n",
"$$\n",
"R_q =\n",
"\\begin{pmatrix}\n",
"\\cos kl & k^{-1}\\sin kl \\\\\n",
"-k\\sin kl & \\cos k l\n",
"\\end{pmatrix},\n",
"$$\n",
"\n",
"where $l$ is the quadrupole length, $k=\\sqrt{K}$, $K_x = -K_y = \\frac{e}{pc}\\frac{\\partial B_y}{\\partial x} = \\frac{1}{B\\rho}\\frac{\\partial B_y}{\\partial x}$. $K$ is also known as $K_1$, the geometric strength of the quadrupole measured in $\\mathrm{m}^{-2}$."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For example, the SPS main quadrupole has a length of 3 m and a maximum magnetic gradient of 22 T/m. For 450 GeV protons this corresponds to maximum $K = 0.0147~\\mathrm{m}^{-2}$."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Skew-quadrupole parameters:"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [],
"source": [
"Lsq = 1.0 # m\n",
"Ksq = 0.001 # 1/m^2\n",
"#Ksq = 0.00001 # 1/m^2\n",
"\n",
"k = np.sqrt(Ksq) # 1/m\n",
"kl = k*Lsq"
]
},
{
"cell_type": "code",
"execution_count": 88,
"metadata": {},
"outputs": [],
"source": [
"Rq = np.matrix([\n",
" [ np.cos(kl) , np.sin(kl)/k, 0 , 0 ],\n",
" [ -k*np.sin(kl), np.cos(kl) , 0 , 0 ],\n",
" [ 0 , 0 , np.cosh(kl) , np.sinh(kl)/k ],\n",
" [ 0 , 0 , +k*np.sinh(kl) , np.cosh(kl) ]\n",
"])"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"+0.9995 +0.9998 +0.0000 +0.0000 \n",
"\n",
"-0.0010 +0.9995 +0.0000 +0.0000 \n",
"\n",
"+0.0000 +0.0000 +1.0005 +1.0002 \n",
"\n",
"+0.0000 +0.0000 +0.0010 +1.0005 \n",
"\n"
]
}
],
"source": [
"print_matrix(Rq, format='%+.4f')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The resulting skew-quadrupole matrix can be written with the help of negative and positive 45-degree rotation matrices:\n",
"\n",
"$$\n",
"R_{\\mathrm{sq}} = R\\left(-\\frac{\\pi}{4}\\right) R_q R\\left(\\frac{\\pi}{4}\\right),\n",
"$$\n",
"\n",
"where rotation matrix acting on $(x,x',y,y')^T$ is"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"R(\\phi) =\n",
"\\begin{pmatrix}\n",
"\\cos\\phi & 0 & -\\sin\\phi & 0 \\\\\n",
"0 & \\cos\\phi & 0 & -\\sin\\phi \\\\\n",
"\\sin\\phi & 0 & \\cos\\phi & 0 \\\\\n",
"0 & \\sin\\phi & 0 & \\cos\\phi\n",
"\\end{pmatrix}.\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [],
"source": [
"Rsq = np.matrix([\n",
" [ 1, 0, 1, 0],\n",
" [ 0, 1, 0, 1],\n",
" [-1, 0, 1, 0],\n",
" [ 0,-1, 0, 1]\n",
"]) * Rq * \\\n",
"np.matrix([\n",
" [ 1, 0,-1, 0],\n",
" [ 0, 1, 0,-1],\n",
" [ 1, 0, 1, 0],\n",
" [ 0, 1, 0, 1]\n",
"]) / 2"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"+1.0000 +1.0000 +0.0005 +0.0002 \n",
"\n",
"+0.0000 +1.0000 +0.0010 +0.0005 \n",
"\n",
"+0.0005 +0.0002 +1.0000 +1.0000 \n",
"\n",
"+0.0010 +0.0005 +0.0000 +1.0000 \n",
"\n"
]
}
],
"source": [
"print_matrix(Rsq, format='%+.4f')"
]
},
{
"cell_type": "code",
"execution_count": 92,
"metadata": {},
"outputs": [],
"source": [
"# Extend Rsq to the full 6x6 matrix:\n",
"\n",
"Rsq6x6 = np.matrix(np.identity(6))\n",
"Rsq6x6[0:4,0:4] = Rsq\n",
"\n",
"Rsq = Rsq6x6"
]
},
{
"cell_type": "code",
"execution_count": 93,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"+1.0000 +1.0000 +0.0005 +0.0002 +0.0000 +0.0000 \n",
"\n",
"+0.0000 +1.0000 +0.0010 +0.0005 +0.0000 +0.0000 \n",
"\n",
"+0.0005 +0.0002 +1.0000 +1.0000 +0.0000 +0.0000 \n",
"\n",
"+0.0010 +0.0005 +0.0000 +1.0000 +0.0000 +0.0000 \n",
"\n",
"+0.0000 +0.0000 +0.0000 +0.0000 +1.0000 +0.0000 \n",
"\n",
"+0.0000 +0.0000 +0.0000 +0.0000 +0.0000 +1.0000 \n",
"\n"
]
}
],
"source": [
"print_matrix(Rsq, format='%+.4f')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then the full-turn matrix $M$ should be rewritten as\n",
"\n",
"$$\n",
"M_{\\mathrm{new}} = M D(-l)R_{\\mathrm{sq}},\n",
"$$\n",
"\n",
"where $D(-l)$ is the inverse of the drift-space matrix with the same length as the skew-quadrupole."
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {},
"outputs": [],
"source": [
"M = M * np.matrix([\n",
" [ 1,-Lsq, 0, 0, 0, 0],\n",
" [ 0, 1, 0, 0, 0, 0],\n",
" [ 0, 0, 1,-Lsq, 0, 0],\n",
" [ 0, 0, 0, 1, 0, 0],\n",
" [ 0, 0, 0, 0, 1, 0],\n",
" [ 0, 0, 0, 0, 0, 1]\n",
"]) * Rsq"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's find the new betatron tunes to see the effect of introduced betatron coupling:"
]
},
{
"cell_type": "code",
"execution_count": 95,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"nux = 26.1300\n",
"nuy = 26.1300\n",
"Coupled Q1 = 26.1339\n",
"Coupled Q2 = 26.1260\n"
]
}
],
"source": [
"from numpy import linalg as LA\n",
"\n",
"w, v = LA.eig(M[0:4,0:4])\n",
"#tunes = 1 - np.angle(w)/(2*np.pi)\n",
"tunes = np.angle(w)/(2*np.pi)\n",
"tunes = np.floor(nux) + tunes\n",
"Q1 = tunes[0]\n",
"Q2 = tunes[2]\n",
"print( 'nux = {0:.4f}'.format(nux))\n",
"print( 'nuy = {0:.4f}'.format(nuy))\n",
"print( 'Coupled Q1 = {0:.4f}'.format(Q1) )\n",
"print( 'Coupled Q2 = {0:.4f}'.format(Q2) )"
]
},
{
"cell_type": "code",
"execution_count": 96,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.007827155836881872"
]
},
"execution_count": 96,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Q1-Q2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Effects of RF-resonator"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The transverse cooling happens because RF-resonator restores only the longitudinal component $p_z$ of the ion momentum, while the photon emission reduces the full momentum $p$. So, in order to simulate the transverse radiative cooling we need to take into account the resonator effect not only on $\\Delta p/p$ but also on the angles $x'$ and $y'$."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Longitudinal momentum gain of the ion after it has passed through the RF-resonator depends on the ion phase with respect to the RF:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\frac{dp_z}{dt} = e(Z-N_e)E_{\\rm{RF}}\\cos\\phi,\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"where $E_{\\rm{RF}}$ is the accelerating electric field and $\\phi$ is the ion phase in the RF resonator. The resulting longitudinal momentum change:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\delta p_z = e(Z-N_e)\\frac{ V_{\\rm{RF}} }{ L_{\\rm{RF}}} (\\cos\\phi) \\Delta t = e(Z-N_e)\\frac{ V_{\\rm{RF}} }{\\upsilon_z} \\cos\\phi,\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"where $V_{\\rm{RF}}$ is the RF-voltage, $\\upsilon_z$ is the ion velocity."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Since $x' = p_x/p_z$ and $p_x$ is not changed in the resonator the angle $x'$ after the resonator"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"x' + \\delta x' = \\frac{p_x}{p_z + \\delta p_z} = x' \\left ( 1+\\frac{\\delta p_z} {p_z} \\right )^{-1}.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"RF-resonator frequency $f_{\\rm{RF}}$ is some high harmonic $h$ of ion revolution frequency:\n",
"\n",
"$$\n",
"f_{\\rm{RF}} = \\frac{h}{T_s},\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Longitudinal coordinate $z$ gives the longitudinal distance from the ion to the reference particle at the moment when the reference particle arrives at the RF-phase $\\phi_0$ (which is always the same). So the ion then arrives to the RF-resonator after the time\n",
"\n",
"$$\n",
"\\Delta T = -\\frac{z}{\\upsilon_z} \\approx -\\frac{z}{\\upsilon_s}.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then the ion phase in the RF-resonator is\n",
"\n",
"$$\n",
"\\phi = \\phi_0 + 2\\pi f_{\\rm{RF}}\\Delta T = \\phi_0 - 2\\pi \\frac{hz}{T_s\\upsilon_z} \\approx \\phi_0 - 2\\pi \\frac{hz}{L}.\n",
"$$"
]
},
{
"cell_type": "code",
"execution_count": 97,
"metadata": {},
"outputs": [],
"source": [
"# Pass beam through the RF-resonator:\n",
"\n",
"def RFcavity(X, h, eVrf, phi0):\n",
" # returns vector X after RF-cavity\n",
"\n",
" x = X[0].A1; xp = X[1].A1; y = X[2].A1; yp = X[3].A1; z = X[4].A1; dp = X[5].A1\n",
" \n",
" p = p0 + p0*dp # eV/c\n",
" # since p*p = px*px + py*py + pz*pz, and px = pz*x', py=pz*y':\n",
" pz = p/np.sqrt(1+xp*xp+yp*yp)\n",
" px = pz*xp\n",
" py = pz*yp\n",
"\n",
" v0 = c/np.sqrt(1 + mc*mc/(p0*p0))\n",
" v = c/np.sqrt(1 + mc*mc/(p*p))\n",
" vz = v*pz/p\n",
" \n",
" # phase in the resonator: \n",
" phi = phi0 - 2*np.pi*h*(z/L)*v0/vz\n",
"\n",
" pz = pz + eVrf*(Z-Ne)*np.cos(phi)/beta_0 # pz after RF-cavity \n",
" \n",
" xp = px/pz\n",
" yp = py/pz\n",
" \n",
" p = np.sqrt(px*px+py*py+pz*pz)\n",
" dp = (p-p0)/p0 # new relative momentum deviation\n",
" \n",
" return np.matrix([\n",
" x ,\n",
" xp,\n",
" y ,\n",
" yp,\n",
" z ,\n",
" dp\n",
" ])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Multi-turn tracking"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First we can check if our implementation of RF-cavity is changing the transverse beam emittance (because we've included higher-order effects)."
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"turn = 20000 (100 %)"
]
}
],
"source": [
"#N_turns = 1000000\n",
"N_turns = 20000\n",
"#N_turns = 200\n",
"N_plots = 11\n",
"\n",
"h = 4620 # SPS 200 MHz\n",
"eVrf = 7e6 # eV\n",
"phi0 = np.pi/2\n",
"\n",
"t_plots = np.arange(0,N_turns+1,int(N_turns/(N_plots-1)))\n",
"\n",
"X_plots = {}\n",
"\n",
"X1 = X;\n",
"for turn in range(0,N_turns+1):\n",
" if turn in t_plots:\n",
" print( \"\\rturn = %g (%g %%)\" % (turn, (100*turn/N_turns)), end=\"\")\n",
" X_plots[turn] = X1\n",
" X1 = RFcavity(X1, h, eVrf, phi0)\n",
" X1 = M*X1"
]
},
{
"cell_type": "code",
"execution_count": 99,
"metadata": {},
"outputs": [],
"source": [
"# function to calculate beam current profile:\n",
"def get_I(z, z_bin = 5e-3, z_min=-0.4, z_max=+0.4):\n",
" # z, z_bin, z_min, z_max in meters\n",
" \n",
" hist, bins = np.histogram( z, range=(z_min, z_max), bins=int((z_max-z_min)/z_bin) )\n",
" Qm = Qe*(Z-Ne)*N_ions/Np # macroparticle charge in C\n",
" I = hist*Qm/(z_bin/c) # A\n",
"\n",
" z_centers = (bins[:-1] + bins[1:]) / 2\n",
" \n",
" return z_centers, I\n",
"\n",
"%opts Area [show_grid=True aspect=2] (linewidth=1, alpha=0.7)\n",
"\n",
"z_centers, I = get_I(z)\n",
"\n",
"dim_I = hv.Dimension('I', unit='A', range=(0.0,+20.0))\n",
"\n",
"z_I = hv.Area((z_centers*1e3, I), kdims=[dim_z], vdims=[dim_I])\n",
"\n",
"#z_I"
]
},
{
"cell_type": "code",
"execution_count": 100,
"metadata": {},
"outputs": [],
"source": [
"# plot z-dp + beam current profile:\n",
"def plot_z_dp(X):\n",
" z = X[4].A1\n",
" dp = X[5].A1\n",
" z_centers, I = get_I(z)\n",
" img = (hv.Points((z*1e3, dp*100), [dim_z,dim_dp]) + \\\n",
" hv.Area((z_centers*1e3, I), kdims=[dim_z], vdims=[dim_I]) ).cols(1)\n",
" return img"
]
},
{
"cell_type": "code",
"execution_count": 101,
"metadata": {},
"outputs": [],
"source": [
"#plot_z_dp(X_plots[t_plots[-1]])"
]
},
{
"cell_type": "code",
"execution_count": 102,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.holoviews_exec.v0+json": "",
"text/html": [
"\n",
"
\n",
"
\n",
" \n",
" \n",
" \n",
"
\n",
"
\n",
"
\n",
"
\n",
""
],
"text/plain": [
":Layout\n",
" .Points.I :HoloMap [t (sec)]\n",
" :Points [z,dp]\n",
" .Area.I :HoloMap [t (sec)]\n",
" :Area [z] (I)"
]
},
"execution_count": 102,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {
"id": 139776964799056
}
},
"output_type": "execute_result"
}
],
"source": [
"items = [(turn*L/c, (plot_z_dp(X_plots[turn]))) for turn in t_plots]\n",
"\n",
"m = hv.HoloMap(items, kdims = ['t (sec)'])\n",
"m.collate()"
]
},
{
"cell_type": "code",
"execution_count": 103,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"application/vnd.holoviews_exec.v0+json": "",
"text/html": [
"\n",
"
\n",
"
\n",
" \n",
" \n",
" \n",
"
\n",
"
\n",
"
\n",
"
\n",
""
],
"text/plain": [
":Layout\n",
" .Points.I :HoloMap [t (sec)]\n",
" :Points [x,xp]\n",
" .Points.II :HoloMap [t (sec)]\n",
" :Points [y,yp]"
]
},
"execution_count": 103,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {
"id": 139776966413840
}
},
"output_type": "execute_result"
}
],
"source": [
"items = [(turn*L/c, plot_xxp_yyp(X_plots[turn])) for turn in t_plots]\n",
"\n",
"m = hv.HoloMap(items, kdims = ['t (sec)'])\n",
"m.collate()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### And finally the full turn-by-turn Monte Carlo simulation including photon emissions"
]
},
{
"cell_type": "code",
"execution_count": 104,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"turn = 600000 (100 %, 0 h. 0 min. left)"
]
}
],
"source": [
"import time\n",
"\n",
"#N_turns = 900000\n",
"N_turns = 600000\n",
"\n",
"N_plots = 21\n",
"\n",
"t_plots = np.arange(0,N_turns+1,int(N_turns/(N_plots-1)))\n",
"\n",
"X_plots = {}\n",
"Excited_plots = {}\n",
"\n",
"X1 = X;\n",
"T_start = time.time()\n",
"for turn in range(0,N_turns+1):\n",
" # the first laser pulse for transverse cooling:\n",
" Excited = ExciteIons(X1, pulse)\n",
"\n",
" if turn in t_plots:\n",
" if turn != t_plots[0]:\n",
" sec_left = ((time.time() - T_start)/turn)*(N_turns - turn)\n",
" hours_left = np.floor(sec_left/3600)\n",
" min_left = (sec_left - hours_left*3600)/60\n",
" print( \"\\rturn = %g (%g %%, %g h. %.0f min. left)\" %\n",
" (turn, (100*turn/N_turns), hours_left, min_left), end=\"\")\n",
" X_plots[turn] = X1\n",
" Excited_plots[turn] = Excited\n",
"\n",
" # let the excited ions decay:\n",
" X1, Photons = EmitPhotons(X1, Excited)\n",
" \n",
" # use the second laser pulse for longitudinal cooling:\n",
" Excited = ExciteIons(X1, pulse2)\n",
" X1, Photons = EmitPhotons(X1, Excited)\n",
" \n",
" X1 = RFcavity(X1, h, eVrf, phi0)\n",
" X1 = M*X1"
]
},
{
"cell_type": "code",
"execution_count": 105,
"metadata": {},
"outputs": [],
"source": [
"#X_plots"
]
},
{
"cell_type": "code",
"execution_count": 106,
"metadata": {},
"outputs": [],
"source": [
"np.save(\"X_plots.npy\", X_plots)"
]
},
{
"cell_type": "code",
"execution_count": 107,
"metadata": {},
"outputs": [],
"source": [
"def plot_z_dp_Excited(X,Excited):\n",
" z = X[4].A1\n",
" dp = X[5].A1\n",
"\n",
" txt = \"%.1f%% of ions excited\" % (100*len(z[Excited])/len(z))\n",
"\n",
" z_centers, I = get_I(z)\n",
" img = (hv.Points((z*1e3, dp*100), [dim_z,dim_dp], group='Still') * \\\n",
" hv.Points((z[Excited]*1e3, dp[Excited]*100), [dim_z,dim_dp], group='Excited', label=txt) + \\\n",
" hv.Area((z_centers*1e3, I), kdims=[dim_z], vdims=[dim_I]) ).cols(1)\n",
" \n",
" return img"
]
},
{
"cell_type": "code",
"execution_count": 108,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.holoviews_exec.v0+json": "",
"text/html": [
"\n",
"
\n",
"
\n",
" \n",
" \n",
" \n",
"
\n",
"
\n",
"
\n",
"
\n",
""
],
"text/plain": [
":Layout\n",
" .Overlay.I :HoloMap [t (sec)]\n",
" :Overlay\n",
" .Still.I :Points [z,dp]\n",
" .Excited.A_14_full_stop_8_percent_of_ions_excited :Points [z,dp]\n",
" .Area.I :HoloMap [t (sec)]\n",
" :Area [z] (I)"
]
},
"execution_count": 108,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {
"id": 139776961958352
}
},
"output_type": "execute_result"
}
],
"source": [
"dim_I = hv.Dimension('I', unit='A', range=(0.0,+20.0))\n",
"\n",
"items = [(turn*L/c, plot_z_dp_Excited(X_plots[turn],Excited_plots[turn])) for turn in t_plots]\n",
"\n",
"m = hv.HoloMap(items, kdims = ['t (sec)'])\n",
"m.collate()"
]
},
{
"cell_type": "code",
"execution_count": 109,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.holoviews_exec.v0+json": "",
"text/html": [
"\n",
"
\n",
"
\n",
" \n",
" \n",
" \n",
"
\n",
"
\n",
"
\n",
"
\n",
""
],
"text/plain": [
":Layout\n",
" .Points.I :HoloMap [t (sec)]\n",
" :Points [x,xp]\n",
" .Points.II :HoloMap [t (sec)]\n",
" :Points [y,yp]"
]
},
"execution_count": 109,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {
"id": 139776834760080
}
},
"output_type": "execute_result"
}
],
"source": [
"items = [(turn*L/c, plot_xxp_yyp(X_plots[turn])) for turn in t_plots]\n",
"\n",
"m = hv.HoloMap(items, kdims = ['t (sec)'])\n",
"m.collate()"
]
},
{
"cell_type": "code",
"execution_count": 110,
"metadata": {},
"outputs": [],
"source": [
"def plot_z_y_Excited(X,Excited):\n",
" z = X[4].A1\n",
" y = X[2].A1\n",
"\n",
" txt = \"%.1f%% of ions excited\" % (100*len(z[Excited])/len(z))\n",
" \n",
" z_centers, I = get_I(z)\n",
" img = (hv.Points((z*1e3, y*1e3), [dim_z,dim_y], group='Still') * \\\n",
" hv.Points((z[Excited]*1e3, y[Excited]*1e3), [dim_z,dim_y], group='Excited', label=txt) + \\\n",
" hv.Area((z_centers*1e3, I), kdims=[dim_z], vdims=[dim_I]) ).cols(1)\n",
" \n",
" return img"
]
},
{
"cell_type": "code",
"execution_count": 111,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.holoviews_exec.v0+json": "",
"text/html": [
"\n",
"
\n",
"
\n",
" \n",
" \n",
" \n",
"
\n",
"
\n",
"
\n",
"
\n",
""
],
"text/plain": [
":Layout\n",
" .Overlay.I :HoloMap [t (sec)]\n",
" :Overlay\n",
" .Still.I :Points [z,y]\n",
" .Excited.A_14_full_stop_8_percent_of_ions_excited :Points [z,y]\n",
" .Area.I :HoloMap [t (sec)]\n",
" :Area [z] (I)"
]
},
"execution_count": 111,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {
"id": 139776838220944
}
},
"output_type": "execute_result"
}
],
"source": [
"items = [(turn*L/c, plot_z_y_Excited(X_plots[turn],Excited_plots[turn])) for turn in t_plots]\n",
"\n",
"m = hv.HoloMap(items, kdims = ['t (sec)'])\n",
"m.collate()"
]
},
{
"cell_type": "code",
"execution_count": 112,
"metadata": {},
"outputs": [],
"source": [
"def plot_z_x_Excited(X,Excited):\n",
" z = X[4].A1\n",
" x = X[0].A1\n",
"\n",
" txt = \"%.1f%% of ions excited\" % (100*len(z[Excited])/len(z))\n",
" \n",
" z_centers, I = get_I(z)\n",
" img = (hv.Points((z*1e3, x*1e3), [dim_z,dim_x], group='Still') * \\\n",
" hv.Points((z[Excited]*1e3, x[Excited]*1e3), [dim_z,dim_x], group='Excited', label=txt) + \\\n",
" hv.Area((z_centers*1e3, I), kdims=[dim_z], vdims=[dim_I]) ).cols(1)\n",
" \n",
" return img"
]
},
{
"cell_type": "code",
"execution_count": 113,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.holoviews_exec.v0+json": "",
"text/html": [
"\n",
"
\n",
"
\n",
" \n",
" \n",
" \n",
"
\n",
"
\n",
"
\n",
"
\n",
""
],
"text/plain": [
":Layout\n",
" .Overlay.I :HoloMap [t (sec)]\n",
" :Overlay\n",
" .Still.I :Points [z,x]\n",
" .Excited.A_14_full_stop_8_percent_of_ions_excited :Points [z,x]\n",
" .Area.I :HoloMap [t (sec)]\n",
" :Area [z] (I)"
]
},
"execution_count": 113,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {
"id": 139776833125392
}
},
"output_type": "execute_result"
}
],
"source": [
"items = [(turn*L/c, plot_z_x_Excited(X_plots[turn],Excited_plots[turn])) for turn in t_plots]\n",
"\n",
"m = hv.HoloMap(items, kdims = ['t (sec)'])\n",
"m.collate()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Calculate emittance evolution"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The effect of transverse dispersion function is included as $x = x + D_x \\frac{\\Delta p}{p}$ and $x' = x' + D'_x\\frac{\\Delta p}{p}$.\n",
"\n",
"Therefore we can remove it as $x = x - D_x \\frac{\\Delta p}{p}$ and $x' = x' - D'_x\\frac{\\Delta p}{p}$\n",
"\n",
"Then we can calculate the RMS-emittance of this beam using the statistical definition of emittance $\\epsilon_{RMS} = \\sqrt{\\left \\left - \\left^2}$."
]
},
{
"cell_type": "code",
"execution_count": 114,
"metadata": {},
"outputs": [],
"source": [
"%opts Points [aspect=1]\n",
"\n",
"def plot_xxp_no_disp(X):\n",
" x = X[0].A1 # .A1 converts matrix into 1D-array\n",
" xp = X[1].A1\n",
" dp = X[5].A1\n",
" \n",
" x = x - Dx*dp\n",
" xp = xp - Dpx*dp\n",
" \n",
" emitt_RMS = np.sqrt(np.mean(x*x)*np.mean(xp*xp) - np.mean(x*xp)*np.mean(x*xp))\n",
" emitt_text = \"$\\epsilon_{\\mathrm{RMS}}=%.2f\\ \\mathrm{mm}\\cdot\\mathrm{mrad}$\" % (emitt_RMS*1e6*gamma)\n",
" \n",
" txt = hv.Text(0, 0.12, emitt_text)\n",
" x_xp = hv.Points((x*1e3,xp*1e3), kdims=[dim_x,dim_xp])\n",
" dp_xp = hv.Points((dp*1e2,xp*1e3), kdims=[dim_dp,dim_xp])\n",
" x_dp = hv.Points((x*1e3,dp*1e2), kdims=[dim_x,dim_dp])\n",
" \n",
" return (x_xp*txt + dp_xp + x_dp).cols(2)"
]
},
{
"cell_type": "code",
"execution_count": 115,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.holoviews_exec.v0+json": "",
"text/html": [
"\n",
"
\n",
"
\n",
" \n",
" \n",
" \n",
"
\n",
"
\n",
"
\n",
"
\n",
""
],
"text/plain": [
":Layout\n",
" .Overlay.I :HoloMap [t (s)]\n",
" :Overlay\n",
" .Points.I :Points [x,xp]\n",
" .Text.I :Text [x,y]\n",
" .Points.I :HoloMap [t (s)]\n",
" :Points [dp,xp]\n",
" .Points.II :HoloMap [t (s)]\n",
" :Points [x,dp]"
]
},
"execution_count": 115,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {
"id": 139776830302416
}
},
"output_type": "execute_result"
}
],
"source": [
"items = [(turn*L/c, plot_xxp_no_disp(X_plots[turn])) for turn in t_plots]\n",
"\n",
"m = hv.HoloMap(items, kdims = ['t (s)'])\n",
"m.collate()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Plot emittance vs time:"
]
},
{
"cell_type": "code",
"execution_count": 116,
"metadata": {},
"outputs": [],
"source": [
"emitt_RMS_nx = []\n",
"emitt_RMS_ny = []\n",
"\n",
"for turn in t_plots:\n",
" X = X_plots[turn]\n",
" \n",
" x = X[0].A1 # .A1 converts matrix into 1D-array\n",
" xp = X[1].A1\n",
" y = X[2].A1\n",
" yp = X[3].A1\n",
" dp = X[5].A1\n",
" \n",
" x = x - Dx*dp\n",
" xp = xp - Dpx*dp\n",
"\n",
" y = y - Dy*dp\n",
" yp = yp - Dpy*dp\n",
" \n",
" emitt_RMS_x = np.sqrt(np.mean(x*x)*np.mean(xp*xp) - np.mean(x*xp)*np.mean(x*xp))\n",
" emitt_RMS_y = np.sqrt(np.mean(y*y)*np.mean(yp*yp) - np.mean(y*yp)*np.mean(y*yp))\n",
" emitt_RMS_nx.append(emitt_RMS_x*1e6*gamma)\n",
" emitt_RMS_ny.append(emitt_RMS_y*1e6*gamma)"
]
},
{
"cell_type": "code",
"execution_count": 117,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
""
],
"text/plain": [
":Overlay\n",
" .Curve.Reverse_over_epsilon_left_curly_bracket_ny_right_curly_bracket :Curve [t] (emitt_n)\n",
" .Curve.Reverse_over_epsilon_left_curly_bracket_nx_right_curly_bracket :Curve [t] (emitt_n)"
]
},
"execution_count": 117,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {}
},
"output_type": "execute_result"
}
],
"source": [
"%output backend='matplotlib' fig='png' size=200\n",
"#%opts Curve (linewidth=3) [show_grid=True aspect=2 fontsize=14]\n",
"%opts Curve (linewidth=3) [show_grid=True aspect=2 \\\n",
" fontsize={'title':14, 'xlabel':14, 'ylabel':14, 'ticks':12}]\n",
"\n",
"dim_t = hv.Dimension('t', unit='sec')\n",
"dim_emitt_n = hv.Dimension('emitt_n', unit=r'mm$\\cdot$mrad', label=r\"$\\epsilon_{n}$\", range=(0,1.6))\n",
"\n",
"t_ex = hv.Curve((np.array(t_plots)*L/c, emitt_RMS_nx), kdims=dim_t, vdims=dim_emitt_n, label=r'$\\epsilon_{nx}$')\n",
"t_ey = hv.Curve((np.array(t_plots)*L/c, emitt_RMS_ny), kdims=dim_t, vdims=dim_emitt_n, label=r'$\\epsilon_{ny}$')\n",
"t_ey*t_ex"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Technical info:\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 118,
"metadata": {},
"outputs": [],
"source": [
"%load_ext watermark"
]
},
{
"cell_type": "code",
"execution_count": 119,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"numpy 1.17.2\n",
"holoviews 1.12.7\n",
"2020-03-24 \n",
"\n",
"CPython 3.7.4\n",
"IPython 7.8.0\n",
"\n",
"compiler : GCC 7.3.0\n",
"system : Linux\n",
"release : 4.4.0-174-generic\n",
"machine : x86_64\n",
"processor : x86_64\n",
"CPU cores : 40\n",
"interpreter: 64bit\n"
]
}
],
"source": [
"%watermark --python --date --iversions --machine"
]
},
{
"cell_type": "code",
"execution_count": 122,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[NbConvertApp] Converting notebook Li_like_Ca_in_SPS_transv.ipynb to HTML\n",
"[NbConvertApp] Writing 21292413 bytes to Li_like_Ca_in_SPS_transv.html\n"
]
}
],
"source": [
"!jupyter nbconvert --to HTML Li_like_Ca_in_SPS_transv.ipynb"
]
},
{
"cell_type": "code",
"execution_count": 121,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'/home/petrenko/work/GF/Ca_in_SPS/transverse_cooling/tmp/minimum_longitudinal_cooling'"
]
},
"execution_count": 121,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pwd"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"hide_input": false,
"kernelspec": {
"display_name": "Python 3",
"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.7.4"
}
},
"nbformat": 4,
"nbformat_minor": 4
}