Skip to content

Commit b51c899

Browse files
authored
Add files via upload
1 parent 95284c4 commit b51c899

5 files changed

+5
-4
lines changed

CR_2DES_tutorial.ipynb

+1
Large diffs are not rendered by default.

CR_DoubleSlit.ipynb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[]},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"}},"cells":[{"cell_type":"markdown","source":["###**Model calculation: Idealized double-slit experiment**\n","\n","\n","\n","> This code can be used to reproduce the data plotted in Figure 1 of Schultz et al., Coherence in chemistry: foundations and frontiers. *Chem. Revs.* (submitted)\n","\n","To begin, press the play button beside each cell (proceed sequentially through the cells)."],"metadata":{"id":"H2WPl-rvZSYR"}},{"cell_type":"code","source":["#@title Import libraries, prep plot settings\n","\n","import matplotlib.pyplot as plt\n","from scipy import signal\n","import numpy as np\n","import math\n","from IPython.display import set_matplotlib_formats\n","set_matplotlib_formats('svg')\n","\n","#packages for plotting\n","import matplotlib\n","import matplotlib.pyplot as plt"],"metadata":{"id":"-X1cTwAH1cKg","cellView":"form"},"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"Nu_OWXfHeMFE","executionInfo":{"status":"ok","timestamp":1692576188156,"user_tz":240,"elapsed":197,"user":{"displayName":"Quantum Coherence","userId":"04118399231983577771"}}},"source":["#@title Tunable parameters\n","\n","wavelength = 4.0\n","d = 20\n","L = 7"],"execution_count":2,"outputs":[]},{"cell_type":"code","metadata":{"cellView":"form","id":"nrAeY-12ZdST"},"source":["#@title Calculate and plot\n","\n","def Amplitude(L, y, d, wavelength): #calculates the AMPLITUDE of the sum of two sine waves y1 and y2 with amplitude a1 and a2, identical frequencies, and phases alpha1 and alpha2, respectively. For derivation, see Jenkins and White, 4th ed., pp 239\n"," R_1 = math.sqrt(L**2 + (y-d/2)**2)\n"," R_2 = math.sqrt(L**2 + (y+d/2)**2)\n"," a1 = 1/R_1 # INTENSITY goes as 1/R^2, not the amplitude\n"," a2 = 1/R_2\n"," alpha1 = 2*math.pi*R_1/wavelength\n"," alpha2 = 2*math.pi*R_2/wavelength\n"," sumamplitude = math.sqrt(a1**2 + a2**2 + 2*a1*a2*math.cos(alpha1 - alpha2))\n"," return sumamplitude\n","\n","y = np.arange(- 30, 30, 0.01)\n","\n","data = [Amplitude(L, y, d, wavelength)**2 for y in y]\n","data2 = [1/(L**2 + (y - d/2)**2) for y in y]\n","data3 = [1/(L**2 + (y + d/2)**2) for y in y]\n","data4 = [sum(x) for x in zip(data2, data3)]\n","\n","\n","fig = plt.figure(figsize=(6, 3))\n","ax = fig.add_subplot(1, 1, 1)\n","plt.plot(y,data, 'black', y, data4, 'b--')\n","plt.axis('off')\n","plt.show()\n","plt.savefig(\"Interference.svg\")"],"execution_count":null,"outputs":[]}]}
1+
{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[]},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"}},"cells":[{"cell_type":"markdown","source":["#**Model calculation: Idealized double-slit experiment**\n","\n","> This code supplements Figure 2 of the Chemical Reviews article titled \"Coherence in Chemistry: Foundations and Frontiers\" ([doi.org/10.1021/acs.chemrev.3c00643](https://doi.org/10.1021/acs.chemrev.3c00643))\n","\n","To begin, press the play button beside each cell (proceed sequentially through the cells)."],"metadata":{"id":"H2WPl-rvZSYR"}},{"cell_type":"code","source":["#@title Import libraries, prep plot settings\n","\n","import matplotlib.pyplot as plt\n","from scipy import signal\n","import numpy as np\n","import math\n","from IPython.display import set_matplotlib_formats\n","set_matplotlib_formats('svg')\n","\n","#packages for plotting\n","import matplotlib\n","import matplotlib.pyplot as plt"],"metadata":{"id":"-X1cTwAH1cKg","cellView":"form"},"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"id":"Nu_OWXfHeMFE"},"source":["#@title Tunable parameters\n","\n","wavelength = 4.0\n","d = 20\n","L = 7"],"execution_count":null,"outputs":[]},{"cell_type":"code","metadata":{"cellView":"form","id":"nrAeY-12ZdST"},"source":["#@title Calculate and plot\n","\n","def Amplitude(L, y, d, wavelength): #calculates the AMPLITUDE of the sum of two sine waves y1 and y2 with amplitude a1 and a2, identical frequencies, and phases alpha1 and alpha2, respectively. For derivation, see Jenkins and White, 4th ed., pp 239\n"," R_1 = math.sqrt(L**2 + (y-d/2)**2)\n"," R_2 = math.sqrt(L**2 + (y+d/2)**2)\n"," a1 = 1/R_1 # INTENSITY goes as 1/R^2, not the amplitude\n"," a2 = 1/R_2\n"," alpha1 = 2*math.pi*R_1/wavelength\n"," alpha2 = 2*math.pi*R_2/wavelength\n"," sumamplitude = math.sqrt(a1**2 + a2**2 + 2*a1*a2*math.cos(alpha1 - alpha2))\n"," return sumamplitude\n","\n","y = np.arange(- 30, 30, 0.01)\n","\n","data = [Amplitude(L, y, d, wavelength)**2 for y in y]\n","data2 = [1/(L**2 + (y - d/2)**2) for y in y]\n","data3 = [1/(L**2 + (y + d/2)**2) for y in y]\n","data4 = [sum(x) for x in zip(data2, data3)]\n","\n","\n","fig = plt.figure(figsize=(6, 3))\n","ax = fig.add_subplot(1, 1, 1)\n","plt.plot(y,data, 'black', y, data4, 'b--')\n","plt.axis('off')\n","plt.show()\n","plt.savefig(\"Interference.svg\")"],"execution_count":null,"outputs":[]}]}

