{"id":808,"date":"2025-07-20T04:07:09","date_gmt":"2025-07-20T04:07:09","guid":{"rendered":"https:\/\/synchrotron-light.net\/wp\/?page_id=808"},"modified":"2025-07-20T05:12:24","modified_gmt":"2025-07-20T05:12:24","slug":"chapter-11-calculation-of-synchrotron-radiation-from-first-principles","status":"publish","type":"page","link":"https:\/\/synchrotron-light.net\/wp\/?page_id=808","title":{"rendered":"Chapter 11: Calculation of synchrotron radiation from first principles"},"content":{"rendered":"<p>Below is a set of python codes associated with Chapter 11 of Daniele Pelliccia and David M. Paganin, &#8220;Synchrotron Light: A Physics Journey from Laboratory to Cosmos&#8221; (Oxford University Press, 2025).<\/p>\n<p>In order to run any of these python codes, you will need to include the following header.<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">from scipy import special\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\n\r\nsynchrotron_style = {\r\n    'font.family': 'FreeSerif',\r\n    'font.size': 30,\r\n    'axes.linewidth': 2.0,\r\n    'axes.edgecolor': 'black',\r\n    'grid.color': '#5b5b5b',\r\n    'grid.linewidth': 1.2,\r\n}<\/pre>\n<h2 id=\"The-basics:-plotting-a-radial-field\">Doppler shift<\/h2>\n<p>See Fig. 11.2<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">c = 1. # set the speed of light in natural unit\r\nv1 = 0.9\r\nv2 = 0.999\r\nbeta1 = v1\/c\r\nbeta2 = v2\/c\r\ngamma1 = 1.0\/ np.sqrt(1.0 - v1**2\/c**2)\r\ngamma2 = 1.0\/ np.sqrt(1.0 - v2**2\/c**2)\r\n\r\ntheta = np.linspace(-np.pi\/2, np.pi\/2, 500, endpoint=False)\r\n\r\nfig = plt.figure(figsize=(9,6))\r\nwith plt.style.context(('seaborn-v0_8-whitegrid')):\r\n    plt.rcParams.update(synchrotron_style)\r\n    plt.plot(theta,1.0\/(gamma1*(1-beta1*np.cos(theta))), lw=4, label=\"$v = 0.9c$\")\r\n    plt.plot(theta,1.0\/(gamma2*(1-beta2*np.cos(theta))), lw=4, label=\"$v = 0.999c$\")\r\n    \r\n    plt.xlabel('$\\\\theta$ (rad)', fontsize=30, labelpad=0)\r\n    plt.ylabel(\"$\\\\frac{\\omega}{\\omega'}$\", rotation=0, fontsize=36, labelpad=25)\r\n    \r\n    plt.xticks(fontsize = 30)\r\n    plt.yticks(fontsize = 30)\r\n    plt.legend(fontsize = 28, frameon=True, handlelength=1, framealpha=1)<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-809\" src=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.2.png\" alt=\"\" width=\"589\" height=\"403\" srcset=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.2.png 589w, https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.2-480x328.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 589px, 100vw\" \/><\/p>\n<h2>Dirac comb<\/h2>\n<p>This code snippet produces a basic version of the Dirac comb plotted in Fig. 11.3(b).<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">N, n = 101, 30\r\ndef f(i):\r\n    return ((i-15) % n == 0) * 1\r\ncomb = np.fromfunction(f, (N,), dtype=int)\r\n\r\nplt.figure(figsize = (12,7))\r\nplt.plot(comb, lw=5)\r\nplt.axis('off')\r\nplt.show()<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-811\" src=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.3b.png\" alt=\"\" width=\"700\" height=\"408\" srcset=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.3b.png 700w, https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.3b-480x279.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 700px, 100vw\" \/><\/p>\n<h2>Spatial and temporal structure of synchrotron light<\/h2>\n<h3>Archimedean spirals<\/h3>\n<p>See Fig. 11.11.<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">phi = np.linspace(0,6*np.pi, 10000)\r\nr = [phi, phi, phi ]\r\noffset = [0, 2*np.pi\/3, 4*np.pi\/3]\r\nplt.figure(figsize=[20,20])\r\nfor i,radius in enumerate(r):\r\n    x = -radius*np.cos(phi-offset[i])\r\n    y = radius*np.sin(phi-offset[i])\r\n\r\n    plt.plot(x,y, lw=6)\r\n\r\nplt.axis(\"off\")    \r\nplt.show()<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-812\" src=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.11-1024x998.png\" alt=\"\" width=\"700\" height=\"682\" \/><\/p>\n<h3 style=\"text-align: left;\">Auxiliary function <span class=\"wp-katex-eq\" data-display=\"false\"> f(s, \\beta) <\/span><\/h3>\n<p>See Figs. 11.12(a) and 11.13(a).<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">bbeta = 0.8 # replace with 0.4 for Fig. 11.13(a)\r\nn = 1\r\ns = np.linspace(-np.pi,np.pi, 500)\r\naux = np.zeros_like(s)\r\nfor n in np.arange(-100,100,1):\r\n    aux = aux + n*np.exp(1j*n*s)*special.jvp(n, n*bbeta)\r\n    \r\nauxil = np.abs(aux)**2    \r\n\r\nwith plt.style.context(('seaborn-v0_8-whitegrid')):\r\n    plt.rcParams.update(synchrotron_style)\r\n    fig,ax = plt.subplots(figsize=(10,8))\r\n    plt.plot(s,auxil, lw=4)\r\n    plt.xticks(fontsize = 24)\r\n    plt.yticks(fontsize = 26)\r\n    ax.set_xticks([-np.pi,-np.pi\/2, 0,np.pi\/2,np.pi],labels=[\"\", \"\", \"\", \"\",\"\"])\r\nplt.show()<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-813\" src=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.12a.png\" alt=\"\" width=\"700\" height=\"521\" srcset=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.12a.png 700w, https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.12a-480x357.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 700px, 100vw\" \/><\/p>\n<h3>Spatial structure of instantaneous energy density for a fixed instant of time<\/h3>\n<p>See Figs. 11.12(b) and 11.13(b).<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">import tqdm\r\nbbeta = 0.8 # replace with 0.4 to generate Fig. 11.13(b)\r\nphi = np.linspace(0, 2*np.pi, 3600)\r\nr = np.arange(0, 20, 0.002)\r\n\r\nrr, theta = np.meshgrid(r, phi)\r\nvalues = np.random.random((phi.size, r.size))\r\n\r\ns = theta + rr\r\naux = np.zeros_like(s)\r\nn_max = 200\r\nfor n in tqdm.tqdm(np.arange(-n_max,n_max,1)):\r\n    aux = aux + n*np.exp(1j*n*s)*special.jvp(n, n*bbeta)\r\n\r\nauxil = np.abs(aux)**2   \r\n\r\nwith plt.style.context(('default')):\r\n    plt.rcParams.update(synchrotron_style)\r\n    \r\n    fig, ax = plt.subplots(subplot_kw=dict(projection='polar'), figsize=(10,10))\r\n    ax.contourf(theta, rr, auxil, levels=200)\r\n    ax.set_rticks([0,5, 10,15,20])\r\n    ax.set_yticklabels([])\r\n    ax.tick_params(axis='y', labelsize=26)\r\n    ax.tick_params(axis='x', labelsize=26)\r\n        \r\n    positions = [0, np.pi\/4, np.pi\/2, 3*np.pi\/4, np.pi, 5*np.pi\/4, 3*np.pi\/2, 7*np.pi\/4]\r\n    for i,j in enumerate(ax.get_xticklabels()):\r\n        j.set_position((positions[i],-0.05))\r\n\r\nplt.show()<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-815\" src=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.12b.png\" alt=\"\" width=\"700\" height=\"687\" srcset=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.12b.png 700w, https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.12b-480x471.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 700px, 100vw\" \/><\/p>\n<h3 id=\"Plot-of-the-gain-function\">Temporal structure of synchrotron light<\/h3>\n<p>See Fig. 11.14.<\/p>\n<pre class=\"theme:obsidian lang:python decode:true\">bbeta1 = 0.8\r\nbbeta2 = 0.4\r\nn_max = 250\r\nomega_0 = 10\r\nt = np.linspace(-0.2,3, 10000)\r\ns = omega_0*t\r\n\r\ncol = ['r', 'b']\r\n\r\nwith plt.style.context(('seaborn-v0_8-whitegrid')):\r\n    plt.rcParams.update(synchrotron_style)\r\n    fig = plt.figure(figsize=(9,6))\r\n    for i, bbeta in enumerate([0.4,0.8]):\r\n        aux = np.zeros_like(s)\r\n        for n in np.arange(-n_max,n_max,1):\r\n            aux = aux + n*np.exp(1j*n*s)*special.jvp(n, n*bbeta)\r\n    \r\n        if bbeta == 0.4:    \r\n            auxil = 20*np.abs(aux)**2    \r\n        else:\r\n            auxil = np.abs(aux)**2\r\n    \r\n        plt.plot(t,auxil, lw=2, color = col[i])\r\n    plt.show()<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-816\" src=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.14.png\" alt=\"\" width=\"784\" height=\"524\" srcset=\"https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.14.png 784w, https:\/\/synchrotron-light.net\/wp\/wp-content\/uploads\/2025\/07\/shynchrotron-light-11.14-480x321.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 784px, 100vw\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Below is a set of python codes associated with Chapter 11 of Daniele Pelliccia and David M. Paganin, &#8220;Synchrotron Light: A Physics Journey from Laboratory to Cosmos&#8221; (Oxford University Press, 2025). In order to run any of these python codes, you will need to include the following header. from scipy import special import numpy as [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":79,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"class_list":["post-808","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/pages\/808","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=808"}],"version-history":[{"count":3,"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/pages\/808\/revisions"}],"predecessor-version":[{"id":828,"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/pages\/808\/revisions\/828"}],"up":[{"embeddable":true,"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=\/wp\/v2\/pages\/79"}],"wp:attachment":[{"href":"https:\/\/synchrotron-light.net\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=808"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}