codex/past-exam-of-the-chemistry-b-course-of-the-university-of-cambridge/2024/paper-1-decalins.py

past-exam-of-the-chemistry-b-course-of-the-university-of-cambridge/2024/paper-1-decalins.py
"""Original solution diagram; Python 3.14, numpy, matplotlib. Output PNG goes to cwd."""
import sys
sys.dont_write_bytecode=True
from pathlib import Path
sys.path.insert(0,str(Path(__file__).resolve().parents[2]/'tools'))
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
import chemistry_diagram as d
plt.rcParams.update({'font.size':11})
def txt(a,p,s,size=12,color='0.15'):d.atom(a,p,s,size=size,color=color)
def setup(a,x=(-3,3),y=(-2.5,2.5),title=None):d.finish(a,x,y,title)
def save(fig,name):
 fig.tight_layout();fig.savefig(name,dpi=165,facecolor='white',bbox_inches='tight',pad_inches=.15);plt.close(fig)

def fused(kind):
 th=np.arange(6)*np.pi/3;p=np.column_stack([np.cos(th),np.sin(th),((-1.)**np.arange(6))/np.sqrt(32)])
 ax=[np.array([0.,0.,(-1.)**i]) for i in range(6)];eq=[np.array([2*np.sqrt(2)/3*np.cos(th[i]),2*np.sqrt(2)/3*np.sin(th[i]),-(-1.)**i/3]) for i in range(6)]
 phase=-1 if kind=='trans' else 1;v=eq[0] if kind in ['trans','cis-out'] else ax[0]
 q=p.copy();q[:,2]*=phase
 def basis(a,b,c):
  u=(b-a)/np.linalg.norm(b-a);v=c-a;v-=u*np.dot(u,v);v/=np.linalg.norm(v);return np.stack([u,v,np.cross(u,v)],1)
 target=p[0]+np.linalg.norm(p[1]-p[0])*v;R=basis(p[0],p[1],target)@basis(q[0],q[1],q[5]).T;q=(q-q[0])@R.T+p[0]
 hs=[ax[0],ax[1]] if kind=='trans' else ([eq[0],ax[1]] if kind=='cis-in' else [ax[0],eq[1]])
 return p,q,hs,R,phase
M=np.array([[.85,.3,.1],[-.15,.5,.85]])
def drawfused(a,kind,oxy=False,br=False,alkene=False):
 p,q,hs,R,phase=fused(kind)
 if alkene:
  mid=(q[3]+q[4])/2;normal=np.cross(q[5]-q[2],mid-q[2]);normal/=np.linalg.norm(normal)
  for i in [3,4]:q[i]-=np.dot(q[i]-q[2],normal)*normal
 allp=np.vstack([p,q]);centre=(allp.max(0)+allp.min(0))/2
 def proj(v):return M@(v-centre)*1.35
 for ps,right in [(p,False),(q,True)]:
  for i in range(6):
   if right and i==0:continue
   d.bond(a,proj(ps[i]),proj(ps[(i+1)%6]),2 if right and alkene and i==3 else 1)
 if oxy:
  for i in [3,5]:txt(a,proj(q[i]),'O',14,'#b2472c')
 for i,v in enumerate(hs):
  u=proj(p[i]);h=proj(p[i]+.55*v);d.bond(a,u,h,color=d.BLUE);txt(a,h,'H',11,d.BLUE)
 if br:
  for i in [3,4]:
   v=R@np.array([0,0,phase*(-1.)**i]);u=proj(q[i]);r=proj(q[i]+.62*v);d.bond(a,u,r,color='#97465d');txt(a,r,'Br',11,'#97465d')
 if oxy:
  i=5 if kind=='cis-in' else 2
  j=5 if kind=='cis-in' else 2
  d.bond(a,proj(q[i]),proj(p[j]),style='dotted',color='#b2472c',lw=1)
 return p,q,proj

fig,axs=plt.subplots(2,2,figsize=(11,9),facecolor='white')
for a in axs.flat:setup(a,(-3,3),(-2.4,2.4))
drawfused(axs[0,0],'trans',alkene=True);axs[0,0].set_title('A: trans fusion, one chiral configuration',fontsize=12)
drawfused(axs[0,1],'trans',br=True);axs[0,1].set_title('A: favored trans-diaxial dibromide',fontsize=12)
for a,k,title in [(axs[1,0],'cis-in','B: one folded conformer'),(axs[1,1],'cis-out','B: mirror-related fold')]:drawfused(a,k,alkene=True);a.set_title(title,fontsize=12)
fig.text(.5,.04,'B folds interconvert; anti addition creates an enantiomeric product pair. Blue bonds mark junction H; bromines shown in A are opposite-face axial bonds.',ha='center',fontsize=9)
fig.text(.5,.015,'Idealized conformational sketches. The alkene segment is flattened schematically; these are not experimental coordinates.',ha='center',fontsize=9)
save(fig,'paper-1-decalins.png')