CR_Interference.ipynb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[]},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"}},"cells":[{"cell_type":"markdown","source":["###**Model calculation: Interferometer**\n","\n","\n","\n","> This code can be used to reproduce the data plotted in Figure 2 of Schultz et al., Coherence in chemistry: foundations and frontiers. *Chem. Revs.* (submitted)\n","\n","To begin, press the play button beside each cell (proceed sequentially through the cells)."],"metadata":{"id":"H2WPl-rvZSYR"}},{"cell_type":"code","source":["#@title Import libraries, prep plot settings\n","\n","import numpy as np\n","import math\n","import matplotlib.pyplot as plt\n","from scipy import signal\n","from IPython.display import set_matplotlib_formats\n","set_matplotlib_formats('svg')\n","\n","def gensignal(N, trange, Autcrr):\n"," alpha_real = np.random.normal(0, 1/4, int(N))\n"," alpha_im = np.random.normal(0,1/4, int(N))\n","\n"," #initialize empty complex array to store random gaussian samples\n"," alpha = np.zeros(N+1)\n"," alpha = alpha.astype(complex)\n","\n"," for mu in range(1, int(N/2)+1):\n"," real = alpha_real[mu]\n"," im = 1j*alpha_im[mu]\n"," alpha[mu] = real + im\n"," alpha[-mu] = np.conjugate(alpha[mu])\n","\n"," # create alpha for zero freq component\n"," alpha[0] = 1\n","\n"," t= np.linspace(0, trange, N+1)\n"," #construct the spectral representation of the signal A using the random samples alpha_w\n"," fourtransAutcrr = np.fft.fft(Autcrr)\n"," A_w = [alpha[mu]*fourtransAutcrr[mu] for mu in range(-int(N/2), int(N/2)+1)]\n","\n","\n","\n","\n"," A_w = np.fft.ifftshift(A_w)\n","\n"," A_t = np.fft.ifft(A_w)\n"," return np.real(A_t) #discard small imaginary part\n","\n","#calculates the autocorrelation function signal[i]*signal[i+j] averaged over Neave different i's\n","def autocorrelation(signal, j, Neave):\n"," sum = 0\n"," signalj = np.roll(signal, -j) #creates a copy of the timeseries and shifts it over by j\n"," signal = signal[:Neave] #remove data from lists that are not included in the ergotic average (Neave is number of timestamps in ergotic average)\n"," signalj= signalj[:Neave]\n"," return np.dot(signal, signalj)/Neave #returns the ergotic average of signal[i]*signal[i+j] over Neave different i's"],"metadata":{"id":"IksVGVrZzYus","cellView":"form"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["#@title Tunable parameters\n","\n","N=2**20\n","dt = 0.01\n","trange = (N+1)*dt\n","t= np.linspace(0, trange, N+1)\n","\n","epsilon = 20\n","tau = 20\n","period = 1\n","omega = 2*math.pi/period"],"metadata":{"id":"-X1cTwAH1cKg"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["#@title Calculate and plot\n","\n","\n","###############\n","## Calculate main pulse\n","###############\n","Autcrr = [np.cos(omega*t)*epsilon/tau*np.exp(-t/tau) for t in t]\n","sig = gensignal(N, trange, Autcrr)\n","\n","\n","## Set up delay vectors\n","###################\n","Ndelaysamples = 150 #number of data points in delay plot\n","tdelayrange = 8*period\n","dtdelay = tdelayrange/Ndelaysamples\n","dN = int(dtdelay/dt)\n","t_delay = np.linspace(0, tdelayrange, Ndelaysamples)\n","\n","\n","integrationtime = 2000 * tau\n","Ninteg = int(integrationtime/dt)\n","\n","\n","#Calculate the integrated power on the detector sig[i]sig[i+j] where j is the delay and i sums over the integration time\n","##########\n","detectorsig = np.zeros(Ndelaysamples)\n","\n","for delay in range(0, Ndelaysamples):\n"," sigdelay = np.roll(sig, -delay*dN)\n"," sigdelaydetect = sigdelay[:Ninteg]\n"," sigdetect = sig[:Ninteg]\n"," intensitysum = [(sigdelaydetect[j]+sigdetect[j])**2 for j in range(len(sigdetect))] #instantaneous intensity at time j recorded over the integration time\n"," detectorsig[delay] = np.mean(intensitysum) #average intensity\n","\n","\n","intensitytest = [sig[j]**2 for j in range(len(sig))]\n","val = 2*np.mean(intensitytest)\n","incoherentsum = [val for j in range(Ndelaysamples)]\n","\n","\n","############\n","## Plotting\n","############\n","\n","fig = plt.figure(figsize = (3,6))\n","\n","ax1 = fig.add_subplot(3,1,1)\n","ax1.plot(t, sig, linewidth = 1, color = 'b', label = 'Pulse')\n","ax1.plot(t, np.roll(sig, int(2.4*period/dt)), linewidth = 1, color = 'g', label = 'Delay') #comparison between reference and sample delay\n","plt.xlim(0, 7*period)\n","ax1.axes.xaxis.set_ticks([])\n","ax1.axes.yaxis.set_ticks([])\n","ax1.set_xlabel('Time')\n","ax1.set_ylabel('Signal')\n","ax1.set_title('Pulse Profiles')\n","ax1.legend(prop={'size': 7})\n","\n","ax2 = fig.add_subplot(3,1,2)\n","ax2.plot(t_delay, detectorsig, linewidth = 1, color = 'black', label = 'Interference')\n","ax2.plot(t_delay, incoherentsum, linewidth = 1.5, color = 'blue', linestyle = ':', label = 'Incoherent sum')\n","ax2.set_xlabel('Delay time')\n","ax2.set_ylabel('Average Intensity')\n","ax2.axes.xaxis.set_ticks([])\n","ax2.axes.yaxis.set_ticks([])\n","ax2.legend(prop={'size': 8})\n","ax2.set_title('Detector response')\n","fig.tight_layout()\n","\n","\n","fig2 = plt.figure(figsize = (1,1))\n","ax3 = fig2.add_subplot(1,1,1)\n","x = np.linspace(0,1, int((N+1)/2)+1)\n","y = np.abs(np.fft.rfft(sig))\n","ax3.plot(x, y, linewidth = 1, color = 'black')\n","plt.xlim(0, 0.05)\n","ax3.axes.xaxis.set_ticks([])\n","ax3.axes.yaxis.set_ticks([])\n","ax3.set_xlabel('Frequency',fontdict={'fontsize': 8})\n","ax3.set_ylabel('Power',fontdict={'fontsize': 8})"],"metadata":{"id":"f932zxF_Wx0b","cellView":"form"},"execution_count":null,"outputs":[]}]}
1+
{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[]},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"}},"cells":[{"cell_type":"markdown","source":["#**Model calculation: Interferometer**\n","\n","> This code supplements Figure 3 of the Chemical Reviews article titled \"Coherence in Chemistry: Foundations and Frontiers\" ([doi.org/10.1021/acs.chemrev.3c00643](https://doi.org/10.1021/acs.chemrev.3c00643))\n","\n","To begin, press the play button beside each cell (proceed sequentially through the cells)."],"metadata":{"id":"H2WPl-rvZSYR"}},{"cell_type":"code","source":["#@title Import libraries, prep plot settings\n","\n","import numpy as np\n","import math\n","import matplotlib.pyplot as plt\n","from scipy import signal\n","from IPython.display import set_matplotlib_formats\n","set_matplotlib_formats('svg')\n","\n","def gensignal(N, trange, Autcrr):\n"," alpha_real = np.random.normal(0, 1/4, int(N))\n"," alpha_im = np.random.normal(0,1/4, int(N))\n","\n"," #initialize empty complex array to store random gaussian samples\n"," alpha = np.zeros(N+1)\n"," alpha = alpha.astype(complex)\n","\n"," for mu in range(1, int(N/2)+1):\n"," real = alpha_real[mu]\n"," im = 1j*alpha_im[mu]\n"," alpha[mu] = real + im\n"," alpha[-mu] = np.conjugate(alpha[mu])\n","\n"," # create alpha for zero freq component\n"," alpha[0] = 1\n","\n"," t= np.linspace(0, trange, N+1)\n"," #construct the spectral representation of the signal A using the random samples alpha_w\n"," fourtransAutcrr = np.fft.fft(Autcrr)\n"," A_w = [alpha[mu]*fourtransAutcrr[mu] for mu in range(-int(N/2), int(N/2)+1)]\n","\n","\n","\n","\n"," A_w = np.fft.ifftshift(A_w)\n","\n"," A_t = np.fft.ifft(A_w)\n"," return np.real(A_t) #discard small imaginary part\n","\n","#calculates the autocorrelation function signal[i]*signal[i+j] averaged over Neave different i's\n","def autocorrelation(signal, j, Neave):\n"," sum = 0\n"," signalj = np.roll(signal, -j) #creates a copy of the timeseries and shifts it over by j\n"," signal = signal[:Neave] #remove data from lists that are not included in the ergotic average (Neave is number of timestamps in ergotic average)\n"," signalj= signalj[:Neave]\n"," return np.dot(signal, signalj)/Neave #returns the ergotic average of signal[i]*signal[i+j] over Neave different i's"],"metadata":{"id":"IksVGVrZzYus","cellView":"form"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["#@title Tunable parameters\n","\n","N=2**20\n","dt = 0.01\n","trange = (N+1)*dt\n","t= np.linspace(0, trange, N+1)\n","\n","epsilon = 20\n","tau = 20\n","period = 1\n","omega = 2*math.pi/period"],"metadata":{"id":"-X1cTwAH1cKg"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":["#@title Calculate and plot\n","\n","\n","###############\n","## Calculate main pulse\n","###############\n","Autcrr = [np.cos(omega*t)*epsilon/tau*np.exp(-t/tau) for t in t]\n","sig = gensignal(N, trange, Autcrr)\n","\n","\n","## Set up delay vectors\n","###################\n","Ndelaysamples = 150 #number of data points in delay plot\n","tdelayrange = 8*period\n","dtdelay = tdelayrange/Ndelaysamples\n","dN = int(dtdelay/dt)\n","t_delay = np.linspace(0, tdelayrange, Ndelaysamples)\n","\n","\n","integrationtime = 2000 * tau\n","Ninteg = int(integrationtime/dt)\n","\n","\n","#Calculate the integrated power on the detector sig[i]sig[i+j] where j is the delay and i sums over the integration time\n","##########\n","detectorsig = np.zeros(Ndelaysamples)\n","\n","for delay in range(0, Ndelaysamples):\n"," sigdelay = np.roll(sig, -delay*dN)\n"," sigdelaydetect = sigdelay[:Ninteg]\n"," sigdetect = sig[:Ninteg]\n"," intensitysum = [(sigdelaydetect[j]+sigdetect[j])**2 for j in range(len(sigdetect))] #instantaneous intensity at time j recorded over the integration time\n"," detectorsig[delay] = np.mean(intensitysum) #average intensity\n","\n","\n","intensitytest = [sig[j]**2 for j in range(len(sig))]\n","val = 2*np.mean(intensitytest)\n","incoherentsum = [val for j in range(Ndelaysamples)]\n","\n","\n","############\n","## Plotting\n","############\n","\n","fig = plt.figure(figsize = (3,6))\n","\n","ax1 = fig.add_subplot(3,1,1)\n","ax1.plot(t, sig, linewidth = 1, color = 'b', label = 'Pulse')\n","ax1.plot(t, np.roll(sig, int(2.4*period/dt)), linewidth = 1, color = 'g', label = 'Delay') #comparison between reference and sample delay\n","plt.xlim(0, 7*period)\n","ax1.axes.xaxis.set_ticks([])\n","ax1.axes.yaxis.set_ticks([])\n","ax1.set_xlabel('Time')\n","ax1.set_ylabel('Signal')\n","ax1.set_title('Pulse Profiles')\n","ax1.legend(prop={'size': 7})\n","\n","ax2 = fig.add_subplot(3,1,2)\n","ax2.plot(t_delay, detectorsig, linewidth = 1, color = 'black', label = 'Interference')\n","ax2.plot(t_delay, incoherentsum, linewidth = 1.5, color = 'blue', linestyle = ':', label = 'Incoherent sum')\n","ax2.set_xlabel('Delay time')\n","ax2.set_ylabel('Average Intensity')\n","ax2.axes.xaxis.set_ticks([])\n","ax2.axes.yaxis.set_ticks([])\n","ax2.legend(prop={'size': 8})\n","ax2.set_title('Detector response')\n","fig.tight_layout()\n","\n","\n","fig2 = plt.figure(figsize = (1,1))\n","ax3 = fig2.add_subplot(1,1,1)\n","x = np.linspace(0,1, int((N+1)/2)+1)\n","y = np.abs(np.fft.rfft(sig))\n","ax3.plot(x, y, linewidth = 1, color = 'black')\n","plt.xlim(0, 0.05)\n","ax3.axes.xaxis.set_ticks([])\n","ax3.axes.yaxis.set_ticks([])\n","ax3.set_xlabel('Frequency',fontdict={'fontsize': 8})\n","ax3.set_ylabel('Power',fontdict={'fontsize': 8})"],"metadata":{"id":"f932zxF_Wx0b","cellView":"form"},"execution_count":null,"outputs":[]}]}

0 commit comments

Comments
 (0)