import%20marimo%0A%0A__generated_with%20%3D%20%220.18.4%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Practice%20marimo%0A%0A%20%20%20%20This%20is%20a%20low-stakes%20sandbox%20to%20practice%20marimo%20features%3A%0A%0A%20%20%20%20-%20Reactive%20UI%20controls%20(%60mo.ui.slider%60%2C%20%60mo.ui.radio%60)%0A%20%20%20%20-%20Layout%20(%60mo.hstack%60%2C%20%60mo.vstack%60)%0A%20%20%20%20-%20A%20simple%20MZI-style%20interference%20model%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%201)%20ASCII%20schematic%20(reactive)%0A%0A%20%20%20%20Use%20the%20slider%20to%20choose%20a%20path-length%20difference%20%CE%94L%20and%20see%20it%20reflected%20in%20the%20schematic.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20delta_length%20%3D%20mo.ui.slider(%0A%20%20%20%20%20%20%20%20start%3D0.0%2C%0A%20%20%20%20%20%20%20%20stop%3D500.0%2C%0A%20%20%20%20%20%20%20%20value%3D50.0%2C%0A%20%20%20%20%20%20%20%20step%3D5.0%2C%0A%20%20%20%20%20%20%20%20label%3D%22%CE%94L%20(%C2%B5m)%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%20(delta_length%2C)%0A%0A%0A%40app.cell%0Adef%20_(delta_length%2C%20mo)%3A%0A%20%20%20%20dl_schematic%20%3D%20float(delta_length.value)%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%60%60%60text%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20upper%20arm%20(extra%20length%20%3D%20%CE%94L%20%3D%20%7Bdl_schematic%3A.1f%7D%20%C2%B5m)%0A%20%20%20%20%20%20%20%20%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20Input%20%E2%94%80%E2%94%80%E2%96%B6%20%E2%94%82%2050%2F50%20%20%E2%94%82%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%0A%20%20%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%AC%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20short%20arm%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20Output%20%20%E2%94%8C%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%B4%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%90%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%E2%94%82%0A%20%20%20%20%20%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%96%B6%E2%94%82%2050%2F50%20%20%20%E2%94%82%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%20%20%20%20%20%20%20%20%20%20%E2%94%94%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%98%0A%20%20%20%20%60%60%60%0A%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%202)%20Simple%20spectrum%20(reactive)%0A%0A%20%20%20%20This%20is%20a%20toy%20model%20(lossless%2C%20constant%20index%20parameter)%20to%20practice%20reactive%20plotting.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20altair%20as%20alt%0A%20%20%20%20import%20polars%20as%20pl%0A%20%20%20%20return%20alt%2C%20mo%2C%20np%2C%20pl%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20y_scale%20%3D%20mo.ui.radio(%0A%20%20%20%20%20%20%20%20options%3D%5B%22Linear%22%2C%20%22Semilog%20(log%20y)%22%5D%2C%0A%20%20%20%20%20%20%20%20value%3D%22Linear%22%2C%0A%20%20%20%20%20%20%20%20label%3D%22Y%20scale%22%2C%0A%20%20%20%20)%0A%20%20%20%20center_wl%20%3D%20mo.ui.slider(%0A%20%20%20%20%20%20%20%20start%3D1.50%2C%0A%20%20%20%20%20%20%20%20stop%3D1.60%2C%0A%20%20%20%20%20%20%20%20value%3D1.55%2C%0A%20%20%20%20%20%20%20%20step%3D0.001%2C%0A%20%20%20%20%20%20%20%20label%3D%22%CE%BB0%20for%20FSR%20estimate%20(%C2%B5m)%22%2C%0A%20%20%20%20)%0A%20%20%20%20ng%20%3D%20mo.ui.slider(%0A%20%20%20%20%20%20%20%20start%3D2.0%2C%0A%20%20%20%20%20%20%20%20stop%3D5.0%2C%0A%20%20%20%20%20%20%20%20value%3D4.19%2C%0A%20%20%20%20%20%20%20%20step%3D0.01%2C%0A%20%20%20%20%20%20%20%20label%3D%22Group%20index%20ng%20(FSR%20estimate)%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%20center_wl%2C%20ng%2C%20y_scale%0A%0A%0A%40app.cell%0Adef%20_(alt%2C%20center_wl%2C%20delta_length%2C%20mo%2C%20ng%2C%20np%2C%20pl%2C%20y_scale)%3A%0A%20%20%20%20wl_min_um%20%3D%201.50%0A%20%20%20%20wl_max_um%20%3D%201.60%0A%20%20%20%20wl%20%3D%20np.linspace(wl_min_um%2C%20wl_max_um%2C%20600)%0A%0A%20%20%20%20n_index%20%3D%204.19088%0A%20%20%20%20delta_phi%20%3D%202%20*%20np.pi%20*%20n_index%20*%20delta_length.value%20%2F%20wl%0A%20%20%20%20T%20%3D%200.5%20*%20(1%20%2B%20np.cos(delta_phi))%0A%0A%20%20%20%20semilog%20%3D%20y_scale.value%20%3D%3D%20%22Semilog%20(log%20y)%22%0A%20%20%20%20log_floor%20%3D%201e-6%0A%20%20%20%20T_plot%20%3D%20np.clip(T%2C%20log_floor%2C%20None)%20if%20semilog%20else%20T%0A%0A%20%20%20%20df%20%3D%20pl.DataFrame(%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22wavelength_nm%22%3A%20wl%20*%201e3%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22T%22%3A%20T%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22T_plot%22%3A%20T_plot%2C%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20)%0A%0A%20%20%20%20y%20%3D%20alt.Y(%0A%20%20%20%20%20%20%20%20%22T_plot%3AQ%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22Through%20power%20(log)%22%20if%20semilog%20else%20%22Through%20power%22%2C%0A%20%20%20%20%20%20%20%20scale%3Dalt.Scale(type%3D%22log%22)%20if%20semilog%20else%20alt.Scale(zero%3DFalse)%2C%0A%20%20%20%20)%0A%0A%20%20%20%20chart%20%3D%20(%0A%20%20%20%20%20%20%20%20alt.Chart(df)%0A%20%20%20%20%20%20%20%20.mark_line()%0A%20%20%20%20%20%20%20%20.encode(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3Dalt.X(%22wavelength_nm%3AQ%22%2C%20title%3D%22Wavelength%20(nm)%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3Dy%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20tooltip%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alt.Tooltip(%22wavelength_nm%3AQ%22%2C%20title%3D%22Wavelength%20(nm)%22%2C%20format%3D%22.1f%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alt.Tooltip(%22T%3AQ%22%2C%20title%3D%22Through%20power%22%2C%20format%3D%22.4f%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.properties(width%3D520%2C%20height%3D260%2C%20title%3D%22Toy%20MZI%20spectrum%22)%0A%20%20%20%20%20%20%20%20.interactive()%0A%20%20%20%20)%0A%0A%20%20%20%20controls%20%3D%20mo.vstack(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20delta_length%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20r%22FSR%20rule%20of%20thumb%3A%20%24%5Cmathrm%7BFSR%7D%20%5Capprox%20%5Clambda_0%5E2%20%2F%20(n_g%5C%2C%5CDelta%20L)%24%22%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20center_wl%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ng%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y_scale%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(f%22Wavelength%20window%3A%20**%7Bwl_min_um*1e3%3A.0f%7D%E2%80%93%7Bwl_max_um*1e3%3A.0f%7D%20nm**%22)%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%0A%20%20%20%20dl_fsr%20%3D%20float(delta_length.value)%0A%20%20%20%20if%20dl_fsr%20%3E%200%3A%0A%20%20%20%20%20%20%20%20fsr_nm%20%3D%20(float(center_wl.value)%20**%202)%20%2F%20(float(ng.value)%20*%20dl_fsr)%20*%201e3%0A%20%20%20%20%20%20%20%20fsr_line%20%3D%20mo.md(f%22Estimated%20ideal%20FSR%3A%20**%7Bfsr_nm%3A.2f%7D%20nm**%22)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20fsr_line%20%3D%20mo.md(%22Estimated%20ideal%20FSR%3A%20**(%CE%94L%20%3D%200%20%E2%86%92%20no%20fringes)**%22)%0A%0A%20%20%20%20mo.vstack(%5Bfsr_line%2C%20mo.hstack(%5Bcontrols%2C%20chart%5D)%5D)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
183425e40ec36caa7d35a880b4b3bc91