codexgaussian-pulse-width-uncertainty.py
gaussian-pulse-width-uncertainty.py
"""Plot first-order uncertainty of a Gaussian third-order pulse-width inversion.
Python 3.14, NumPy 2.3.5, Matplotlib 3.10.7. Run in media; PNG goes to cwd.
Response FWHM60 fs, independent measured/response standard uncertainties2 fs.
These are stipulated calculations, not observations or confidence intervals.
"""
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
M=np.linspace(60.15,160,1500);R=60.0
P=np.sqrt((2/3)*(M*M-R*R))
uP=(2/(3*P))*np.sqrt(M*M*4+R*R*4)
fig,axs=plt.subplots(1,2,figsize=(9.2,3.6),facecolor='white')
fig.subplots_adjust(left=.075,right=.98,bottom=.22,top=.76,wspace=.30)
axs[0].plot(M,P,color='#245b9c',lw=2)
axs[1].plot(M,uP,color='#9d592d',lw=2)
for ax in axs:
ax.axvline(R,ls='--',color='#777',lw=1)
ax.set(xlim=(58,160),xlabel='Measured correlation FWHM (fs)')
ax.spines[['top','right']].set_visible(False);ax.grid(alpha=.2)
axs[0].set(ylabel='Inferred pulse FWHM (fs)',ylim=(0,125))
axs[1].set(ylabel='First-order u(P) (fs)',ylim=(0,35))
for mm in [61,120]:
pp=float(np.sqrt((2/3)*(mm*mm-R*R)));up=float((2/(3*pp))*np.sqrt(mm*mm*4+R*R*4))
axs[0].scatter([mm],[pp],color='#245b9c');axs[1].scatter([mm],[up],color='#9d592d')
axs[1].annotate('61 fs: uncertainty exceeds inferred width',xy=(61,12.70),xytext=(69,25),fontsize=9,
arrowprops={'arrowstyle':'->','color':'#555'})
fig.suptitle('Subtracting instrumental broadening becomes ill-conditioned near the response width',fontsize=12,y=.96)
fig.text(.5,.81,r'$P=\sqrt{(2/3)(M^2-R^2)},\ R=60\ \mathrm{fs},\ u(M)=u(R)=2\ \mathrm{fs}$',ha='center',fontsize=11)
fig.text(.5,.035,'First-order curves only: near the boundary, a positive estimate does not establish a resolved pulse.',
ha='center',fontsize=9.5)
fig.savefig('gaussian-pulse-width-uncertainty.png',dpi=120,facecolor='white')