From 105b4c098c0753cdc141d4964a576e9db3f5d172 Mon Sep 17 00:00:00 2001 From: Dario Antonio Quintero Dominguez Date: Mon, 17 Jul 2023 14:39:33 +0100 Subject: [PATCH] FEAT: Further documentation (#19) * FEAT: Add top level port interconnection * FEAT: Integrating further functionality * FEAT: Sorted out docs build --- .github/workflows/code_coverage.yaml | 4 + README.rst | 15 +- .../img/piel_microservice_structure.png | Bin 0 -> 491705 bytes docs/autoapi/index.rst | 11 + docs/autoapi/piel/cli/index.rst | 27 + docs/autoapi/piel/components/index.rst | 4 + docs/autoapi/piel/config/index.rst | 25 + docs/autoapi/piel/defaults/index.rst | 14 + docs/autoapi/piel/file_conversion/index.rst | 26 + docs/autoapi/piel/file_system/index.rst | 197 +++ docs/autoapi/piel/index.rst | 1395 +++++++++++++++++ .../piel/integration/cocotb_sax/index.rst | 9 + .../gdsfactory_hdl21/conversion/index.rst | 68 + .../gdsfactory_hdl21/core/index.rst | 246 +++ .../integration/gdsfactory_hdl21/index.rst | 106 ++ .../gdsfactory_hdl21/utils/index.rst | 29 + .../integration/gdsfactory_openlane/index.rst | 45 + docs/autoapi/piel/integration/index.rst | 341 ++++ .../piel/integration/sax_qutip/index.rst | 93 ++ .../piel/integration/sax_thewalrus/index.rst | 49 + .../piel/models/frequency/all/index.rst | 28 + .../piel/models/frequency/defaults/index.rst | 28 + .../models/frequency/electrical/index.rst | 4 + .../frequency/electro_optic/ideal/index.rst | 20 + .../models/frequency/electro_optic/index.rst | 13 + .../models/frequency/electronic/index.rst | 4 + docs/autoapi/piel/models/frequency/index.rst | 76 + .../frequency/opto_electronic/index.rst | 4 + .../photonic/coupler_simple/index.rst | 25 + .../directional_coupler_length/index.rst | 25 + .../directional_coupler_real/index.rst | 8 + .../directional_coupler_simple/index.rst | 25 + .../photonic/grating_coupler/index.rst | 25 + .../piel/models/frequency/photonic/index.rst | 68 + .../frequency/photonic/mmi1x2/index.rst | 25 + .../frequency/photonic/mmi2x2/index.rst | 25 + .../photonic/straight_waveguide/index.rst | 33 + .../piel/models/frequency/utils/index.rst | 28 + docs/autoapi/piel/models/index.rst | 25 + .../piel/models/logic/electrical/index.rst | 4 + .../piel/models/logic/electro_optic/index.rst | 68 + .../electro_optic/signal_mapping/index.rst | 80 + .../piel/models/logic/electronic/index.rst | 4 + docs/autoapi/piel/models/logic/index.rst | 17 + .../models/logic/opto_electronic/index.rst | 4 + .../piel/models/logic/photonic/index.rst | 4 + .../physical/electrical/cable/index.rst | 4 + .../piel/models/physical/electrical/index.rst | 13 + .../electro_optic/basic_heater/index.rst | 22 + .../models/physical/electro_optic/index.rst | 13 + .../physical/electronic/capacitor/index.rst | 51 + .../physical/electronic/defaults/index.rst | 28 + .../piel/models/physical/electronic/index.rst | 67 + .../physical/electronic/resistor/index.rst | 33 + .../physical/electronic/straight/index.rst | 36 + .../physical/electronic/taper/index.rst | 34 + .../physical/electronic/via_stack/index.rst | 34 + .../piel/models/physical/geometry/index.rst | 28 + docs/autoapi/piel/models/physical/index.rst | 66 + .../models/physical/opto_electronic/index.rst | 4 + .../piel/models/physical/photonic/index.rst | 4 + .../piel/models/physical/thermal/index.rst | 20 + .../piel/models/physical/units/index.rst | 30 + .../models/transient/electrical/index.rst | 4 + .../models/transient/electro_optic/index.rst | 4 + .../models/transient/electronic/index.rst | 4 + docs/autoapi/piel/models/transient/index.rst | 17 + .../transient/opto_electronic/index.rst | 4 + .../piel/models/transient/photonic/index.rst | 4 + docs/autoapi/piel/models/utils/index.rst | 4 + docs/autoapi/piel/parametric/index.rst | 66 + docs/autoapi/piel/project_structure/index.rst | 44 + docs/autoapi/piel/tools/cocotb/core/index.rst | 118 ++ docs/autoapi/piel/tools/cocotb/data/index.rst | 61 + docs/autoapi/piel/tools/cocotb/index.rst | 146 ++ docs/autoapi/piel/tools/gdsfactory/index.rst | 100 ++ .../piel/tools/gdsfactory/netlist/index.rst | 91 ++ .../piel/tools/hdl21/circuit/index.rst | 22 + docs/autoapi/piel/tools/hdl21/index.rst | 33 + .../piel/tools/hdl21/simulator/index.rst | 22 + docs/autoapi/piel/tools/hdl21/units/index.rst | 39 + docs/autoapi/piel/tools/index.rst | 797 ++++++++++ docs/autoapi/piel/tools/openlane/index.rst | 468 ++++++ .../piel/tools/openlane/migrate/index.rst | 40 + .../piel/tools/openlane/parse/index.rst | 287 ++++ .../tools/openlane/parse/sta_rpt/index.rst | 167 ++ .../piel/tools/openlane/parse/utils/index.rst | 70 + .../piel/tools/openlane/utils/index.rst | 26 + docs/autoapi/piel/tools/openlane/v1/index.rst | 157 ++ docs/autoapi/piel/tools/openlane/v2/index.rst | 29 + docs/autoapi/piel/tools/sax/index.rst | 168 ++ docs/autoapi/piel/tools/sax/utils/index.rst | 164 ++ .../piel/visual/auto_plot_multiple/index.rst | 41 + .../piel/visual/data_conversion/index.rst | 70 + docs/autoapi/piel/visual/index.rst | 105 ++ docs/examples/04_spice_cosimulation.py | 92 +- docs/sections/about/motivation.md | 2 + docs/sections/models/spice_integration.rst | 1 + .../gdsfactory_hdl21/conversion.py | 28 +- piel/integration/gdsfactory_hdl21/core.py | 38 +- piel/tools/hdl21/__init__.py | 1 + piel/tools/hdl21/simulator.py | 22 + piel/tools/hdl21/units.py | 67 +- setup.py | 1 + tests/tools/__init__.py | 0 tests/tools/gdsfactory/__init__.py | 1 - tests/tools/sax/__init__.py | 0 tests/tools/test_hdl21.py | 7 + 108 files changed, 7412 insertions(+), 81 deletions(-) create mode 100644 .github/workflows/code_coverage.yaml create mode 100644 docs/_static/img/piel_microservice_structure.png create mode 100644 docs/autoapi/index.rst create mode 100644 docs/autoapi/piel/cli/index.rst create mode 100644 docs/autoapi/piel/components/index.rst create mode 100644 docs/autoapi/piel/config/index.rst create mode 100644 docs/autoapi/piel/defaults/index.rst create mode 100644 docs/autoapi/piel/file_conversion/index.rst create mode 100644 docs/autoapi/piel/file_system/index.rst create mode 100644 docs/autoapi/piel/index.rst create mode 100644 docs/autoapi/piel/integration/cocotb_sax/index.rst create mode 100644 docs/autoapi/piel/integration/gdsfactory_hdl21/conversion/index.rst create mode 100644 docs/autoapi/piel/integration/gdsfactory_hdl21/core/index.rst create mode 100644 docs/autoapi/piel/integration/gdsfactory_hdl21/index.rst create mode 100644 docs/autoapi/piel/integration/gdsfactory_hdl21/utils/index.rst create mode 100644 docs/autoapi/piel/integration/gdsfactory_openlane/index.rst create mode 100644 docs/autoapi/piel/integration/index.rst create mode 100644 docs/autoapi/piel/integration/sax_qutip/index.rst create mode 100644 docs/autoapi/piel/integration/sax_thewalrus/index.rst create mode 100644 docs/autoapi/piel/models/frequency/all/index.rst create mode 100644 docs/autoapi/piel/models/frequency/defaults/index.rst create mode 100644 docs/autoapi/piel/models/frequency/electrical/index.rst create mode 100644 docs/autoapi/piel/models/frequency/electro_optic/ideal/index.rst create mode 100644 docs/autoapi/piel/models/frequency/electro_optic/index.rst create mode 100644 docs/autoapi/piel/models/frequency/electronic/index.rst create mode 100644 docs/autoapi/piel/models/frequency/index.rst create mode 100644 docs/autoapi/piel/models/frequency/opto_electronic/index.rst create mode 100644 docs/autoapi/piel/models/frequency/photonic/coupler_simple/index.rst create mode 100644 docs/autoapi/piel/models/frequency/photonic/directional_coupler_length/index.rst create mode 100644 docs/autoapi/piel/models/frequency/photonic/directional_coupler_real/index.rst create mode 100644 docs/autoapi/piel/models/frequency/photonic/directional_coupler_simple/index.rst create mode 100644 docs/autoapi/piel/models/frequency/photonic/grating_coupler/index.rst create mode 100644 docs/autoapi/piel/models/frequency/photonic/index.rst create mode 100644 docs/autoapi/piel/models/frequency/photonic/mmi1x2/index.rst create mode 100644 docs/autoapi/piel/models/frequency/photonic/mmi2x2/index.rst create mode 100644 docs/autoapi/piel/models/frequency/photonic/straight_waveguide/index.rst create mode 100644 docs/autoapi/piel/models/frequency/utils/index.rst create mode 100644 docs/autoapi/piel/models/index.rst create mode 100644 docs/autoapi/piel/models/logic/electrical/index.rst create mode 100644 docs/autoapi/piel/models/logic/electro_optic/index.rst create mode 100644 docs/autoapi/piel/models/logic/electro_optic/signal_mapping/index.rst create mode 100644 docs/autoapi/piel/models/logic/electronic/index.rst create mode 100644 docs/autoapi/piel/models/logic/index.rst create mode 100644 docs/autoapi/piel/models/logic/opto_electronic/index.rst create mode 100644 docs/autoapi/piel/models/logic/photonic/index.rst create mode 100644 docs/autoapi/piel/models/physical/electrical/cable/index.rst create mode 100644 docs/autoapi/piel/models/physical/electrical/index.rst create mode 100644 docs/autoapi/piel/models/physical/electro_optic/basic_heater/index.rst create mode 100644 docs/autoapi/piel/models/physical/electro_optic/index.rst create mode 100644 docs/autoapi/piel/models/physical/electronic/capacitor/index.rst create mode 100644 docs/autoapi/piel/models/physical/electronic/defaults/index.rst create mode 100644 docs/autoapi/piel/models/physical/electronic/index.rst create mode 100644 docs/autoapi/piel/models/physical/electronic/resistor/index.rst create mode 100644 docs/autoapi/piel/models/physical/electronic/straight/index.rst create mode 100644 docs/autoapi/piel/models/physical/electronic/taper/index.rst create mode 100644 docs/autoapi/piel/models/physical/electronic/via_stack/index.rst create mode 100644 docs/autoapi/piel/models/physical/geometry/index.rst create mode 100644 docs/autoapi/piel/models/physical/index.rst create mode 100644 docs/autoapi/piel/models/physical/opto_electronic/index.rst create mode 100644 docs/autoapi/piel/models/physical/photonic/index.rst create mode 100644 docs/autoapi/piel/models/physical/thermal/index.rst create mode 100644 docs/autoapi/piel/models/physical/units/index.rst create mode 100644 docs/autoapi/piel/models/transient/electrical/index.rst create mode 100644 docs/autoapi/piel/models/transient/electro_optic/index.rst create mode 100644 docs/autoapi/piel/models/transient/electronic/index.rst create mode 100644 docs/autoapi/piel/models/transient/index.rst create mode 100644 docs/autoapi/piel/models/transient/opto_electronic/index.rst create mode 100644 docs/autoapi/piel/models/transient/photonic/index.rst create mode 100644 docs/autoapi/piel/models/utils/index.rst create mode 100644 docs/autoapi/piel/parametric/index.rst create mode 100644 docs/autoapi/piel/project_structure/index.rst create mode 100644 docs/autoapi/piel/tools/cocotb/core/index.rst create mode 100644 docs/autoapi/piel/tools/cocotb/data/index.rst create mode 100644 docs/autoapi/piel/tools/cocotb/index.rst create mode 100644 docs/autoapi/piel/tools/gdsfactory/index.rst create mode 100644 docs/autoapi/piel/tools/gdsfactory/netlist/index.rst create mode 100644 docs/autoapi/piel/tools/hdl21/circuit/index.rst create mode 100644 docs/autoapi/piel/tools/hdl21/index.rst create mode 100644 docs/autoapi/piel/tools/hdl21/simulator/index.rst create mode 100644 docs/autoapi/piel/tools/hdl21/units/index.rst create mode 100644 docs/autoapi/piel/tools/index.rst create mode 100644 docs/autoapi/piel/tools/openlane/index.rst create mode 100644 docs/autoapi/piel/tools/openlane/migrate/index.rst create mode 100644 docs/autoapi/piel/tools/openlane/parse/index.rst create mode 100644 docs/autoapi/piel/tools/openlane/parse/sta_rpt/index.rst create mode 100644 docs/autoapi/piel/tools/openlane/parse/utils/index.rst create mode 100644 docs/autoapi/piel/tools/openlane/utils/index.rst create mode 100644 docs/autoapi/piel/tools/openlane/v1/index.rst create mode 100644 docs/autoapi/piel/tools/openlane/v2/index.rst create mode 100644 docs/autoapi/piel/tools/sax/index.rst create mode 100644 docs/autoapi/piel/tools/sax/utils/index.rst create mode 100644 docs/autoapi/piel/visual/auto_plot_multiple/index.rst create mode 100644 docs/autoapi/piel/visual/data_conversion/index.rst create mode 100644 docs/autoapi/piel/visual/index.rst delete mode 100644 tests/tools/__init__.py delete mode 100644 tests/tools/gdsfactory/__init__.py delete mode 100644 tests/tools/sax/__init__.py create mode 100644 tests/tools/test_hdl21.py diff --git a/.github/workflows/code_coverage.yaml b/.github/workflows/code_coverage.yaml new file mode 100644 index 00000000..e420c7d4 --- /dev/null +++ b/.github/workflows/code_coverage.yaml @@ -0,0 +1,4 @@ +- name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/README.rst b/README.rst index 5b34168a..ddb1159b 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ **P**\hotonic **I**\ntegrated **EL**\ectronics =============================================== -|PyPI Version| |Build Status| |Documentation Status| |Updates| +|PyPI Name| |PyPI Version| |Build Status| |Documentation Status| |MIT| |Black| Microservices to codesign photonics, electronics, communications, quantum, and more. @@ -37,6 +37,8 @@ microelectronics through the functionality of the `IIC-OSIC-TOOLS `__ and photonics via `GDSFactory `__. +.. image:: docs/_static/img/piel_microservice_structure.png + Some existing microservice dependency integrations are: * `cocotb `__ - a coroutine based cosimulation library for writing VHDL and Verilog testbenches in Python. @@ -53,11 +55,18 @@ Contribution If you feel dedicated enough to become a project maintainer, or just want to do a single contribution, let's do this together! -.. |PyPI Version| image:: https://img.shields.io/pypi/v/piel.svg - :target: https://pypi.python.org/pypi/piel + +.. |Black| image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black .. |Build Status| image:: https://img.shields.io/travis/daquintero/piel.svg :target: https://travis-ci.com/daquintero/piel .. |Documentation Status| image:: https://readthedocs.org/projects/piel/badge/?version=latest :target: https://piel.readthedocs.io/en/latest/?version=latest +.. |MIT| image:: https://img.shields.io/github/license/gdsfactory/gdsfactory + :target: https://choosealicense.com/licenses/mit/ +.. |PyPI Name| image:: https://img.shields.io/badge/pypi-piel-blue + :target: https://pypi.python.org/pypi/piel +.. |PyPI Version| image:: https://img.shields.io/pypi/v/piel.svg + :target: https://pypi.python.org/pypi/piel .. |Updates| image:: https://pyup.io/repos/github/daquintero/piel/shield.svg :target: https://pyup.io/repos/github/daquintero/piel/ diff --git a/docs/_static/img/piel_microservice_structure.png b/docs/_static/img/piel_microservice_structure.png new file mode 100644 index 0000000000000000000000000000000000000000..dd5fe31e30dedde358931921e4be533e26cb3430 GIT binary patch literal 491705 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%0DitpE)`{Nr$aDHPMaAp*w%Mm zADTX5^18awUvj@|Fn@o-kQg@JKnsXjR_dQ@6owo1K6$5E}N^C1vKrL;Z zC9!HRXcf6{$<^k*{S7}~I~u=nz0*n!^e16maz4t>BAE^$yQMn$|CrAPk6Tk^ ~H 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°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

ju= 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±^2;)AVRAP&>t(+>$iH*l{=4QO`GlWQ0m`L9dju%TLl4fHNj6`_G z9w4k4c1LCwLb4NL%g!4HW3`m$OfpKnDC=ori#2&A3Yd4wZPcrXs~H%@bY;MT1Ed?Os9m|4P%2^UEGMEFbduE=EtYEeI%Dg7Fwr z+*JuGjVzYsifxL7Y5-%WsZw~aOR_|2mD4tGBg8^K{&UYs9(eHo`Dm0YHvq`T!;kS z>rQ9Rezx#7H8n{Xn+^*RA$jT?Z7bW^u{H<4hkv*+-mTARlu!ASJ0hCZBU^c_$qj5S zP3kWaFYSjo(fi`F$SIB7mO$O4`m)wla>WF1lT%y6hOwp>*RnZ&N#AoNR7Z&nDdwAb z%b`HG#M3bavq{3iz(QJ~Gd8H!nj$@hY`@S`w1%o4xv{bh1`t}$} zuYB+yIe%}5lm)vGvZwM<^t7OQ7+6Wvmb0QZ9z*PbPj*rUr}Uu~FSdfCpaMm@&QcoE zE}?sSE?Vr1?&foR?<$1)LS;iBmEY(+aRufIr*Z49!9v0lHr zr+T7+)aIAKkH{uTJNc-m)1fu%zN;L(klM%qS-f@oNpt!p~#Ck!cgQ*GDADZ8SJ>}x8Ed^cgLlZX56@< zr2}A-RB1IUL+#zNVLEGG0p|&Vl0K_``>TkJ?g)d*Zl|IB15>4WvnN@n~1 zPz@0aw=Vw%6tT7j>Wxr1&%_8Qth{^T|De{+cTSeGr*IKZE|-~P?~$pnfal(7{}Qcq z5$^3ZHH}o`K30dZ6J{3U?_6zDqYH2pwVIV-ZO1_3wlQ>lt$7km;-)SBn*!Sn-Hl)* zzXs9^bW&Utz+sj{>9{GRtBI2o@!d%lS<{GeC#Z&lR{nFXiwT-Q<}y`wv|?wd-zV#s zCc23^iPCeERz*37*lqCxmcdXS&04-~|2bN-oAr5Wl!8ShX+O@7jdAqgD$B!O2NQL( z7jYaoC+l!#lVjDz0AZK8ytonO6bB!Uo3s}{N@NlHw(4LWry#1Qr-yYe!gI=J z%BfxkP^rY2dNVl%&zhH;5=jfELYT^MiK*iU3M=$C%vF$MLz z^i;eVIu_`JV~x3z8p%Sni-V8MdE1w+uBaD2*_{=h^PVUF6T3%%UnMlF5*|pPJX^kOKgaiwE%h`x;7}mDYuLPTgK*Ye1Qp=`;6ew za)VoP6MpxwE+|*3Y+ZlFxn>``)cy|MvLakJtODd)t&pOb+s0n7->Ix`-pHS0fA>*= zDnNSvbuQcPg5;areO_;s;L8ypW^|czt>emh6R(*6Zspa+)^2&&T0x`p8&Ixw9lnqfaBy({1#~al}I$87JxA!}2|5?i8z_-hT%B z^Q+L;>D>sGm+J}HVGxn=nK^XIniVfp{Xik63&S@ z@6#uq0SLd!cGcH6`7ejr8~i5E-j}+=dPfQ{v*<|P?e5}(XT3{em*DY_OL$AYhR3IIWb+UW*VLw^s@bh$C z-_wkRxl@6ngTzH}SRlPdQ0Sw*pIwgJ)W{E8ZJ3BiQgKw5FpAdvCPP6~!eP<5=#rk? zn2OPV@(GvyI&RVt)eye7KN=$8(yZKPjbl8R$Zc)^HU)nmYK-&OAAZHfh^>6Rp5Y-t zYI`@O!Qj3dYbaI!sKro}Z{=q;gH7}L^&-~S`dfM9+u-kYX}Vtnwr~Iei*iu0LuP#F zBD|vr$nmBo`)*BfK_Pal-jy_C$@LlzN1y}TxC-{_1m#L}SIQUu*q`&g=6n{`kS&_g z%9&YT#=6TJ-!*}0o2dW}B{0dl5sZ8h>(|FbLwk#cj?w5m-<=Xjuh9cv>I& zZ)7O&;w=Tg>~QUNoA>od-RH(MGVBwtdvrNm8^<7TyRM~qeoX6rlzX(-s2RjPwm_S) zCrs8x|HAYNvnG}k-`oKe64gkPz(kY8T3Usy-Ck-`WX6hfmF5k2k*T)%O)===H|6>m zTAo?xnck$Dz~anqCCF*0301pzKP0Dgj=7`=LN9LyaKqD1pyhAbaxQ7(8}Ezo#>-YINmpL=eDq+@Y?L zuLd6Iy?w?> zIMRvnur{{afdr`ODrw*{YI1%Qa<{=E^FDq8u`r--Z7-R<{x>E~*`rL{392`a=Fy9A z7f-tjupCIssKhP~1b=vb`?m{Ypa3ccl(f*nJ(v7r9eT3Ke-cnqQcAPw>Fr%z#*xZ_ z!9GVsLr-e{gwAV3tVH!_CnqQG=AR?|=;|>Rnb4~!K;R~2KeFmoGsmONHcSS-oV30SaH>z{^yBo4Rpo;x}NgLB9q(Jp! zS2@^}>y&do5HemTo+Kwsb2iIw*nNh|fM?u>+3@ttL{&o68~r4Ov!FP8HnB|Ri`>hk zU}f@*0wpk10x&4~t0qQ88L&G~1MPHM5@adAthE;vH;yf~+5Jf0^9T;sz+Bq4mIIU=Ic*id3#vlvJeT*Cw4 zzMRQ52F2>=NHE8u?JUV;WP^NX75X$>*U1U#eKSLElNj^+>O+k8%nvCZD>bkTzUV-Xlvhh1 zd0&#Eru*HuDw(@Y9lPl*j+=JmZnbdSAv4lh`X-dH1*;IE!8DT?{^3dzxh6a5(xrK?CUY8{dJ5MW|G9{T#~*Tp6x!u{ z&~$Zr_Tfq_84NRc=hW$BBE%d$HRjl{=+VK>cXFFYwqxHC@Rxhz5!n*Ky03oN1s6Kv zwTsmi&Rx+VM&t3)Uw5ap?Z<)eOV;|vHU4Yn12#1m1!0$M#DT}7-#=gU*1=yf1s9F0 z8KrsQ867UP?`#l-RSPq?=h;d^!I}&?CyTnlfJtxo=P=Q~0bbA*QI;e8Mvyd_s#e?~ zLOdDvJ6vFo`H~ugA-M&rZ<~L<5lBN5>N1l5fg8hl%|??nPGl)kRWBR++`IT+eEJWP z8{^8nJX)(4kaf&N3N!ku>b-K*Kf(TDx_+`y$6l<>tC6>o{qJ!%H9OF z-9{0FUj{z}H(W}YqBob33SV=CTq$&pAsZ_{|I>F=8%h)z8T`_`%x%w8e8vJ|2g04Y zlij{O>&Bp8GS3F$drm3(P1t32Wa(vr{MldAlcyrx@%|#PL`f^DfDByqzI^D4IKO2! ze^cLEmdK3cvYkHbua;xkjREmidLKE2O8WL2Ubq2{Yl>d>B&}Ih!TA*GVDKxqITJ>$ z%VKeW-%|Yeor`O0WRBSk?BB-|-=2(Gh&ASkx*3V|g<0vN8IwwO3@~WTYV=ZA)qbr< zT3JTe|j!UuRAPr05n8m$CT8*v7 z1eV8$Z5BP&>(HE%nK6t)CiJXiNg3MG11CF2LiBT_k4hf^rc)!iSeqrwWWj-gy|wZqC23)e8Kg~4>FOx zj`d-(?a`fr#?{}TF6;2)ypKJFV46*=rec?j$mx1EPMqNw#~p)A;qRm)iBr+jn8c(& z$b(tV@m`|PgClTut6F|(`TauqQ4j2YctPARb2e621D>|I(NY`#Dv)QJPa24VaSt4u z!QcX(y-Kw7IO*LZD!0f!6op0n08v~FrSXvt_UBx0YuA8K^T5)VH(setF_4#3NYPu2 zT>Io*HY&Kto8L}G^xa8ElrY?XqpRWE>C;}V;$}PNBl@S0@l;~jHgZR$F+Sey*xgx- zGDE}Jt}Gb{my>Vu5)TeS6&7VV=$yLzIX8m?5ylzxJj>(36;vNQR4H=`60 zE})5wwE1~X=iL*pp847BN9{TE&-VIx@Cn;;(+0v*z^B-!&EB}tZoB?lIbZkLGOY;9 zeeU^tc5)Ud1B5}4kQ^z-A!(+>GLLbkJ9Pz~yUFWrxI~26aiBj`hAlF|FaC5aZJQ_9 zzbf~tT)D&*n55J9LMrp|7+H*p$SD&fu%Kch?akdrjeHtgXY7jwM-$;t8Nw9bC6zw8 zDfV3Y@;tekEFglD50PdV0AN`Ile9Axesb(#RZagau)!co%oa9CFfoh&$jOciJ>8Y{ z#QyB-ROd-sn&Ag~*;+gHV5<)j>CWKoim<lZS?wy4PVH!X@C>iU)n=Z6A zc_6=Mcy$kmB5Pxc%M&4uF*0?5T}D-AK|5@9c=h*Gm=`WcVEj0xqxDfofa1Rd4AujK zw^8ZZU(NQ1?JuTY$X@dFns7b5!+NS=@p{DHi@R}If1p$=N$lXix!?SK->qS{hukG& zV}HtF;|s!WS{#0r5t%&1jy3g`UwkT--5Ry2gNlc@t87qs%q7rJ?meeZ$$}v)o!;13 z*!2}7wTB{sO5e-tqMyXQXc-3Ok33ul?%LPiioW(o>a_TFLtGfDZ$%t%)JQ_RfB;Zk zYRq5-6_=E8#z(rYv{=X2ort8`EBH zUd*}(p@qNgo+R#Rej~@fUfLkC_8Lh0?0m|QqFNXhov+*mWmCjktL^UgFtuI*$goCI zuf0C!Hs8ivL1=*OjPb$9sqA(?pIyyZ$>!I)Wdlq8DeI7TTvi@8&MpogY)$RiUy02s?{okb{cGOi=w zXtYP>Xn;en7N9ehp(36yqq+xE2Xg-ouUU{>J836t<8R(+wf|#7zm+tPMs_7v8@ix1 zW8Ihsq`sIzIm%#y*|{`^;nvI0bd(`?4`o<@!1nCB*{B5MTq9bp!X&?Lk(A zHjLeg#hFD#rNad-I?Yz^g*CA)Gq@<*75!4%9B77>G>v1H>0*gll8=RL@VANmgKvvX z7#50{vE}tEUpYITB+BAqBt-NolTO~`hLNZEuo^kO!90`#V4qt^gDW)<4T`!M^I3=? z@S`?u75I%~O7tVd{+79NYycQ{`vV+z0SofySy@WcS6IN7Fup(T2O{hj%GX8&FBt9{ zJ03xNB*2Ty>B-2r9V*ip>3XYRT<7+!FmW1x?3NI=z7elh$tAJS(}I<(u!Dz139C=3 zVe|=39d)jl)lrqX&$5nPogRPVLJg0wexMB+-K9CNd@Q_|P$q{k=v29K&w07D_L+_I zCfBkcKj6mLZ5w8CK2GLCZ|wPQ+4}XQd^Umxy^E|*LCbU(yz$QReGCToRh-;sB!h!M zYHw_=fhJsmLt8<0D``r@{)0f)#|3{kJ5cTcFM0Shn@X=DL34BQD=q;ctnJ<>E|;bI zW+hKwHhL)9Gi|%i%Uu9{XVw*zZRBW0_?$(jo3u$c7_EE2j5<=zL$`c(_JMTY;|{0;$JzF!5BvhuM?9o!fu8SO}(21YAM4P1d$ zeo9E1z3=~PN9Rct?!)RGMuNmu!8QMc6%{@AX8Kp(iWBjfq+>l38ynl*{7($XOGztg zzloKM1hKP$k&qLe3U12f$X7pd-#IY%{tI;dQ}iS-omK)!SGqsHVYy0~tcz!mGJZMW zX8C$fD#9tfViq; z!Q`|?f7t3_RY6Awb-Vye?d))0k+Tf2aWs|5gB`Rs6>h>7NO_9>u{{9(+EsDkCpcBD zgmbV_ZBSD5+4($rDz4%ubdFBcF`o#N9Q#5x9o)Q~COzc+WJ;(b|0|mdq0FHgVQA5S zLQB*UMX$+yN4fXNRGw!^-&~j>^$VO3X&JJu=TSJ2NQ}KiSW`CQ{Y{V(t*-3vH{kA) z7SxWK5sOz%4JXPC?-Zn?E&3+O1udM(Mpj1~6R(~9Fe$c0>LpPH{rfouxVCkU#Iy60 zLt^|#sR!QAr-EukJdweCZESawp0XFz_l;aD6t8t;+Ot-~!qlV7H?Dvp71GEgGb-$+ z>E&12_s@^=%iz4#4-D=u6lrFnN4jg(Uw^S}#Eln`7hN3x+eL)$=^t-Mv*Q3X1_d?R z<6c81^NYMf0>=_{WruyYcjgm6)8Q=d^GC!clx9CzVD=-{-Ti`xMn?)oNK5TgjIsk% zj9C4|o_j~0S!U6XhA-@|LX%j=1l;4U@L@_+z@f zGaNZp{4`Z@+#@{kv}Ae+XWLGpTG>k6O$W*h%M0af6N zM40FxV#u>XiV?gTR>WcTcKq8l*fmW+Rb+7=*5dRuiEdr$h@=0}N`b?2cXxMH3&Oy~ zoxYwuIdOQf37uhdAF^+ZahRdDupOxOvp&3|jsnsHp*k&!|i*QVjek8zbMqYMtL@IJ=@Jc2Nt z=`_vF9|XJ#8?KqwPG5XG3}9EewD^-46Y`J?@K2;6A)11y4Pi&0Z*R+^aHlqgHQS(E zv!PQSr}!&$AS4TSB&{3GC4_K)ofP(ziUcwzaw4EMiNuam_%6?_@y20nJf`Cepp?j>1ibn649ZJ-0QgCEtTwvG# zU`$8H+(}%Z|1c`8@#TuY%Vsy~WWuMT6=2+ftJEj3Gk)fctmez`O@12LkNg4fo_UGx zQpO_qudE1DG@V*;#}36Owhv*(vlM+w`qQM%9Tf!1vukDGV7x{HOhJ;`zx0Q70zbG# zuHS`YVa2JIVGPxaZvvf?rWnh$4HRX&6Q5~Frlh*_cycg?pdHd7naUYmwrK6q;NGHA z|H<PLR)W=@vLJSkt`lOa|KXnWhuOvbZ~q+R)m z1gJA>uWop0jT`|qTUdauhWmw2Hj-OHL13CR$yQw3Z^Jnd*(J*0$O?GRwHm}1Ted#i zqf$EHUa`!oCiBJIZJf2cVp+ACTMeC>-ug`7Y*@)@la^}A2zAv%INrJHOspG1SWUo) zx+7EgEy?&Bc1m-i#Xhx<*4hJ^Kf0w~HeP9bRcFtQkf)3SGWE`>7I2U>*{+LGyc*ow z>~T|WOWP^=Km7G2E23yKl-~K$wo~joNY;`A!4GAU?#lghrcANv|I8n|aA9xeR0Sb2 z9Q035M<_1vLEw$$3Mpk}QNXlq*o1_@1-@kvqmb1=< z!TcfidnMo2=fPT9$F@FfBx$x7+qh#-G~Yn?2sAPxxRf1aM@mp~)YFYLY% z$xS`_GiY%sx2U6V1?6C8@O_%xQRald^h+V?O#@NB?I_ z;geXcEx|t}G;+_AnD+BLPkit*29@xu^c`o$m?=}q0GYWi+f$|as;ugDDnrifo0_x8 zEpHarBAf|*PrZo>?mojxyuz`MKo1Bh(%WZa3q&XL^uDAoo_c9oHaTnf+nsNRl6w?P z+XdcWa$lDheI3F!A`nm|0FoS1JLX=OE&B#J=AyIRv5HcILqF>RO2Te1}^Vb%tsz zT&ITmsNDQ?+D5^(N_x{lQ)a`fxUm7f2u4h%3`8~5SQ%kSw!k}h(HYc~`r|oA4FUxX zHOkv?xjnqNx5w6F0-zJV!9H#@H){5w1(BjCh z!uxA9^Vlw?<|+cuZ4A~yJ|fE6M43EdbUz!~(#*07D5Q$todyS(IAbjdb>u!DZubJ( zI|`O{Y0c`1Au|^m;$5J#6=OSJ^@Ognn@w;lCv6q6A-y$6!?Mc%!>O&W2A zS&$dB%SBfa6=*)mF_&nmf9L)nLsx~RFQ*&vYZNZl@3*}GON=5}^~>myF$HjDO@!;y zIKfP?KNtoaT43AD2;^fOnPDcZR<15*71j*xC>vVXU<%d%!LPTUFqiJ^>VWdWNuM+t z>Msa3h%JTLqjUuy4Q>^B>EC|<2#u*iU(k2X!_aX!-K*uht*P}(ztHz+CT?@LRqUZx277d!#Q0I#B3k^=f z%4cJVqlt%MjYECU)hFK?Da^p%S={su*=LnH&~@*%vz;E-YFgRz^QQN@Rzc16%oh&8 z9`8sJLXzAlSPd4@V`YOs4Olc#+8tcH*r^mEYbYc7uGbrz?VQequMYVn<=-T+87a+h zx9A5`%C5<2j!XheaesdI;Eg<9sm zn!EVvnI@3|o7j%*1fwa@T9+=T{HDEX^XRo;KRdM!4nyN^Yq zt|!Yv1U`|l^FC5ZK^(xAUw^HvwTt4^_@GTVsNms9h~XGgc4@@G=*T~JSuy&Brob*y zl8$h^Sw1;3YwTob*qQqO9Jj?+@e`Z#CZTX5M;VpkztA}}c2VUp^^cl&$j$oI|D#eb zLdO|s_I*!Q1~0JWs548WevlGav3ZqaO>RT!j=(qTlhSu)cQ_XXI0WV` z_PETRbNRo1yble@PK$#up0{qwO-6%34HdSSJrH2Bceuf`La>I?yw<>80?tLJ3uF zXR_=n^lo3rcrtF+aVsUB|Av$IeZnhzDo&y6w~+e&p2n3)>64 zh>X@!j7Us1dWpqV?c6%Xf$BB;N!2j@q4AuviPzkB_)=qKSX;hA?EUj;;Fm;+%*Q&D z*)Fg=F!A{2Dzu9knRDkbMVc)79RI~Q3Ld9auNTU&t5J#v9>xK*{4-O`)KQ}3-i*t@ zeOaHAQU1sX`LkuBhQhzFoA{Oy0|EzE@Y4K!OV~7Ay|)G&-G|Ic=#XM=-qZVWDzMdp z%f@uhQ!8?0!Crgz$YwBDKjECF7B%&IWz8Lg_|L5T_DH0Jq-}0i7x|0osB{YsL{1NE zE)>mB%2vadn?AhrMc8M^{Z!9Trq#e0z$Au@jEY&xq6JorYex1zb z{nd>mCwG^F{L_O%Dx~H4bM9Y<|%( zohcN`fUUIH6BN>N-eM#-btM1F_=P`Q8k{@q{_y#E5KeN$uYCkt8!BIPIMpjtF;-O( z5g+BT8IzjYT6H8biv}E($(|lWt4Iaq9M5Bqv>win1dpG-ieNl?O1n6H;T@Z-rUF0D z5qRJgn=WEVJd)D|vmbA(Lv%xhni;Iz?&eK0dpnmMbKREFF`oV<%idfKB=rgoZq(;d z7T;2T6ZuI%YEcrYw0?{fdVGc(;3R8oJs@NrLN(#Ox#w{~AJ|3Xh+7 z8!PM@=d|6fymj$Typ4;K7#{o8FMJoDtrES7nos3b%>ft8MAesV`dkb?4u!Hp`mP<% zrR&8}dHd;$Tc0JELqFCI@xI|pT`%hu_t?=mLGCx0R9yWco*#uUGjJEH`Gq82T)sg) zBIl01>eD&cm{bhnh(J+sxSp?#>dR07$3o3MMxqsxNVM|hXZHo)yN-mMbWQp6cs|x2~U}#%ngR?tpApS5N0g3~)9(MGu zhO$DNr}0n~TB0+8^jXTs0~45Uu8M@l8bk7G>r;~~gbxzF^|Q@JV_qyq2Jmi@MIInG z(Ux0Fj<4g+)VczoQH;d;MW~ci+*46NK*APsLYjDp6n;+knvZp`&+gI00?)^6Zz+#Zs=ay;n&1ZKfF9E@KsJdVo>Heb9Tpz$->|O$4?<3 zYmBm#_t%}iMIiEJ9$gqXzz}a|Jeylm?4sigfV}2*`_;uxiw>W_oOpFSAjKJg!Xi62 zM31jTaiqB|Bv&BJ$Y&TTK#h+^o8Po%@j|d3s?s7W*S6r7b*><4xTse@V6jS{CJ?8r zf{2^tKEvIX8Z4grBa5Zk`--m9QCt;Qr1*hw;Lez0F?32>0KV z*xG$8fS|zTP_f8!X3U`!&pGe7@K@lgu&7_N%X9tj-&E|2j!t`&$6~Q~-goJ|7&L^3 z#c$VgadpjYZ_m8l=m{%R!^tu%kTFiJzhGA%tO((s&Wt}1q3)P$EGaD=7${*lJ4p#P zFLa?^fabQn^NLoS&2Jk#(Og|zohzWf^-AEMu47sAYv!3~+|#Fc!LTCXOxKQCQfB=- zS8QWa5V>}nLud&7#wWLZq@@3xq|38Zjs%~yK_^8i?Q2=l5Kk`QDP8is{w>@zHWzf^ zJ~sS84{Oo{L&FzcFy)fwLZ^ND3=ei22+zMAHC&)gEG}?SDs7NsA}XTcf356{Su@Ci z$8Ya|q7h`ajTzP!eL+M!WT>z=+5fwnxVM!SE_y>o813D0xp4H3i`~P_$A_L64>O2jaSR$U)Pte8F8z!ieR-a#x3% znAX8{zIOCg_#tdH0`Cj5yL@i)@4$YreS%!}bESp(A<(5t>i*VO>y<$l^!5^A z?jr(LF>dW_FSFL%c8E7|wE*I|;FO%j#Kk%?yxr$B{Lm z%AR=5iVu%B)x;HwGKZzssItL-+b}-YO|geipDwUbk#3MwoQ#N4bCOa+)ty^HLu7!a zM3O!-oDXG8X`Q2c3EdAt`#gg+0)60XE?s7KOd-u35yV9R@g=8JS-#SSB;$^<-=3EXF5Sx30HLXRq41)h*%h z&kMYstxy6X-;%sXmRp)Aj1Tg&dC zXzOyY)!f-WiRpusa?Y^(&IjPjv~D@1qd=Gq*BI*{XM&)We${&_)m#0$6Ru>~`F$*m zltvrw{;%x=Xt8-!R~Ui;Zs&Ssbr`YHzck#1PWlQ~Z^oDtyBy##36kdwW0FvxO$lqc zA^9yilB{L8^%ozo&F^3pUwS4bFW&DoQbL5FlVmeuzBxIqC_=1G2c zev1fM)6y2G&l8I)F|%LwIbEDNDw9-T%7aw3K>1}af4#;fe>kfwoT|$~p?{e48t$)% zBbSA)G^8u9%yT0o)Vopa?C2dPUY%?{z6U$@!Zk!P5GhIDn+D0RyQlw@Goi4r!8AI^ z#{9pb&$$7~L1YML0%Hhkm#_@-&xzjY=R7y4dYXjya^d76Cp>g;+&9pPW-EF)(CyrA z$nHfLvL!_o&0XRCn5CCX%hbU>89k>9kP;&DZVJf0I|eNN7CFTctG=hR@7PbpMMLc0 znVFf9q*znON+(NGGq}ki+idociRL!(AA}h29mlh~dMfo)shdkUzxqt5*VEjXyqB4adbX?a7X~Trx>Ha19P-J%zDUYu@ThR>2nQC~s|BJwJw_&3WWW|xmR}+6mHcjiG!j$%$^=9Ax_8O=zs%(9P#RwFTlnJ7IRoELa@xy@!MeC7c^Nvne67 zQ&vn6(F{33wZ1 z*NdrY{ZrTwpHekvhg!sqM9-tU-!D7hp+I&uX(ifGA;^xhl|k;zbriQ4*z{-A^IgFz zkaqeOnd7PK=)h66r@MJlPp7g^s%0QBzW5w?e@OzsO?&PD+Ny$xFo&42eygZyAcqat z;@$ocwx0Ns6LcW&6%vm_Ssm#(bPzfdqv^w4jS=jmi}8$QsTt9Mnm!UX^LCSn?m2xmZ6g0-aI=Lpp!H^_!1ff!+q{9;JF8SM%}W{|n5d^aEhV414`; zHcS^uT0WMQF)Tj)ojgdrg!D0;d(%LX&P!Z11&sTMyYh6y_Z`7iC274tz9ciY`ZuUo zqei#7Xw`fkVf9Q66?ri7eM3BK_fb3PUT7%||aNt0*saV!+33SK+syL7;- z6=`l!j{ah^5){rMPLi~t_@wTy$zI_$+Y64RAE6kh_|;N1rO8zgB~D^V0A zW!*#=QV!!{hlk#jKHEfMf7q!-L}T*C`l8%9v^Aurvh*o3XMf(CFIddu{3uovj94?( z^6+xlYrD^Zx+vCrWKo&KfFo0o^xfgneWSWA-J=hD49TLykbttS-?sdKO*Q(v{zs5B zYFMDuFWxC!dDDrF{|>EO&!-Z7 zytmt_WSIZrLJU%hOh&a{Qvi83@b%6pA^cgq(@D(_ag~nR3L)I%_0j}b&|D~}==3@g z|7%i~Z*5{!&_m9K@PpAWGVi7>Mv}#WAzw_H`v|Db$$pR?m|pgj>T}X71@%~pBRU^A z6q)mJLOtPoymj83;_xgrsH}-k)dU!Y0#@!)QrI9+U2_(JU5OehKKH#(Saow?{9Zm{ zHuWT?ew#);BWN8fr@cLbM5jmmR1+{A(?wG4?R7kp1@^$WV$AEOb9%(DeHEpiWh z1=U~0#i{<{^UlbRACaI^xIeps5VtCPaFr|0_?_PX5gk(Elq>)R)_2 za=NcIY&3xkx%Oj9$1bX@@k6>8liW1mW{^;+$nKWiQrdXB7~`3D86!hyI&$adM**5g zu*vrL6mk>`!bY|%-sVZ-C+c(b7*-4BtE*>+?IfW|gx=U6YCb|PT`n)TRHXSCa7QFm zOImw-6WZ#Z&Qv+wt~v$IxQ`RRv+l*LS2thT-B9fs4{wVya*zl8&;UQ@$d1Y~@u;W` z@07B}q!$h8NPgIjk}~q{LKWM8UWUdIzSCZnho~^gQ#H0|U?m|0re!$!qNmc6Ee4`r z_NA8FZ{*T|o$3hd=A(%WFjfqc(klKD(T~CD_KRcw@SQ7##>;vof8^~PaX4g4M(Ye! z!yk$8K@5&l^FfupYS?A>KVzAooma`QtEuMxb%^roSYQ0}zD|NEqRh6Ri|8WBiK(k1 z%0B-zeL{;5q%3GhFtg3V3&VU$!U~g4X{&&wQPYLBi&M zaCAub!X)XIWonUe!9FzaYV}*Q)WkOC2)vj|>JAfkz-J3v(^YqmvNBGHs0L4+QAOQB zDZKRHQ{62uV7j*3BnYhSM)`8uRPJnh3cR+AOz-WM^IGj@zzmHxF~jQ&df~3N7HB@6 zRTDq3R1s>Dq6+^qj~&cs0^&T1{hIEjF3)>J9Jak{@RgGKz4l#hJtVRvVy*SRia%lh z-DZRQrKAu9OU0wxVOkn;`*X94e!}zg4{KRFE!8M@5C(_PAaiWx5_xQ^WC;hn$q0%njAHRjn#O@%~mA zr+mLiOF>}-vK>nV)cyYZt@U+QTNsP_h<^F4l+lou76HGH?>5(1kjE7iC2P%1@54Hq z8`K}_@W{x<$a9l^oJ{}xw{`VPXXI=GZi)YY(f_^gg(R+cNWWcb8DqIsQKf335=BPj z@+`;4Q=M(z{fv<7YmW`WgO$@^bh4Z8{cPZ$gw{4^37DE2Z=Ra4cE+H4hx-ybZsY*( zQaKd3&Myg$oH|Bhd<1Gatni?lmgPcMVb30!dtlt8IZ-^+j`Yh=be_t$hl6c-hs+#^ z$mRt|Yr!zEGTLj|5c%Wf-LDilBeKtd>**n7U)Tf8Vn~)8CHPkvX`iKkrDmIt&N5Hc zTzIz`bAXp4eoj6|+RgpKU|AAb?*InIA4cY_m>ONF37xCk(7}4DGa?&b9~xu+OgAFe zC{mkNaKfCu;kE~Pa<}v&B)G|h%<)@=g`tl^qfRI(1~$kf;hNo&v6SfnO!wpMzI!0G z45tCLI=VxYbT>@`!;NzfcIy*+S4;wJ)xk1rM8=wBc?mr7OyIjGwGbNWav=q9@g= zSVb)l$s)heFFG zr(J@O#W!s z4ySfg6Qf!AEBAs?$RheT(Zk79RAf$`DLR1~`}~x9Yz<`uaeSCc zE6am=eRmYMyOGRUJ}3@fCT4mS>7PQX+TFiK#t-ccd)(#v6{sL_Rr#af3r$ZU5K(7K z=oHgamW)m7-8a1kfc_g_eVXd}?IM{He`OZ}Yj&F7KZ6tID1lG*fKVW1kWF0(aMGkN zuYwx576 z`*q45A4YivYRMmJuty#^&NJa(j0JD4 z)$0u?YU+1CJuGQ7BCLr%t>bF^y!q_K7<89h1T$(%W9SeUP8i+T#|mTrV}XOy^{NuD zK6+Jb*;5HUeZu+h!zUt!gpur4%~*=Z3=plkNLknP2KF*@c~^k-B$#Fnp-vHtoSNFM z61iWw*uY5ZT3KT)^zfYK3q}jahIc7&xosVMXBGTF#&JV0E4p-}td;$j)ATmh zm$PUo-Bk%SZkI~uw&r@~x9}D~;&{#~>qDs7RTkG~8H`AhWDD{|BeT^keV4$g zyOrtJ3lI5t!s0HnZ?yAWLDnQ2#0g`s8biF~PUlEzz}?y1oRF%))>%4agX4yNKkqsf zBSoJ^PoCs2&ZbVuz9-mAI^$U)=GmlCks#IS#qt)SZ~Y3}(cAa3Cfb(RFeYJO2>15r z5IL^eP4&ZB1?1Mp@67W{wTlt!t5L_uS{CNJx7ESo^w=XoKIb%|_RvhH)3&(5?9rhe zj4v1RhF*p%kXJ8Vql~sAWPfT;PRvHVw_HUUY9aa(;WMT@PkmHe^u_oS$b_lFx?cg+ z9KwyanDDT=n0K>wz`_s^3{u*lw|<^|Ds|!;ndMgI_Xf@Yfgt1X&dX&kg_hVMiJYF2f|J@FsU9iU$YDcS2yAb|gNi*X?4~a3G zx_r8PMa3ESuU1fWSiqed|D}3vC}nfzt!l`tBGQF}A|G3-wKX25+r;kT?cifo}ObkAMCH zy>9q7$#-2~&(#&FUubWsvSY(G-KU$7H;0%?dlELVO-0Jyi_TFrfOR8ByE3Y^FJ+Hv zov&U?-K8ExEzL7MdPi-8`L-#i9IxpC;z-(%^p|~gb$#MHsbc5%zTqE-EBs}8^@v(% z$7@E^np0Ge@w2-tG`4!F-w2kKnEAhk44x^y3NSz&^DvGIVNvjU(<#D44%|*)xC}W? z;lT5G-PEX2t~G;HWQ|(n@wYxYJhJGQp!Q+I_NuzGcqkc6jlXH|TJyNd4Veh3n57=a zgUY$X1OxiJu_55*(L}U8B{!fK4MK+X0hm<5uk=*{kv+OSZM~uW zYWLPc1AFX-s#3VTaebiQ*qaV%)+n_RPZLI>&=kULM#kW0Q>p~Lamvd$MT<1q&afQw z%)hz-0h8Dnfk!(EH&#n@-d5fpVS~>hL4&B*X`Lcan$S=w<;j_7r}l80O#LI+#p%_u z2acl#YsZE-nj`W+LAs=>dPtBSqWqB_?}r6kKy6c7z`(?ZR-n5A_Y2TOc9Du07!||d zLw{VOo_2Jw_7C+WZ;2Wyt0!=}!Gc67>=(ux7DK94zTGiGiF-0R_+#N-zTxCLOBnKF zD`UwVeSP{-1&Qwa$hD#W)cob(bO^`)B9Ky(3noU?aL!Cs)T7ms3R|w6B!82s53NNP z&O=)z^w_0C#`68W^(~~0@)C5u&c5PQ@cQTjaVyodUu|+5O;KR6ql3~a^-qd z`b=I*GoGAv!m6AEX=I*@G|Ps!03IKjHLkh-&XfC{RMuJH3>bLKz|b%&$E7pa{{^h} zuv|sYvIurvx!$3RnoH`-FIpe-jvZN>0k3}Dd4-P|`C$h^pQr$+J+kQ$=D;=(e~1+K zrtW7e4|5oVvZ5>+LWtw6u00o6nI2+cang0VM;pj~Ue!fo(JeeIM;8j8s_d!fDDh@2 zbXWc}K%6imkXHzl!QiXJuYPsn<~<^auA9<5vn@JDaT1xAe4mq(hq&?>qddJlCdvoe z81_{PkEF1i-zN(APCq1Bk+?I-B}|wxbymLeSa!*jB)$_v$zeFwi@S6fNc`=yhHfP4 zk%x)GBnPI>TPp|H(6AehYw~-4Ggg7d-ulRL zKDhZVbZ_;f$aSa4tzhsM*E2j!_S3V75B+5g@t)lyp>Y0+8c?1CW^R)}_vPuZMHy|+ zkfewD$z%x`SIt93?0ExY=Eyo9R(2hP`0?|`GppKMx-UZCQPEv6UM-Uc62-1^53+8|(Y(g?ME?Vu`YPMqxx--)?>2=1 zva|w#O=r#bqbMe1G3X!EY&L5?ahM3pf$S8-4muF5A zVr^!f&*U)p_X2o#zW#;QtBm%xdP4O%^Y*_j#P}{B%z>Ab`C7P#})ySL6JpW{}owyH9Y5c+#t1Kx{y@i~tW3~~Np(!4# zsXqXsPC#;(Wuon2-d{^`I6Bog{)s-Y$B3{Kw;T^dJfB#a^{>tq5df)4UIE7E_UnUK%$`!~HKPM(+w}?amivJtUS>qZKK(eiv>~jVHCXAk&$KM} zAn)~&5~1n+vebzzAq6!v;($Ch!$Kcpy_p4fQPcu7Qk+m0OkEX!6hDD+7#&4jQAaIm zve~-zT1~)uVtMPDEPaG!)2N^=p_=8sTv|rHrus~x=VPmCbX4>i8lzfLCtVPVA7$Nb z(`1m1TrRkd;#ajqEA1N*VaGXP86!g-g#*^{k zZe5Qo*@-@Dnl(S`klO$0M)#ao!NO|uP12Jw*r2T9b>+wQGRO?Oydjm(^?wDpByuwR zsN9eJZfo{Q;q7rIdmlKA)%@Rl>5a#RP{t1~pq=K#6=7-ZOKbH#yXe+Qu@>Lm9A~ko zc#J>1R)zDiJX*cvlCT$Xx29YObB3e;;xYK9)Dm^HjR^%4lRS&k7H9V6Pgzd`37>IL zPy{?xVd3Qr7bk`$cPN(rsn|({POY(6fV8{QPDuqEPM+SUui0aFa6nOKT6I!>AoA!S zKrdu?rq|tVzsTZwlfiG!iLFL^l8S&P#6Dbkr5)ipF-lG9x8O-~@-Qk2OaE}qqPbb3 zh!mO`E#|X0B=U70mI{7Td~%hf;b-> zD{?a-SU7TSfL;{M)==5Ujl^8lFmFwciQdC47zDXcZo!2OFu4lQd9X!Tt-Ho}MO%Z_ zPUpec_z)dEHQ>aXr~hYiFcDL-cEQY3xgkgK4B%i2lz^drjb!Nj#A;Oa9l@mtaXi$fk8h1C$&lP0Zmj6#2ZtRYL7T&F$W1PC z0vw=$tPvUSS~3I|{HQ!1O{;Giw3*j*dL7y z-iqygB>`|xHz2Dg`xn=gtjr;>$q<+FGEUC5{?dAHt-(D&Ye1`|dKG&`5+09cpEA3i zIET*2c9u9hAbZrFD{NnnD!KCrO18Vn4i)V`J+t=rZI^3i=3YXO_2RjJ_|v6KQLe>5ToO2~=b5z^n1r7oABCmB-_4PBSeg}4xDgB?oo}!fL#B4_1nUJzX!5{LXfsyDqL@7(hqL=G2 zUy@JC?tZ%827MOLA4tfdD9`Tx+AijNjk$R?Z6sJ`9pdvA0izL^{b(X*5E%*bO~fNi z)bAAK0g-TG%5@E)`l7YRBi1E<_ArTph}18Jb#A}Ih$u;$m=y3|?RtZjNJ2~+l74y8 zPx!1#mA`+6`lZz2W98r?Vd=Q4_!`kNt!y_(<+&7C0~;VwasdCsdng@P>?jSV@lD2- z6_Fs0lVe8#v8~YK9;thGJPu2k`FfETqp@8|Wqqj*e?LXjHbFpwcnHFkY8NS^SjNSQ32P%2tupTcUtgbGcvM!$Ycr)Q3 zBCPL*Wne21z%d4;EwzU0Q^3iVqVrgw{$7b8(*yL*Hlzfp?hGR>Hpj?vk)u8zb2gOm zzSnQbSulU1k)xOEPeEk<&D!4gV_h_m1)X{DFjCRl<4h#B9)XB9PXtXxsmgnl8^9V@ z9xHvX_D|T5#%SM4ng}dS zLR^B>DbmrJTl&>at$vK#X|1k$cC_+nvHw#-MT~gNeXY~&$_VX?9&P#PeCAc$l{xJ* z^5QaAwr41mYV`v3g#$Rm#d6n<*F;zRIC}OmX%QJy?%$7G5dOPmsWB^L3Lm4P1WxaXp zR8-kqj4r_RrRpjlT~0SB_Oni}{@Rl}lB9YR(ok!d&lolu1{IQhT@z+J>JS?zdqn&q z!OQE$u2&4|Sjnx(l}iq6Ft;&3iIwIBPCr8iv4Q=ui&j< z6RdijdudxwlQtI^6%_KSIi-&F4zlrV{&qbp^92w4L&peH~Mcp>9|6^Sqy9{p9(p&cdig1jF?$8TQJ^!2V0dJrldU0lC3 zBwF4FS1SuKEHv)A5=VfUcLR4z0>qj_|KerCyOB|EH0c8+@B&iUXB%GN{mdh^JSnR} zb*ncOWf;e24OL5QF9A+;{%*qi(Djo$pJoq0nsy>*nOdS%fwtls=mC!k${Z=Tq@fD8 zAh7zu8ObC(p1o7SceU6y?IN-J16oXUuBg>@tTkHlP{2pDWR73mC8+I(=FE-@Xm|Oy zIWvQR@Bz&JD4Pf<=*GMVySZuWZD<*0!?C<3t4i$hn$kV`fHYu?Yd<@NeNEKZzg^js zt0os{NH;k_eav0I@Z6+g#vDXTm3=B^%kfN=E8vY8tFfz066dP1LZHk)U9B2>*PhibR!w!NM(kRl8hkm8kWy1%^CKQd`ENjzt8DPV|JI;D zWnUFUkdc*P|C>-`RkDheqTcqgtE=_42>?;tKjWlSc2#Pz!JW}6sru7@%$2v z@b{{kngo%zGJmZJgKxdWbY;^bJCbYZ=$QSoG|d08X0`%zZoki|oR;SA81^&R5t^gQ z7B|{RA&ZV*oxq1>!8>7j@R0^DOgHfi5PUZ(zW~cz3~dXll;WSn-{!Arw8g& z-lV+^YXUW{wCZCw#xOSG({ajbgYh_0St0|dmYGXlcMjCA2-c2;2LMhWE;bCwtRP=} zOO;!?MduUH6B6TjOi-sm*s5Jee5y87Udc+zwP*(1UD=_b$5c*zTOD*WB=^AOgVZtR zumTje)UxqFr_4Ps#BtE8T$R0jxdI7)3aZ_7jRuEnU)4m(n=mBjMYC+gTAZT}!w@9@ zxah}(lG>NFbwn0>H&PKouR4{V>c>v9U3A(rN`nGZz^|G{kz}43wdof#_5DQU zKW*f8Zo4}Tl`Mr^rD7nkp%TKq_U^YZ_16<1E?%RxC>nC!UO$NLv2n|fh_?U7PJBNh zFB-y;7Z?Z^ayI3MD$jiDK}j1SjFl|oD;%=hZk8+b>gnXyuU}gtxGELJt3fv|O8 z{}Y%8r_QgE!+ZT$ICa`7(@KEIH%Q+Bl(*J2^6gLI1`Rybp&X39x)s)+9@?bbjjg@x z6_{*|Ay#h!Q9Ae?kULV%i(r}`2Q*8o_KS$`5Xlvh@No>?wlpYqj`&OA>)HaBt~Mz5 z$2|lTP12hDy7_lKOCb1otljw1f6q}$du9M5Yg1<-0$?8b&Q0CDZE z>EDS0DXD60)OJfbL^KcjE5lvd2^YPm&Ni#ucuT{2nJtSZ>ydvsq$3HLcON4YVES6+ z+&ep#S>m;NRZ@^o{=CRud)NPS~^{~S{9Zr}W}`|835|LN1zcP9{RG;Uhjjm&n3(hQ-Z zW}^7K{>oVUOCKH8zhV*7@6HQ2oatQZMM|s9@c+hXHV~(a`@lN!LkSuFijhk(>ZBJg z4i1LNib#}^D&>oV_@LN48c+TKixup*=sPel@nbaK5W&a&m_HZsl}IVoR=q;$aAo`o zjp@7K^WjmVdOzVXvkxv7r_4SwD^XW0L!&qceu=;a$m3wn<9Pr&Trbw$O0E@Zj z5n?2CE=fEejd2wZKScLq#NhqruB%4S=$GAfVe4N6pj#YYKu6bQT_@ z-V<^V*@w?y1bj-Ql1BDUESXzfiJ56N{_GWOxFO8pZRiZs!ldWWksCd#ewYyk7dp#7>zc+|zX`=@{y`a6O5fZ(a6fgwJ}s%R(W-D&hO-eMuigS8I7(gER zAHEH<+!&=ck-PG}d(}{zT&JTn`SFAq(I`fO=!GIQkKd9?q>_Ch^_pSbbBkM+_u*>9 zrGCv-7g-{6hOn6cWTmqJCYH0>8IDJJ62bpNXRkhg;yw8YsHGP%DO-&ur(l6X%heml z8^bnvEEERk`<9ghg8vHfw=;y+40lrrLk-F(6h7EPS&HuOM-28%p+x^gp3%mfi5^gu zGnoyg{{acM07%e<$JyE4rF`{DbUz4`>Jh8-J}~=jvBuHci|ym%ube5}_6?SbAFX8s zCcV#Mzm6m)Crc|TYTmiY|10(vnlI_rr=-j^-d3UhJ>z9uq3XUwNvm=g3WI(RdvjK! zK=-gU+hgsdgz9fR&5&mQC#T%7V6({f@CdSy(qs5H8g<=-`DA~1XSd3Hrun8 z4ntpy*&6V)crGOT1Ls`Lb45(|GW_k@x{07KKiqJ(X)>!c41SlwLD|E4QsVG>TUU-z zt2^`=3jI%qRT1p9g^+IM*SMr@K}2Lep{2@NU=tZL8y~}+1i10fFB`)OH?$pcaYSkD zrJlfFDjod0c7(vjmB_m+z#EoL&n1)4D^cX$vo3&hzg)`}jlAGCBDOd_>`5r>aRBBu z>ShB#*{LJL%r`Z79pO7^+1(UCZ{i zmArG7*~HQ;RuFAOw=taudugMGytS(Abg+YK{90A|g2k7e_PW-fjmad1v z0=6rU4$)&I={&<#XJs9D!Cpxh zxFFLqkw#Nj3p3@TDWkA^K$o^)XWy%@b%+~Tu_0YKg%$_Iot7u= z2zcj)#2z6{EUvt7*IWJA&xfpl`5O2j#ZaxZr5a$!9Lon6L8D@wiK7D#9zsANxCJXd zeN4f+&)k}CqRZQPT4Ilek*eGMGpeO>#(^W5#HM?3Wo_$=4zHb1QTO_EVHw&)0=>Rm<^IF)I4O-cefr( zTX^BU5A1?uB<~O2it77#VajgiRZpsEr}<@!z^g94GtC9$na3$X_jiRGFYu|$pPGB% zhne6K`>E|I2U3(aG+(M&G%Awhy;f_~J-_u=Lr74`HL$S4AUNjg%9QKZRNZM*$DqF)9G|r|f1EBjT2?7E5yD5hIIZF8r?-wDqyk~COs!=LO7qeN`l z0%KhDyWV&mR(|W1wX_>l`}x^lIPeYbiLj|x>f8N~m{w^H{r3nOU&v)mX7K1Awmk_S zdNl6=S=R5yfmq|S`?}Y-yKYQJR6(>IT8v=AP6O`qq$o5Z(n4DEs+-+}ubImK0nBDO z?O^@OKC_;nccz|Z;VS)}@1f#vE(VbPshOxi+fAiLYcCHg@z>2L?2oIo(HoD5Qe1}b zqa-sJB3@x|elO*ItRsD0Qc)o#E)M6Upb)KsZ0d_XqcyiVUNJPyr!W2S$wpq2yxr%pxav2C zj&qX_+ye+QU2pd{TcPsfx8_hJ#i&sPi(>Yk+K^iH!z=1e?91=7D`CKN*(YJIewACe zDO87k0oddKOC-6bu#Y2%TNvZC@030W3wBR$5TwBgj7uL1Il`9C+LJ#+N#!xxcMGe$ zoZ*_y0;t$VyyWOc0cwlGLnF(G@k|l(2|~!EZ7beKNtzGH9wl;0IV+}08|V)n!!oTL zS&z1qB?x zj9k~MBq^;?FLBTMgc&4@lt@m(-bE;F4521|`y5e{tZ<1g9ANMu@7;2b|LrDj^7B(I zly&Dwum{BNHBgY3U6wYgJl=_$43+X?pspa2#nkUaMDThOg7Vb5@eS;;H{_WtO6e$#Y zlqcx05P+!~rhduIVFrAHUq5z4lgf5(6P4fGv%!1vp8C%5KREl<4B@Z}l5O%L!=oJ7 z@4w;4*4%UaAsqywt9tq#ufGbR57C=!@n3+iiP(?H$B-`H@2|lSbwB2RQ*D35z}`QG zsl6lIrB|8a?Jr-aVHnlf1A;{YvHLkKo2W6$i2Lu+TzOWT-dM`^9v4djW>Pz*d##X`omj&MxPy#ans#cMpP z!?07^T9bUS6&WNN_+Ss2g04l=G}CZzv#NZCc?TLh8cxn z2qnXHeE_->*7aJqb>zin&p4+Jv=r|=L-$Rb_GQn&w$Lf;?QseJO|oHY+Hy@F+62XX0`?!c3-d1O|(5(0_`uI|mWr1@#7{ndJ8kLJK!IE)A= zKA-*D%q~De&)dA{o&C5Dx=WR};J?3qZ#hm)ptc1(O8v(hVsRMQ@#LKXDpIQF`R2@o z{Y4<9S0u~%*C&<#%+Ea!38`cA%SpI32@d(^7{si>1LgQm1YWt>-RsvpqQyS}%lbQD zOG-*eo=#Qraeo&6RrLyLBtWpqg#M8kPzymc-&B;n}7A$vELXTQxuIPTo?7rS#( z7e2GI54V@2-hKl@o-u31^nF>1Je#&XIixkB>eYs3BxoPw^zQWw6&M`*HwnN0lp2u4?tEvpdn>=^j{Ah$~=T4pDU`82YILxxlD-lDO$vd_NytP+dJy z3RKDm$Z}~X=G0SB@0nH>Jmgkw_j|JMsr<0iQv!u6G`d|3fd=QB*7P#QefA5m&j?AD z{jEMM>kJaTvve<^S5gAX+)GxmpBeXPD%6u%3zFOOW{&6vHbOZBrir)XFJd-p6Ueoj zJ=u6UKb`9Ip=47hebBf186q+FI!^x*2{1Pi!!NFge4LokV98=;L;}vy zX3sI&|BTc7-)+L*Qz_rM6MXKN7<^#s{`XW2*yGUuP(_jXr!pG;u8i?wA&d2Nmv_B? z3_b)?~pb1d)Im-9}s;0(~CXu7jrS-c99)?NfjiZh#N_xQG|2u#CqZsdqPMIIa2l77Os~AbfKN;G7CFA#|MNL69dELW@5j zbN^Hw%B_p0(Dy-AQ5Qqe+yPiV%wqT=Ir@7t6l8lUe8|tIwzp0g7S$469E_6k#rZvQ zM3OwIJ9Lvzoa4kO&-SB=zE^eTB)z@;tir1TBvX>XY+Lr8k4Ek40h_^PD{(`B(a4);l;p?t+R$n0_5Zs%Td8!UgzTr85d`up_JPP#eM(brEOBA^mEwn{(=CQo+f7+XvO_%6LpgK zJu1fIYq($k-cP=~f0mt`8zB6QG$SD<5d+$(WamvUR?&Ul4IbTe*s8KbO2tZ}yQ|6D|zBWvUp< z`B~V{0>ce(7}N#ne`O3ww5&Ep-L$G`kfr*!M(i-ZT`TvO{6T8doE*%BA;VaFIz3ug z3ElHpZr2Q?DAohLSl%xB{E5~cBtyl*ac!oQ=JjA(>vA1a;bTk{C(+aBsOSwC+-Aq?34=Zyv{y|0w% z2fk>lJ)iz4NW@nhrlu|y((%}jB`~Jj+cTtX>Fa4oo*I%w_)xjnO@5z|x1JdrDFEnc zGQZW2XK1!Qc~!@WOzq3AB!pkX*iI|Uyz%WNrVB>{FZqs^JZbB zJ`G-b@V)QDal?(_twKJbVB+yJwTBms&)MlZ@XUP@=2tWQG_)z9B=Ns=vv(E|!{aY5x@ zOjQj}+TpTg@Lx+Me;@TkM5(4P@@2HLN687elXEYun@KdnR0w1Y8J8gzz^NCxZ%92*r^pKm1Jd7JD47 zh3q$kD?&d1!lVl3y6a~DnUxP=q`$&IMsmZiRy2?#1vE_As5?2*YUS&m6@LAa^SQi$Rt;}+rH*pwJDL2iI|;gn71Ul~ zbCOMJNKADfu9tpxW!)N7U!7+aWML%=#R3b)-HLbgaED_HDEY#_b$T8^iVp06nCrio zNiM;bJuPEw_R{!~2JpreYMXC8qwU6OAEi_=CX@u?RPIVp-Y3r!7nR36hcQN2H-9V$ zuTE>q;hhuGt6Ucb`7HjL^|_srf_nulju@9JB}|;4jZ9<9Y}1vwh56$V%qc`k_-bysXQn6Ah&VM*lv%BFC62i-Q->g3ry|cKUMU}tb zzCr}ZDZbJf*uttv@hkS{9>5AtcEx$6!>(#mgxv94!=WutmZ)2aJ%0Bl zd~3X?@+pM^9-;hW+{eR-cQyyZy{^G^nbM7lTaACMB>rbN5bt}dV=ky=q_|Y7voWG1!DRUFb$0|E3JF{}zpEt!hMB+DLy$F%h@WF1>_q>^yhJc8|KFkzi2qqB=llb7 zi~qzdAdJ!eCtjU6gIai1{@_(f9jV)sb}6Q%rNrwM*!Pj$zFbiv1^S6peAQeUji&#*%hBK;La zs876Bc-_91V|mWHA*l`F|He=HR3d-@M}W-mGeYhLSf0aq<($_X)}9Pl#DJysl3#wD zXzOuMnXpL1kqE6xZ#4c{G5yro3@{>T{^;-Tl$RRt9bh!N9M*No2%=EOba{3QOr=$S zLXRJ3TXf2ET7k?SphXGF$e1~ZtCuHF;xnP-atXM6)L%P^F}>fwtslK{-T~4fSt=c4 z6ZXc1IW{hicAp=EBj`9DSnsD#M}^k^LgI6|0$PLU<&j>c9)H>S1wV-$+}W>aU6&m; zOqTfe;X+?ji4X`_eg{_98HeT<*T}2CububTsncbz%yEyr{0{GFxt{qe4Lsj7eBBg2 z9aeW|nO-LF#jJ5DJ9{|$-vEl`ce}b1Fpe}|G~YXcbYqJsZ6VpMwcXe_^Dn!MZ*@Ga z=T)qiFR=iz8x!t-2}RfilE)sf{t7Wug?M&#I{%%;^e<=Q-vkr{vV|&>u@oAgJ;1QH zhRuST{tclwXTWwx>~>eMRPL80t0Ykpe5q^+?V#Alm}2g8*ldGEmG0X~4j5 zZ@PVA#?d9NZ&-ZIpo(4eB;R*=bZcicE{0hgCPKD1tY z8l`x_(z~oSy+hHKT+m>FUtfTV0GUVsnc96SYQck`StI`7GXYS}UTjS7?U(YooKd^t z+RK7-InW9ywO!CHF-sNLyzEGUOv$jiIhHn!l=@smw~b$GKxz&u$vzx^zBMUvW>|AYoj@`gAjn-Ok3iQF`A%^Vdcy(|=I>8vw;W zof*}4o@3-snBP1|LFT^{WC!Os75qniJt8+Brr{%>I$|Foj;JL*8J zQ`1S59fyHCewOeWpbymBIn!#065gG&?)Lp;Ne# ze6Shg8^wz{Ao-4={_rLk>#bN*uv&L4QcxyIbJC`RZ{CK^f#`g^euP%L5g0qqsjll_2oF^@I8!}AI={9nDa#wpO-y5fw`*pC)Qdwwck7!~QC z$ux{KD<$1^5HrMk1-$B<6j;D>t60~wP~Oo;A|D8 zZcNT;;zA(LGF=530qQ&plL9~8aA(U?x$4aua~>JZ<-w^OU~mTb0D~X+vHD>HH0?z3 z6x77^GTrR?=XS%LCUC@Zt4m=;+R7F+-N;%Hd1;z%He$2H%I+qjaVr0s|X3$r`yacmQuMUiH>)gk_ z;z71pHHW}~&Nj39+*fD7;}3njCY7O}61XqZGViiM8-dS|OtJ;7HP8G)e4~+t{Y*6T z#^8sUF8S&ysAAiU{!u>~&!fBMVW39px{vVPNm)A1XXcg7YnBsM$m31sz*fkASX?9X z>C%kHuyWoZ<3?hojmRkjH;iHeMy$Wn;vhzcMj#oYhjfeWD;=@BshYo!;+J&5@S_P} z$@6b}E9_i^J03Y)@B1T~H1Iw%tuhvO^oF6 zBty6|kV3jTTV;quD?#Pv+YtoUr5`Vq0Ntj%aNP5f2W52d;T$NuIQrXDy+Z@Ob$UZ%lh8qVb{T@ax#OOJC7K%8Ng9f5hRJ z6vrBTDK~R}d>a)=8wheC-Y?gR{3%=TdySpo^gQ^ zCA5m?sB4sVC)BIIA;2CzFPH91f|v)c9^MS|)D<{)^9=6OG|f?iW&C2dyb5=Q%b}}jiA~4fbt`X52is2@dvo5WMQ+6^$X9iH%^yGPdk_{ihN@o<_)6rl zxr>3($C^-&Lz*r`c&Sa3z45^xJ;Z$d3g2T{8+a{}e-5~AAfBGl&~b3A^j;Z+-|^EO z2gVh)Bar>nExs>Z2HbHh#gXJkD5m?nPWAddf)0OX07!aNPY=_)p@>IHn$!D%@=cBYn$`wFs&0z-lSqXBBozs zES=*1ayOwl)|1fHEMEXqb|b-zUV0l#xnBB*dkCU~Lpib_Cx&o>lR7n7U_CM0zx5UEp->A(!091kbEDIk$K@#Ya{r zb-QL*4EA)pMVZiGfn_sb5nvLk(c)e|G3q^GETrtjjvIaHtDRC7-1_#F2qX0panVY(%%D^Xe2 z^$u4V>}8^#QjYLgV$iw;%RUTpp@+K5s?=wsAp7X`)@V1p@KHe}GV1^8Xox>o)^R>}mEdneK-+$}-r~0tuy6Gl?;zdI%M7f1e%jC#<0P ziL)JQ|Lzu7Z=3(7Kprg!1FJ-h2lr|6_nYFv*mK6Ovp>QV9IfeDu_mtkI^^zjO`i7R z?NH29c`{)~k-je^X7O0h?+4vw-$JTrG2qCxIyxqkhq60l{-_eu=^f$j+j?lwL6z@Jc zX2wU5_)(ihbZxW6u#X(TFX^6@@8rb!fRGCxIegDP_sRJ{yv<3SqKPJ3+I#cv(g*XE z21R?NZpF2Z$oH3W8S&0{Ydb{@2GM+*H^REodaO}Fps|@bB45#@COmt|)hj&v@N&}a z<^)6M6q^VqHeIb(FJc)SF1hi{;_*|7eR)yewaIR#_IR#&WPNy_3}oVIc&Md_FvZ#? zsmk9`%tserWoO}$uQ49qIpYa#^zs)R$0S0GK4T0s$0M|z`N&>Bgs@P^mBvTxGg2#T zhJjQ~dL|YARd{nhjAJgAP#h+J-9VRR)yv=> z5aERGbi!(&8jT>Wx7HgSmjn-6eu{oGMS#$?^phI8WQh*e9viv?=c9q+6R$}Swc0Z` z4!a9gWiP_AD?*ciwX>)fnSWr!s&SyH*9`Wla8^DQ*343@hl8>Qv7|5;U5u6>1hv$GlLDdj|Jwl~JzRW%H^@#AJFYc|KKIh_??4)C1fa{NN4qFA{-T-9ciRjOeg7bzqP`$zv*~mN%(k75&gYz6&0K$oO$n z&aK=^e(2-pk@kkH3&h@&^fT)rqk_Uv2la?IgsT*W>5P+rp3^avA!{AUn_X5pjHCChRMI%&GGZ zqxFY9Sl0Z+-IYJ;|LUCeS!em6`NzWC2kw3) zUX+=!wD8)QHAS$?YLYOT<51KR4bc=(VPkMk@2c-_p)$N0mM^m+A6hwML(uxLVCBN* z-pTWvvcQ$Ex`D63DW40%RnMYAAm9wQ6r8(Et6@JVcARF2kd`@1G{P3Oh7Zppk#hL} zvZuNP4NNJpwnI(Ycf~_D_`_Z1X+MK_pVB<75*-8^zv=+r!8Zk~#8Io&1(xUj5=>Df z|47yzvMymlO5Fu9J~V3GBnT3onw-xRI=^rYoe@09VL6B@Xk5$`kezX*HO>cT)Ufko zAdPhEbX#~z%1K;KO_anCK6)6rRQy%?nt1!aHDms|mt#hS{@aVgj4q^GpdZfo-7+9n!8{OK%+ zoiP6+lc*<@=*(zUh~d3?u(7m0EwOD`(AlPkEuNc>O>FN=dmHFh!W6{^EegKrG%4Z7 z3sq~)303>6%N0d;;uq1j^oH{&_uB2k_dw9ZHQ^-$mL-wX@$_h!zUuj?UCU0my)cUz zMLA4d=nHv4T+@+j>ph1lpBDUH1TkqNjG1*3r<$8Jxe*)kx&OYFhOwjMxn#r>(4ElI5>;aCj$H>anN8oimRsbNI+~A3A9eVK(`onWNh(Z?PW$V`xc%h6S!mn|_J(N8K z>ar!$R6veMIJxdkn2(XicvxDiVdgt4bKv*Ra7n))UeS5o{JByvhl9w>c!P#i@rFDA z?}c?H1Dymn6uvi>iVn`p>(f@1E_Ha#s8e&J23vEz(XSKgKkBaAJ-MAUjiKOE zN*D8XXl)s-UCjmLRA`7x6}|aJYN!M6D8Dp+(4;%!LqjejkN!l3ybaJ>*KZ z7J>$l^vO1Te31OSjlHp@w@gxH`;(yHcnh~6q6d5shX^w5=CHZhbe9zcisAfA2A4gR zK|b`rXZqY2(6P!UC8#I0Y%Nz*L^ur*PC%=Z#pex;`3$Pv^QU#^IiTh3;Tt~gT@IQ1`WfSK`RS7K z@n(%f;7pQFbQHg4gPJu>5;K-9aJoz@_-x-zw8p5t`PeFCGAN4Vj7+oem*yNH_1s-> zf0 z@3q%kLpnb8o@YeaXSFv%ofxrz5F+8~d<^sO*yB?~u+}mYWBTz>h0MK859r=*4#BNi zj|x13g@6+TYHpEBYdb5)F@0F0Z#R|km?Lo0tfulfStVUXEYnVs_D%exPib(3DAF0- zegv}QF#?OLk*D!_QtCB5dTp^Ms(-^-$`Clk5QQ0(q0zxmpDsFP7Uc$LEx7nBTwY99|Rba%OUtp$qfN{(2GjfX!yk zJ7qB!=sl1FX|#J6j4bkQXt6%kEAt~gyz58lyWeH^Qj;GxbWL>^(yW~Dr5L#U@naDH zm$gL4`hfba*SM^b}$cJO~n?jRf&N}IKG8J$}^!WN6c>7g(_B?5Q zJBU{(`y1L!@-J8v3h|#NHB-cgMC?|~@6Q&VF-49_0N-y*7?gclVpV-J{!_Mm6h+yh zc~|p;_6$l)ZVFq86aRD+sx)WQN_;{%Wz!oWIhT(IhDnatQNhX-(6Rq<1}+=qC$0GO z!;PiUIw>Tm93C+$gY^CknSR=Sh_}~7{>1sKuf<_;)~wQ-i$tE9tJsO{^~iHq#^V2P z)riw2Eu(%D#X(pDy<-}^4KcxC0Sda0-Etwqc-*c^43HS=0O)w9x#@72rpNW`ZjihmLnhcH{0`qd{Yaw zN*yODN`sF9=&|?QvFY;yj2}EJbRY)JSKIKk>Mfxf88|>EBxF|FAdxR@=kPkNcp?(P zkQ!4iqxbM@7nUa0S{`OiUwkQIU-)_%d8)Mag(TNzfh$;$h1;B0xAygKJrk6q`KHm? z2`bQo1ea;}%_nmNQn-1KP>#<+JFx`hjrr6$vp09UIVx zNR^=PG2oP-)~{q}a`@a>{&a1#p(jk3zipAFCA69`TiZ|a-Df@*9<$Wgubd8X64lBM zUjTK3FqukKbwD?^led8Wb(>nHd=vuDaTQL{NuRJMa5ER#oX!>1mhxeZs%(ZdZj8R*fP) zd^S7`|6m?PTq!uX}8yk^>Z!?iYMmX>UIS(>8`AUe%vdRI+4 zYHcMCI5F68X)@Ie6Rm4S4W08s9N6`6mWw>DoP}(2@ofJFk$Y!XNLA(C`jAf@rs*g_Rw~t;emm}$Zed`w=7~`PT~x{SGmT$c!uolS__z7!`V&5 z2yR@w5JoaRJ{5{c>NqF}o~RGY(K_nFlHW>%z|tkv0vfoaf4lX)Ba&INFlwJRl=oHN zsvt)ncv$^2V@9dj8|}FSwR&w)wAyQ}SDy;LFu3+5`r@3{)fore_afdHP|$zPTbE@* zup!{QAZzozw)NL-LNACZXUR{oYk;&_@4!icJ|}JN$WTpm`y-+E({dAHFurR$+)c|J!W-Sd+_C8y9xhlHMraEaT@%^q{WklmrkY+n}3BF-R>8E1O#DLC|n|hZ#{%XYB z+9rVBLwsJ|bd>l3ft+$Jw?f5qO`N}XhA=v~F_+cuf?GiFP(il9VzAaW!IeU_I$WyR z?jtfmUB;R*@*%HF$h~O|ggT#bKr-~_pj=AmNOxmuYXZCN*gQ86H^Y?e>z-0Bl1;ne zb|Vt?!mf!W!+hs!DCGLajhzGW{)r%-%-YZgrPkDme;{o@9U)(geWA6J)azV zygvT6o46?xuBCquQaz6zK~_u1Nf@(CegxmX8!dXQG)&a*Gu+Zc{!zzV{D}L50xe#Q zZCat}qs?X#5v3v>Tuukgby^t22!uhJ-L?|D#R|OLt{9i*lY_U9lCl)?2NB zs}5=~o~ZvS+SGJ(Sh~|{gb4QTMqC($HipKMloXb8d8GUOBVP(4hWY!wY{u}Icydb# zH-z?#jk#Q>!pjZSFLg|{Of2kZ`*m}Be=V%xU|(gI?l9z%pfM6yeT2*+jG3o>{YIj|c8LSU9WfvoSO9-V^!WgI=I_N+c961U`du||5sjN^# z)mCuDr37Q<8I^CsRelW`zz5Q|4>Zc;!zrLGpe2%a)$fnvGWAK}1!5JQZ1`zh>m(IG z*=^fx&|}qwq;AZqxd`YA`}=wsB3mGg3%K86$ya4Go*>nzxr&3o#%r55pAYM+w>L6T zCN#1QuC_v$xzgN3`|8Ah1~Ma0xDU>gM$@x-7=B=d%O*NpWdSbj`E(&yqhc}lRr8L}9mmL=ZDcE@#WZm%nEm(gU;PcV8aGHJ3oIkFs)g`!ETKN-mMPdqW$^ zQs`Pp1?8h&74++>p1gAs(GLcBkYKl_o_(U`#q>w)$Cd4Fwb7T*N|)^3W&>wvMns65 ziEsc@{;IV|U4)SqrK!U5{i{doMCJ7j|8OkxjuFFRR<1nYQBpgILTJ0|ofH7C00uM9 z9!F1RI9*J$E?8x9eW^Oyum0;o8;`*`ECYFV1>Ma@h~P#`OCDpc(Gi{SlA**pdk@FD zXe=p{BYY1l$tyXQPP=8Kyds>+e@LDGM@U;=U8Oc&@}d9}(NT0^uEjZ0a}1#Y^~!f> zKKQ^=Ups7_#AN|@?w|x-TveinB-oJFujQsN!YX$tUXVtdBifBDSoPe+6_8q7ZGWlB zBdDRKUb2uZsw5%PIBXaK?*j9MaP%f6;W{%t-=H0VFKOzeDc0y(avyWj7ag6l7acLK z%X2F+FVi^!fV(=mH=P-@FmxAs-Ou(mop#<&YebcpgbJa=iN(It;}8}8A3eW?gZrQ%;{`AV zupcM=ZiDihXHc;WqdN%?%A;m=c4fKOwJby=+Prm?EVSeB=Jkqv9*wqp{St zzldEgO=G!&<1!CsxV6~5+_tBN`dkQiiK%h-V?MPLh(mIrq_`p01jc;0?S_d^ zlF`zJ?VQdKxrV(JL9P%txIl{Ci?faQ0~o|)hvsGH6 zgufPyG7fL{HFNz31$oD7PWg|}$Fn%k8}rqSxNWQc>~8oZ)8)R-l2Nc&s+E%OVafUA z6yr09Akf+aQaR?IRM(VMI#9Z=s)^-ub1tzn>WY$jbqH6&R>D=nm-@!SD_V{ygM7$X zZN1+}Z8NG~kB&??s+$R`Gtv#-yy&axBnG^SaFtR$ame6oB)+j*WsHG&Ni`U^WjO9z zzK)VdCkY0s&48i#Yd##F*{H%7a~+A+DjkvTI~ws*Jw=O4ni&yRdJ-Xb;Hc?~q&Ms+ zt^}UymG7Q-ttma&t>NSDQoy!q{t+);%Aftw9Do+M<$7$Lj^TFTpkCoh=BMH>+(ci7 z%oS@cTE#^m*Cm?XWI!ck4)ZHn#Dnn~WtS#?u?0kKX2sWyXuf-0IUYgDVj6 zTg#>Uv8~{Gyt6rhUA5>kuQTR-rA!@UIT?sK)?K$((ZPp8vMQ_JEUPx6-M=JL%$MvP zkiy7ZV;`83|6;AXzlj|?n##BKaLG_C&3xu#8tkMATudPUuCTH0M4hvPR-I))5>J~1 zl@*w5~&m4ID`P;wPrN}%3)21E^Z zCs;FMM2G2p-LnH7KWx7JK9U{>f=tE@B=R#6~kdCwf>UG71o~p;^ zL@yn#&I5Jj=63*ISdh!ax!7jZMPeQ+>~}FLk-$`4b@0PDZs-yw#ky1!+DJCmij+Xr zjOW&brh0KbeEN5%5S0yBO{*8X;|lJhLl5QO1cMPwG^eBO=49*meohU)X;+i@efQ?) z1F@V0zCsg~`Dd7&rs}hhmHk!7UyvMx}|q z3cp}UHvIRgPxYh&1t1+3;Q#-4sj#NjqX_IQF>aIkWQrV&P!F5ysQdFeOvjOAQ2$sx z#r75QYgEfg`x$YSvwZZs!v9ZI=I1VSK? z&coytNH8IQQH75Z|2CSTZ#6M^#i+F~MA-W~%lT$^Qazcj-f-Bavb?-5tAjWO=45|p z*jt#d#!W*Y6!O!&j8aRDorzYQy^+qj8NIsH#c0GhuS|SX?RlWov?<{yikfE{JU$9H z?_p$Xj<&6=(Qhui=ZIV_E`%;x;D}J=iZlurSS>_8v8IUf8|=`?Rvb3iq(!>Ly6tcR zdXCO!s})gnBvPD$l){VjH4j@VR=8a4o>s^;sU|pNQVce!T+{t#EzcBmP07%03s0*- zDWq@yQYsGve$1?+^ea)CvA*!F`(&RWbdh}Ji4-6M-nNJOf>n&Ej7oJlbiw8tW`i4en3dKo=i*l7<$a7M>HcftWlo?Bv%H$({q@%(h2RzJ`xbmdob)Zd(P4R30Oh7CvybCot zZ~+zCzo#gZ1hx9Nr5T8Wxc!bESH#f@j*mQUUvIis5#~7VR{UUdF>)t&hEZ%eqXL`| ztjR8o%Gn-di>;;XRl>go+sCo30EZ-3g#FKM+0Q>MOcN;3bl<-~ne+-G{;*`&emJ!M z#fH%{%bn=xfA1Wqs|UBnYqXq4^S2(URBMQR!_%v=>F({;|IdbM1r7qgI(Tc%*sf~7O{1r&aMK+lJ z;X2rp%94smt)sp#Y?ye)Wpn>wZL>H~eWv&4QJHWXPZ);93u^UP&Si^wOdh!N`QHvQX%~lq&P7p7mMV` znIPZ`|As~+Q_Z6L_ze_FWoCSYdEn;0cFJ%igHGlIdrKr0iz7;rQcaEy5Cp;Ic&eOM z8S7yx76yQL-U`J|j|>JT&V$@kL$t%K*g^HYyPz$WbrF zpJ{$3*T#-7`BOy5+$UcUVxC@vM?g$chwrr&e4M`#_>+UZ2wnclFEJn~&U;R)j4Rr^ zlIuce7@_D;dvQlk|K0e9SXYctY0lA{!R5~0k3UQD+ruKx5;E2WPe~6vhck@2G@HpZ zU9V)R9AH`>qB7m^C)^5f^&+s>3aUS!zvJ$$^1=!LHS79Aw++cK9uK5@SEbL`v|BA> zhAZHvoeHI~TjfqUv+$2r)*Q|+ud*}}sc_kJ@eUrkf8K=z;`g%qa~B}3A)LZ2esvH3 zB@c9lxc%?Z`*Fz;LYvvIZ==9b;+swGA1Oi1cUd}Gl)Y_XvuO4E&{>{^+mT?|DzijU zgh)&J2+vt#+>$4b&G~4w0emE6M_@cQT%w*DT^e{rX|tS z(j-=sBTB8CJD@ZxDd1+!>d@TAk1Z27ceOE}*ENkQCQZRXV>t8WnFl71avU~kgLq6(|xyI`9D;8um zKzde#xYNbpciQv|Uhq1n#OWkzHAk!(?JJoQ{4QeZOZbgJ0vb=1YNJ*~iT(+R!hax$ zQ1OoKw}oy*s8YT$jD?pilTEC<4xUDdk~R3#I4g%-G=+cd7_4)ayIXrrHAPH(6_w9^ zeJskwC|0zBmiltUC-OQ)kbfwlz-4tc%etSHZERvXywEkgoRVIHn|3R&hh0AvlOU`I zu)?4()sw%H+^GHmTyJV!)v8iWkk;%flN6(6ipzg}D-jfdZaiE`bx3g+ic@$l!haAw zohpTr`FV&kRhoo$Q=`oXU@-M4%ZN^5)<^j>WO)5NB7W?krBY>&Tpnr?#d%b6yn3P^ zPzSCDK*;;p>FC+k1xWYNqyy4k$Z#(*_@WVlW`aO@xc;wO=$zy&8(F49zMZ~4#+V|R$ z-r!xy!Xo4Oq5e!1a}nLRjqJz{NS|8STq^Z+OHoBL736D{eTMVYrnF}f#{eqrgVabH z)s5s)QVbPFWAeTzV}^s9>W-}Iu<2HWhZ2>p$#Rz8ONG|ln!F0*EoHS-c|hhqlL&7) z+xzjXAYwGSG@mo0=oCkrk?iBmV5}9hR)44J-h2}7*;M;^Le^jPx^P=zOMZHEeqQbV zz-T}n!}Zjbyg;UO!Kmngg(!R|-|AHh>q6m|d_~6W8ap_{-mVa{v`ZcV_X*t;$-#E- zR1fSbAox@`C#$7N_w!jptmKOrqkak>Sci9QWu0HX$f zZGRbn`Rgvrw&EB?p7{%*)PsP z*6YaYlquu5F`s?gnO=1;(s*z6Q^gc8Qg*9q)w|%Gy%*XUE>k^_hKh4z`lI#1@{Qd- zlL#ZAzB?kbmFl3m=&a;wDMu5z)60#!gd4I~!du#^RQS2zw*FGxnH(FK=n9Q; z-(4`ECZt4;03GwrPs38*teYqbx|8C4ovq0&gxyN5{#03zW*VbUh_#dtBd%X;-S} zU}>(XWDe1Y8dSW-$ZTB6F9Ei9)t&*)gcZSYp)oSHwpChGgu+1*t`cbdl4-d&p~7Jm z2}U7*$0r3;GiTzPZi?QpVLY=I@p0A8HHUTeqIST`HMoF9tH&QTA-Mkug;4?GMe^A| zqs6CNM5knv+r{;huqBuOjejOeih_4;trUYJvmvt|V8X%=8xZ-TTA^Y=Cbx2aXd zD_brjg2IrlbEf8vFSF>`Rrl~0A|5%@jXg&~gp){;PC$bJ|ITg`4N!L_>o$Rb%_Yv> zW5r?ui%x;goKaRNS`=kD4g>RGMnUn_H~kIAryJs9hgWVpk_?_qZXNX6O7yjGhQD(e z4GU%1ufDg+P`nAXOk=d9RI;GhnnmP>hG`V8^V8%C<#gYL2K1Nxn49QZWk1I?*Y6Q+ z66kgoop)?TK@h#Xm*BXxY<*u%gCWHe)OLFS{-d|t;y)RVa6#6%fPd*VEUVZASV1<31;jV%M#hhD~?J_<2_du(dRNG zeajhk%gNbFY}9+VJM?5TrTJ^RySuwjngOZPjcV*4gTcs(GJS1io0{wLa#>$g3~r%% zcE3#Jr>sy%%2Szq?~m}DySmVKAp{d>(c2Y~eob36O0g4SA*u~hu^rnS<}7Roj%ID9 zh#Z#oX$mXy?h+US=TniJCiM~e&;#Y_sB%SN1yVtlrFi9hHYIes_XS(cAOY1m2lgVm zT@Bq`b>k6d@1CN%7Dd*N4uDQ_k}R|Cy?nn<-G*2-83HBKncVX_eEn8cq9a=;*u6VdG@r@0}ZqocH-?6$IVY2%LnFCB;=P<))|LwpR z!1l<8P!pc`xLj6Z+!~Y&n6cED81WxHe!R4>5$DtJOb8^ z7|e!C6L*?Cc|>P7?JEhoCfdyhXlg~{Axao2=GVRoc8O!TDHFVs*x~wEY_myq?R zMrH@TmTq2s6-IcdUIvRAl7BnWx=^NJ_y@L%R-#t^EXSdFq+T>sc#PBZ?N;)wT`+m?xDY1!GGwrffu zurU0p`g*5rdleOx(+R~fG1$9z?@lK$#}q~Es*{KT)(s-`54pzYuM21#j}}88TeYf4 zwj;g^PS!)hDyrY{luer`z(&5}ekrrwjWw zOCLy!BRMXWW;*g3b%QS$Zj-?lff7V@fgjCU_>!TtO?v(0pX=uX+5`~BK-fI9kG%v)~H*QwI3u!UMWkO(w78pg;%Mlo^_++RhB z;ZZe>jApn4ffWHkghRbZrO&2LIl8|{2_DU zM=(~vPnypChe(663B)K;tdD{GW1)Azk+9K^J2>xw4mgnz+7c>oJrmlVYq_L%&t{7o zH1x@>u(^i8JC73-M0kT9N`OJ^bPldr(T1Y95pj9O44{AcEuWs<#<)RBB|wE;sQMw$ zZrQurKF#*G{nVJw(=0VQT6V(`35GOeE-;wbGjr$&4U{}irAg`n$3JUC&lv@IN8Q*?+`^U+hKtOe#3GLU?Z3Bx?dGv@a7EmefxkZiZE1A@6+v1+>QH3T(uScOahqk-AD5OFO!?q z_GktXQTq~|ovW*>q@bVI^Ip~F?w+3aEv&@4<%Pa9)i#7e;^M*0feI$3rv93)yT2%# zR9PpmSb*S1fwF;tfoL|M$-Ys{bZ@KqBTX*{e8RaG05p_SN7KX82iymLFsdUYVhn+y z5???ExsT;i@s&JjcK(duuca2g^Q!WECyL@g;a8#J(yX7oL}Ekq#sYdIZDLAHoZ@=& z*rdd*d6|GYwZ*-VZ&FunRbzc|X^gTb^J-%58WI*Y^6uiAL}3j3*YZVeRymn+L9b#j z_)N4T{*qku>$$w;{<*w|#8J)e@~*?2uA29-yZ9b>8d-xlZmL^RL0WAub5R(%G3;Vf zO#{(>VQQ*-uBL>i7WA9rbYi@|X4E;u@o-=*ha>l3-~6m3%zfgLM~8PZeQs}j>Uz5| zYC6t)DwRNK#Pz_o5Q!s&v49p%9OkPzuwZGM18%vjzf`QM@{Q!cizE(oI8B=R_3LNy zY$(r7i+I7PTm-Nr%e1j;G%4zACJd|ERv6C)`3>uIB_vp~l`+h$)-|*s-b|Yc4Xhw; z)WK4&>Z|YoUj@B2o2Yx-M&*en(Q(*M0X@K>S^gb2+3lXe_)>?d;P_0zRY;+!!9O!X zONDB^J}3zeu=s#3X$Yn1@=-Nhb|g*NhK_($Fdk21)`v`4c<7FTW){YdH!W$HK z=0aLe&rV}5_)=uPg^ZiX%9fV__td`Djd`#{kmz;V!2jNWmsLEuJ(S1byv30sM*HD~ z(S;AD8(M@xT)Jiidn3aqg~X%AjG9c=zK#AQ`He48$h~Gf{<3N>PX@~NV-TKfO9P?T zi|KA&PYDh16D^%F6?sI|dFTpPxG-kXNwxw~;41IOj5Ve(;^nK5#(x>R`{_$RX>AK@ z?Ej;k{Ph3Jy{(|2K=uMI5EfVXCW>2GRn?@D2i_&@GhwveTT~1h{udc#Wo3P))S+Xj z)h!N$%oe5?h&u_@p_d6IB_*c@zXwl|ePC64^jR$7R8GhW=zy)qN5~~k`DzzUgvd7Gdp>gj?RRqe?flU`!sJ)5CeY0K4U>c1*;{c zdR`f(1;xj2_NoPgM0)AV;-kCnAh5 zJY11A^*1VU&C7V*jwM#Uq7KTv@eNGrF+={*^UV&rU@o{^^;{1_t2ZR{&R-8~jwA-- zFlaC)R>$e>Y3UUd5(ZeHp}pZzL@-=-ZMUe9LV_d3Ty{6ZgA~SH59NH+*LsFelGU`W zXXQfBU8r=pNwtblNlC4xTFZG+Y$h?Av0Fps{ertVJ}>%uV_z z>bK}1f~=@dK9^20{{~EU)s9zh6HlOX`VuoAeLNHXxRID+5s=sDJP(XP7>{=N9{UaY zR*zjy-t>#)_-Z~(f-E9E_Wz5S5?1)ygcK?2XqzGG=~qNu#;2X(u^_Kk?mI%CGn)Ad z5g_B4E)usPGu z+&*a=Qd(3ey-3NDMt$k|wUuvzA93^2us1@?nB}atnrpmMm#*-E3#-YP6|Li*fbtOSN9#(+gl3<*tS@C3( zzc;VwqWj`#g=uSoio;y|7E23bmD)}PzA7$*0kI{zLLE|-gi#yn+tFfojQ6{!WIslD z7+cKg#)*6BF%x)<5qg;7ag!+W)3v(Ngq27R;ut{>dKQv!)hibLJ;$JdiG4Zp(N_;F zabGJf>E3@z`BIcrDK%Bvm)qM=m(lTk(CP_U$8f3&`;OGah(1+pJReO+KLvM`A|7!M z+s#Ghn^=M6=R_p(oaiZ8Kx+nVT)9rITK);FDrUiQt50LW9by5XbXT=|!D^>2mD)SS zz2OEgTqc|EA0*!(ZTivJ<5K)ykBB;nahdY5I_5f7LkSjXyU1lw!1%k%k8Q`O0469R zyk`^oOXU!LHE@{GuYTqFe0g+IZoFxYM%`ly4 za+o?U)rRD*LIrvE2Hr-CG^OND2`4&#DRDy&oMi!W+EN9mep)Y*wn)w1*3Qmu*U{22 z!O;R77vz;OBE()V{lQTyiP`Y(?T(&iuM-eHYU2g?wJ*Gx+40=`8MU=;afO7SW{=yV?3j$^ zf_4GmgC=kv}&{|h~HO@HQ&;HHZUH1W`H2CjXWxju`1y4n}$qN~TAy_Uz$ zD>eezj)fW~HDyZBVyy-bw(j#|zA7Oqbr1OE2N>D~t*LuyI`0BxZq4Li`}thJ0kS4Y z!FLs-yw~-X-JkTE6@RZc>h+Fxho8i2xB60oG65DjQ*+?q+IP=!w zJtG+dT@uj@jUs?E&Y=BITA*z_PuUj)xu|2nX zjF4NpEV3*(Zk5j{{tf_2IYz8^j`2AIndzNLP0xH;%jPCZ;d3-TElB&bI{w{T5QV~M z3tEuX6yr1zjqYX=Y4ImHeiAz?#Wb%?vW~PD%uCO5NVUylWo1N#d$mcu%yPTuLd`91 zRP_`YQ3!$cDU_==aE26=bm3qaOghX zxA;@h5U*VUtNh5$rq-OG8pmj#Re+AAhCeg6yunIJm?AmS@R}}m%y#G1vmp(rxHm_~ z-Q;Rckz%v)y4ML%ajPkb>G*l?1Q4NKSZz%@?NC_%E!bMf*?p4&w~p^9xRms(0K1(fCXf>wFt;1hnExEWA zSv@E#bGyhfgcq?BdKVC@U1&9K)*T?OHIR(g2|)Fo@pb)$`4ewqDEuu241aXrd^m zjgloJ9s>np-AG6K4t=xSub1o;)0B7(VZ!|$B0cp+^3>4UzU6tXgvyxvX&3A6UQvWj zf!y>fRm#_kbGcof{l|+r5gYakE)gv=fr)GqMkQ8k4~^ z5uZt=02LAvVwoPMoC+0KtO}^cjYNP`bB$A-<)>rC#8?8I;_8M98a&Hy_8u<3Z&nLT zn!&_qJ%`SA%Y5ZSD>F=`gRXVNj=NoJ_F&Mzp}J4_!1{}FnR~ZA$;ZCi!7^7%n)h!Y zj|iSvv{p^;Hq4K57<%spYaxcW9YSeW@jW*2S~#3WA_7IoO6x=mQNNi zEXu(i-?+6aHo|@>e)i+so9AK1h)c2K>m9>|uK;4q6OIA4HkQrBBxXgZnH6_u-Y#&f zfkwc}9?ws9_)Mwor%R#ZkIA!>id_Pme5?XFOpNMt3j$MHTxWi>J2pb7B~M zzt6_4-=Md#b&|r-uSRy?j!Y;f^rtzE-pXASbva4$VA0~Qg=IP)`sBU1wSqLiQS!`4 zI7sM4M5wk?gvy2VFmKt=bj$C}VRGK#ZvP;H_B2BIv^{ScIMd31}SO;E_8fWGYLKiQx z6B`?wr9m#!-=cL|Z(>xwpf|_;Vr{D36@{*zwDduBn(~bM3K-V%A_>o;-+);20V_KF z3xxu>k-khXTP9tT8etNzhXMc$@o(+wPdBM)Xon7Pj=k?Md-Qrph=FWFgcgLn2WFt> zqO@D5$+6px4)7V4(If90r5A~K$1ytyChBK+g~8!+K^7Y$}s#qfEwnnJt=+WU@WyvUA29bvFfW)`qL9&5uObFS{2Ddm{2E z&*kX=1!36PBkY!zk>fje!4EY3A8QsV?k`VxJ{64%*!Iqyt6>$E*aNEiZHy-~sY=J$ z>7x0u`HXn!gu7f=@|2)v^he!tK-#Uy5Dw?)!hAcrVzR=*^+J$cZe8J6p9d4M`;Y0D@SH%gX zX)g!fb~So=JmoqZVxeymQ>WfJ>)yhnFQUqsYqKouX%wg_SBpOwKj$6d1GCOP{!XdR zdFMK-pspY}JSDeouwJKX97bT2x@j8r_zpdpek@YUJh(qP0scEtGTEnA`|f&tWepjX zEr85|L4XEq<*Wr2u*Kx*7>@?l?jiL79y@WKOuK#rGbTPU(Y6lqI}|lsw5Fpm4E3x9 zyLI=vi_g)>7xMNk8W8R>aNMyZ)n4#WxTwLqlv`b`tTnh3(bx59Hd{smXtjzI-dZ@S zE-Gw3Q+V$R^qy`yp7JX>pcbtiT3`M!(B8kAJ(>U9lko!J_pa;kGPA26iVU(+FNj!t zYv87teRwC)ijlNWx}3o&V(L=tXI+m)+SSzQXqVb?pjJ%;slFIly9WpztY|Zy*O*FR ziORp4D5n7bJXs+FK!_MpvPv zQU^ZQ<;wQj2$wyWcWYhuvzk8`FG*{>G}7d(f?e0KOv^4E^suQe?G2uKh@7H>Dth1A z+80nw4Gv%dw15mgXe-U2Jm3b)6R8DOGm4zLjcgw!{wq0urtSX6;O&1-S1^=LI0P8I z0E1z3d}bFX)UsDM)n~FvS=OAN1A1-KGu^ED)+#B=g>mMdgD9QChnRc!%ko%snV1(s zXmjo6#vTS;@*EP{`b&fLU^N3mcVoFS;CCWcl-uLef+XzB*3((ft7}2|n5EImRqY1NYO-&{#iGaGkLdpbewA1US z*954WKXADAol$w5QkNUI$mlxIxdmC7w)51AX2EY15XW3{2ZWFyZzQ<+iI<`fP}!){ zlH9^3qu*X-C^srCB`bsC2r@!J{tOgK+q=o6TpD%H8noDp@r1?gyXSgdJ^fk51!UrL z1rpkp!}1= zN@>ShSx~g+a!OCKN6~R=J{FSO;~MXm6Lo1h5h)zG7FCXLtx#qGLJ^LyyqjQ-&Ul}=5y-?k~SZfO* zz0XyFy-DWV1D%e{;CBI>>j&#aYbAQ_^srfr_A$MDT5T=pM z1=8==GQe(%Ey|q zj72xI>eHn5I!RAZ#D)@Zujix~n;VM&?Fzx@n?Hm`rEhw3}HzEee`4_8C(G4E!*BPt(ZX~+TK4sBjV$3B?^*w$D zkW~S3m+L7g42&g)NMJaRU$24$qSYe61JA>?aVm>m&(a^dsT|UzDRDoUO!vB1V62{8 zS+~t6Q>_H3TpvE&{y;wBUzXFY0c{7W@uVO&d`@3zE2N8eQfrJ!TU=K> zHh_rJ0{n!YVy`!{Xzc5N_Ikb!DXQH1w6^^-@iBlMCgDz|;Q|7t@vxhB5mE+gN|0;E z9%DT&s&IIYiTiL(@zuLZ$fonpeW>FRf8`rO+?KfIE}*jDT|H>gUazqrecY+aLRhrr z-J0|!-nbk3yzd(CU!?#4ktKCr?sk!xCnJsC0j>z>RHwIst4A$SMxT{5n5%lpJ|W5) zT;{w+78RmVhMhY3?fc=)JR2+$`j5rxoiPjh;S%wnc_I}BD6?j-Og4wEo~>Vrj$3R; z!bkJp(yKLKMBs-HU9Z-DCeg-m4#sljsXxCxp#_KmGN`Sa<3bH9rk%^-Jr= zazCD}f%*fwH*PRo)xga0O<#26I%G@{YaHGwrMr;anR7%-__m6)ARJjoun;?FwY@xi zM{CaZlPyR5!4;b(W&XvwuRBRgWMRY8S0e9ingQ~_t>9j1UuChQ3}Sk=dlbt1XOR6iLe@+In$5O}Vq#|K@x41{T`Z`I!)3C0eav^&xd$$@!b_%aI@6dp2o( z34;Q2L{e23{m!gIfX>C?JE5ye10O5%LUke~8iwB9DO;-j?kIRGlwu*<3vrnFp z={uxo>igAu0`)KuH<((YrYZZ821F7If5`emGdyJBeGK)N6FPJ(9=D%sRts4r`=mvz zhm~B%-x(LM7EH!xzSUp|m$vsTr4TfRr`HI*lhTXe}G83M}LZIDl;P{Yoxt63;QrQ7z zHrRW)R4o4eF{akzoENO@ll?@lm)OUbMXx7B>xYBd^K0$fOUf_pG3|ixb1QQ2V!e`vVmC^PnrYtpPQ`7|?#u zZkq(>mC^OdtAtca;2B)};s_L-Q*m$&gL}6l=d=iq-xc#u-QbgDn+6WR0#jWh?{6LB z^TWnW>RRCng}h{5Nea-`l;*3N!gOR~OoI`*6n&M6nF=@J?Jo5X+Lw|bBk30mNZP8?iW;*sUKN-k8`e6<5lhrRWrma?bNUm_Ja;WGOP^^H77NSE zUilJQ!grt3SDlG9u#ebr6R;z8xl=QB|=a@^qsxPVYQ86MI_fX^%r=))q# z8r9v<7p?<5Tb5R8J0l4|mfW_mMSAQs%))T|Odsvf6g{K}bxACfb%QV*5nTB^I`y_c z-n|0zRPeOHqd!XRphOScrtDd&epgc!ER{pVao@!+KrbS}G~SOf#D0b<<#AsoHmAEe z-pPB7mXv21rLHE_mcF2O-b(n?T+?2XRLOdSR{qQ26Peg8WLM#{f`Pntx`_0kNS%Wu z8hPHAcHQCp#Ml^Ij_cn8i+r$=`v6f9nVtwwRQpT-HGtmSipV!O;unmNi%pAY|&c_-&NSr~45yIeOjaI-t_d-WoVC(?Q>NGZ zk{$iJ{$rWEIy3Ez<%-oXphm%THL{jZ#TB_?W zIwna2mg5$VT7q&wrUod@C8L(NOgGuDstf|O*4xpXc8|$G%T5@4Z7xF(<}22nW8X1! zAIk^^CrZLxI^d)MXpZhioSH(2-K<2zb5{yTFZB5;MI^Eg|NVH!qC513)dc>G^-Jl^ zY6$ak;@8kI4a^c|+CR)fV&)OlF$ zFe&=Hj=cv&N*b3MPN@fRAey!wr@OyRqT>tWjM@Sco_-tJt0v+4D=KrhIXJe~ul0Xg z4{WPz`*CmVxnt7OlFHy*o{obduAwc~7!l);F)1-#S0J+8@3x?ss^ryof9JqW0?a zEgxE1Z}#$!54e*DyCv>O%d{)=!r8Hi!>qf&D3wo(KSg(+gVUAByL0N=wV>OI-J0sa zk>={X1NI$-a_@1eH+jdVVS0#5Qt5TK=*obZPy_7+^J({EK~l-pplECOOYQNH;(Hn@ zr|gLpYtPeOnmt?00YRBbHN0(#i=TTH(1u1{(_yP2WsVMMj`K`LQ$YiiQCq8n&3u5O zDmI_cl)e1>JWB%PmBhnciXYoSF{Gp>mJ*IlMw?&~*R)mSNA^ z3<4%-1BlVN}{z|ER1nA9KEYAL2q0IV$ zXaR<3+5?Sjk}jLe(l%q_*6wUWX|3t=g!rb{ z0Meg&M&>4!UE*aWX~rMGbS;aaE8WOu@85h*F-3R7oBu)`0=S%O0x{8>wmuGKVUJGj z!&|{-0G$8JVY0y{fwA&sG(eWt>&Cp+%b!9G@He7$_$P!9q?N^l@$-R%>`gYhh@V!Q zKdq7V4ua3~J@NqsVR}5s+Q$kBz8QZ>tkK&EI6RkgkO*aOdi=HE7*dV63rOnLlQ5|U z@y#GW;$B+#Q{K)$@vxKW%&V->(PQ17X*~1U7#V2yo$)4FG;r}j*&UBlnHsr`)gQNU zHZQIH{nqdYwh7y6%12MC7x3g;gJ2tuD{hM|49 z@bh^|WFTJMc?z-%+~KoaalV`3ebSoViBY&)JldwKb81ib3A>L3dV9Ev$a72<(pd&1 z(rsC8r6@ol$p_{wnZPU$`wNoBz8}{nw1T%V)z*c!He?!KLn(NN%S*|$IrBKe0cAiO zA2U0~Ri`J7rCi(eTPg_plXB(cx9sHqv;i5M*2hY8fgwuo8bVP|yuSuFy{qVXK-u{K z6A-6s{N)WXdgMMt_kHr^f^cZiqT>uO{_Ugn`57w**$_~cE0U)nc&RJ``ezs~DBk0^CwIvBksNWaHq1W3(m9;iTn!BfIKa2e&hE*nCnX zp+`bZ)TZGWaZ#hE7+cS@(?MJfjpkj_FD*AnN0%d5-8p91T*lXXIasclb@kDVxPE=^ z*<#%vmebCHHC+qhPUc3K&!&3dU4x?J-WNsA1$-R~nZgR$K_WNofLYt*({gfBgqn9m+hVjWQX2V~h(O+M|7;i3@mmQII1{5HTL!$iR^8fZbLbtgI4o1#c@Nr#+_0 zczGv9d7F~Sh)xzNwGHP5D{ZH}(Qy7I6VEk;^?#jOWjMF`;F`Zb$+G?M8RQLyq_td(HeQ`iGdT zmgi0=CmYTJe8ini9Ia$pzJSq+{qMy1XvN$`8i>Bar%o`r>A+;%$3%B)JsiKcZ@zoi zH|@Sj;LhgLf{ZI&H1ARd4@NxKddOT-xYdd;3-y0@@=|)i%8b*ZJ6jXGHOw^Wv=ruZ z-&|#U8-f^DY?~zq56gTSCbHP8Z(1IyP2DT&5J(VdJxH@^Z+yu7f{IL`{rYRLKMfup z-hY8LEGb!nsX1B3y=zTp8rQssIs<3HMNo?ZC=kXs%WV2?bMibIZm4?FN${9r-{{>A4sHV)Hyb#@@=k=lsk-# z-mw@z+Fb5|_d74{(ZF5z5r)lf)qAZa`Hg$61!c4BeygGkm^;EbWMn+CXSm51hrF#P z7U~O9h&h?LHAxmW!{b*2jFX;APaT8W!*P+yUrq(8B9_DKRi|3c)@q&4+G4vUa$iq~ zbfLs=k9RU$m@a&D%Pk8>xdxa@LF#1JpZ@AQ`aX#_d4JlJhZShUR}&}k`V%`R>}(vz z!GNjo-@K%i@M2DMn2C8Nl@?|EMMoj_^ou!mb=`SwhHSC|_e6)mL`Qw$Yi1~@HfzgY zC$oQbcfR+8fMn_G4dvcfQR?!=tnu-W$7E2)i*9MTcF0DgD>HE z$g7+521%ezJ2uKk+cP#*o&3Vr%Txf^+){Bi- z4xiJpE^J%(x_QS+SsM*#KjR_mI%mRra?okEGW0lm=i#BpC-G#2TLHDWulmNE-;DrC z7LV`84*8v1@Da1AkgrzyarG;>jy5y@-QkaQct|oYRC{!&aNn-MnDctKjb7zq)>FL} zBZQQ*oc$bviNt2#^XpIiyG^fM9NizccxPvzh-NcMSrDV{3C%aN3%AZ{Xp^*o+X)>Y z%(>_?PzcLdu6*S3&wSgqZLz0@EWEDeQD@)9r8AJ~FADLaeXU^EH(>8a%+YtiI|JoW zX?9xlgkqn4iQNGF`w+`#a>)^1pm_h zh&x8iyHaV~VV;+0d@})V>wcE=@je>|wFZMj^R$wF%@2C2`n9XZ^_U*(L(^kZ7mD^U z#>R};{2y=b^4m|ch(NNH>}TPu?i&(OI1-yBlXVQ>ko3(9J0XV~8cBL_54?IU;o80r z*w{wJZremJ5Y4joDc5$}OgNrd*^f$-BW`DUw=dS@Zca4&(vp#qAOK_MUR}Hq! zUViLV>R-UqS30#=bGKH_xR0&9dfRKhh#%6a1K0D_Ew-PF35lOx+LhF-uEWL7g;#Vx z@pS*p^+Uopo@*WfwjZU{B)Yph!MT@_z>z4hEpnnGIqOOm}eJKm_6{=-73hZV0;Jhyj54|aEY zsb?Dq4-1bcYk=UxZ)4&n4TgQ!zbU@AueFYVlp;8*b?stEaA7fs+beyIG*Xvk!;aoB znW14lVXk8NW}OTOQl%%tr%WBCfK(uBW7>z?_bi$@u%; zl2bSDUJ|Kz%0W;p+P|BuT*6U>GSWC*Tj8KTr@a%qN#~cYtu;~MN|9XY94ko2KkZvO zbp}~1u^zFXVN5<*->*7bf@Wo@Z+hn)Ljp>Zm*j9-i)4dgcIp-zfa;WcE@X@*- z5l^A-nh1XI@}A%RlsuM%c)ABHiD5F5S4|w7-tQZulDaaT-k^3bK6M`$7sYA5a%ALu zqEicm8cjLwInuQ+w5+;074^LXWHH z433q`+4)~=h>Cbto^O86*u>IUwEpV^aO-LGapVKZQ`zsWC$qNP%kG0>%8`}T=Iar@ z&WKes>Go8iiz!3+GX{4Utr zit88YUS;NhFW_YW3--k3`uiEMe4g<5c$aguH<7KGx^?%75F<(5*j^Kzo$6)0CwY+v z>6MmE%>pmHwi*^H3hjH29hPU}S)p$=6Jd$-&A9wyUw<7vd?@UofW^*YV&Iz^t0c*6VK!pnC85nf9?`8P zA}2$L7HU9t)HA`Pq&CM#W8_#m8aWFZWS4TS-Dj&68(Pma88_ljDAD(2k&mzaImrZm zo>I8cB@>#9t(*y;YT=!r!{&AHQ>IE(K+<*brhI4NJhZX zPY!(xwy{AxWFtNkhI;kr_oL!IY~HGAiEfMJ{h5st@FtVIoc6cz*wlncS!lW6h+Y@( zB>mtOWZcfdJecr6j+BGL zkge5vSPZk>9X`Dmm0N%$aDOK5b{g{3sKrQBi;I}{?AWkiyKVNa_u%t;=wkZ`7HOpk zp&MWfeVycWzKK7jE5PFX)r|mesFgPDZ}t}vC0cB|i!Fs_$1Xv2W|#eh?3r5aKXbgV zDBOZZHuZ;*Q7sL%;G`%>g%1bx0t(AclmAxB`LWim`XJSq-%K|D!^BG;?8DsbjQ;{XWM0w%O}zT7GGyvfjn3pzPD(1 zURp(DG%<$OZzMYP3-?c+`OFB6^updA=o3`#I=ycb=7z=>yCXYwUC=nl1uNbtTxrEI88Rz$ERPOZHnk2av+mw~H_32P~#C25gFetFB zI)u=r6SIzp$)|F^;(k-yZ#R%y)J6T=f7EZz#RALHTi8jJzx!Ru)9j<6XSJHT$r(Pj ze9+q*aBoMukxPd>iwjCm(vhdd~N)Tw-1BS{K{nkN$6Lm4ow84fjRE)Vdh+`WTD-^N7o$US_2T$f~=E38y=BdP;J?DdW+L(gDt9*)c8&XDcIuHu+;)9iS zF=xz%uU-`{Pms1&v?OXPQ5L$h3{G`N0=^1|lDZy3*dfo}sz${-PFt`!Af(}o&S(+O zi!!>jU3=XWvv|Y*&siE^LJc$2qvr%~N$OOG%g=3!=ej(+*zLSx8h5QF*=}SnP?#-4?Nvc%#@~e%Pe13&WNh+Fr(92C zZ~0Ijw;_O1?ued*2I$E`2dQPDwcVplq=B+f-f_8lcFv`5wW%vgQ9A#8Pl^)@kJ@S0KfAF=umkYf#r3mk9Th(j^Es)j>7?-8M(cKwdfoHi>Ex)eZt9+#(8!u zow%0M{y;KXYCnk@fWXeuvUAG2_9|d8fGlz1=;5co6s~x9S);%PAD8~>zpnX{^L&{; zR$~vg%>X22P>Xx2M5Mv#0X~~KYPcH6F}^9_L;Y4I^^AW!(4FH_(>h2z-B|*sifm{d zbg^PJki8=oSZ5K}?PBpd*7u|TFggR@nWgnIdI8RfvY1Mt!A?#nc~;NA_Cy%S+BML< zJvNQ(#p<7V-V6bu`&$Ju2|yuXl32d{YV4Va->&6)<@#h6^?$=jg>1~U@CG3b<3y<3 z`Y9I4du>|^dNP|-V<=9mKdRB`9sl^Q^h3ldSCA48Y=ip(#)n=R$2&Nw`J%0}qVTgL z!%K%)%+0+DHi3T*ue>&BF%`er`gLmo%WT2#V%m~)^$Nl?57~)YrP#ye$T-fI?k5DD z83H=PY*HyyU-w=9l)STd|G)JmP)T5n{leoSgf|!{>gc7$PdA%sSV2Hco^gmc{^Fhf z?p=H9=`02d36gaFwuay29mnv`5jnDYzI_k7>?R$*)?5Q4G*ckePmO7+p3dEgHqtt1 zom*$~+nJ%l+T-S`&b||R9zRzmRp0oPhTkxt3%c_v_oCv&+YQ@_OXn!Vi=%A1(k^<{ zr@}V`f`9%78v%f`CG6mI)sN45cWXSFd_=8Vnnirz&B8v==AUD)4(B)BqxYxw6MW?( zrW13*CjWV0vZs~wVx}lRyED_~xYTEao%`%L;`Zsy?N>+SOfTINNCzCHGT z{VVVR?~h0&{}lTE`j_ zQi_5It1|0e#>-1jMzI+{kWwN-#=~C*N?WltuKs^Z^)>+GR3qg^c9^aaI9$OoWp{;Q!C znT52m|)b_M$lo>_+o$+Z zmSBxTXJZQR+4?*r))hkO!*`wDZVjDur7yDNJGaVxBpg0fuZ2x$%p>~YhpYFCbzO%a zh5UzyX>cB7R_8cOJl)w9}b{pHc&_O7hCZwh*?7H#mU6b8GFeK$~8R8*N7 zUv`OL&#E@Dr2J*-gxg4+OK_DGJ;k)2;G4W(j>bdZXBle}XKHMLlfe*Y|qIpJYh{UUBvp3W=mQWBchvwy1AI&qr&J4QZ! z`F6zrQ1RFEM9)w?nwmgX-dBUXCVqk*F;uM%q1=Vq4i=6gFr4>bo7%CC%h5GbIaR)_ z)_&Li=C?qVz2z2CscShOp1CP=54)c5o0ng}Q%XOfcJVdNZJyW{o1d{jfAg76pqf_k zsZ2I7T6%)m4?61Hqa&tg|J85EAWw~Tm~GspkgCTx?Ctcf*yJbaPVTVoUx^ala~at6 z48xkDt-^igO(qW;5fz>a*>1&~ucQ>GbVJq)9dHBv6(V| z0M4PBTNMl5iuQric38n7cdJlQp$Oq0hZoD zb(hWi4!g<9mmX37@iU0UU_GPLQ=#l)>+qn+~8CR!;0aF4rW@=arZP7*?<`HShN1Fpti z=_!c~h&O}o_KMR=ez5W}>b?zw$9@S8bg+G~9p538iaO5UHyo2B459(vkHDJEqbsEF z6n`~3w`xfB>0Fk@lG}xf?!U??h8L`42|pl4l^DW{`Wu|g(htp(+|htCfagdoc+hjb zGN+XA;v3by9ky$6yeP`RbTfe;;&)-?)=LJco|#C@L)fW>AGzGaf>n1TVXMz@#Aj-n zk@Yo9hi?EXwzsy7^QY_K6eCzA>u0m!VbE!69Xxba_}UvZBkH|(@o=wotV|2>&^(x8? z!B>Ky@7-{QCP?-ruU3J1w9h(et<(gnA;LQMbEOc7TZJio4M)94Ku`ENZKZh*$Ax^z z$!wNzOeVx92yTk>CL?$t=W8jGHp5ZWCvJ|>osbxc1}sU_Gs{nQoGpQdem`G4-ib4W zLSb(G=6>W>Vz?9^->1Ow+EM?1Wxh~KLq%7FYL!mAOdOPhZplJ3C+@Kz^1e1tQea# zKpZ~v{>WWgH(5HmHEWOV8x9%FH^Sk)X*8AcZ+~>?JeUg;iZ#TR*>4gx!L46D(WUD7V~DrbbrfO6(^A_ zsBd}kC3n<__MN$Trof_DvZEi8&L{k)w@p#JqI;A-d6eC#BhgTZMlXr-5~s3qG=+1bYo=drlwbn9RE}DOS>4w!;jM<8gn=$C_t&~*+p@bE zaSL!6aaQgm2F?njjNXK(&b z2e@CK^w%PmQjjj`x`^Wr7@4efiJ_ExZTvdPl-!X+W7h{XrmyU$RRZQ%0J^SKC>5}d znF3qlf}EEF>v$Wd=IXfnf_%$`{$9H<15wW~G$h&iWH%bYbKGup+fX+q?XW>Ib;kC) zZF~2{RfMx$Z0{}+fMDHs>l{Np^(1(O%6kGzmzD<+^U!u4+9EcW7bEMhod#&9YoA-! zJ1t)jrL!7pg?Y|ZN!5EkVnLneq$Tn+Lecr5?yyd!X=7L&2=EC@`i3=V^ZoqwxZZg0 zA7}Mz5WzK1it6-`#`KaGYUL8Km`L>U-u%C*!~BH3CsoZmLm*JCvC{U2Kqwo;X`KG;s z9ru+Pj6Q4S&Ij9;&e~IRv}Y4!F{Q%@MNu^^C&D`@#g9}jM`k1j4oU(0Et!NJbvW(H zYOzlSnZM&ad%v?TKIBMJes(A$Q4Y4}?we^1_`j+A799X5#%M9Hw_8s?U7xvcKHp#R;ov?MBeby6SVFlTC_%rgG)EZXG0LvP^LhH{|p{@L2 zq3;tobt~48>x`Bk*oa>5q2YU0_0?#)+A>45`PoJN9m-iAfSuI0Yf)vy73QU)Uatwf zU>Exa(zyGCvVbJU;L>?TeMI&~V?n=_gSn3`f(=E1&1O6N;9M5|qtyafFL+hSn~%Hl zjLE>#{I(B){BAjgfCw52xc1%T!krddKOU&_1=R7nerlyHj~f+AKMHds<7Ob1*#tw9 zBZ}B$ePF)up~1TN!2I%lL$m6&L0Q4I+M>cum(lec<6P&mL`z8hYU35%xAy={w*F^K z2D`DKc=_CJ@|)N9KYg{1Tua=|mg%j-Br84w__Haqp#L(2 zpJ2Sx4c3}BG&59tuzXad{^Og0<#RVFn4OH1bD$5}qJD5`DzT(2$6i+<+g4LOlFU^M zcrEL*4GrA1<4NG$e|%VRBK>bWsk8aj7=o{&`&^COa|zEpI(7w6qPlU^pHF98CF@>F zKi&~N>0nCDy!i2prBvoGq$QG`Bh7F}fAny!Rw_{j7m5vPQ99#x@f{>TfMfAc5WrTc zx1UIqv)Kl~>YUe0)C^=T_D#y4$x7&)8_29@H>hbrQwLPmntco`TF0LnB%D2nDKrx!$5k3p? zDlMEYDx79V(K!Y9seP+frI%RqhW(y{KPu{}y^^5JCz6aI@#!%99M8LAT3-!!&CcXR zd0GXo_&0W0xoG2gP_9{NoQL6BdL!LRj7{>wx2Z^5p3w8%h}L-N2Zhka+n%}^fqU$2 zUEY}v^~1;}ec@AmuJ)bOnyA9pG-@s}j^Tr@Xe-oVVPSVjqtU4CHTd}b4jFY6U0eWu z5SuFCDE{2?Iqxh)#htwB+f~-?*`?@($q+10>A)dxdtGN_rpb>y6=H2rhYjt!Ug!SI zMd6n}b6UwLbou&aZm4!^+3T_aDS#X(LM^>X@`b*3cUqHEPATq1wB3)B#v zuo4VEr2!lwn)1941)P+{g%pB0fU=Bb*C+O{!2d zyq^+NpeVHv6{rt6w4AGM>g9ZKn22$hAJVmh9PmIH|Iq_2>wmmP7JEDeCg+#Jt+k?+ ze2k!kP8(WxMtCcB(J+_(Yl!bxwge}U^uMLksZGwozhUL1`Ofclpzd@vhHoUG_1~2C zi;+$7dUSloj5(gntbl*tNlj6<^Dy3Ymt|iz-a6iw|BjeBkRobliR)^c3F|Su$Z#)1 zRN`mhdY+#O)x5ZK1mIOp1U%#2}ojUlQi8)LITnR=2eLAN|LbnllzVr}h4T=!QS{CdKF zR&2rp|J2_*?;Zi1MJvs0-cTbynskhiThqYO3`8UY!da!!xThx(@kG=Z+= zZd}6ismPS3WCJ2mgurG4;?8R_TiJ9@UptE3=GS7gx|S383Qcq<8E~Q6P}UCO1deIe z%9d>durlBVlgg?9Bgh+t$(EmYzADJEPwb6foII)cswXwEZ}ew3^SW~S+{@supWV?R zy19E;--9oHQ4ZpSzQ0@#V z@4OoTE+&}MLE?z=g}PXC9~l~38w^2P`#hF=*W2Puc5FdT-Ehm+n^@SS9-pX> zHpra%;}>(OZb7xVHJlw9R=5T+1W(B(bNV^}v1_Mvnd3vXOU((~R*FGv-gW|C6z8Jr z4G&>lcgn4i9$kNRGeaUF#Mw?gLVLii&)$jxVr1wilzw;V`EHQ!rqJ*G2R1U8D@^7U zZ4yT4u+C-K7}f*~d{D#%aqXdDypuaE#_$NU9UZ(v&b=L0psE7zMA(M+)#}`GMYyLY zDrcX-hx&z()0_2c?rwl1LW$E>O;4qLbTx+Ug;b@Nlo@WCWY>jwg}YIC+ZBJVlu@sD zF*1vjYWV-y`|7W#_qA;cQ9w{(07>a)Kte)5x?>b+25FFz&H)8R1f)~x?(UYBkcI(< zuA#eO;Qi`8=ULA=XYcduKj8h%#d0yj=dSC%?s8oI@HK3M9l;1bhV_s32N?fne4p^0 zX^&#u05j=Bk~cV=NxnAStKN3WzHb-1WC2Ot;Nxv}MyI|lYNp>T)T7-jIc*{R*Vobs zl%Ic*)ov@mP*-V74(^U8aTF9hdAEAYG!}ccW&%T5{iEK9y?UYHq@)ZYL5CajUe)j= zZ8zs1kJlGDfjg;G+b}KF3e}D@1eGO}BF(G!vlR*j#Z2yEC;sajI_WZXqas+mMs+xP z4-UO_Ys^iAGtN?3)JI?&{oFbs{lf@?b03PjyQWnofN0;mc)JsQ=Z0gu=aug-EFiz- zCQDFQ@mRMCtLb2X_kSRaEkv$QH0$A=VMKLNeMia)+eCU+P%6rITunI;VN~bI+39q-K(y%Thb_#l(rw zpXej5A~#R76W!5yU^snlVY<-LIR-5b!XQg(r0vBE%nKWRU)fT6q}zi+y(NdHZ|Qzb z4=38Ry=(`q4rlGRe8BZLUnm}P0p6Zr?Q&z`TPwGNuoK%h{83+&n-Y9Q6|GtQH2WGj z^RBsarCQkD{$BgShNQ4=4hS9BLQ~L?oK7dJJfttGXg@){@UoTgZ227vtRYd_M7yT4 z%ql8Rqs0N`VEd5qTyMUV?vD7O3daw&$!iL#j!I%onkD}rzX_+V$Ie2 zd;d%;q!EM;!FC19z80cRK{QEx8E^3v zwa_Ac1XM?v5c}j&Av(vv&f5bOmB+?)5aMB#v7;YZiG}3u4btfxjsu+CcLFSpy(Mmc50s(HMT83YiT#Yo4$%G*tEeTR5tu~Hl|g0C67x$O zn%*)U9WT0~W^Yrp!K~N+&~q7#{7F)U;D9%U^-Su%dgrD?FD8%R9)-pHU(q!z0TaAj zmY(;2=jH(7jVO{~-6kV2o~E5W(PZv+1)y1`!OEEqVvG4hSy9RLc7Q^Ae2nhJ!GxNA z;hWx*XkG_ONMBCume^T<8qYHXMS+f2^+xx7NaCh@(Y(*Uxzu1rS(nIuCUmNZ9(8_7 zS4CbjN4f~hVW1yHEBy}$p*2_2<`@EXk->x`M1+NP^M%!M8KAJ8h)W9)b9m2l%yoXr zudf5yBC*#}H6nGWW~bu7$|{h_QO~fv>!tx$^SFtFfT6p#lgx-)DN?71x#QVZ*wVS? z)Yh|Q?L$@v#1q5@x3dIV|KDEc(@#mZpZxaA8~SF}Q8psqs+KQ&LOEJGADfgStEmZ& z0v&|(>_l!T$DvtElk^!WAuH5%9gxp`A!o;V8?VoY%>pq1`e!PFfCyZ&eRa*0k|@*pYH8R?FRTW^y7 znRXb6;yA$*VK{2yqO38SIB&1oOM_9MLj9x31-|p z(Vd^lv@hwiIp)*PW<+JA<_}f_Uf1yfefLxzzpP1N*qKm#DQXTYMh6uI{`KIzh#|vw zajQq>MxNJ1gcy?pFbV!FgUYfNL*x{bIw^e9R7>MdzO8O0w3X3p6C2r0&Vc$s->a4 z=l6&%VwX4$XH~ApJ--7ZVgFhJH75|>=l4)>H1Q3wl|t)ZeE92fqYNox`aaJgI5#gh zcXK5h(^Bv4zn2j|a08mIZl)xjpt3Rt&fWkciT?ACv&zlOD-&+z zJ`8a>GR^j~)Z6{*(y6&2Wmjrog4>DMh@R7bRyIGB14TQBG1GCNBJ}uDaGe23`Cq@7 zp8UowQ(_(-9w+<}u0Q*I+_|~A=jJfQYto~*g#TY?{r@%bztO%hytKF2xj)x@yTcT)y)bt^I3p-DzkS|Jn5IytgQ4FvGf*YM@J(1WkE-<()k0jegE?- zq>B~`Z!``!_N{Tb+)+oY46)DfdACgDjcRQD*mS4R&Zf zHBtgC4BtCuR1~ZT$ zgM1xcV>CGK0c)2T+VeTT{dvC7R;u}6@7gef@p0s%XL$x6s$xY9zr>5gTwX5Z*1AcW zuq81rGGm_m!*3f8wS?InwmkyFrBD_k&u7-AL}$pytMXGj2bzyx84mIat0S9;LcTFY z-OgJ2;(D9Dt4|TR+2fV6z7P7!Y34Cz!DZN-+*N9NpkxDw=QSZ2(OG@bAGv^U`Q>Y! z3cF7IQU+MB$y1j(vp-B9#ASTira74EgbbKGsCL@=Hl5(ipqvo>2tU&_N&I81Ud?6> z!N$eggSPWnpaG*h@bC7bB;M7UvOOG!tZ}Erlp_bE1-8lN*d`0tnP3b!q1Z9(ldXhX z11aMBc-Oml`}2O3ay`*(NwVc;gJMv(HM+IQ3JaCF`8dKvGg1BJq2*_uSC2JIP@nUs zobzeZ?2ynW{N~@t_}#c69|s0*rWwgq0dTm#EBuRafl0T&Vb-QOk>o4_zZ17-)swR4 z(_WAfYNV>6{oCLJE zlOPC_qK7?G>3d#4U|z#y6AyF$$V&Enczc1UJiEBGIXNFOnSJ#(sMnnDWo5y1Z1z*l z2Z?1bzghFsv*FG%cAf4HIGUGQCwcIjgzMCL@I&;*Qd=s0GUY=s{4)B(Bf`>778du- zn`BF!XRq3}wo*gdp``{v zSPMJy=Y1$5FuXY1D7D*p^n}N?mQ2v|g<7*5KN0AYGb0(YslqZ*<2eSLq;__Po;%FH zRiL{a8-)*I2c=##I-zqtxQaq>_{SwOMc#$IAy}mWKK$^^IpgGun*X+j3`C#Ts;4Zg z???P`+LGlke80NABfmw2R5%dp$fZg|gDr5Dl1gyQM%Dqd;T4#9WT2&`3b7e|Y)IcV zamSe;NLw{~(Dj^sjn_*fs?r@z~bcKpg| zvyIdId8&QFRLX$V&Z6?R#_5~(@8iy_tQo0d57<~oQd?%x+s>uNJ%sMHl7j~I7=eU6 zr>^p^Z2iPY-8x%t(sbT|!`qn=sbXxE01`_7a(0eCA)K*|g~erPD2e}Mv`JS*Lqokh z`Tg$5_Om6Ghzy=9O-V&gR#tX%`&1s>Fhn+eOdT-Q= zetfQJ@Rp`PjFMwnnd#5R%J0a9n6oVn45B6V@PTyz!!1G$;`90a(sx2$1l#$waIB|h ztAu!EO=#tKI9FThqIL6ITFMDP@9sFW>eNY3hQvK4AS6V_L;ycJ)N)V|rg+8V)1eSm z=e#pHO{CcGH9s^uWHK(c*0Aa_wwHSMx8Vu?ZNtkMq`m=Lvi0Mf&S*Wp(u8|Cl51(4 zo(aGR_TSccESCy3)XSA*b9`C(8P{{rF9HT4I$JJ>RF!VMCHzZLlSE~_tf{EJN&dLI z#3#jA+AL-1CVaITV2VdaZ z?VUeF6b0B=ubSQJ_{Y>j|I`)+z-=;MI_*Ss6=3#EWMY?MU1CY<5`aFXgor^;`vw3H zfM*fl&TaDza0!V7gxgV0G@U((Xw0Q%pKm|VXT1~lLr!ztYr@wm?@^-K@kDfPU}5$G zzut%_i!lZ_9J}4l`_ds@rfB**D8mqZohBXDYNKQup zRTB?ETI=qlQo?n*CE?_PPLUzP=Zr1{`@qX><)9p{uV7D}nRr_Yy7N>clh}sjwO4t1 zXRBYYuxXfqd9v)7nSsk=uNjo@0J|B~01xFh6@*XH6MM6Z5}pq)>QttP5Pe6EM6o0aQ_OP66Crb?Z-Vx~Lp zKq?jmCQ;u46Xj1nre!RSSl!1WQ(>vs}-gfifboGG%vUBP1KqgzMp~2%yI+GE`UwD3o6M*bYUA`b&obD&|(iB^LZ>~drY2L zoEc1glW6zQQ<@}rakr*cKugecs6QMouP(cxADFK0-AUn`SRyZQL`kC#B*|2A(LeEf z*npC8r{jDO)>(4$y-gPpk{LHrY(E|LTH2AXrfaz5PEPHTk%A2 zwl%WhaJY)928ASCE7E@Dkm+}FH$p+&L4EyNa% z!(g~Q32vw)$bRYFn|W8N0!g?&_pFyBiBc>}R31W-`Et|>mr|G-7^#mav_CNgt%LBb zKJ~@C+2EBBux4aT6t;aOyv3#DrqzexvTQAW1Pj>dSYvApYEJCTnx6^dm%IhzCh z%TBPQVMisFar>KqS6ZwV#;Qs6|FVg0%-62q8zSd+jI*gKh^7df3F{jDS&DU$=m@C7 zc#kp`HuiK$aU&sUJz;087s|X5_eE9*2oB`|Sgq1jHZJyGde?ZA3g77dytvA2`2FdY zv&OE13*^`pY}~w7(^N@^NnzQ=MaU`izIjoY-Tug0y;b~L$IrMSn>L9xK4a~%tJF_3 zOnYTvEJh2x0O%2jxfRC{Ef3^v*-d{NESSn-`|w&JS=l}<%GXY zL+O7eeXB~QX8R>K>nRNqZnLMR{fQMZ`}hG^!@8>3a6XZldL|H!TUWQu3}cOVOYb;e zO4ygxt6(xgH$Iz`Jm_%OFhe?W3D4N_%^CnkJ`ob)@=wa#Rob9N*y!|V61<@VKoWYo z%05KFYW(>iO$gVbIS6p*?eL9R61FIOldfq&=dBda@MA!qW@a7LNbo4w>O9Aj%D|@Q zd!3XS?$=>M=I4F+sSO6HKYxIpd9LTr6-L8XU9F}Y<%L&;)!f(wqAQBB2d!pqo>ik{ z_-%*KHCo*O-opht{F6QZ_Ao(G22E$M9P$ylk08OMSmUd}MCrybWqPO33R1)}tF??a zME@7M$MZV%aoC>XXS`vXlFiWoSlHV%=UckmHo3hdyK1sT1iyk6#hIgEO(d!?`HgyB z`t_319|)@P6*e2|W?fE-f;P9(_KZDI;%H}T3m1cOPkIPuH#{@2G~j5VW0;+JB-^@D zYK4c4QCn@~Es z;bvbt-a-zUYQP<0YiTS*+JXDt>RrC(Wd~P}M00@rhyT}r#re;_>$Sbq`VvII2^}Yq zN)!~X`9(YR7NO<3BjUnEy}|v_4l#unpG+DG$5)-+R(lBKq$zw8k}RC9wgxk)K~k(Q zR^n{B0e+3SsOicLvNtGAi4pRw@`9DVym)sxMlTvzXEWY&A7~fUDRzxf(5%(UWY>Oe z$7$E0qgn5e(=ZahKmbzOI`;W;zK_g$obW9u9KRD-h0vcQNJDeiA!5RZq$>=A(g?H* zBCX48qQUm#iSC|PEHl{q+_B%fdGeTueLXGoxq=xrsC5cnI66A|%)rU!iQAIZ*Q;zv zwMTlKk6xr!uM0gXF7wA3Ketx%Xjry-V!t;1R`6odz+l~HWytw8&DWA@vF)iEL$GY$ zh$kWMlk7y3S%8F$(BYFW#WFdEcs4$k(mDfUr- zzaOP_sJKmkB%30Ok!#v~snNQJd$k@PY%}tUd!C=Al>kJkflH5~;*{MYsogiRX~x{P z%bmukzf!larG-xtzGKPH9AsJ$>bz30_gK*)tt)_h=<@q$z99%-OJm$&TG;&Lr%R2S zkUMVq;b8M(R$o+qXMPv+R3OPY4lLpGgSIbqTgK9`_r<;Veq zW8ztZ1LZ3!#Ji#*m3bp3Ks_eyC2!pL`<`XF&Wd#Tz*wjZ>tsO!wSy@e_h`!)ooQo? znAs^aSX(#VUpvJeLJxe-M-Y-~#gESoOW7?r9P35^l6?o6-SN71|0>{^%c@n*Xs7Uv zTh{XeIeQllcS>rPisQBN79^|%w1bSJQjFJTg4z9eo2_QNZU-|bH@7tA+w1t$7Ej9l z2-(HVo_)H!jTdU{dMs7e)1_H#vpeIg(^_az+@JDLm1@%t!DqF~_7jKG0uy!arfT`R z6%tZMX0#WkO)*E4e4Gtl`20?ru?^{Skm-h)#+WzN>Xv3Ha{%H>N3S{?txaN-y3h9I zkC(%I4!@1bbwFJiZ1v~Mzu_(CeNF0G8_wFI!+?kPAPU3U^VD7aYvhS~w9)Rypa+Bj zCTKU~Ef!fzWW_M_-P_KUt}2KzY-waS${dy(>MdXJrp-3d|@P zJYnmz2=n~ANavy~RT93XcHGT8$wKc&PD-~mb`o~HSl5-3<`>_7cYVIquhjg)~ye=0h zx2SH}24eZCDn!RUx0#&Ic$J^pqP)^Q?<2icn8?h=ym_>CVCUjl_AB5lT&yW$Vc}7Z z#~k$O3UoM)1g`~n?(|eL*)TL3&gXx$L9sG#)-9la{a-QcJAPzt+IN*V=(GCb-xGQ> zHH@V(;L3;Ouo)k=8^Phj7Fsgb{8kB)@W$!fMmEK}hh5AhtOREi>YEXSAZrT&&ODBy z*a7dBEk*in??=N+N{)_wo?ip4y%x_Od>w_Adt8i})eKu&jd2F}AMCJ&gCYp|E?xm< z&~bq1`J@=PRcJ80G1{{D@wKUJt7P0#tFJSw2W(S;-(j;_=t~5J`$1*GP^vThP{)Nk zFBJUFA<6mWH1X7fikk%6Z(!j> zP-AD!j8E}H)oY@okpGfmdBT_eXC_*NMK%!2o#ISNI02#Am`luv8A4WG*Pq%>5m#vy z&5JKc??zyk17wAb7u$8o#l^-w(Iwc}Ow7IDpOWwfd_vH6{FrKo=TQooaJh)-ptVe( zyOY%{ZCc~GYIKkpV<%yUh_x;Vq~vv)f+IXG@u`1}2_V|?Vu8Q7*#B&yNs6MCguD5*@E+84x79>stiOA+lo~!4ET#QiZX+Og z$aq#|4d&r6)`%^c0|MQ3{y15$ndrVXcPNZ@U%DtKW<7G8(#XGD0jNDZmNzWtO4&jgle9KD=M)o;Wr(5=Zwb3&N9hiu~vb zjrq)}+tU2GweD`&DMnythT}C8uq$G_4YvL(;hnT^KbH}aZmBCZug2PPi0iF;wC)v? z2fUKLt#L}_h%`0AuaebR{{qF#Eb-soxq{)1txVfLx2{~2J+8_wMh%7yndqy3Ej6oE zoz1DNW0PrmF{R?Zsdjr(u5Pp;1F;9u1m^cL)Ks&}L*<(oVQU#N2Gb>gie3)ssE%hH zVM`K$D0IganEiOeQ((d|J|dg`Ix56Nsqt~ot$*bE`xu@5kP`ivDkPP%tE)EX#DKjbWO&4WLSL2>E8xjP< z@D2uVRj{!<|FPiwsgs#iK^~&NI(fA5?ER#rxoQpMTc-KIPyFFT zmNDtC7}kZ<)ha8CMiEz&InG}8Fi-fQ>2XP$vV3@IOK;@}dg+y=_B(gl8pA}2A{FcsZ0#o^B-*=BmBCvrCW%&s=*s|%McpjAa8;1-m1?Y> z7Le~i+F%A#Iq$FLs*L(ZAa*C))2Y~4Tf2ck z_qQ!cVhAM@_#AcI6fNj{@SaCL31MXZLZkFc@n^d#r9jWzS0!>9bv-y;2?W5Fx^)mB zL(p*0*Pjf)iX!}g6U(hjqIPw?nSdEdHd;~WI9pM~)oes%*EccuVQa&oXt8X^{kZk6 z0%7tULeZNkHyEFqKfJe0ra~;sh#iUF{iq$%rzw+0_VU~Hk@eX)vMw(-ug)SfE9=^( zpur?FS838Qw|`B@D}jqE<=P6YyQ$UAufe&dW=iZE(Ii+W(luryc_~uG#uJU6OpI)J-T@ zXlqFW0d~Y)fT(;Qirupvccn%J0{^lj7tEC8DSSiy)i6O$hJGAVDA!L&JDrBvvV2ar zUN9NvanZpT3hKEV{NzipPpxkyE?jrO{-w<(vZ>!B#u1Y8*+43o%wGh(rhI?-&J#&^ z^HN0i`>oIKR*#|LWc+sHCNa;bTLkS+Iov7=0*!t0=p#W!kN~U;@}l6XyKh=&VDnWk zj>U(-dJT6*wJ-0(aN$LmlJIL$U<*y$rR5h1=5T+!&j zRIx`m{o3`!%1&!Z`@BEa08;!sf8xcM7VGXw)epIP=sb+IrZ9ML-YbC~ zn=Ub$*#B~8Wcj|Ja_>=%L1T(~FTSnXGl_e2EsUIO-?3MGyRAmORxYg&Y$pEa)^!qNgp4xnPf&g}0XDI=UeFb$wct&M%3NqnhDIXR*~m(4_H z1Hqc<0Dp#&v4I1TDDG6^$l?+^nFw<5Fg{TrM2>WBH zhqzF{YRk(tjV1J}Of+7dDu`){5@uxY`WTK5+Wn9}y$m#~N+ytU-gr^E)YenwkfL8!AP~44M70AfhF8g3TA42voq?C&B>DN1DvOk3a!6QM*fS zY`2DQvDI|k-;!8eZF95>>X0Wkvqcqf^s*F0GGxMSwquh96!D|L%l6ZS?2LH`*{j+a z12q{_N&6wfM~qr}>-Ez-25N^{w-;++eM^F$)dk#(?r1+Z4_spEbZn>}dUrEDl5Q>C zdV#3vimIA>+f#Cp3Dlp^P$pQdKM+k{pJd)*SC+XfDc`nj zH0UhP?x>KXwaKd~fynKA&2%O_O~p#BL!^i@NIphBH8La@_X zpef2m&NWJ`L_rc>`oJz`=C(=`YUGO=i2_3F%ftsQ3?B~tZU&H?3gft|L191W-~n6V zW60~;)t7lvsGTbB1SOW1=NC1Z7{*!>C_0?->H{@m!pN~AwypuIpR}jx7;asc`f!KZ zZD=ZYP3LyKo)EgyxbkG^nCQOSyQcLhx(bz7>y|#B?4U6g?cqw6rbw1m-U$cMEeDk4 z?E6!HEJs)9HFs!b&G{q<^9UVgVX5UR96lNt`QWeKDX4_6BrNvQN^j~gpfxl=ymqgJ zW3}F@H=lZ8avfCELod2#5KiHw5cp0fPvTjpKvbwgF`k<$o_l3-_U;#ms>W59F+@L4 z{Tirk0I(F;%gv?g0GV%uT@2)(+<3un3(@la{ah_T<_4*ARp%xz5fD98pByt9$TAzR zQ5$Gc*%F6&T_$3($x-JBC&O{b zWt5&XW=eWJYdR4RJao|1U*AUI`z5&y>{Lr3^iW_iG3O~|1%}nCOCC3nc$a#c4|Fk! zF1rzWGy>?0Ztc^-q-|_1i6<+r*z0lWo5hPHoxG1RDwRw09{n~bzXS%m##mU3haZtc zZwt#+a+rpc3e;1kzI{h>>gf<07%M!AY3ngh&=P6I z=Qo!R9TTCxFetb2V9b+Xr9&3AkNxW+UjiU!lyytEf+1YCR9m`&ur9?#`X=E$#`Z za{tqh-7#EZN!MWhNEQg_6lw=_I!MjkP^wGZa>s4Tl?4Y|ZUYf*Brz|a;5QrK=?xw2 zS1w=iOHwBD+}ahi-qSKyzCc<`*{y=E9A2tV=BeLvpoh`Ryd_rEbMEWMgQkjYog`l| zAMJIED1`E5+k}_?r9K^yLkGZwZdM;zId8f0t9s26Mes?hG(PqTjSUI*`>_+Q9(qry zJHoB{^o!z#WNhVmJIki+o*xUc!;scy1Ct1OUuZcsdmSbkAh4=W^A8R`-$M!L!;<{V=L^+^xFdV6#1D8qq6UG2Eq7c}K}Dw!^gh*mv7wggq842^|5%Q%kvD80&279)QW69bKArQ)hBgSi z8_9muo%<&5lOKg!c8fpO?9Mcv1){JuI6<(?q|Rw47$Nc+h%oH&Crkk+lrmkyB2R*L z6*UOle+d`B2?bRY;ujUlX%~GcF-?S3f2yOtuH|&?s0k520mwwEFaXO~X9{$&U+LJ{ zcSoD(;@OyKo7oEwmFB{!e=J-DM;p3O13KYaf!zxU921>KXcR1X%W9K-a+?l_;O zL<&o*%+ebBkt6sj!x(`UJahnn)~I~>HeZAtv~S|C2-ZK{yXTyMz)n5KkOLnCT(4G# zBx!#9_S9CG<$Edpt!Eb^a1N`ZK=su{UXwIKhFTnO1Ydw&T>hM5Tw6;0&>58#Ubk}Z z*~`w4^}QXDhkevg`sH`C$b&KN@V2XMjyEBZ#=S>klBM7dy)b$;WaH z1;rc+Q+*vu5z~fE9x{BJv4o@5YW_ySj?7eF-%=iCQyg1D9!bKfaXgMj)gfgjKO^&j zUYET$>8Z)}pRq8N;)A`d8%p1?O*(gUE;7(6bibwpq=!0Bnj6iUkxa-!`c^gxO%T|d z{48tF3i^zt-E@u_fJH+Hq7b&bMS>ru5^KJCS3Sbsb$Dn%Mgr z!{n_tyU#_rJBups3`Ct~iCUbZ~JC;Qv94{bTC7LsCn(h1 zyMj|Ok5uIPGPX!L9$g=kvBqqzMrd17dZIyX;&yDXt$9i6>G!RCDytD~Ba25l>N9pT zufEL5@(-%q>!AVICAS}7w9dv!v4D}FtT3nDD{dPk-zJIUSf0&LuM!b%R>bdp$B zXapWcvZ|!sb~@MkCG5Asm)mgc>WP=3Qr-^iv5NyAX`9^Ye&H#C%Y6%ZVuwc21%AB1wFQLh^4^vx^4LHr!krK7vmxbTP>r25!ldN&sfAF2u79 zojhPqh(!>yu09`jocMZYO?JYdlPB1U7Rxfppo#idRz`&@sJ!ICc|m)D3*N(m1qA^| z&Sc0uk@O6KO{eX94jye5JYsbLDSA5nc?I5j^i!rmvPcIV`1`i8CZ*&W1!rNPEDU(GiW~;-dSFJ>HupPTD>yg*!*qb>a%#v>L*@n zcuq%>HGZ`oC#jX8n-h<`w+&;R!bbkgc>_&y8MlEX?VWw)rew&x;X;d8(R~MEJ7CXy zEv_UWu1{P5g+k$%U* zdc5Y*AZ+M!Z=)yqd%P#hm~t#J{k_fKA@*i9ht=@%MaB_}`h^6l2*b_OTcWAHVcnpA zf*Thhz3Dow=Q#Ijk?2r~ke1NrM6Ff@sr6`NxAzDAD9lgPZ$R zTy^%|u|bM!hn{=4iFSs(B}7V6#0?}1DFiA*6{;ClM^7E{X(L?V!rLI}VKLz*UCKkA zT4>i0-2aKWw*lN6KR|01Yf>6oO_Yi@aGg96bw%2HD{VwIc|s6*y3pzk^d!xA)CHL* zOcY<0(z%ZX%CLMVfhhmO*duzY0T|9OdpOCTqvc`;pb21b#TtzRlL~2#wOt(2$_N0+ zrR3~lO91U~0mnDg1r|i%8lnzRbnZUm7?2|Sr5TYBCN0U^#eIK_Ff@Vh(%mU zloAAt0}I~&Bgp`fbBBG%xUvlU@a>L;!&4?kmE6H*GC&&1xBaXw2!Z_*BOke%o)>3a zoySj8wBIfE_Lf+ypU&$ViJ3GVqqMUcIA-@e5ncT45S1v200fd;T`nKE)wW5xFbUqT z+rS&DOfIkV8uxIFD*#X17F}d-7#@tE3X&XPIy2i>GI5rIJYC*xV*f27rZu%Ok3A9+>{=&(S+8IV1BS?*vv&=WYmx+olGY zh;0imSLhT7)F-ha(3F)8(4Z<(kohNow6fYU;Pzt+8GQ{U)~!<7MoXKsO_VzhtHJ65 zU%pt9F5QKhB(__0X_o>!OwoTi+sf77 z3s9~(gf=TWbKcCX_ z+{mS%F-vhh-cp-z>$SxzO0d`IG^S!H?-|D2p)Jem@CrjDLH(VWKJW9Ghf8=}!xnFD zIM1+zG9r+?E*LWCOIpXH4R_BYS-_cvA1S`#9k&fKB=x_A%o;EHoq2w4?ZfBS>lGHA zo!`RFfpU_NvdEY~jb+H|7Z@M+57=VX*VE_!8;L}G4S3`zontxpe(*?(v^>ElDKCvMw3V3B)>^@(TV_!RE_G4_R(iJbi> zozCB)lj*y|Mwd+6Oigqep8N%Y3KH+@apZlwcq`e!>5ULrXTq)_lAK`NPNqR(Zh4*M zBPWqY)M9uHD6eL*vXLYQpqxyG{n{%TzJPg#aMjh3yx_}ipN@nRi-<;3fl%|?_Ct3O zypNvH=fz3whi@b(((||#fZw-3DI+JJyd*k{#UZx zZ7!gi%5`44I+VAd9tqH0 zT|Odw|Nj!;uYB4}q?+rS$GNAN=bFZFYOu>v6hpCX552Z(%~OE&EH2HyXH^$i{NCPM z2G|IAc$q=WYmjc02?j8n4qwPGQmmC!5^nm#8KNH)l{CL6x;SWadXMad%K+hP`gj3H zEE*9KKXt(`O70accVVXU=xy|S058VD;2nR+?%p1~!rS1`0Pnv@ogx%g>1&^C9|TD^*H?gv1rJ;em^0=>)>WkF-I17XDMFaNx19r znLqA?_Vc0L&wXiCzTb4A_&;7|e$fz>Vmy0O6Q4lfcn2(%#w)bj;n#zI$ERy^i<5Ns z)kdR6NojVkx@Ir$Z{|xx!>=u@&oF3pMJX3Vm| z!p`Rvja67qEWbanRUyX8sYpx}eVlPBfj!t}+NWFz)v{b2TH~!dcx4La zOq9famch!BiT&8&ykLKI7vE7%_&h$gz~b4XL_(8pWn|2fvvWv3@etk?cGv64B@dP( z1PoCL9MRm6HV@qPgKpWnB86F3Pt#&`HZGT!<>R0+Ru?6T7P9owfWQ268d~0O=rIVZ zG{|V)uXVs?lb{z_2^P(dVfptr6mVyQn$12SeQr~!X&MB(I8M=zOEeRNq@ zH#KlQv>2oF^jy0AKbl4W3ioLFOV*Q_Apg4@u+p>4JjL*;pR;*T-h>go?vVw~nvRWYTIl%YlFcK0Ez!(& zEN}*{TZRzJrw9wni+I;*L6){MnCuA`EP=gsXXZRbGSbsAx~aj#qNwadg0kxK?362_ zs-d!B%w#7n79r<%UIU77bISmgnb~F`gy{dvlM#Th{BX$wiZuA%UY5s$2v;Jqcgg=J z-cZd-!1q8{rbVI&(Ay>K$8?-gdlltjdn*M_uvY}2!cKWBtP6c5_AUhx`@jmD2`THDx~>%8z&* zN`12W0F{3Q+)CUQhv=Iu#bxh))wI~H!WAk8aBiIO7?7RsMyI{RrO zhAi?zTf8`#vgdQzP5#Nw)-9&WNG9w-+$tR+ngxXo)Hu)PYsRrp4|=s6-kE*VeDPLmYBGf3(e zjKvbic2AM-X`)N_*B)*%X!q;?Rg+!TRIRqTHZ_}GW8>aYC$+)DF=e|uA{Fy-$6#ls zfw%6*uWWK(QT0@#pNd$-IM;N#?13aa$M7F2{ZQ;*L(G0ys~@i64;pcfydhSye20g0 z*J|D&abA{S8rq%T)wKImXP-f!@Trd9QBjRjdg%NAssm+zPHh2B>@G5hoZVj^&GS1y z+VCqCa9p1Qd!5M}8Kjj0e$0+iDe=YEH>4uw&uVd=e0@rWQ(F2EL|D&_W1&`1rWwVA zjq(gH%~nzHgy>v=$6;NG6L;o!!so8eUxTid*sU_kiw8*i(V71I~+he5yUATsy5 zq#2p>HO4vFa&3REFUpYoZ-4*-PNbA2p>ZCN@+v&sKAYGmY6_O7aHVAcDvBRvUuQv7 zSH){n#YD6@<}`8k@j*@=*erg+F`@LjEIX+!-xMiDcNTV!7%x)^CvghoAykaaIEKbd zf5b_Y)pu-Nk#5ccaQhVnq~{(t!*luaUpR@V(echMJq8mAd_e5cE4-(w6Ju5L3n7LP-fWT3yf zo5y1Nz>ygi!r!z>**RbM-Tzg60MLXfP*en1k^#y`phoRK04UJCVERKHlAK#W<8Q%3_WPT!Zlw2_-c`RH)(Tb< zUf11UwCq76H~G>6ehZ_+)XI+In&1@`OiJ^RLO{@Ck) zXWdSQdcnCS3-S~#v7Lh8laa~%H*w=1FtAFX!8{T%;FFfQYvPY^Jt8(IE}|PPl>g@3FCREwv7A% z2E#Y0QiZ<`cdKhzP+#>BJW4rR-ce|SLzD7o?W5Us&+$a0saWez7XlYuyM*Xy-~F5G z^Jju(rOwC9N+7OReVX;2_+tQ%*Pti(B|?uy)c^DSrblHqw|cINTj=R%!T<1uzDojs zM)1iY_(g$W%K;=<@yYl7i(};M`5nv@xk+FX8l#yA1{5LH{-9=F2}pNry1Q$$;r{UbzH>g`@!oUp{fFTg zFot71&wAFHbFDeoFZ!U=zj__W? zet*wM+g1B{RVvgHNKC+N=P@w}NtFBri|c433prDu+-J#0K zYWU+dpttq2nX}@q=K-Dgf0yCe&R|Fp#xEq4gOf5&mXvk!O)8-neYG~)!riYE64Z3q z>sl`1>N~3mc%lK6AO9A%0jizGYXMBHVYT-;I1S#pWc+u#;)xFzI5Q{Vew=rMA334L zGor?6<KZ&a{fl-G{AGEZ;w(8iw1N zK39dTBKgVhAM@*&%LM)4kqjw;sevCL{8(wcprymcdYWmWykKGTyogq9b2jj$LHD@i zo1W~xg4XP%lU<}68sM)VB)PMNSYF`vBm2VaR&@>?@O)?q5=`ZF#q8uc@Aaj*?HVXI zq^Uf8Nr&ACiqZJw9funHJ;uuc(M_0jK$Dr}tam!VAOD>|Nfv(C1A-zN5JJE0 z3z9s)B8lx&v^gi`X&=3+2_yu{Nt&SK7!`uNMU(xbz9XT;FXWhWYppfH`{TY^Q`Jog9{|OPlfq+BM)%7DN zUhC+{1;zKkk?+XA5DCCU-JYukJz7ojnuM}`pP8b-Q!rA8&DZ+$SwO#iO88vEJw zlDHow5x}^3O#RLdVW9Wg`6z1!l$yWm-lelDaUbm7Cn45${%r-m{n=Mo0Eo~~;Vfj+ zIvjhVpC1v4;{AbYS~S2aKxp=~&I@{rz`QM~*yZ0wLY8ilOo8X>PN{b7k3AzWY-&S2)S>xWY~op*5d>A%?)CC`^A zDc}bCnv|l3Icnc$sj$9C#l!Ts-|2*HNi`V;MZNakV~8%6Y;NAAb*(>Z;G6np5z0fe zQ)METg1B`D>*{tPY7TH6O4=`oqgtioI}LMZQ^X&{fyuD)lC!{QLB{d~iTzWDwAKVJ z@?6OL#hXwo_mTeiZ+d?tzv%RdO^8e$)o5BbyL%=#)lSVzvKiI`H-TZ?<4vy#F}?;cbU_41YxE{s(fvjNThb zCf?|Da8FKaF;So(w5S`N-JxTr_=$F&tX28J`{O4QdPe$%2j1j!Z`>H;h|aGRL6$7G zt03$l(x6&?H{Jsrh~$!lyt)Q zsrcTx{*(gwDE5+2&lS)5c?1`|4xtH+YJsfOPxLK%D|g{8S?U5ss?`9Y`4}0doG&ZEl zVaASI`z!tFTDjHjS}B{`yP0l1yl1_I#I^r%oAuOm6ODc|`0*J9^7$v2m68imCACa& z%CM&Z0%74W%})%^MfPGMh*{|Pr?%=D9#dN(#bVbyQ3uNHUD3{u2$%XY7VhV}f&4kQ zK{bcM?m14qx2kwJ?~{Rr8ZRz(Cs8cf%qH3ZOCO}FmUoKU@Bsj#RfEA49Y1WbX!K^b zBl~k5_eY7E#lqz<(BJ{Ca9`u~$?@F$h8Dg_nW5dS#tn@k2-gj{j(>X**ApdOMuLKU z9o$>yc729q2$z%ru*;z|6P5}>crUFtf^`WYX)kd3gE+(l0wc)S#aHSMk*4ggAujG3 zlh?=rNr=c)mKnm6BY9;{o%U&=weACr1vay*REf6^9H~FJ-Uy~9gmCGuv?VO|CJy;A zmq12F*cz8Hbn)JxpEr7~T5!EX`+j*}c?qPq^y|m8rTHqdC8h|AI`TKgA`g0y*%U zv0aoT=5K}7PDPK^z>u<0*xwRm#}lIC|4porUQGi%uP*NaQ$2M5-QkkFFO(v zVX59}1uSeosf0`jqePhOYJpbyr)ZwvT)P;vkN7{*w$S~HDP0}BChl?qHIbL}7UeA{ zTG}JTp~!{-?ZD=$9JOk**Q&tgur*(i6zw0>*zza@_Nv$jug1@529PWNl5xUApw&D>8E z#9H)@=h!ygR{7t3V0-Po^+sR*`n~)9OvB(un-m#^te1}5F2@+R;lzHu2;l=R-9qK9 z4rF1IdmJ;_j}4IjVn{2#qNj0FNjRRl?<<}t;#WnBk#W(|2SBp{o{tI$`mL*|!2fwD;ToG$_nR?|%sNYO?NxP&os}TM)ye zJmbuSrGaqMle*@SldH(J1-Xzk2Py9}gv~@gSbVjT8ePL(ftNqH|ky(mtj?$pjsDW6gn3xb=kSf%RJv zKkJ%z?X?ZrTeF?a`wOOtwu^Mwn#Tm}+AhQpM!NR$8D*cCgeO!i!WLiXTgqpQ#3df5 zdR*F+g6lsDMnWC*o%{3z>cb+kM0fTakV4vXr5di%*8ghl{7papV)R{aM@hkrAYW5; zh4A}Ac%x1_--0rQ9I=9r`Dl-zS#SO4SD%N1oC4+`(SSAe333Otd3j?o-(mWuIr^lqzub?=5lF8d25 zHRUE#eKsP|-|42I&D6MtmS)P+qGt;QA=i56jy-+6v9;0tE0h6u6mK z;AVIXJSG8UU-V8}^x|fRoXD0q_EWkv@sV9ew>SZYpHcu}TW}?!b?AlqI(Z54X&T|% zn>sdR);HjJIU?C>Eh!)HOfxlgr5?I5Em5M-@8KX_m?c_Wh*^0`|NS~p@;v|zQc+Ms z%PeB4cOez>&~9M*7HV&qwOl97R%u5F%B9|#XfLqZ3X`}VmQ#y>lc7^TZf2N{okNHY zm?l0-*T2sAbm3@Nv_l!nVS<$<_S>w3o~J13(N|FTcM&(~NkvDl)7-qjkCxRF@hT?( z(VhQDQRc!8ZkK4L3{SkX(q|`B&WmMYLX>LiIpB^i8X6*VG7ig}Nt4Ne?&@(4Y3tc( zX|G*%6it9N_4RE9CFa-N4$SMFy_n9qDbpsT?x=RUjH8Fl)r|#vNA7lw_f}8O3qvn* zMIl|6B+7VPTLBZI9>w!C8!pwuaasE9cFjD8BY=Wh+=hvN5Axz%1Nj5f0YbeJM1JmY zI!JQ&A49|oId>%yU6L2o(d-XAV(lHh zN0FRHfiaxN#;EL6VuWO*qnK{t;Y*Ot_aIYdCJ?4IE}n*1$Q69+KBn0VL`AH7}Rk@qY!3 zGksBgRY{3ccN_EdBo**o9aN_)HIIXms|Mgpj0x5nJWWGf8m?9->zT#zlJ~lQ;x`#5 z3$Tx5Gk<#rTH&!msN_j;NY46kRww?H1*)0n8C%nNagT|Mk~wxNn521#BsgnJrnd?u zq-;N%PsRI0VgH8*Ap!_STu*qdFELI7w{pNoF%rJl6zRLf@20`5c(3325d2h=mj8t5 zhBKa@jW-Wv&4!4p7WGb(9&OTuOqAV0b&Up-ZXC~%hzfgJB4T6HsxfylwZtcr@on>F z>7hNB=q0Hf?u;^)m#vygsgfkk9(npPT1HUvZT#eLoQ5;6d%PH@`3BfH8rV33Sf%_k zRy=3>8GxMht$xAmMLG3}-NWH=ViBe>sM<+|L&B1D`G>@R>WfH%>(PL50ci>5NT_A1 z1>tU1{LU!0f-7YA#|Wro{0q(l`oJ`#9{6fI9v+TT(?KK~ja+)$b{|>xPTAIoq5EWA z=5WYe|JbTJDVYbUOptQ-LbqX~P!@%x-@vL>TFW!(F2~)-eJYgCX4S8tCM{6s*X9R`6eF7!4Y(1J!<>L)vjkX(M zx1ydYBTPha=5dG$yz;XQa6dzod|^W&*qqUt6R5=15fji`a0o(@(p-O_}8s;eoTg46YfBiX|`+YQq4RNMvKk2xB7Fcbb$ z^z;dRM_@h>ipunCSRlhOlZ@HkWE%J!%8rBbMk`y4*DI?@Ml!3zJhtuS!OlYp*W*jgE;TL_QPBpnpYhC@03#DexoD7BV zex9AVMp<`!LB8ns$K-UlS}f&_*8UU98~BmTJ7-@}bdKhp;)m7iaq%}_GS`4re3`7^ zE{_(indDL&2d39h&xP)nEjL1U=!CG69?Ll}$ZLy)sy0#l&6~~qV_TNL`tmN+>gBX4PEa7( z#eAjZhIHm982QsAaVmD=qvt?8gX7r4CK`INA*DiF zNHdkOh*_OH(KAI7>>F@OPZ!J0ce|Zapj1o&>E|ghi2NCPk!Bg02&kEI<8!IbuH0=)icKw z_AIr0{(^clZy^%jf8&=40Kf1#F!xIRq;7u+qCamKLMO4Pd@2*Z7$Jht=ny5hyAo8A zAyzw#?z{-!(6pO#f>L&4`P#DFYl6Sb`Yn&ch+O{FV@&y?XzabLQeM^sgo7Sf00G#p z{jTXH=;^u%zV2Hy&gG5WW>g-+xF!Rm?*Syk%_Tj{-ByJLpw|cW#&%Lf?ElHbHlW? zp-x}x9`mjr`);hEWgTd-#8gAyZnvN`@ZUChy`J5Jb0nvY-@6URS>twiI5x-oCyj*` zDVNLfOK$Yth=#S4xD*@|QTglJU(eni%p!x7@w%18D`SCKCKmQofdUNBxvH2%6X|** z70)OPS%fls4#ubA;xf*(kO}7v^&t2Kc6HO~_5p3=yV>y(Ms%Pk#bjgv?eV+IiTr+# z?v9R+Y$uDSGyt~ogj~)3hHiz-_)vA`2_7zk@#q-xFgsEnKNhk5{ zeS)rE2sa{i>)z={SC}dE)~dt0=W|?l&nz&p$9=g<*?FF3U2Erz&pxTV%*6riHq6*x zHkA~LAslwyJ^LmUWqs#cfeXIUNI`n>Cj#zIhC(iL)+nIIUU9nH?l%t7bw(8NU>nRm zYr6KV`OncjKFtEd8Y;9X@Te}H_&+kBgl1`AjMDUR)bL@;P~S7Roaq3vmCjHjy$>6T ziQ0yE@!C#^L`(t!;0mzquaMGbvKk}<>vJledY1|Vw(Ragbil5FN7O7y?S^^I#+?^K zUyRFlgOmeHQakdDCasn1HrZg67KkRkZU>7VCRxKs^Sil?hs@oO z7$89>f*E_oURsyic{3ccMQ?WmuJ+;y|9Ny+cUcV>4&3csCaHcV_-ZE!Ra6mz6Yl07 z6O!Pxc*Znzyyq>OT2!IFU*D}v6q&?7LS7sK6>ijRU*(?W09;jE+>p$&_I)6VMlk^a z?j=rKthj=%AN=#<<4*KmWm;)=pHm7(dX0+nqmGVZB)w)0X4Nd4pH=nSU~e6bs$}HH zaU+MhnO4!Kg0GUNKZE^79agnjGQ<1>0DI0nj$9V>bL|=k+bBf?u#86l^RyKbi2kU) zr!Cz82>8EkfPMtfG!4mQCIR#q@-AuF9moLyTRN|Q6-?Sp5}0_$C`f~}V3L)=o&<4g zmI3OokDT-~@#xlA{effTepTJ{F@GC3ek)4iw?NZstRvypx_@!2 z$%PVAG9O~d;pyX88>=&H*|yW@6Yc)F{7AY?@}p2!sN(QEbGy#i8iJ$HZ@yNq)IuzTqvh^L=@_uotb|g)^h@)hkCkqA6`eJ@YgOd zt^5lKWf)}Bw99>tr7xDn!-gQnw32z5l3+fJo{$5(B<>>2s}iNwB4+;;HGN&W+$|eg zHIpD{K={+0gY1}Kz`ejql@>0bHg0*<=qy+$LEV{qc9sByi@cg?#spQ|C6eHk=E%k9 zR`tkK3wFuLyc@S_E7B>9-`v%voT@Jylk*z6~KEOnheM{8zU|JU=TuK1jzbBG#umD4`~xA|b2lX0jo1sw!j( z?-s!1Os%ITj4-MLZ_L+C(DD)`6F%2|RfMVNSpL`7q7t+NCMIw01vagg@>LO*R_;A_ zLhLZgn}9z>X{r_W^Rf;uE$GRg4g-gj!$cnnjr311=F87FnaVDebb1fkBwyexqDWiu zbyLd)hnsV(*4yu9_0*T8=(^5Vb8=aQQZ8u*{aTMvlHPq4TdETVIcj1ThI}w6oJRTtfI8&77mSVr|xMXjm^d(T=rhh@LpY(HmdS*sz(;%WKImXyfN zKfwYG%hi!lP2}?9@)k}_b0gpF(zi0O0X*ph;g5~7-kJkR0f-;qk@Eake>(xdEhGye zE{w;N0#u*Ze8pL(8qV}|VLqcJtx3sC`sTBGI|=f>rjTgcw6Vt9J3nHLn zGp*K|pmEL1y1218q5Dn=Az^Kde{bBN1H$lwm+uBfp0;>JQBs*ufv?qFbO|{Wi8UmYW`6<}$@pwp)W~ z(E!8gBDc>o?Af-0aQ7fd7AQI{&~3jpB_3|gAu?#qAqGBE%R0F^P_R)DIBziEh1cXp zSz~1CC;~a_jVdCP?ItsoZK&x$9NP{P4_f(wNb-qJ@hNV-`(-325zzIQGo(*M&R46O z5$7ZUm+_{X&7b)OvXY<_x=!gt;W)Zl^im;i$u=A}+H`@11cdoJkfQXxwusf1xAj6! z-Dip;;SM61ZCSz@wO2K2JiUNKgK(QZ*A)F?U8=oQx}B-mD&vmPbsK;>Ee2b#nq;2* zs@y@iL%Vy?7b!0VqW($oZSMo^hKzc>GoDD3cLL$|DAT68ipkd*s@DN&2H=^w30fg2 z$l_u6J~`r%b7n?efRLcfV5cHgrF^7Ve#UtDrANF^8EZa3FgEfFe{ zeI0z?G`6bG`?2c7?rf zNhE)%Xt^M;FhboC{6AbQoT_2TS>|B@R~f&V_r$k};;E78(IR8e{$eFhRe^{|z}2EV z6RF#F*7eIo2FTIF{n53~A)D>3gDZ&4twq=Y%U5=~Ca=BQF+RNQId}@H{5&SLE3%4l+gyKY~&e#m;xGaRagM zUS}1(+&k}~AOI3gt)6a-LS**Es!7qLulR_;g7$rjknZlhX#%^g!U_+=h{-{AY?0vB zDGeQV1PNcDf+m9QY9~qA^(cR?l|AVp>C&kSWa<|XNmV4Au->~5ETjY{k|yp2XHR~m zzL_>sqUY>)jAGwbjEmrqjA^i9R!MJe#+E=G49alc5a{;9J(YfLQ|JFMvDB0@I4K zyY8KHNXX#vo;ndT^`+D=sRf$tVnfG;SJJ$~(=ys?5vrpZ!l5-q1^pz`>MZ6}F9)>N zBBYw%3bvd|QPf?!rj47dqznuX8++ANd9A)HEzYZEx^r3^0YP_a_Ns14{a@tV=3b}^ zj;+*IkJd~9DWCtt=y>6STG#)OR+n=pm10ly#=gVdE0Q+TF%rA+5 zg~ch8THgD@5uhLkypGAsg7Sd%rzol%JxX~1z++iS_wlml_9$%UBeS`fS&h{JArNCl zTGg0u`1+A5T+6qHj|S9#0K%kaQp)r_H1_#oMrU}#?JE>PA8$QqL9(fwK4{Hu*^ZGV zuVVmQGpQ=N$+x_jiE>US9eWybsSO8q1y&YA+zc#UW((8e*{= zhj8KBE569ntR%570Y~O?q_!m!NtK;Y>kJIGU8;XxRrkTFh3P$fg6l|EAu1Bsl`Kmv zpo@<6Ve?8wRY!;$GU3xktO9rjT72s#!jK z(@BbF(d;n4;q1Jy2$Lq;IpyS@LbtaG?6ONh|l`qwo43{7XoW8-OGZ0kwQ82vey44R;wWb-N?c4Aq~?#&7hA zJhtSdjdhG#MISy-mu^QWO`{555gF-?41$>NFTsiSS6eC`a!5*x2t|!#GpCx%ZRnpV z1Yn(@ZJY6_faHFyIHRif4DYQ_H40(Q6r6STqUcf9300bcydg$|HVYC=NwVMQG`4QP z<2(!G*7N$j2TR4#9%%~v%%Xu!DJb!vnNKN*$4B4!spyi7_oRq`lhsmiKu)~ga`8CJ zRlnv;l|f9ie-vx?U%)|4VpG~*?N#3RGkO+~1~O*9>G^wqJdENA^+H-8G`{q|qUsL~t>05TWY5vj{gEQ=+CmV}x^=d*1$7-{P)fV<#Af|e%xDFAl?a0ZsM zKu;BiaoeJ%Tv&7K@HlUxGA^UW!zXBqaKz0-DiG+lXh4knuXk7d`YfvzqACs-#+(lN zNJ>zr%I2^r)_)m%)%J}S9{!#b1=HS%WvWdl{l|+Wkj|Hb@VzP^w32H5_KYDI zh`!Sqy!xCb0E>1x`=9YZ^JWm?-_c__NOq58lI~-^OT*S>FlMowKV#4UOj6(3Z6U|pR6gU z;&j@_H$u(ubGF`z^hp@(>Q%;G88=7QU6P^VbVOm!AJj+zo<#d!PeN&*8gySjIkJH4 zsij9F7||Fvy-(+-_2pXb)ZSH!s{%7a8&!CVNdoL}o7uqiP3uD-NKX6cv?g1`S)(Mb zq3@_f`o$Nx$yui1m)bYEwm&cIwE7d=t~Iy1%(Xz%xxQ6{V9>PD&3x$~+KaaOx2NOP zAMY5h7~>j#ve^}%B~6I;qtU(j5Aj`Jxo(J|~IUyOil4!ie{+a!uKzR2OT)a1#$_XCYV2UIGq2xXhHI#A8Fyhb1J)iZ=vtU{?@o6RjlxN*3l#`NtdTdl!YAoT7` z(5CL4;$GSMt^SPH8=G_X<(cMQOCSZq{$(HgQXpY~r-zNV!RWT9_agI!P(Rx5jWqP3DthcFF20g1lraK zj>7G6!lM_-udkOI>hYa~U-W>Ra6VeihH}-Cbg%NfFT0b~nba(2J&KrIA=T;iZ1aKm zKv~pJJAc)_TWqmJnByDAx?preC;1W9u?*VMUu7dIKM%y3aj-8c0-ByGB<#FZ-PBay z09nuDfN;YS38sqTMS*V2CPqgsDdUDdxL_m9%({X?7o z?d=O6?OtX0IyajLKH?8Wva7zgB zyomG=^0Ld`wvvpe?%q!=px*~)$zGq0hHACH!E22$W-`UB>?u&Jhuc*$jTB386mM4q z&SdWOwmVeA!$to^&te5mj5XL#wU(qkn@0-RFs-uzE+>9sDv1k!m{$b5)q}QH*xi0~; z;^C|L=L38(#WrBRScoLzYxUoAzRS{G&S>2KHWmF@;vYRRf9#ZbA9FL#-4S$wet9Ji+C;c9hAeM)ck18GuPcJ>tXRe?so-IU$!x5S_ zKSv(L?4Bvl#STK%vUhTuM{Z8bua9@-SaxoUug^EJRJ=iD7wpU1n(z9WD}?l}aR`xu ze_JeA9zEENcQ?b{_r1+nklA4`BPMeH*r&gZEf73gVoCJ>_ZQU-d|Gt0e(@#mrwv11 z$BmQ%PfPKM)+~7Rw@3Z&fX#SS0&wFAkMmXSCM-C=q+tUWbr!fkv`oINc2#o zvU|L?8trHE`ZcR~HL%u35lKP4py}T6IHIiG+;D|zJN=0tW5|vr+g}2eFGcpugL2NE zkB>m|T=6}mUWhH#z^xt4gqu2(_AI!|>aH}mMMFNvEj?8NqZfHTnYr=QS@LU(AbV2T zJ6J0kXrw<%&1<(9TA+O6Syfjg(4fKfRJc?#P?E!{H(Om+=is0%kLNSg875!fk&~pb zbH)kFg55us@Gk-d5Itwx?2b^T7S4N~T0UyZztoBUpXr#P#$qnyL4Cv8WxGQ8N1Z|M z?$Z|vE2Tb@0UN#>)d;`tsXrYI6?>^eWKKD0YU#f?1i}Rfq@Ub7g0Ab zF$zodqhT!YgHLc08W=#x9#F($*>Au}bQnjYZ@QqIT6k(vhc#o*VZ*8vG+xdvO_!)w zN&ao(Z)T~#+4}ys7Z@tH#n4H{x^BiAq%v-bpAAXffd&BFg3*Lim@GG zNi{TUX+9v*%LX6I>zXSMS_fO{jr~p772F&ogT_q_R0vPUvndj7-YVVI^f zUfDsqih2u7s>hQVXlN%pNa+3Zzd29-G$;RW8NO=!;u7O-Cq(%q0i@k&KaIP*LDZOY z&j1}=uhBKJpLTG74zZp?54llq+8M*{S9HT5Cz8@Pl1N5(#EDQ89j#xu4;*E?9Bn;I zPl@h1%Fd_TY8ZGd6drWW0vTM^#~NJjDyB~+48!%OV23p>;mtHp&~`Pz1kXzkLX|ke zgnHHUa(au;Se7H=@SU!V!di@Js2AKZ#*YMoRnb#>nvQzK`Dks*Y9}uOL30J$BLzEH+yr-8!2v?_r<`GUapwf57TVBJ+PkNEOMiI+0ckV zw=wwdhp`gR$1$ZJxR}rI+EO2$;of1Y+!N_^9_e2q=yV@_mg7%14!uPvR4!`IQQTcQ z86aHk8vxX)_`@3a)MlEq@TFQ{xaXyNz>!9X1p!A2u{;}n7>dJpyP^(jaHi>5a(*&S z${C!r#23!B1cU2IrgFPXpngW71CjF~5eSWYSktSz?(=9mJ2Tuq9thutHp1YaddulA zXn$6n^pRAQvH^sa-ruJKtBH=i8C}rOwN;3iwC0elHAWGNOG!gYre!)uQk3=YEO}VA zhSpS^oRO5kC`GO4GZ#;6n3W=PUYXsMu6p-HMvZm+7K8dnJq#~;iYdnBB9Ue6B)Lu( zv5^@KdL**(fhTe3?T1ujDY>>@3bH&Ai!yondNUP9Z%D7>OY{ru%0!Gxy?3Yu_@5u# z8J*@e=YKG&mnweXZ>>&uWW4(3c{$s78Slm^KH<2Vm{)2mGZ=|Q_OAF7Ie*~X=*8r0 zz$4-j0p|~48J5ucV`P_n>}4aE_vbILd_NZltSXSpYPuu$;@smb>tSdo0cj%Qs|#bkDN7C>EmBB8wID$PEDj;DMR(uBQx?L)pa^s;F2RnJ?M?r%LjN%Qof-3$?BKOA4A z%xM{_L+1B)uA}_Y==yd)h-xVxsDP{OuRdeJ+tlD`a0I5P&B_ur8-?tc8l`Bz>dOmb zLt~m*){yx@V{k2GrCq!*PAZ>hziU|^v60qx;SE2&<=sheGKsp{s@lDN^g(5TIg~+$ zsUlzWwQDhmYgUOzndiWb$7E{{)liL#uF5Xf{A+FHaw#5N7fm*BL@ob1qPL#m=4M{0 z*H6rHkxy7AB1%e!7=NSaU4F-OT6x?EUD7v0eJ*JEajXRRod(ER@HCt0ch@vN-dHdPU93fv(HiJ z+7@zcD{DC`baD^vPZuZ^0}Tv%LTJbOow>M@+-GM$EjAZgQ9s_#iQt55_AeYD=z-@@ zN3EYSf>13Z*$BA2PhPK+@kXrG>efw$_SCk!_$L3NsOm<}R&ed3*C>FINd$v;W z?^=S3!#`X1ys2B1?jWQ$bXcpFwx|i6WvEo0xJ3lb;g+{_;?y`a4Gs-$?C;&C`hm4$ zCUXLX;pJygA_zMqDe5MON=ywK3mBA>!Nyr&&3GQgilO4baMGw%xJKymJAvW_m}+js zvCHt${tUHW6U*H$_x!P+1-dXUFElWBi}l|_E$OXN2l8;c_staFD>ZImI~A-L&~VPH zHZC&S^&TKqyZg?7vj9QMz>V7O2o07^_ zLS1X9FKcy?4>_J;t$RGbfAL6Mxn_RObx1B_sQzTFzR8AsGEM+0_2jXa_~k0=|B{ao zJsZ{CBEO=I+y20dfL!Sxn{$56%tJx6tdB03O8H{l8uUHwENQ9vOD;TB5i7l+-w8!c zBCmeXtofzNyJV_w>cV-?4dy!(XgIgvx4FpsQzmd`9vTb8<}#M)|u zQSZHQDTo*i9b&4bO(gpODa6I1R7KQPLiR;c^mW&9&L8h2}Ku0x_)>ThcNSZI?e)|oEUb#FRht>)%N$? zcn2+CKy2VW;@(}?qDWqQk;D*L7~75uTUe+{o9%sIofBBI5$9Y)8gdvdsRhM41o5bG zk(wFOj`!Qm$&pUH5P2P^V#>ca@E(Cdy;+M!QCkIc*%ZB~U+Y60k?l}9C z6JCDz_}%GJ0nRLW8smG95*+LauNJ3u#CoX&JCoUpT7~GC&cgopr&UK};D+3N=)Hqs zk=IT1seUi#8z=gNJn0pu_aO~Qj}@cK{o__Jt1`9_qQdm|wd62MA+iZ}s)P5yZjBZa zZWrQ4H*!u-vS4vPl{+Fi^17Q>Lh8lT4VK6!Bv&le=11boPC7XfuQrVfwW`TZNASM~?1GO^V-Dt^V;1O06yI zM9R6jTijyLn`%&p)T(cIYOd1pB64)uLgR)*g$UHY~B5{S1IW%9C| z7<%M&o{3k{vQ9VqUdybjd@3K=crgIhF7F{?KlhPoiCRUUhp9S6pXet=RTb9xw6#%p z@5RaQ9ro&YFIZ$kU0TTRxwKVPO!wgF?944D&wRXHS?8Nmo@tvZQ0jhOS}Bjl_EU~( zyV#_rV0AH@qan|Wv49bx|Lu~t6$IN;3_7+=`YS5Gd!4N2L?by`;o*F(*J+<$)8KK7 zT`(N@so8R88B5IlsqygFV)Ht^=51}GHwL&~OZk%x)0>#H^77bUseOK_#Ex%%zoCrW zA*|N*`fT7iEx|i##FWcy`_1Kj(*%gbbtq5mp)LIuW|BIi-P>mW=(C4wKR7xNNHwvH z0CFV0`bhwDSnTB7k~@4EHx$XTIdI!aJ@}|9<2x8Rar%rt^tqIZm0e18Gg-yx{_EGc zr8B0QomNCM#wZ8}hJ5fgmvg>>?qgSFn4E;I$NENhUerWUmEuGe_o@%yHPGUq6X?A1ug^pg^T zcFlvkt7_WG{+Jei$XtD?Z_)re?9#r65|Vy11>@;(SIa36I!i2+n$m#tnN2pop60^FH<8 z|3;a<(0JtpiOgyY>>vA3La*}9)`Ffxxj1_lM!S^$F%vSyaLe6cZiN7E&P#p5R;GtN z3*9Uw+KI{^L%T+u!>ZE#KsWE&n7Okys&5J}anB}5bSP3~1?tOo&osjZrH11vwSi2L zI9@p~G`f=&x^v-((Nn0m$E})64jMaa^(PXTwnSaiHQ8!$Z zE+=uI*hkt)hn6@IWr$qgyb?t~T>be~u?AkX9Z7AV0VIghwbdw>sp!P-0;(hY#9~Zu z{$=rO;PYZ)=*E2=p6=WPprQdEJKYRCROL)Mf7e(RplY2^+S9 zpFZF6x2LIN*ukKS@1^|ZIL!KM4xFqVK%4UVi~hR*B?ats$-k_ zy@rb3=CyHBFUr*IL|HDA#UxeVj-CikBpJT~`UQ-!Y3WH0$pB!Ly%j()qJb9)VmDzw6MJP$awe8?=>t(dhbso5dNec z*4q4`p&LYF(}B)FA>mcLbK|ewLyj38n@H?V8Ve4$A;z`o{WrzrozgrBT?=STCPh@D%x1#E8iCkja1;HB^==KXmMa5levJDqAGs|ZyOD#e- z{lQoUrK-Z0bJf;sV=JB3)7m_aAz>Q>OZP=g4d(6_*DT7ISmvcSQz1CJ)WDPV$2gMT z3f3Oe0Fphk4Y$|f$Cm0bM#C#U49#e=8n8J z@=|j~8;dwYz*F{v5OT?d*ovwEeCchu%T6@%UL-~4$|v6x01@9Hi&f8c)z!EsO_3+e zrXj1&RDXFSExWdUj(kVu-Pp1Ri(>5c-tPC%EF;9zD>PS-Uea9oBtdu)3 zTj}Dj{NmL3ig(cWs<_oky93|h8&=^!1W1aU(H|@8jCMVAL(YVTfiJP%(ujR@V&A znmi;AqOn;x`lk)exoYZ^f{4#QduVemDy!d`ZXkNxT{bm*6M`HG*+A}@Bm-=#g9G@V z_h5~f&}3BGjDWSu5wuc5NhJ~otcdQ>)X zXjM;QQ{SRXiGEb?MX@GGJ}8FU3oniLxPKFIzpi9zi4>Fs=zj2?W>>VTjtz!j>P%M$ zjb_=`mM#-b;e7uAD*@%uQ}G3u3^)v-$&YNdXvSpdl5^-Gm4f}4VQVdefry>M`ER&t zsKV6ne+pBR^o{{OJ~3tQNA+sK*JRc*^I8@U`Ulyv9zMH@b}^JPH~vq(d{)oaTb%wd z>Kx6XrupxacrAV`HN}@HWmvz`i`>eS@v9o`?-BpgV0+W;ew*LAyGP3D1Uc4*F*E=9 zvnJ|F^iQ#+dnj_&2>e?QpDh>t`*(K|@wy1htV?7>vtuaUW9}K{A%mo;w2jIUo{aM@ zp7HR4U{zh`Z{&a)Wd|=ZUi37)Um(D44YB0LcEb%`#Yp-^C2$tFt)Aoyc_JKJuDu$=`g35VBUfa?$lJN+^*68`;ZEI0k zt>4e*p>F}g-I}B)D-}zgt46UeOt0UAAHB3R6E2q8>=>@!1L`>7hI)aU=4hi)b-M^< z-z2s05LYE;k^Az!2cd=fzK*9v5fkpi!HGoXav{vq! z9#pGlx-Gq(B+mTV0U*u_EA)8ti)JCOt|w;QAEq0P#2MOzdN17)=uWk!R%xJ7xS!yh zA9mkCDM8cy8|?8)8SbxZrXhe-8Pn~gK7IwT{4kQu(*27DwZg)}4nVk7jDGZM#E1dk zFY<1%iGcBwL1?dMIh9tOlm7IOqf}&Xp54P&m>*8d<(H23IP#|ryuEy(OmqATYn1^# zUu;AWXm~&HJF)*uIXGJ$?PDNyRFU7a8>eeBG}6E+_Lxl ztFdhjfBj!C#I%Tdu=ZU4`Gx*)*cu|NVTfg5R{-NuO3|rh7XXXq7;(WC=fL-ea^8^U0PS`TmCamKH! z;sHVxbah9X-=N2@8nggJN-^B4$0D`t@~QT&kxUI&I_6h##FxZnZrR?4lnP?} zE&0ueL}o{yYX^h%W(f_Aq?YhCeV}K;O1Ylj1(nuVHWMpTFdM`NVwn@Ea`&4P&s8p* zG?s?Rez{?3JV$Lbk!2-KCEw`>gis?3UU(h$9$ zjR@x(0S6p#7pCP{B%5KJm)Y0+fB_XwhUMHmdgP1bHHABkvlMVBSB+|g^F6w7RZiO0 z;%4z;(8QJfPVNG2JXCK2e*Ii_w8Rg$>E&+XkMJRC$?st%I+(Y8?$1s_xMYr_dh#g@ zMJj)S&QsUg;{=~uXq$S37f8=*+o=tuukDoaLwlId_iXFEmA==z;Zn-h2D(6hI80Q0 zLS+_Cfx;xKb`_k+`Wm*`L(4Qxnc>i`h+OB8s8-pJcL`eD~yU|@)YsqEA(67oED!R9*s=>VT;T37B`oPFVJrC?@Fz`3rVJSwKl z4LK<5(X6X|TiG!j3-95Lx|BEeD1t{FIDW>E4rZ%slluQ z!4kGNo4(>t+>K32*f<}4g?lwGH#iD$svukDlAQN`%*ovv#}fz?dCPYr$bx>dR$I z^L$wxjQGJ{trR)BG>%9de$5K)N)Lus*%F38reCvvbA+UY*)I#C)fp;&+?x%$Tu@f8 zd}kcxEPL#e`6hWU4eXlM4B*!>@{5(i#nV2#PBq=LD0A@bwoaKZb1emD3EN(LW;cl2 z!hzn=*~gLSHebFt%vMYFS3=@bQA%%4S+dzh8{71@t5N}#m?tY26`$yFFyx=;G6>r; zRX9@+weE1&%h1<)Wq~^;nMf!NnHDbqtfNEPHuqt05|u?;c*F^S@3?Mu%nHvc#^Gb6 zH@`qZ(smOGrME#f7dnXzJnpx#f1)$f5)5k z28DhtE*t9bPemoyloiHRH+JG>JYjXhBV>c0`UG=cO(H3#+fI3V_vmYp**uM>Si5ka z{s3PMHtOHIvmLAf;FFIFWKZ;@#pTItapseC%jSJ)teXSZqC>&6@2E1&RTuaugY}NW zuN!h?-WL_1xq>7t$JM_@;quJAi#;P@NwxLyKLDhpLEIB>aNTwGwFiugWEh)8m=<>g zhe3wbQ|;-qG<;=eW#BAQ+utEdK1PO*Os#k1DbcIPma8FTAtrg2`V_JK<&K#o)%6NF z=AZWGjY<5=Nr|R>MdPy?2$uPxF+~5QPSwVxg;=Co=#MZYmj30$PLYVR8jl~krI-NS zPR9O*bjW4gAv!b*+)1(sb66oo$sS8ZAC61arwdS!x#cSlp(|J1WmrA z;VMY9CzRvn+S5#ub=ng88Ci;UIo&H`gK{v<9_v6oTY&cu<;0X@?(*Hw8NYu}HDCDX*J>OKgI~b1lRr5POt;EUx?cs4w z;Ng%wjdE(&Y84lasCRM2oG^%CBX_m6`QnvafS+T1Q|ic!dX3wO7iGVc)S-EOwwRwm zhKmPsiph1BMfL0##!judDh;(#fu{1`D1?p@F!a({QH_FYo`1{0zROcr)ZGoe9xJWm zEM2CrB-pQrtP_>;CFo5um5KJe;xV%M)8>kz$U9=wP9CBJkp?`C>#V!a+RVE@QzT;t z<%`>@*aqZp9fE`$+&ZcU= z{J6CybarOo?a8^&sddARRwBitTv2}TG8fh0K%RpYRiI6x0K2iH4PmUx`I`$!iNafb zaoJF~q}!UZV&gkPoIj~6rE%oaMQJu_BTuGTQFL3Xrr$?XH@SA{7UKx=cF|U=UlY2p zi4N5_${{&`IjErK`~0b){GM;CEQZmOx;hdr$*>|32Vyf1}ShCd$`M~ zEKpHsf{D1L$EutSF~9e{@h(w*)$37hh=ijRcg%;ZWTHi9T1Vy^MINzH@m8qq1S|(MgN}|Xco>^za^Wq9iA|dNBmPPm9{29qVIC(_Of{Fs z^fsq!jgDt537D>!ygUN=kaGpkyM2P4>7sMl($?=0n6CAI>2e3xU)uEUAKGN5_OHhC z3=V(As_|YzFPoe2uyqO|UwWO{OqH4QtzmJ-oY&noH~9<9-wo+O3RjC4-1=j5=O@^W zKaKK{^xraLxaZ(hXW1!f3q@Z_e0LPD{CdiK$J3~PCoCcjX9qGLSEiNr-}%q7VSWdf zz=%5~!2J%|)R?GQQ&JDgyn*giKAipt>{Ftk!4#k%IMm#u{60xL!h)6}~{>n0sGf>Y1%x3CvwC-!PGOwwDd(;m2V%#@}6y#->7*gMT1bc zGU>tzCPI{Moiqj>>_S`a8)D_k^@Jp(>svg&bu;C%edxA2Csm3Usur{Krc|b@IuHrr zGnDrzb?vKP?(d698-aOc{%xM^yC&ic?AY@9eE6=z2W7VwuzW^77iacVu;JszBbGX+ z%vn^fqmEcH8n3a1&-w9aaTqd9@O50m=dvM%gfnJ1sv%Z=>ASp>Ti96Cu-du2bZTEd zQ``WFKzfx(WTfxy18ewr?0?Z|Do@60%tX-f_M}t^W@l$nNe>D?Bo-_wsjuX}hgKwg ziL3V$Lot-L@Va*#S;9qjmvhrBDgto{Jv%vq6~Oim_t+N%1nN<=oZ-R$DX{-1;pzW7 z;f=4~d}1n-|G}_Em(icxxOjXW5oi#%_+sjbb+N}E*y#Y?4%Oh-osYJ{DqYiD;T`S# z_@?cl1ebzAf;7xSJB-{k{frmQW0LDo#S=u>0rG7s!SBqprv^OE8^ip=k2zB(I};9& zIab4@BNW#Wi-88bGLg;x8Y5U0#zCte6w`4A%RI@F*%_*>$)kOaJXV%f1{;SNZe5j_ zi}$3(l`aXbl7CtbdvBGi@N~nTBvNzmjvff{g5=XqykeUx@KR4N!){=)IvZy}!8F9W zB4+*wqTOau(}rOX^FlVucX#IdtQ4c)K4M<{WC4)G;w7y=LVS_k1v)5Is|i3EsxoYK z0TB)TaFRea>G_HPLAQ;K$K72VSHfJBX66>(yqlt9-;w6mu~1Wv&|wm0`@RTyhJb8* zWj9^0+M8w=C&0|wtkVps&Hk7#^}#mH>qsm-BEo_#yFJ?g{$gW>=W))ZGdirnUv@jN zFP)fc@_X1bWjyT@9i<3bD)gY0T-~(L4{rHh@6H7OHZcERIuT#e>DuUa7%3S zwoZ~5C3#WzG9biUS0{U=k_{5w+u?fLCjjN$n%JuS9o36tCj5Spsh`Vcl+ff-V# zyUm3dRi;{CTy(X+gH&p?*oDZ~#8fdBZ^b5?<_=6%nnONaY!b(wE7#KkQv<<(U zH%J;@_OAh`$Hps>A}jEbG)a;6ccv9Ghlgo{n+TC?vz%<@7~8khH0;r-)&^zo&G$q% zXYZ-DB@cETR$XXR>T2Is^ls%SG;G{KgD*)I9{?FfYsnxQ?=w$Oq7^6C&+4EO<@vNt zwIRj%))6;WlL~~yu9t|h0Ysz%H0B8XnBgI?c!p_G9)rK)%nM+bp1jfH9HGD|_3_Gv zg$JY5Mv!=JB1cKpjexhVQjvW|Gq!bS6aff8um)i<@uFeu-p3Cg2v+149aXH29BF78 z@g6>6t7+~fTt=|fvRed$o|RG?R*fC-QG%>x9Rp8bafcW$T;S`pf9kb~AJxkAtT?2; zba;AhA6Qk&PgrytFEAh5Q{QcQN1?)8)h`}WugKgs`rKF;1{P1THFp*3X6RL5q+B;G zKX?kr5VOcIBQBY%8Yh`L-uNnNY8k(c9tzsXhrJ0lu-~e3i}l4A#8jEwq$E|Oz!@lj zqj?LDSvbT-OQusX4zzv7n3EcD_w0ImN&!G=Kz?5}*K*^8^&=;B**Z&U)VvG-OO@}( zt`ST7iGW7Azb9A(daDjX%C-5zBg$sfBObWr>tj+?rZjTYI?P38*kIyk2h80hMdD^o_TW{B2~I-Lb6#4;>G6y??kq1bdZT zVSt41GLd;#7d{m-t9yf6^WT!Ui?&icgpOlXhtEvTfHOXa#@?2Ov#Y{zZR<7_;ro^1 z`L6?^bMqfWE&v%Chdwi|h9>8AMI2>-;o7fayDG=?Jw-3a{kWVS^(yjeQn z0YZpK;%2h*0e(X{P) zJC4+&^n#3*7+%&UZ))!+VCuzo=YkkuS>~I|5DXtE8_N$%Ec*5!T;eC(7Jo zXHSSS9o54Ar{>V)c@7KfbtUI^sc+Lv#>rJn|Ve* zknxhI`O2y=!_cVE48yssl6QR<5NUf_(^nB?h8wH1c^##p%&Bvv)-TP!aE!YwLSK)U ze-(K5p-Mt;3^R0*V8gx%d)P~&`fn>2`41ZxAbBYKgzB@0HpnxVWx0t7pDh(9nvBCcS z{w)a3Z&HyYr(dL^_r`NdTidsND$ku`{GYz~o&q-*h@nQ*&UZTP$h$UnL;XM!~eJh#bv1HO>K#8zc#$F(n2*4ZiJwRPddsih#*xtl8NHG zx*(JGVOF;*|Kmrm$uy4t5e$#4=Pj!#!9WxT5Dg1d+zclc^wH@1W zh`H|s9ZbU#cG)3Y_Mk*~yUOJFUXbVo5Ips@ND`{%NwTh_F|lD+>?Kzq=sHC@V-d{ zcd{Wg+)+R(;QSdONIvzKSM(cLW9p&m(7V`H#jCb)7fyDO)7g8Gek6cMpM!S}CIC*> z!QOAiJ>LaiSmJ*M=h3mH$MiMaygtr|?a!6Mj$yAmw^5i+4!^JxChELACtI)*>}|ED zAE8T9l|JZ8r!m$)6=zP*G5@~vtWXbR+%U?wySQrZkEAA9T(=0{mPi&9HETY1)@*Jw zFW1945;aOB&9}Uwo5gdgyA>07Wc)%OJoLjN)t4Xt=v2mNosOy~L{(REdrbiM!F(FS zwmvl%l1wz`OT-OAZ37hzJrGr?>bfRWP_(a_YKwwvjxX3EBOncY$2Ie?lBdVcK~I&J zJTvPN$C#m_n?ZP)7r`b=JiLFZms~Cm`z9HL=FfY+f*+QOK6<%ihWpJIV8fEcJx*N) zv`M(uU~JB-!#Xg%(WQk?><-Llp;#bDj#kuM>6zK%%KlqS;S2q*Dt@{kGDQdA^Wv#6 zn@Jg%gb12r+5ve(xnfwm{G!H1{L={8Lvc2ZY z0emiZaZ(@gei{;0B_i9T#4+h6Lw4j5;gJ#<<<1WNw#>&2T``V8O+1R8a*ZBwd}@cy z`etuAW`x7$!`*=@`J?n98K=EP2*Rjz>|BdHe=K4 zhV=J2ZneLUxN`inw7AM-FkeAo3`+u8WYgY+BQZSPTkk%Vad3^^67oVScm`o4=f|g2 zU7IwKRKq%lcR^+x01cQ%*<~@foyGPdgnh|JcKT5CQ|SZok`EcN18%KXxAr_< zcgF{`7@WLyMq)ttU}rz}6Fp9_w=`>JTmGuzW2gl$%n7GZ)T2?jq*+d)ju?H!9r$Nuz2T< zM^~^FRV^PijTDYEHpZZg>7vq7pf2hUVyp?m0!@8^9Y9YN=7BC4N`K3(zc-)MIZxX6 zv&)KTj(oNrkev^MS%yvRot$`hvF<|%=QE&+K~z|nhlLnlW>(hhDzJHljQsG?qtB1z zBtNL5mNayHis>Y6VWGTF(5y5-DwEGxPUVNUEXS%{l}6@5(+|buQKHhp!Od9pOez;R zpykNoq$e2bR6mdcg|dem0~N}9wUYC`7NNgN3;n(LzjKb~kP>HK^`dr&3rHpNCp~ip zY4wlXsOaq3<3Hu}HjjS2`0$|$mD+{zFKyOw-Wi1IqzKqz7jD|N;oA?x(H2gbCl2T& zR{o%$iAbkjkxSozm;qnETtB`d=ijFf|DckJfAIyQTcv)SnDIG~9=s8_1R1zCWSZK0 zlAFy!cAP0?cvPP19#H_l;&8Ddd|#Q|%MGDcJ_W?5Hii!r`aFrrD%x0s&;UhKCg&aa z{M#FOd){VoE$e?fj^!FScz0GoO1`Hl{tdy$?6qc^um@p=Ch_ziDMJ)5XP92D8MQ6% zEHU9@ai(&lVNi# zq5BCJ{Ocv{$%~lH<|~7XM^ZFg&sO=-;0C5k9@LRFqQNGnOxDlm<7~ zotXV0$z1uXm_0&v=C+OR2FQPLjs8YESB%s#b<5fzxzaH~e!*$rTr}3|#g&nD4Gq*Kw7PZ0au7|H#52Z;kyPN}5CdzaWEPIXnB0 z*%6s?Y2AmO9ZRD$D)w7`DOSVn0horkoMlF|SE6WgVq)Ssz{%NpUAW|9%5O(Dv7CT1 zwtsR?7_>a=YUfA1h%i(Wgj8iLsj}GOG7iAQ4wuc;|9AH#hB{p7X6;VZqDJ)Ad2 zbaeRFYZY{j^)JV3-`?H;JR`_+yu0;8Q5@TC2B>PEuEDL4#k#N$lK3u`e`Elq!VV2- z3(xFca{s_J*iJS~lUT){9$Bix0|e;ppVq~`Pf-l`wh4H1jURtn&@kiB?leRQu1-XYVUc2dceYPtlTXJU24QUO3_tPj!2UtxK z991jSkCt(+*uZX{jwCi0(6>nLW#1J@=9#|%o`Z&THvWW3Rj6ohT}Bna#_NmAKpalc z9^1j?rH(x^o8)N7vNjt9_F&|eLiSB1B>A{4Ra+h_KI8C?wun zJp@!P&oI$ajg9UcA55!jX_c1xO`(o>{`~P{iUBb`%*J8Brpb?x8_yPf#mXM-yyWR8 z$7$HMaT7{mRg^yjm6q>k5xKcj1VbK}*nBxV8(>OS6oXGEBm#h)y_o`tNzBsVjMV514tg?0JW8IGpuQdFSDe&sT=hPA{tfE@I7$zg>rUAkuXjv7s#~L9&C#+f9|E!^<2bce(!>cWPHCq?4f6g3V z_1@-1Fp}OdGLyiX_0~fr2WT<&tKJ1N6KkOBlhGK_SG~>H*23A-xhEf>*hpZVru+r+ z*l}zx6$TpH`fQ!>qGzeQN>rWI8SOZFia{4q#{P+=^P|cuAn*Tb_gt!MZI}GVE6KTI zX7xq`3~oym)&jxhK(F62@Ulk_4avLCu4||{r6Cd1atP;rV2-f+2h@z#+czA{{I3F0 z&F_*@UDhS^FPt323S1&F-nwnC%N)N}IL^-M5hi-spK)K+Sz6!Cs zO}x|NQfW1{1Qh9>?(jjlk3Bf&Dr~i0;feIaP4*MYXU|K|P8!$0w;~x`*IURE)UUNr zpR>P=AmblK@b-U2ehcwmY9dQYCLbGT>njhlj6muL$u`q*E!*FL)JS@E^qLUyF)sEH z8&n&*uwg}*Ecr&Pdy#=$B?FF{kLHT% z%S)K(W}kpLx*XfzaKxC|GTzfZ&u~jt*@wEA^Q7F3cLW&uvB6Ycc0la*A>@9mue#R7b|Ta+8euYHEI!LK-MVamjNjTe)p}q*^TZmtIc^RkrlSyt}xaexYFUO0D{*>L@F%QvqrDB;XFy%g0E{!_$I=kwd&|(k5mV0~0iu!mQ zid0wpGeUr#^uJ=hQ^7AG1L-qV_p-|l%VrFNS|QL8DB zRLSUyFuU#NE#=6(Sbrt-o8;Bg2=ebIM8}}6M_1S)5P;E|$rF$sUZF&7hl>p#8S3eC z+mePjB4ibpWK7n$pSRk5a^OjgZrvnoQ_|YB?}+~ZfRY`iDup=%!4-pHe*}6hDPUtbMooEHH@vD@}xQBXH`3kzV-*yH36!_6(D%b+oHV<8=so2zbUAt&m;Dchw-;hu=!UNnmm~&HE*J-f%0Xma)ig@ zJZqaM`Im$H=gr$hPz87Y&ht+od+yN_!1Sto+OAiI6-Q(0mN#hmQY4Snd3`LZS{m;{@_VnA5Y3 zLi(k4wLxaNC)5eYwACwTq=X&j$U3`UlS%Zw9alSCks zTO{jMMyIC!WI2~syB=w}Hs<8R^hhO8d`>K?D2osutIXC5s6gR_c~V(hW`QUvVzv(Evv=Yiu-*}_GUJ# z9JwT+Sw)plil=SP7#D&g6CFk9)Y{@66RzK0tecHYyojQ{jH~XYogYZuj3wi%iz?nw z>v>wq-DXJ84U{3Bsm&HVLqhy<4{X^dkiO4R2*rHTc` z9tgnGBQws_Zd1z#)}62dk1x4r1VafbLdg$&GiApaq~Xm!_JJv6=MRg})2~7`Pwk~oMT!`=wfUM4U4$45JvPrrVSLmSdz2n=G7r}K9j z6I9s0Q8tw3nYOgG`n)(f;`u%Mup_JW^Z<&RzMi@5njF8j_w!Fjmu%&^X~Z~rc9EQ; zJ>!~{SbT%Vby`KYlpm1f>EO3@iOln1vXICU)mTaC3&s96cV?1y8O++cPe;H!M=CCi z#_rm)86DZKD&inY2;Gt?<(YX>zVfxhT5ZpwQ`5&(lL{TVJxnf)APv#i+*n!A) z7AHC<1}6`yJ=2V9K?d_^o^!fv~-TIU|GQ9cdA!yXC&dhrJ!emC?B7Q_wV=ZEqYd<7SuTfRe3e# z_QOEWoR6D+_j`Udj@#06<$71`j>ua$?aTL`>mPFo=Tvi!5WgBA%QKCa1}*^gVvoa_ zH*oNS3KtjGz60d+2oZv*r>A#=5|rn`50`IyvDRDNRoZP*hzJR%HdpNLeyaFRfpwsM z$Rk5PmfRjO8ZOCj)46k*)%rz?AGP}l`)RxC{@o-VVyzkNkeI-vDM>LB zsp!k-z|8p42op0fC`1a2iJLw#E|t9bo(*A;7=mqemEseQHkq;> z$9-Exghk#uFA0)HzL*O)FFQPHKdBIhIQ_~B>!r0su+QLzfCG=6g!y(!YuqEGaZfZq zA)m4E*)9rebBX3YpA|EDO_!-z2Jg}GsP)K>T%+}w43{SFf^B4u+ACbp{@qMoztyMkdH zwHdYZ+n$I1p(`dZ%jFPPOxg^2nq#t2uh{hR>39KIhs3KW?H{XB7*&!XZvhN^%t#zmnU5UISdDP-~JoReTmssS4bO4DYr`sVh!=d{9X2sRH*3 z9amm1qYVOsP`iBpWUSv6_Ij>gcRnCGsgvuqFsR>}wY1(q*Tes?iJ`&oPt`CsO4egf z6W4b^Nx9IW{)$>)}xHn+NPKm%LuBkj#@XtfVdM#xPbZHtCSN zX_m3Z1PD~-p?RIq_gy`T_gCseUB2Mn!u&bOFBjdepnEJjwH0Ixg~dXSIQP8*+ingM_{1`bn0UR%Na%Ck{o3~--ZVWEG?Qdkqg}=uWXG;W+W>EF zg8?bDbbGpbw<5qtb`rK;$s=ZM@5Kc;uP}C)EAi>E7Fbh566z zPa^ntyAK$a$K~Y(n_d3)#B(0K)p_h}Z}i7&3MkiG8t;p}YOkaZd`cU>1thX47o$*C z-rwIA6~4I`O?jw6+lR_ZVs2~v>e_JX5YtYDH5T>j^PGpa-kQsMRD)BC_EOja)!nDA zIFh)F`v~^-_6|kPK7a9|)cr_}!?0szGxMarv2p&p!J0uqQ7=sLK=hN3a{cx|^rzEH ze$~?l4!^J;A9JyZeTfd;wg#s(zn~Bm{ww3-yiJW=qRX>G9;V?WNrrfD_t)T_;Nh5B zha1OZWW(luqeK(+i**PY4sGaI&K>tje8k{J^HQ!?64)!r;G(c)9b9pRh55vwRs>C+ z!AOG5R_-$-yh>Cql}(XgI4Gm<&a1kNkw*F%h;G82mi`_`GUOc*sb_f5z76Bx8Ux>b z_HW=D<8(qltyVVrL(EBV5eA-!^4D<#@0DQ(XZ_grSwifPm_ox!qgyz(@yAnim)ri_ zc`^T7Wa0#ETtN3%>=BpqDjMKZ;k;&n=+|An#!Nr}CA!msRMW8Cx0NfRqsjLHdyWZh z8FH7RQW2-*YREBbrAxtbQ1-^6Y~AwX0P3ON)w-dPj*oXG{*bM)U_=5J1uiIK&DN=~ zp)4j-EY#B-uegs=g40sduSR>k-gDqe6mEUzCmpTwzQfTXux<&LJ*V!|)rhzJq*Al$ zJ9SL?!$o93wuo6;D2H*mAebuUll`ch9sTeD;{mRW93i4FHHE-bJz_adFcmH@bEV?H zk9-rh>4!1+Yg%ALOl4pzQXNbI5Up`M6vb`q_;g0j72DMv9JF6XXTBhv5IyvhtHk7s z&QniKmNZM}5GyyW)Dw@4=CLcC{XbuxG-|P(ecs9bc>Ju?+o-CN#@^ zOYz;L&-*1Cu6J0+72!oY=H!(++j~O{lJD;(UUtlWtd%T{FJ#v)<~3$R0^#PrNxQLc zc%pLKjk(F=g8Mf_jzh<~M!9G?6N%BZZRu7TGRX!-^PBj&2Tqwk^%(Gc(jOF21!74F zvdNRqmtA}m&=rtg2}~u~33JuKr&%5;W3ouCzrc=W;W+!fX#!_`btCqERr$+_6bfJQ z-p9p9brs*|f$=UhaET;Yp}AK8j!Gvj zV!I!~A3vfv?+McH;q)Q=s_28y{^?6Sy=B~axU`voF`TEKmhi2J$8RGPynJtVQVv&J zUYdm&!UdOw{qFBNDHm=}?ERKY=q}e^(b0YF6`Y-$oh@-kWE5ZdrHDzI7Jm%E?8I;t zJ~Odo{hOX8|1|zz5aXw^Y3sV%i57T%-1nyHxbpe&)TO$>Ml3~$FGYmeDVvBZDFL`9 z4K338q^fQD-Bs!lBI54r{LA3(!{UZ)bbgkeIYuy#tpdTcIx2I?H5qtw5FhOZi7`yr zi_!bbgkcLy>0g);8doO1^vn1XgenRdBdyf#s0p|22uWSTe@u{^T;8v>p1Cah*GjyZ zBZ(v{6i(=957?h)4f^22FnK^5y7n0@1XtF4q3b2~i`YKfeUCC6b7Kn;JeFy35jL%D zlh*k6gFHPeZbYatGqUmCJ}7^}{f|U_|;MiveK`H2fU1EaD}EFsD<#N zeIMUTmtt@)D+cu|8<&;JRh6^+v=b}A#mN_@dDUAIuee8K+WZbn?}rm)a*XvuuVOVv z|2@8=CSOnnq<{P?S?GsE?mHfuRk0UVP*!!X)OR;*G_{-w+JY;c29f_&;#6xfH5jGK!xl77327C^+G_e4adtZUurDcEgi ziT-<{CwCw&SQgUT|KpeDOzZ#$Bxbn(H9mCduP&J||8) zRYY3#uc+Ttq@1o5f#`C3|COJeDjQVj^p?)3)1bDH8O*Zli})F!_!-JagThU!#0wQ3 z`!NcV5xx1{JGi=*JICt+Y*){3)$tODOCO8eu(>%+U5k+o9eGSn*t%AwuRV$r9o?r& z1Wy;K6!|^eQztj_3k&O^fcC}jCdKc-LCJn*a`K=`@gy_|GwDjVy;GN|YCbD9EzMQH z0$OR5pxQ-GDF5L>iET zo4mFqZmDZ%r9#qzImYQ%uXdle89So0VTC4fR{+FM}}A9grv}<>+1|g<~8~^2fi8M?s8$BO5Q83-|{%{DV8LSx;}Wfl{z{v z2DO6-%nNHL$P>iZ*FIdF5)Gl)^8Q7vjQe{AucwLRfY-zlSyUqzEXI&`Si*@n0%`2s zy)9_=2qiS36r#h9Q1sEq-`a4Aj;3YX40$o`i)1gvkaK9&iaMn14H&NFy~}Mc8$Z;B zQ`AM+uFC%jIWdUgr!r#`VN;SJM;JUH73)#_oaz2QFN=En zB2Qkix#3&Z;KqV)Qm;nM7xv=!kxZ#zKaBp3+SiI5vR%i+FHvd;aUpow=B2U^%f_6a zkU=2HMrCb~QM>UsY(TuJ{)cocY8?_Bl;+tjusp5k*3{=xlriGcJgnb1$adk;Z9J}t z*^VM)Po+AldhjBUV2#h$zJdMjG>==2a~W`lf-=6*^Khsi1RMz|4f3Zwt5pE^lic_&DC1 zv^)_j#R*zUBHF17m5h~kdSb`LefMly@+OlS4@+{9ZRF*=sJ#BEwyK?Te?3-8ix5r|7Q2stu$} zf0IOYUd43FcLRjvl;;ed2EzgNAt?%pm#|-+x)kL%H;4VJJtumN3m_diXHpzaZ-)mt zb7fAmv5|UR3oKSvA=0<%9)Ese%pg_+n7Zl{K8_mnwBr#TI0un+N^d<$4=$2L7g1{a zmKqBe{!lm0&CrHRXjD)BU{EVZ)#k6-dzfnJ5mYk3l4{}=-=FNRZH-J#a^qaw$2OxV z{u2O7pBFe9>GJx4cJi^EqnGq6w{Ap^)tl~QJ&f8lsV^WtM_hQHFpOog#Q)|0N7-8j z#o={XzyBn-26qVV?jGC;?$&4s?hZj3Z6LV22AAO8Sb`I*aT*QoZg1zAnY#7NeQ(X& zZ+xJttGnv#v-jG+wN6@5aVt6fTvGy1OKD4KJ1PC*JqL0eVq`-#)lYls?jdHE`5d5n zEzOk}rrhbw`z!I7-m^6THu9dl=2(Glq$6*WdcJj-n16zD9t^KB{%8$Y<7tW_8U@O8q zmW3~WG>hj9oKW7p!^bJ=h)a;|$S?~`+@B}Nu=C0Ss>bVWUxiK2$F`>9ZURg|u(z!x zNk^jG7o`gKTpHfia*JKSYnq#KYZ{G;sPkRQfg7ebeJ`ck$mnZ~Tb0KMcEMHI1Q1{< zfWjayK#w+V$+^Iroyuzqn{_QE{TckOb&woPZQ_3m++(a2W{yxev7SAaUNreTB>ftW zYgaw2@IA&+*i#qRiYn$VH@&LyUF?WCY-$p@z1^EHQ996utwJY+wM-}by8JqhUgwuu zZs9cPQ#b-fGHY2%{1+&%t=CaX=m(dgQ8GzL<|^A`(-s#+a=2u=?*5;{naLAXT3QM_ zoR2Z4Ple0AU5|bc2*kZLm*3ahn*#t2!x)_l{9ImFUS8hMIm@(njFH?>E~e`j08?8W zNpNsx00DmJ=;+I2ZHJ#79p^D(s>MwGVq#+EI-ZSZhrR!;J$+pJ&k6AKzl$pSLXK;l zqfm=Ig)!j}yDKpVh7s1?503SS%cawZOQ~}6cJCro0leUY=G>QV5V&xiA=|?m%gjg; zq+R0ay#_-aGRV(BZIre8gm07z0Wu=VG<{22dTAJkKoYJV6x=x6QJ`HI?dBy)y`wr+ zvD_LJ*9jG86n~Ubx0L^gD7FR#(rL`3SCmS-f;(6nT=)s+{qL_%A4SPcI-H#iVoT;E zVKW4Wvl&akWBBhLQ<_kO0S-&Ew?d(bQ)Jno?g@ENc9?I z*@xuiL_5s;n09RMeL}Zf)QuAjU!6Wg(rD^C-=IGzC`m6UjHCAXZXfr{JD|Q4^Dl0J zUdt^y>-1c!;2m@n2lD!r6T!io>MA#%aSY7zs}N#ShD(IlHIe@~o|}M9T+>EgI71l5 zW=)WA!#f}}kF)n94{lG2rj49-@i_fVfbk@@7)5i1Siw_Ju~3gJK0=ef}@bBQ1~4+_0p&E{G1g-~!fn&~BNr zYkGTwXv1GBe-I<1qg~b=B!%j(XGkBUek<{Z#WsnJ&PSuRwot(?18#zlHHrcgk zJLMNM|Ihs`Tkh`eh3ksI^`>J1V3OQH{&cO&??8J!Q?w&1ou?*@5og}ticz?kLd)r< zy3PHi^CojLN30sw3je4v`D?Jd-n^BC4R$B-f?5JDo6^T_55qxE!x)E4SxHGnVozRR zr@+fBjD^DTu%(;R^;&d;?+f3br_`YJ7Q;fMQq^2Xu3j9TM-Ys?FQ*rW?XKH}TrD}uTB8cMDk*7x-PWiya=_!FcczFj3COxgQD6Glw?C}C>2SGR3C^+Lv`)PwbW9)q8q9fhOd$LE0^0%%iY^kZrCQ%&e+ z))DHqj^(zW?q#FZ`h(cj=@wr7#xR);(-MUQcdiQu^1_O2;r3zYGXoKrm2vbpY!}}4`>6&4O zm71s-m7fl_z!kenc@Ox=i4a`LiN-X@;EgUzX~&77zhHePgf>=ccI`t<9#DqGSDY^W zd|XVV!}(=Eg3h3cWBdmDGW(=)wkyT_lX{K6^gZ@MgQBv<(HA6F7Wx$rOc#^kUufO3 zCRc8BgFV)nt#OO{bsr3kF7;fx6!V=!(oxcoPzUyWeBNUPkRE9A@clsRsB=96 zGdJ}~4*xVDEjn=400TK6oz>T>TSHqJPj$fR*mOU>nfk^hmDQeYD=fG-Q~G!r{#WD6 z`G0SG9ifA$xioaY+uh21Rnm&CZglHCnE7i=v}+G=J$O~NA(4gQyUzV7Jw+G zkv6m5R}9zM+J8sauJ+M3>fFhs4KovQ?|hSMlb>qPh3EPR6ue}>x4FZm$35}adts8z zM|8tx`+a9JC#|<`il0gq&D6S7k0ZiSD8vI-poCxk?*A^27P+r$a;zbB0J4cW6RST^ zeunY#rk(PuNC!0W6jA96{Z2zGP;I1R#g1?2vH1!`1LFN-S{lkp%NR%-H ze`TL7utbK024k`6Kx7;3N)}vx6&CZ18Ko?g61Spl=@CJdwzEK&CObz9N#R+ zRRM6G>_+h-DCHR&G;YJ;e#h{D4k|Q#b$-B% zG~dYAL%>wEjKpRlO&mD`6mf77#%KI;uNo&Xv&)Dta^O5sB{_Fp4bHPcmk@hII=A~U z_R5eTp&|{>k3+UnsGSjyBBW5hXVU48k2UMW`OA0tCm&>-u;`sK>GV(K(U`HuZiVhu z>Qv!wbKs1fj!?{_NANXy-5~17b3PxEC!$pS9xo5w=ow)>DaEJ<+>$*tqz2?XOk9|K z80E6~DSMf6b2T1D9&6cc>e986QBLf9P*?RsYN;K7DJ#TVI|7)dU-!S-U-?QGJo0G~ z#scEKL4I`Hg}Shg_;M`+a!nC2)BC*@BO|tKjmkfQm3qny4~s4c*|}?k=9WZxZpET>!NS@{+@j``89(yTfbgG~ca)|prUk7%;P>kI;DKkk zm`8#g^B4w#<$>EyL81nW2@5RKP#MXlbRApX_{ss1=C_yWuAr4P4tr-I9Z}g$ZZok0 zp}_&nb=h_oR{hdPLI=-u7oBlsSaPgCjOd?nSG92n^B0?!8)>Pq>eza*9?!GriweGP>6;~5OeQizBs_iUWc|8t^L!p zO3LeVKadY#1qs)M{o#qF4UwDQ$VVqU8DcCY-_xTtV^}M?lWL_Uo$fYNNXpXhJRs!t zo1AgK06l1@`2X`iFD3gbi{yOp@rMpc_-8BIlVkQK)En*6_>#-QSlSa;o9KyB+A`}G zOALmQS{zR@q4Dcyf2OJ9$VGmx9eg?Q0pY)Ag|XCeEAwe4-oYqlK8HrZ>z**HSZO~dE#%J|EF+n?OF{pV!+ znE&55{mwTOVsbB;+yg3K`lzqr$Zf|z|28;N7N-??P8sn>&74j0F6M#e`jajUP`A>M z{thoN+Qi%-Z82Sbmp_pPNXH}%-I~(>41yVm+EVl)d^J{ye_eKr|ESZkmIFWOG02CN zFgo-T*AgRFHijvFm$&d|m7n9$9Wjf*|;b<|eIv!V*3!(`~QG@o%KVU{%Z)^x4U@BPt{6^#M zF+(Kg&oU&7!^xckOxdBbuSRwGVG8UxwC)t~gdQ3zeS3W)`4$5Q-yL+eK}RK(6@}t} zr3sMd#_FSYCgF;hl2D3TSe73;QZ{3J-jP~dUT?`ahJR^QC;PXcgtvW zjA18Y)gh^z1Jn)onAG4uVaU2>l#NHaiP&cl;`p%&?BX}C7z6HlA2HPkW^@kJ_$&Hd!tqo7Rscb&|>?u~|vF-0x zT@-5HGF#r$B;aZGTW48PSmH>9g#EwC8TWYedrP+&rTvFe4}4>GxTI3wx+ z6ziM`_@Gu`S9@xvx|k|#9SaKWP$_q^IL;2BVy|IY0sjp5ty{CQu|IQr8hiBe{CHGbJ@@bjDs_FpwzG3{{3CGmtPr;1G$vw_COP^Kz$d`3 zOgW=aNb0uW3Vhp`_gvM_+vx(M9hQ#UnYCJNXG$@KZELxnoOEyBwtktbfL-IKus1O0 zI-XX^=@2nU%hyUYVMYosfrzE?EdEL_KlcAuW4`jAlXSp;U-Wc}@3EWM_(S0@E+)5f zJ+U!qdD49lCdV4R<3u7BbbaG+^O{CK*|oTQ5)L+0q-Il)3yW}3uT@J&~r(Phjxcj?f<5+b=lv&3pE0%&{CzqAa1ABS$hR4qQCXT-9?80?h zJAPw8?5q2@vJRf&Lmd!hBiOO*KcxWb<_6j{c0 zc|qT7bHv_T!A3SL8t6>N2X=oDJrXL~%uUF;%8c6Q&`zGzFMJxOU>`Zo`UvGw#|NSU z-3IrFlFY8s>Gi@K2f5rkbeLUY=K;d?80*(5RuJhQKvV~6=K7cl{CP79;|QrSa#D*! zm+0jPx2L}5DaTE~N@6^eZLRGbNU*r<9BjAXRB3ASi$C9ye&nVQwzHKN^PKfC(4Di( zlNXAAC{U!yk$5ijnj2l46A8NeCI^d=XJXc@J>W{Fl)lx~p7#Fpt+_> zOSNQyZ>N2Br8^*N$+$y6O|!^kuH=VFyYykT;lbc3@IUH>J+)Ei;lcIs^IucAr`)Lt z%*9%be)7Fm;`}eIv>qPc!K~%IH$fJ7KWgeJpyP*wgEQCRfr5$}gR%Gdv@et_!d^V! z!9C)5>9NxEIXc3a(3xD&)iT2Ehwgr#I+57Ja=zGn#}g%$6p%~nP6dVwt}nozoc&8p zp2oDBBza`Pgp4#s{hGg6hLc-#F47(Bq=uwl1IS4ruUh?h>*6FcGx)@stS%;SGd10gO zQi0b@mueEp(^p&d>al2G8*&{3Jjx7UQJz5~oS%Gdp1J^=Y8C-`xLKdZD3`feGdvgX zGG?$nBcm31vQ@!yLaNY}94qDd+s~>;^F`JWO?I4b-Uzkj2rH6bTrSpuO@7Ejd~Sq7 z=A`egXZ{q0p&-gk2RWm?3m@QCqfd|!QuwoP12E$u-@?-5Y)p?yQ4!ucirxp_!gUcbq+bz$X33m{JL72!CO+#O^dEKx{W&! zqOm?@{`i6b?5SfSU>r8n5mr>-qyU<43lJstu^2$bbD9^rx}hL&FxD&M#76#b?@fXa zbuyAHU&Jr0Vv1_~PW|iUpMBNgpYCE3&4)xo-bOUKZa^0k{)}z6v|rtr=?AxA`>^;e zth?w8iRv+o!13&FwZh_0yztYT83R$LrpZZoQH7lYVuL{v%qHA<8=Ti{^Yy%cuA}=3 z9#~IDFF{910<(3i$B8AE}ysc$N)b)sC_)k(zm@czEAL{Z@onNpX#LEN7<0U z+4Y-Qz}d%PPYNM4Bk>~>$cWK1zc5;87-W2VlhkO|&fw)n-z!<-1-1q6n+GDWyq^)= zymYVk|4maDUje4F7fy|a3Wo_Vx1m->@>NrhgzZ42b�r@g8lZ!l#=c!$(7u&E&(a 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

f-MuR7%3@ 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

yVcD&M1n_cJWT+FzukenS7 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 STG;XPXldxHm#RH@_J05!Fk{yM literal 0 HcmV?d00001 diff --git a/docs/autoapi/index.rst b/docs/autoapi/index.rst new file mode 100644 index 00000000..7de4a30e --- /dev/null +++ b/docs/autoapi/index.rst @@ -0,0 +1,11 @@ +API Reference +============= + +This page contains auto-generated API reference documentation [#f1]_. + +.. toctree:: + :titlesonly: + + /autoapi/piel/index + +.. [#f1] Created with `sphinx-autoapi `_ diff --git a/docs/autoapi/piel/cli/index.rst b/docs/autoapi/piel/cli/index.rst new file mode 100644 index 00000000..33fb8cfc --- /dev/null +++ b/docs/autoapi/piel/cli/index.rst @@ -0,0 +1,27 @@ +:py:mod:`piel.cli` +================== + +.. py:module:: piel.cli + +.. autoapi-nested-parse:: + + Console script for piel. + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.cli.main + + + +.. py:function:: main(args=None) + + Console script for piel. diff --git a/docs/autoapi/piel/components/index.rst b/docs/autoapi/piel/components/index.rst new file mode 100644 index 00000000..37bb8a88 --- /dev/null +++ b/docs/autoapi/piel/components/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.components` +========================= + +.. py:module:: piel.components diff --git a/docs/autoapi/piel/config/index.rst b/docs/autoapi/piel/config/index.rst new file mode 100644 index 00000000..8e492976 --- /dev/null +++ b/docs/autoapi/piel/config/index.rst @@ -0,0 +1,25 @@ +:py:mod:`piel.config` +===================== + +.. py:module:: piel.config + +.. autoapi-nested-parse:: + + We create a set of parameters that can be used throughout the project for optimisation. + + The numerical solver is normally delegated for as `numpy` but there are cases where a much faster solver is desired, and where different functioanlity is required. For example, `sax` uses `JAX` for its numerical solver. In this case, we will create a global numerical solver that we can use throughout the project, and that can be extended and solved accordingly for the particular project requirements. + + + +Module Contents +--------------- + +.. py:data:: numerical_solver + + + +.. py:data:: nso + + + +.. py:data:: piel_path_types diff --git a/docs/autoapi/piel/defaults/index.rst b/docs/autoapi/piel/defaults/index.rst new file mode 100644 index 00000000..1fc23dc2 --- /dev/null +++ b/docs/autoapi/piel/defaults/index.rst @@ -0,0 +1,14 @@ +:py:mod:`piel.defaults` +======================= + +.. py:module:: piel.defaults + + +Module Contents +--------------- + +.. py:data:: test_spm_open_lane_configuration + + + +.. py:data:: example_open_lane_configuration diff --git a/docs/autoapi/piel/file_conversion/index.rst b/docs/autoapi/piel/file_conversion/index.rst new file mode 100644 index 00000000..626c9ad3 --- /dev/null +++ b/docs/autoapi/piel/file_conversion/index.rst @@ -0,0 +1,26 @@ +:py:mod:`piel.file_conversion` +============================== + +.. py:module:: piel.file_conversion + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.file_conversion.read_csv_to_pandas + piel.file_conversion.read_vcd_to_json + + + +.. py:function:: read_csv_to_pandas(file_path: piel.config.piel_path_types) + + This function returns a Pandas dataframe that contains all the simulation data outputted from the simulation run. + + +.. py:function:: read_vcd_to_json(file_path: piel.config.piel_path_types) diff --git a/docs/autoapi/piel/file_system/index.rst b/docs/autoapi/piel/file_system/index.rst new file mode 100644 index 00000000..45fed232 --- /dev/null +++ b/docs/autoapi/piel/file_system/index.rst @@ -0,0 +1,197 @@ +:py:mod:`piel.file_system` +========================== + +.. py:module:: piel.file_system + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.file_system.check_path_exists + piel.file_system.check_example_design + piel.file_system.copy_source_folder + piel.file_system.create_new_directory + piel.file_system.delete_path + piel.file_system.delete_path_list_in_directory + piel.file_system.get_files_recursively_in_directory + piel.file_system.permit_script_execution + piel.file_system.permit_directory_all + piel.file_system.read_json + piel.file_system.return_path + piel.file_system.run_script + piel.file_system.setup_example_design + piel.file_system.write_script + + + +.. py:function:: check_path_exists(path: piel.config.piel_path_types, raise_errors: bool = False) -> bool + + Checks if a directory exists. + + :param path: Input path. + :type path: piel_path_types + + :returns: True if directory exists. + :rtype: directory_exists(bool) + + +.. py:function:: check_example_design(design_name: str = 'simple_design', designs_directory: piel.config.piel_path_types | None = None) -> bool + + We copy the example simple_design from docs to the `/foss/designs` in the `iic-osic-tools` environment. + + :param design_name: Name of the design to check. + :type design_name: str + :param designs_directory: Directory that contains the DESIGNS environment flag. + :type designs_directory: piel_path_types + :param # TODO: + + :returns: None + + +.. py:function:: copy_source_folder(source_directory: piel.config.piel_path_types, target_directory: piel.config.piel_path_types) -> None + + Copies the files from a source_directory to a target_directory + + :param source_directory: Source directory. + :type source_directory: piel_path_types + :param target_directory: Target directory. + :type target_directory: piel_path_types + + :returns: None + + +.. py:function:: create_new_directory(directory_path: str | pathlib.Path) -> None + + Creates a new directory. + + If the parents of the target_directory do not exist, they will be created too. + + :param directory_path: Input path. + :type directory_path: str | pathlib.Path + + :returns: None + + +.. py:function:: delete_path(path: str | pathlib.Path) -> None + + Deletes a path. + + :param path: Input path. + :type path: str | pathlib.Path + + :returns: None + + +.. py:function:: delete_path_list_in_directory(directory_path: piel.config.piel_path_types, path_list: list, ignore_confirmation: bool = False, validate_individual: bool = False) -> None + + Deletes a list of files in a directory. + + :param directory_path: Input path. + :type directory_path: piel_path_types + :param path_list: List of files. + :type path_list: list + :param ignore_confirmation: Ignore confirmation. Default: False. + :type ignore_confirmation: bool + :param validate_individual: Validate individual files. Default: False. + :type validate_individual: bool + + :returns: None + + +.. py:function:: get_files_recursively_in_directory(path: piel.config.piel_path_types, extension: str = '*') + + Returns a list of files in a directory. + + :param path: Input path. + :type path: piel_path_types + :param extension: File extension. + :type extension: str + + :returns: List of files. + :rtype: file_list(list) + + +.. py:function:: permit_script_execution(script_path: piel.config.piel_path_types) -> None + + Permits the execution of a script. + + :param script_path: Script path. + :type script_path: piel_path_types + + :returns: None + + +.. py:function:: permit_directory_all(directory_path: piel.config.piel_path_types) -> None + + Permits a directory to be read, written and executed. Use with care as it can be a source for security issues. + + :param directory_path: Input path. + :type directory_path: piel_path_types + + :returns: None + + +.. py:function:: read_json(path: piel.config.piel_path_types) -> dict + + Reads a JSON file. + + :param path: Input path. + :type path: piel_path_types + + :returns: JSON data. + :rtype: json_data(dict) + + +.. py:function:: return_path(input_path: piel.config.piel_path_types) -> pathlib.Path + + Returns a pathlib.Path to be able to perform operations accordingly internally. + + This allows us to maintain compatibility between POSIX and Windows systems. + + :param input_path: Input path. + :type input_path: str + + :returns: Pathlib path. + :rtype: pathlib.Path + + +.. py:function:: run_script(script_path: piel.config.piel_path_types) -> None + + Runs a script on the filesystem `script_path`. + + :param script_path: Script path. + :type script_path: piel_path_types + + :returns: None + + +.. py:function:: setup_example_design(project_source: Literal[piel, openlane] = 'piel', example_name: str = 'simple_design') -> None + + We copy the example simple_design from docs to the `/foss/designs` in the `iic-osic-tools` environment. + + :param project_source: Source of the project. + :type project_source: str + :param example_name: Name of the example design. + :type example_name: str + + :returns: None + + +.. py:function:: write_script(directory_path: piel.config.piel_path_types, script: str, script_name: str) -> None + + Records a `script_name` in the `scripts` project directory. + + :param directory_path: Design directory. + :type directory_path: piel_path_types + :param script: Script to write. + :type script: str + :param script_name: Name of the script. + :type script_name: str + + :returns: None diff --git a/docs/autoapi/piel/index.rst b/docs/autoapi/piel/index.rst new file mode 100644 index 00000000..89bac12e --- /dev/null +++ b/docs/autoapi/piel/index.rst @@ -0,0 +1,1395 @@ +:py:mod:`piel` +============== + +.. py:module:: piel + +.. autoapi-nested-parse:: + + Top-level package for piel. + + + +Subpackages +----------- +.. toctree:: + :titlesonly: + :maxdepth: 3 + + components/index.rst + integration/index.rst + models/index.rst + tools/index.rst + visual/index.rst + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + cli/index.rst + config/index.rst + defaults/index.rst + file_conversion/index.rst + file_system/index.rst + parametric/index.rst + project_structure/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.check_path_exists + piel.check_example_design + piel.copy_source_folder + piel.create_new_directory + piel.delete_path + piel.delete_path_list_in_directory + piel.get_files_recursively_in_directory + piel.permit_directory_all + piel.permit_script_execution + piel.setup_example_design + piel.read_json + piel.return_path + piel.run_script + piel.write_script + piel.create_gdsfactory_component_from_openlane + piel.gdsfactory_netlist_to_spice_netlist + piel.construct_hdl21_module + piel.convert_connections_to_tuples + piel.gdsfactory_netlist_with_hdl21_generators + piel.sax_to_s_parameters_standard_matrix + piel.unitary_permanent + piel.sax_circuit_permanent + piel.sax_to_ideal_qutip_unitary + piel.standard_s_parameters_to_ideal_qutip_unitary + piel.single_parameter_sweep + piel.multi_parameter_sweep + piel.check_cocotb_testbench_exists + piel.configure_cocotb_simulation + piel.run_cocotb_simulation + piel.get_simulation_output_files_from_design + piel.read_simulation_data + piel.simple_plot_simulation_data + piel.get_input_ports_index + piel.get_matched_ports_tuple_index + piel.get_design_from_openlane_migration + piel.find_design_run + piel.check_config_json_exists_openlane_v1 + piel.check_design_exists_openlane_v1 + piel.configure_and_run_design_openlane_v1 + piel.configure_parametric_designs_openlane_v1 + piel.configure_flow_script_openlane_v1 + piel.create_parametric_designs_openlane_v1 + piel.get_design_directory_from_root_openlane_v1 + piel.get_latest_version_root_openlane_v1 + piel.read_configuration_openlane_v1 + piel.write_configuration_openlane_v1 + piel.filter_timing_sta_files + piel.filter_power_sta_files + piel.get_all_timing_sta_files + piel.get_all_power_sta_files + piel.calculate_max_frame_amount + piel.calculate_propagation_delay_from_file + piel.calculate_propagation_delay_from_timing_data + piel.configure_timing_data_rows + piel.configure_frame_id + piel.filter_timing_data_by_net_name_and_type + piel.get_frame_meta_data + piel.get_frame_lines_data + piel.get_frame_timing_data + piel.get_all_timing_data_from_file + piel.read_sta_rpt_fwf_file + piel.contains_in_lines + piel.create_file_lines_dataframe + piel.get_file_line_by_keyword + piel.read_file_lines + piel.run_openlane_flow + piel.convert_numeric_to_prefix + piel.get_sdense_ports_index + piel.sax_to_s_parameters_standard_matrix + + + +Attributes +~~~~~~~~~~ + +.. autoapisummary:: + + piel.numerical_solver + piel.nso + piel.piel_path_types + piel.test_spm_open_lane_configuration + piel.example_open_lane_configuration + piel.delete_simulation_output_files + piel.get_simulation_output_files + piel.snet + piel.__author__ + piel.__email__ + piel.__version__ + + +.. py:data:: numerical_solver + + + +.. py:data:: nso + + + +.. py:data:: piel_path_types + + + +.. py:data:: test_spm_open_lane_configuration + + + +.. py:data:: example_open_lane_configuration + + + +.. py:function:: check_path_exists(path: piel.config.piel_path_types, raise_errors: bool = False) -> bool + + Checks if a directory exists. + + :param path: Input path. + :type path: piel_path_types + + :returns: True if directory exists. + :rtype: directory_exists(bool) + + +.. py:function:: check_example_design(design_name: str = 'simple_design', designs_directory: piel.config.piel_path_types | None = None) -> bool + + We copy the example simple_design from docs to the `/foss/designs` in the `iic-osic-tools` environment. + + :param design_name: Name of the design to check. + :type design_name: str + :param designs_directory: Directory that contains the DESIGNS environment flag. + :type designs_directory: piel_path_types + :param # TODO: + + :returns: None + + +.. py:function:: copy_source_folder(source_directory: piel.config.piel_path_types, target_directory: piel.config.piel_path_types) -> None + + Copies the files from a source_directory to a target_directory + + :param source_directory: Source directory. + :type source_directory: piel_path_types + :param target_directory: Target directory. + :type target_directory: piel_path_types + + :returns: None + + +.. py:function:: create_new_directory(directory_path: str | pathlib.Path) -> None + + Creates a new directory. + + If the parents of the target_directory do not exist, they will be created too. + + :param directory_path: Input path. + :type directory_path: str | pathlib.Path + + :returns: None + + +.. py:function:: delete_path(path: str | pathlib.Path) -> None + + Deletes a path. + + :param path: Input path. + :type path: str | pathlib.Path + + :returns: None + + +.. py:function:: delete_path_list_in_directory(directory_path: piel.config.piel_path_types, path_list: list, ignore_confirmation: bool = False, validate_individual: bool = False) -> None + + Deletes a list of files in a directory. + + :param directory_path: Input path. + :type directory_path: piel_path_types + :param path_list: List of files. + :type path_list: list + :param ignore_confirmation: Ignore confirmation. Default: False. + :type ignore_confirmation: bool + :param validate_individual: Validate individual files. Default: False. + :type validate_individual: bool + + :returns: None + + +.. py:function:: get_files_recursively_in_directory(path: piel.config.piel_path_types, extension: str = '*') + + Returns a list of files in a directory. + + :param path: Input path. + :type path: piel_path_types + :param extension: File extension. + :type extension: str + + :returns: List of files. + :rtype: file_list(list) + + +.. py:function:: permit_directory_all(directory_path: piel.config.piel_path_types) -> None + + Permits a directory to be read, written and executed. Use with care as it can be a source for security issues. + + :param directory_path: Input path. + :type directory_path: piel_path_types + + :returns: None + + +.. py:function:: permit_script_execution(script_path: piel.config.piel_path_types) -> None + + Permits the execution of a script. + + :param script_path: Script path. + :type script_path: piel_path_types + + :returns: None + + +.. py:function:: setup_example_design(project_source: Literal[piel, openlane] = 'piel', example_name: str = 'simple_design') -> None + + We copy the example simple_design from docs to the `/foss/designs` in the `iic-osic-tools` environment. + + :param project_source: Source of the project. + :type project_source: str + :param example_name: Name of the example design. + :type example_name: str + + :returns: None + + +.. py:function:: read_json(path: piel.config.piel_path_types) -> dict + + Reads a JSON file. + + :param path: Input path. + :type path: piel_path_types + + :returns: JSON data. + :rtype: json_data(dict) + + +.. py:function:: return_path(input_path: piel.config.piel_path_types) -> pathlib.Path + + Returns a pathlib.Path to be able to perform operations accordingly internally. + + This allows us to maintain compatibility between POSIX and Windows systems. + + :param input_path: Input path. + :type input_path: str + + :returns: Pathlib path. + :rtype: pathlib.Path + + +.. py:function:: run_script(script_path: piel.config.piel_path_types) -> None + + Runs a script on the filesystem `script_path`. + + :param script_path: Script path. + :type script_path: piel_path_types + + :returns: None + + +.. py:function:: write_script(directory_path: piel.config.piel_path_types, script: str, script_name: str) -> None + + Records a `script_name` in the `scripts` project directory. + + :param directory_path: Design directory. + :type directory_path: piel_path_types + :param script: Script to write. + :type script: str + :param script_name: Name of the script. + :type script_name: str + + :returns: None + + +.. py:function:: create_gdsfactory_component_from_openlane(design_name_v1: str | None = None, design_directory: piel.config.piel_path_types | None = None, run_name: str | None = None, v1: bool = True) -> gdsfactory.Component + + This function cretes a gdsfactory layout component that can be included in the network codesign of the device, or that can be used for interconnection codesign. + + It will look into the latest design run and extract the final OpenLane-generated GDS. You do not have to have run this with OpenLane2 as it just looks at the latest run. + + :param design_name_v1: Design name of the v1 design that can be found within `$OPENLANE_ROOT/""/designs`. + :type design_name_v1: str + :param design_directory: Design directory PATH. + :type design_directory: piel_path_types + :param run_name: Name of the run to extract the GDS from. If None, it will look at the latest run. + :type run_name: str + :param v1: If True, it will import the design from the OpenLane v1 configuration. + :type v1: bool + + :returns: GDSFactory component. + :rtype: component(gf.Component) + + +.. py:function:: gdsfactory_netlist_to_spice_netlist(gdsfactory_netlist: dict, generators: dict, **kwargs) -> hdl21.Module + + This function converts a GDSFactory electrical netlist into a standard SPICE netlist. It follows the same + principle as the `sax` circuit composition. + + Each GDSFactory netlist has a set of instances, each with a corresponding model, and each instance with a given + set of geometrical settings that can be applied to each particular model. We know the type of SPICE model from + the instance model we provides. + + We know that the gdsfactory has a set of instances, and we can map unique models via sax through our own + composition circuit. Write the SPICE component based on the model into a total circuit representation in string + from the reshaped gdsfactory dictionary into our own structure. + + :param gdsfactory_netlist: GDSFactory netlist + :param generators: Dictionary of Generators + + :returns: hdl21 module or raw SPICE string + + +.. py:function:: construct_hdl21_module(spice_netlist: dict, **kwargs) -> hdl21.Module + + This function converts a gdsfactory-spice converted netlist using the component models into a SPICE circuit. + + Part of the complexity of this function is the multiport nature of some components and models, and assigning the + parameters accordingly into the SPICE function. This is because not every SPICE component will be bi-port, + and many will have multi-ports and parameters accordingly. Each model can implement the composition into a + SPICE circuit, but they depend on a set of parameters that must be set from the instance. Another aspect is + that we may want to assign the component ID according to the type of component. However, we can also assign the + ID based on the individual instance in the circuit, which is also a reasonable approximation. However, + it could be said, that the ideal implementation would be for each component model provided to return the SPICE + instance including connectivity except for the ID. + + # TODO implement validators + + +.. py:function:: convert_connections_to_tuples(connections: dict) + + Convert from: + + .. code-block:: + + { + 'straight_1,e1': 'taper_1,e2', + 'straight_1,e2': 'taper_2,e2', + 'taper_1,e1': 'via_stack_1,e3', + 'taper_2,e1': 'via_stack_2,e1' + } + + to: + + .. code-block:: + + [(('straight_1', 'e1'), ('taper_1', 'e2')), (('straight_1', 'e2'), ('taper_2', 'e2')), (('taper_1', 'e1'), + ('via_stack_1', 'e3')), (('taper_2', 'e1'), ('via_stack_2', 'e1'))] + + +.. py:function:: gdsfactory_netlist_with_hdl21_generators(gdsfactory_netlist: dict, generators=None) + + This function allows us to map the ``hdl21`` models dictionary in a `sax`-like implementation to the ``GDSFactory`` netlist. This allows us to iterate over each instance in the netlist and construct a circuit after this function.] + + Example usage: + + .. code-block:: + + >>> import gdsfactory as gf + >>> from piel.integration.gdsfactory_hdl21.conversion import gdsfactory_netlist_with_hdl21_generators + >>> from piel.models.physical.electronic import get_default_models + >>> gdsfactory_netlist_with_hdl21_generators(gdsfactory_netlist=gf.components.mzi2x2_2x2_phase_shifter().get_netlist(exclude_port_types="optical"),generators=get_default_models()) + + :param gdsfactory_netlist: The netlist from ``GDSFactory`` to map to the ``hdl21`` models dictionary. + :param generators: The ``hdl21`` models dictionary to map to the ``GDSFactory`` netlist. + + :returns: The ``GDSFactory`` netlist with the ``hdl21`` models dictionary. + + +.. py:function:: sax_to_s_parameters_standard_matrix(sax_input: sax.SType, input_ports_order: tuple | None = None) -> tuple + + A ``sax`` S-parameter SDict is provided as a dictionary of tuples with (port0, port1) as the key. This + determines the direction of the scattering relationship. It means that the number of terms in an S-parameter + matrix is the number of ports squared. + + In order to generalise, this function returns both the S-parameter matrices and the indexing ports based on the + amount provided. In terms of computational speed, we definitely would like this function to be algorithmically + very fast. For now, I will write a simple python implementation and optimise in the future. + + It is possible to see the `sax` SDense notation equivalence here: + https://flaport.github.io/sax/nbs/08_backends.html + + .. code-block:: python + + import jax.numpy as jnp + from sax.core import SDense + + # Directional coupler SDense representation + dc_sdense: SDense = ( + jnp.array([[0, 0, τ, κ], [0, 0, κ, τ], [τ, κ, 0, 0], [κ, τ, 0, 0]]), + {"in0": 0, "in1": 1, "out0": 2, "out1": 3}, + ) + + + # Directional coupler SDict representation + # Taken from https://flaport.github.io/sax/nbs/05_models.html + def coupler(*, coupling: float = 0.5) -> SDict: + kappa = coupling**0.5 + tau = (1 - coupling) ** 0.5 + sdict = reciprocal( + { + ("in0", "out0"): tau, + ("in0", "out1"): 1j * kappa, + ("in1", "out0"): 1j * kappa, + ("in1", "out1"): tau, + } + ) + return sdict + + If we were to relate the mapping accordingly based on the ports indexes, a S-Parameter matrix in the form of + :math:`S_{(output,i),(input,i)}` would be: + + .. math:: + + S = \begin{bmatrix} + S_{00} & S_{10} \\ + S_{01} & S_{11} \\ + \end{bmatrix} = + \begin{bmatrix} + \tau & j \kappa \\ + j \kappa & \tau \\ + \end{bmatrix} + + Note that the standard S-parameter and hence unitary representation is in the form of: + + .. math:: + + S = \begin{bmatrix} + S_{00} & S_{01} \\ + S_{10} & S_{11} \\ + \end{bmatrix} + + + .. math:: + + \begin{bmatrix} + b_{1} \\ + \vdots \\ + b_{n} + \end{bmatrix} + = + \begin{bmatrix} + S_{11} & \dots & S_{1n} \\ + \vdots & \ddots & \vdots \\ + S_{n1} & \dots & S_{nn} + \end{bmatrix} + \begin{bmatrix} + a_{1} \\ + \vdots \\ + a_{n} + \end{bmatrix} + + TODO check with Floris, does this mean we need to transpose the matrix? + + :param sax_input: The sax S-parameter dictionary. + :type sax_input: sax.SType + :param input_ports_order: The ports order tuple containing the names and order of the input ports. + :type input_ports_order: tuple + + :returns: The S-parameter matrix and the input ports index tuple in the standard S-parameter notation. + :rtype: tuple + + +.. py:function:: unitary_permanent(unitary_matrix: numpy.ndarray) -> tuple + + The permanent of a unitary is used to determine the state probability of combinatorial Gaussian boson samping systems. + + ``thewalrus`` Ryser's algorithm permananet implementation is described here: https://the-walrus.readthedocs.io/en/latest/gallery/permanent_tutorial.html + + # TODO maybe implement subroutine if computation is taking forever. + # TODO why two outputs? Understand this properly later. + + :param unitary_permanent: The unitary matrix. + :type unitary_permanent: np.ndarray + + :returns: The circuit permanent and the time it took to compute it. + :rtype: tuple + + +.. py:function:: sax_circuit_permanent(sax_input: sax.SType) -> tuple + + The permanent of a unitary is used to determine the state probability of combinatorial Gaussian boson samping systems. + + ``thewalrus`` Ryser's algorithm permananet implementation is described here: https://the-walrus.readthedocs.io/en/latest/gallery/permanent_tutorial.html + + # TODO maybe implement subroutine if computation is taking forever. + + :param sax_input: The sax S-parameter dictionary. + :type sax_input: sax.SType + + :returns: The circuit permanent and the time it took to compute it. + :rtype: tuple + + +.. py:function:: sax_to_ideal_qutip_unitary(sax_input: sax.SType) + + This function converts the calculated S-parameters into a standard Unitary matrix topology so that the shape and + dimensions of the matrix can be observed. + + I think this means we need to transpose the output of the filtered sax SDense matrix to map it to a QuTip matrix. + Note that the documentation and formatting of the standard `sax` mapping to a S-parameter standard notation is + already in described in piel/piel/sax/utils.py. + + From this stage we can implement a ``QObj`` matrix accordingly and perform simulations accordingly. + https://qutip.org/docs/latest/guide/qip/qip-basics.html#unitaries + + For example, a ``qutip`` representation of an s-gate gate would be: + + ..code-block:: + + import numpy as np + import qutip + # S-Gate + s_gate_matrix = np.array([[1., 0], [0., 1.j]]) + s_gate = qutip.Qobj(mat, dims=[[2], [2]]) + + In mathematical notation, this S-gate would be written as: + + ..math:: + + S = \begin{bmatrix} + 1 & 0 \\ + 0 & i \\ + \end{bmatrix} + + :param sax_input: A dictionary of S-parameters in the form of a SDict from `sax`. + :type sax_input: sax.SType + + :returns: A QuTip QObj representation of the S-parameters in a unitary matrix. + :rtype: qobj_unitary (qutip.Qobj) + + +.. py:function:: standard_s_parameters_to_ideal_qutip_unitary(s_parameters_standard_matrix: piel.config.nso.ndarray) + + This function converts the calculated S-parameters into a standard Unitary matrix topology so that the shape and + dimensions of the matrix can be observed. + + I think this means we need to transpose the output of the filtered sax SDense matrix to map it to a QuTip matrix. + Note that the documentation and formatting of the standard `sax` mapping to a S-parameter standard notation is + already in described in piel/piel/sax/utils.py. + + From this stage we can implement a ``QObj`` matrix accordingly and perform simulations accordingly. https://qutip.org/docs/latest/guide/qip/qip-basics.html#unitaries + + For example, a ``qutip`` representation of an s-gate gate would be: + + ..code-block:: + + import numpy as np + import qutip + # S-Gate + s_gate_matrix = np.array([[1., 0], [0., 1.j]]) + s_gate = qutip.Qobj(mat, dims=[[2], [2]]) + + In mathematical notation, this S-gate would be written as: + + ..math:: + + S = \begin{bmatrix} + 1 & 0 \\ + 0 & i \\ + \end{bmatrix} + + :param s_parameters_standard_matrix: A dictionary of S-parameters in the form of a SDict from `sax`. + :type s_parameters_standard_matrix: nso.ndarray + + :returns: A QuTip QObj representation of the S-parameters in a unitary matrix. + :rtype: qobj_unitary (qutip.Qobj) + + +.. py:function:: single_parameter_sweep(base_design_configuration: dict, parameter_name: str, parameter_sweep_values: list) + + This function takes a base_design_configuration dictionary and sweeps a single parameter over a list of values. It returns a list of dictionaries that correspond to the parameter sweep. + + :param base_design_configuration: Base design configuration dictionary. + :type base_design_configuration: dict + :param parameter_name: Name of parameter to sweep. + :type parameter_name: str + :param parameter_sweep_values: List of values to sweep. + :type parameter_sweep_values: list + + :returns: List of dictionaries that correspond to the parameter sweep. + :rtype: parameter_sweep_design_dictionary_array(list) + + +.. py:function:: multi_parameter_sweep(base_design_configuration: dict, parameter_sweep_dictionary: dict) -> list + + This multiparameter sweep is pretty cool, as it will generate designer list of dictionaries that comprise of all the possible combinations of your parameter sweeps. For example, if you are sweeping `parameter_1 = np.arange(0, 2) = array([0, 1])`, and `parameter_2 = np.arange(2, 4) = array([2, 3])`, then this function will generate list of dictionaries based on the default_design dictionary, but that will comprise of all the potential parameter combinations within this list. + + For the example above, there arould be 4 combinations [(0, 2), (0, 3), (1, 2), (1, 3)]. + + If you were instead sweeping for `parameter_1 = np.arange(0, 5)` and `parameter_2 = np.arange(0, 5)`, the dictionary generated would correspond to these parameter combinations of:: + [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)]. + + Make sure to use the parameter_names from default_design when writing up the parameter_sweep dictionary key name. + + Example project_structure formats:: + + example_parameter_sweep_dictionary = { + "parameter_1": np.arange(1, -40, 1), + "parameter_2": np.arange(1, -40, 1), + } + + example_base_design_configuration = { + "parameter_1": 10.0, + "parameter_2": 40.0, + "parameter_3": 0, + } + + :param base_design_configuration: Dictionary of the default design configuration. + :type base_design_configuration: dict + :param parameter_sweep_dictionary: Dictionary of the parameter sweep. The keys should be the same as the keys in the base_design_configuration dictionary. + :type parameter_sweep_dictionary: dict + + :returns: List of dictionaries that comprise of all the possible combinations of your parameter sweeps. + :rtype: parameter_sweep_design_dictionary_array(list) + + +.. py:function:: check_cocotb_testbench_exists(design_directory: str | pathlib.Path) -> bool + + Checks if a cocotb testbench exists in the design directory. + + :param design_directory: Design directory. + :type design_directory: str | pathlib.Path + + :returns: True if cocotb testbench exists. + :rtype: cocotb_testbench_exists(bool) + + +.. py:function:: configure_cocotb_simulation(design_directory: str | pathlib.Path, simulator: Literal[icarus, verilator], top_level_language: Literal[verilog, vhdl], top_level_verilog_module: str, test_python_module: str, design_sources_list: list | None = None) + + Writes a cocotb makefile. + + If no design_sources_list is provided then it adds all the design sources under the `src` folder. + + In the form + .. code-block:: + + #!/bin/sh + # Makefile + # defaults + SIM ?= icarus + TOPLEVEL_LANG ?= verilog + + # Note we need to include the test script to the PYTHONPATH + export PYTHONPATH = + + VERILOG_SOURCES += $(PWD)/my_design.sv + # use VHDL_SOURCES for VHDL files + + # TOPLEVEL is the name of the toplevel module in your Verilog or VHDL file + TOPLEVEL := my_design + + # MODULE is the basename of the Python test file + MODULE := test_my_design + + # include cocotb's make rules to take care of the simulator setup + include $(shell cocotb-config --makefiles)/Makefile.sim + + + :param design_directory: The directory where the design is located. + :type design_directory: str | pathlib.Path + :param simulator: The simulator to use. + :type simulator: Literal["icarus", "verilator"] + :param top_level_language: The top level language. + :type top_level_language: Literal["verilog", "vhdl"] + :param top_level_verilog_module: The top level verilog module. + :type top_level_verilog_module: str + :param test_python_module: The test python module. + :type test_python_module: str + :param design_sources_list: A list of design sources. Defaults to None. + :type design_sources_list: list | None, optional + + :returns: None + + +.. py:data:: delete_simulation_output_files + + + +.. py:function:: run_cocotb_simulation(design_directory: str) -> subprocess.CompletedProcess + + Equivalent to running the cocotb makefile + .. code-block:: + + make + + :param design_directory: The directory where the design is located. + :type design_directory: str + + :returns: The subprocess.CompletedProcess object. + :rtype: subprocess.CompletedProcess + + +.. py:data:: get_simulation_output_files + + + +.. py:function:: get_simulation_output_files_from_design(design_directory: piel.config.piel_path_types, extension: str = 'csv') + + This function returns a list of all the simulation output files in the design directory. + + :param design_directory: The path to the design directory. + :type design_directory: piel_path_types + + :returns: List of all the simulation output files in the design directory. + :rtype: output_files (list) + + +.. py:function:: read_simulation_data(file_path: piel.config.piel_path_types) + + This function returns a Pandas dataframe that contains all the simulation data outputted from the simulation run. + + :param file_path: The path to the simulation data file. + :type file_path: piel_path_types + + :returns: The simulation data in a Pandas dataframe. + :rtype: simulation_data (pd.DataFrame) + + +.. py:function:: simple_plot_simulation_data(simulation_data: pandas.DataFrame) + + +.. py:function:: get_input_ports_index(ports_index: dict, sorting_algorithm: Literal[get_input_ports_index.prefix] = 'prefix', prefix: str = 'in') -> tuple + + This function returns the input ports of a component. However, input ports may have different sets of prefixes and suffixes. This function implements different sorting algorithms for different ports names. The default algorithm is `prefix`, which sorts the ports by their prefix. The Endianness implementation means that the tuple order is determined according to the last numerical index order of the port numbering. + + .. code-block:: python + + raw_ports_index = { + "in_o_0": 0, + "out_o_0": 1, + "out_o_1": 2, + "out_o_2": 3, + "out_o_3": 4, + "in_o_1": 5, + "in_o_2": 6, + "in_o_3": 7, + } + + get_input_ports_index(ports_index=raw_ports_index) + + # Output + ((0, "in_o_0"), (5, "in_o_1"), (6, "in_o_2"), (7, "in_o_3")) + + :param ports_index: The ports index dictionary. + :type ports_index: dict + :param sorting_algorithm: The sorting algorithm to use. Defaults to "prefix". + :type sorting_algorithm: Literal["prefix"], optional + :param prefix: The prefix to use for the sorting algorithm. Defaults to "in". + :type prefix: str, optional + + :returns: The ordered input ports index tuple. + :rtype: tuple + + +.. py:function:: get_matched_ports_tuple_index(ports_index: dict, selected_ports_tuple: Optional[tuple] = None, sorting_algorithm: Literal[get_matched_ports_tuple_index.prefix, selected_ports] = 'prefix', prefix: str = 'in') -> (tuple, tuple) + + This function returns the input ports of a component. However, input ports may have different sets of prefixes + and suffixes. This function implements different sorting algorithms for different ports names. The default + algorithm is `prefix`, which sorts the ports by their prefix. The Endianness implementation means that the tuple + order is determined according to the last numerical index order of the port numbering. Returns just a tuple of + the index. + + .. code-block:: python + + raw_ports_index = { + "in_o_0": 0, + "out_o_0": 1, + "out_o_1": 2, + "out_o_2": 3, + "out_o_3": 4, + "in_o_1": 5, + "in_o_2": 6, + "in_o_3": 7, + } + + get_input_ports_tuple_index(ports_index=raw_ports_index) + + # Output + (0, 5, 6, 7) + + :param ports_index: The ports index dictionary. + :type ports_index: dict + :param selected_ports_tuple: The selected ports tuple. Defaults to None. + :type selected_ports_tuple: tuple, optional + :param sorting_algorithm: The sorting algorithm to use. Defaults to "prefix". + :type sorting_algorithm: Literal["prefix"], optional + :param prefix: The prefix to use for the sorting algorithm. Defaults to "in". + :type prefix: str, optional + + :returns: The ordered input ports index tuple. + matched_ports_name_tuple_order(tuple): The ordered input ports name tuple. + :rtype: matches_ports_index_tuple_order(tuple) + + +.. py:function:: get_design_from_openlane_migration(v1: bool = True, design_name_v1: str | None = None, design_directory: str | pathlib.Path | None = None, root_directory_v1: str | pathlib.Path | None = None) -> (str, pathlib.Path) + + This function provides the integration mechanism for easily migrating the interconnection with other toolsets from an OpenLane v1 design to an OpenLane v2 design. + + This function checks if the inputs are to be treated as v1 inputs. If so, and a `design_name` is provided then it will set the `design_directory` to the corresponding `design_name` directory in the corresponding `root_directory_v1 / designs`. If no `root_directory` is provided then it returns `$OPENLANE_ROOT/""/. If a `design_directory` is provided then this will always take precedence even with a `v1` flag. + + :param v1: If True, it will migrate from v1 to v2. + :type v1: bool + :param design_name_v1: Design name of the v1 design that can be found within `$OPENLANE_ROOT/""/designs`. + :type design_name_v1: str + :param design_directory: Design directory PATH. Optional path for v2-based designs. + :type design_directory: str + :param root_directory_v1: Root directory of OpenLane v1. If set to None it will return `$OPENLANE_ROOT/""` + :type root_directory_v1: str + + :returns: None + + +.. py:function:: find_design_run(design_directory: piel.config.piel_path_types, run_name: str | None = None) -> pathlib.Path + + For a given `design_directory`, the `openlane` output can be found in the `runs` subdirectory. + + They get sorted based on a reverse `list.sort()` method. + + # TODO docs + + +.. py:function:: check_config_json_exists_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> bool + + Checks if a design has a `config.json` file. + + :param design_name: Name of the design. + :type design_name: str + + :returns: True if `config.json` exists. + :rtype: config_json_exists(bool) + + +.. py:function:: check_design_exists_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> bool + + Checks if a design exists in the OpenLane v1 design folder. + + Lists all designs inside the Openlane V1 design root. + + :param design_name: Name of the design. + :type design_name: str + + :returns: True if design exists. + :rtype: design_exists(bool) + + +.. py:function:: configure_and_run_design_openlane_v1(design_name: str, configuration: dict | None = None, root_directory: str | pathlib.Path | None = None) -> None + + Configures and runs an OpenLane v1 design. + + This function does the following: + 1. Check that the design_directory provided is under $OPENLANE_ROOT//designs + 2. Check if `config.json` has already been provided for this design. If a configuration dictionary is inputted into the function parameters, then it overwrites the default `config.json`. + 3. Create a script directory, a script is written and permissions are provided for it to be executable. + 4. Permit and execute the `openlane_flow.sh` script in the `scripts` directory. + + :param design_name: Name of the design. + :type design_name: str + :param configuration: Configuration dictionary. + :type configuration: dict | None + :param root_directory: Design directory. + :type root_directory: str | pathlib.Path + + :returns: None + + +.. py:function:: configure_parametric_designs_openlane_v1(design_name: str, parameter_sweep_dictionary: dict, add_id: bool = True) -> list + + For a given `source_design_directory`, this function reads in the config.json file and returns a set of parametric sweeps that gets used when creating a set of parametric designs. + + :param add_id: Add an ID to the design name. Defaults to True. + :type add_id: bool + :param parameter_sweep_dictionary: Dictionary of parameters to sweep. + :type parameter_sweep_dictionary: dict + :param source_design_directory: Source design directory. + :type source_design_directory: str | pathlib.Path + + :returns: List of configurations to sweep. + :rtype: configuration_sweep(list) + + +.. py:function:: configure_flow_script_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> None + + Configures the OpenLane v1 flow script after checking that the design directory exists. + + :param design_directory: Design directory. Defaults to latest OpenLane root. + :type design_directory: str | pathlib.Path | None + + :returns: None + + +.. py:function:: create_parametric_designs_openlane_v1(design_name: str, parameter_sweep_dictionary: dict, target_directory: str | pathlib.Path | None = None) -> None + + Takes a OpenLane v1 source directory and creates a parametric combination of these designs. + + :param design_name: Name of the design. + :type design_name: str + :param parameter_sweep_dictionary: Dictionary of parameters to sweep. + :type parameter_sweep_dictionary: dict + :param target_directory: Optional target directory. + :type target_directory: str | pathlib.Path | None + + :returns: None + + +.. py:function:: get_design_directory_from_root_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> pathlib.Path + + Gets the design directory from the root directory. + + :param design_name: Name of the design. + :type design_name: str + :param root_directory: Design directory. + :type root_directory: str | pathlib.Path + + :returns: Design directory. + :rtype: design_directory(pathlib.Path) + + +.. py:function:: get_latest_version_root_openlane_v1() -> pathlib.Path + + Gets the latest version root of OpenLane v1. + + +.. py:function:: read_configuration_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> dict + + Reads a `config.json` from a design directory. + + :param design_name: Design name. + :type design_name: str + :param root_directory: Design directory. + :type root_directory: str | pathlib.Path + + :returns: Configuration dictionary. + :rtype: configuration(dict) + + +.. py:function:: write_configuration_openlane_v1(configuration: dict, design_directory: str | pathlib.Path) -> None + + Writes a `config.json` onto a `design_directory` + + :param configuration: OpenLane configuration dictionary. + :type configuration: dict + :param design_directory: Design directory PATH. + :type design_directory: str + + :returns: None + + +.. py:function:: filter_timing_sta_files(file_list) + + Filter the timing sta files from the list of files + + :param file_list: List containing the file paths + :type file_list: list + + :returns: List containing the timing sta files + :rtype: timing_sta_files (list) + + +.. py:function:: filter_power_sta_files(file_list) + + Filter the power sta files from the list of files + + :param file_list: List containing the file paths + :type file_list: list + + :returns: List containing the power sta files + :rtype: power_sta_files (list) + + +.. py:function:: get_all_timing_sta_files(run_directory) + + This function aims to list and perform analysis on all the relevant files in a particular run between all the corners. + + :param run_directory: The run directory to perform the analysis on. Defaults to None. + :type run_directory: str, optional + + :returns: List of all the .rpt files in the run directory. + :rtype: timing_sta_files_list (list) + + +.. py:function:: get_all_power_sta_files(run_directory) + + This function aims to list and perform analysis on all the relevant files in a particular run between all the corners. + + :param run_directory: The run directory to perform the analysis on. Defaults to None. + :type run_directory: str, optional + + :returns: List of all the .rpt files in the run directory. + :rtype: power_sta_files_list (list) + + +.. py:function:: calculate_max_frame_amount(file_lines_data: pandas.DataFrame) + + Calculate the maximum frame amount based on the frame IDs in the DataFrame + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Maximum number of frames in the file + :rtype: maximum_frame_amount (int) + + +.. py:function:: calculate_propagation_delay_from_file(file_path: str | pathlib.Path) + + Calculate the propagation delay for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: Dictionary containing the propagation delay + :rtype: propagation_delay (dict) + + +.. py:function:: calculate_propagation_delay_from_timing_data(net_name_in: str, net_name_out: str, timing_data: pandas.DataFrame) + + Calculate the propagation delay between two nets + + :param net_name_in: Name of the input net + :type net_name_in: str + :param net_name_out: Name of the output net + :type net_name_out: str + :param timing_data: Dataframe containing the timing data + :type timing_data: pd.DataFrame + + :returns: Dataframe containing the propagation delay + :rtype: propagation_delay_dataframe (pd.DataFrame) + + +.. py:function:: configure_timing_data_rows(file_lines_data: pandas.DataFrame) + + Identify the timing data lines for each frame and creates a metadata dictionary for frames. + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Dictionary containing the frame metadata + :rtype: frame_meta_data (dict) + + +.. py:function:: configure_frame_id(file_lines_data: pandas.DataFrame) + + Identify the frame delimiters and assign frame ID to each line in the file + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: filter_timing_data_by_net_name_and_type(timing_data: pandas.DataFrame, net_name: str, net_type: str) + + Filter the timing data by net name and type + + :param timing_data: DataFrame containing the timing data + :type timing_data: pd.DataFrame + :param net_name: Net name to be filtered + :type net_name: str + :param net_type: Net type to be filtered + :type net_type: str + + :returns: DataFrame containing the timing data + :rtype: timing_data (pd.DataFrame) + + +.. py:function:: get_frame_meta_data(file_lines_data) + + Get the frame metadata + + :param file_lines_data: DataFrame containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: DataFrame containing the start point name + end_point_name (pd.DataFrame): DataFrame containing the end point name + path_group_name (pd.DataFrame): DataFrame containing the path group name + path_type_name (pd.DataFrame): DataFrame containing the path type name + :rtype: start_point_name (pd.DataFrame) + + +.. py:function:: get_frame_lines_data(file_path: str | pathlib.Path) + + Calculate the timing data for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: DataFrame containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: get_frame_timing_data(file: str | pathlib.Path, frame_meta_data: dict, frame_id: int = 0) + + Extract the timing data from the file + + :param file: Address of the file + :type file: str | pathlib.Path + :param frame_meta_data: Dictionary containing the frame metadata + :type frame_meta_data: dict + :param frame_id: Frame ID to be read + :type frame_id: int + + :returns: DataFrame containing the timing data + :rtype: timing_data (pd.DataFrame) + + +.. py:function:: get_all_timing_data_from_file(file_path: str | pathlib.Path) + + Calculate the timing data for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: Dictionary containing the timing data for each frame + :rtype: frame_timing_data (dict) + + +.. py:function:: read_sta_rpt_fwf_file(file: str | pathlib.Path, frame_meta_data: dict, frame_id: int = 0) + + Read the fixed width file and return a DataFrame + + :param file: Address of the file + :type file: str | pathlib.Path + :param frame_meta_data: Dictionary containing the frame metadata + :type frame_meta_data: dict + :param frame_id: Frame ID to be read + :type frame_id: int + + :returns: DataFrame containing the file data + :rtype: file_data (pd.DataFrame) + + +.. py:function:: contains_in_lines(file_lines_data: pandas.DataFrame, keyword: str) + + Check if the keyword is contained in the file lines + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + :param keyword: Keyword to search for + :type keyword: str + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: create_file_lines_dataframe(file_lines_raw) + + Create a DataFrame from the raw lines of a file + + :param file_lines_raw: list containing the file lines + :type file_lines_raw: list + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: get_file_line_by_keyword(file_lines_data: pandas.DataFrame, keyword: str, regex: str) + + Extract the data from the file lines using the given keyword and regex + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + :param keyword: Keyword to search for + :type keyword: str + :param regex: Regex to extract the data + :type regex: str + + :returns: Dataframe containing the extracted values + :rtype: extracted_values (pd.DataFrame) + + +.. py:function:: read_file_lines(file_path: str | pathlib.Path) + + Extract lines from the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: list containing the file lines + :rtype: file_lines_raw (list) + + +.. py:function:: run_openlane_flow(configuration: dict | None = test_spm_open_lane_configuration, design_directory: piel.config.piel_path_types = '/foss/designs/spm') -> None + + Runs the OpenLane flow. + + :param configuration: OpenLane configuration dictionary. If none is present it will default to the config.json file on the design_directory. + :type configuration: dict + :param design_directory: Design directory PATH. + :type design_directory: piel_path_types + + :returns: None + + +.. py:function:: convert_numeric_to_prefix(value: float) + + This function converts a numeric value to a number under a SPICE unit closest to the base prefix. This allows us to connect a particular number real output, into a term that can be used in a SPICE netlist. + + +.. py:function:: get_sdense_ports_index(input_ports_order: tuple, all_ports_index: dict) -> dict + + This function returns the ports index of the sax dense S-parameter matrix. + + Given that the order of the iteration is provided by the user, the dictionary keys will also be ordered + accordingly when iterating over them. This requires the user to provide a set of ordered. + + TODO verify reasonable iteration order. + + .. code-block:: python + + # The input_ports_order can be a tuple of tuples that contain the index and port name. Eg. + input_ports_order = ((0, "in_o_0"), (5, "in_o_1"), (6, "in_o_2"), (7, "in_o_3")) + # The all_ports_index is a dictionary of the ports index. Eg. + all_ports_index = { + "in_o_0": 0, + "out_o_0": 1, + "out_o_1": 2, + "out_o_2": 3, + "out_o_3": 4, + "in_o_1": 5, + "in_o_2": 6, + "in_o_3": 7, + } + # Output + {"in_o_0": 0, "in_o_1": 5, "in_o_2": 6, "in_o_3": 7} + + :param input_ports_order: The ports order tuple. Can be a tuple of tuples that contain the index and port name. + :type input_ports_order: tuple + :param all_ports_index: The ports index dictionary. + :type all_ports_index: dict + + :returns: The ordered input ports index tuple. + :rtype: tuple + + +.. py:function:: sax_to_s_parameters_standard_matrix(sax_input: sax.SType, input_ports_order: tuple | None = None) -> tuple + + A ``sax`` S-parameter SDict is provided as a dictionary of tuples with (port0, port1) as the key. This + determines the direction of the scattering relationship. It means that the number of terms in an S-parameter + matrix is the number of ports squared. + + In order to generalise, this function returns both the S-parameter matrices and the indexing ports based on the + amount provided. In terms of computational speed, we definitely would like this function to be algorithmically + very fast. For now, I will write a simple python implementation and optimise in the future. + + It is possible to see the `sax` SDense notation equivalence here: + https://flaport.github.io/sax/nbs/08_backends.html + + .. code-block:: python + + import jax.numpy as jnp + from sax.core import SDense + + # Directional coupler SDense representation + dc_sdense: SDense = ( + jnp.array([[0, 0, τ, κ], [0, 0, κ, τ], [τ, κ, 0, 0], [κ, τ, 0, 0]]), + {"in0": 0, "in1": 1, "out0": 2, "out1": 3}, + ) + + + # Directional coupler SDict representation + # Taken from https://flaport.github.io/sax/nbs/05_models.html + def coupler(*, coupling: float = 0.5) -> SDict: + kappa = coupling**0.5 + tau = (1 - coupling) ** 0.5 + sdict = reciprocal( + { + ("in0", "out0"): tau, + ("in0", "out1"): 1j * kappa, + ("in1", "out0"): 1j * kappa, + ("in1", "out1"): tau, + } + ) + return sdict + + If we were to relate the mapping accordingly based on the ports indexes, a S-Parameter matrix in the form of + :math:`S_{(output,i),(input,i)}` would be: + + .. math:: + + S = \begin{bmatrix} + S_{00} & S_{10} \\ + S_{01} & S_{11} \\ + \end{bmatrix} = + \begin{bmatrix} + \tau & j \kappa \\ + j \kappa & \tau \\ + \end{bmatrix} + + Note that the standard S-parameter and hence unitary representation is in the form of: + + .. math:: + + S = \begin{bmatrix} + S_{00} & S_{01} \\ + S_{10} & S_{11} \\ + \end{bmatrix} + + + .. math:: + + \begin{bmatrix} + b_{1} \\ + \vdots \\ + b_{n} + \end{bmatrix} + = + \begin{bmatrix} + S_{11} & \dots & S_{1n} \\ + \vdots & \ddots & \vdots \\ + S_{n1} & \dots & S_{nn} + \end{bmatrix} + \begin{bmatrix} + a_{1} \\ + \vdots \\ + a_{n} + \end{bmatrix} + + TODO check with Floris, does this mean we need to transpose the matrix? + + :param sax_input: The sax S-parameter dictionary. + :type sax_input: sax.SType + :param input_ports_order: The ports order tuple containing the names and order of the input ports. + :type input_ports_order: tuple + + :returns: The S-parameter matrix and the input ports index tuple in the standard S-parameter notation. + :rtype: tuple + + +.. py:data:: snet + + + +.. py:data:: __author__ + :value: 'Dario Quintero' + + + +.. py:data:: __email__ + :value: 'darioaquintero@gmail.com' + + + +.. py:data:: __version__ + :value: '0.0.43' diff --git a/docs/autoapi/piel/integration/cocotb_sax/index.rst b/docs/autoapi/piel/integration/cocotb_sax/index.rst new file mode 100644 index 00000000..69dd9225 --- /dev/null +++ b/docs/autoapi/piel/integration/cocotb_sax/index.rst @@ -0,0 +1,9 @@ +:py:mod:`piel.integration.cocotb_sax` +===================================== + +.. py:module:: piel.integration.cocotb_sax + +.. autoapi-nested-parse:: + + The goal of implementing this integration is to enable co-simulation of photonic state evolution based on the + electronic test function or logical state implemented. diff --git a/docs/autoapi/piel/integration/gdsfactory_hdl21/conversion/index.rst b/docs/autoapi/piel/integration/gdsfactory_hdl21/conversion/index.rst new file mode 100644 index 00000000..fec83a0b --- /dev/null +++ b/docs/autoapi/piel/integration/gdsfactory_hdl21/conversion/index.rst @@ -0,0 +1,68 @@ +:py:mod:`piel.integration.gdsfactory_hdl21.conversion` +====================================================== + +.. py:module:: piel.integration.gdsfactory_hdl21.conversion + +.. autoapi-nested-parse:: + + `sax` has very good GDSFactory integration functions, so there is a question on whether implementing our own circuit + construction, and SPICE netlist parser from it, accordingly. We need in some form to connect electrical models to our + parsed netlist, in order to apply SPICE passive values, and create connectivity for each particular device. Ideally, + this would be done from the component instance as that way the component model can be integrated with its geometrical + parameters, but does not have to be done necessarily. This comes down to implementing a backend function to compile + SAX compiled circuit. + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.integration.gdsfactory_hdl21.conversion.convert_connections_to_tuples + piel.integration.gdsfactory_hdl21.conversion.gdsfactory_netlist_with_hdl21_generators + + + +.. py:function:: convert_connections_to_tuples(connections: dict) + + Convert from: + + .. code-block:: + + { + 'straight_1,e1': 'taper_1,e2', + 'straight_1,e2': 'taper_2,e2', + 'taper_1,e1': 'via_stack_1,e3', + 'taper_2,e1': 'via_stack_2,e1' + } + + to: + + .. code-block:: + + [(('straight_1', 'e1'), ('taper_1', 'e2')), (('straight_1', 'e2'), ('taper_2', 'e2')), (('taper_1', 'e1'), + ('via_stack_1', 'e3')), (('taper_2', 'e1'), ('via_stack_2', 'e1'))] + + +.. py:function:: gdsfactory_netlist_with_hdl21_generators(gdsfactory_netlist: dict, generators=None) + + This function allows us to map the ``hdl21`` models dictionary in a `sax`-like implementation to the ``GDSFactory`` netlist. This allows us to iterate over each instance in the netlist and construct a circuit after this function.] + + Example usage: + + .. code-block:: + + >>> import gdsfactory as gf + >>> from piel.integration.gdsfactory_hdl21.conversion import gdsfactory_netlist_with_hdl21_generators + >>> from piel.models.physical.electronic import get_default_models + >>> gdsfactory_netlist_with_hdl21_generators(gdsfactory_netlist=gf.components.mzi2x2_2x2_phase_shifter().get_netlist(exclude_port_types="optical"),generators=get_default_models()) + + :param gdsfactory_netlist: The netlist from ``GDSFactory`` to map to the ``hdl21`` models dictionary. + :param generators: The ``hdl21`` models dictionary to map to the ``GDSFactory`` netlist. + + :returns: The ``GDSFactory`` netlist with the ``hdl21`` models dictionary. diff --git a/docs/autoapi/piel/integration/gdsfactory_hdl21/core/index.rst b/docs/autoapi/piel/integration/gdsfactory_hdl21/core/index.rst new file mode 100644 index 00000000..bbd13ea7 --- /dev/null +++ b/docs/autoapi/piel/integration/gdsfactory_hdl21/core/index.rst @@ -0,0 +1,246 @@ +:py:mod:`piel.integration.gdsfactory_hdl21.core` +================================================ + +.. py:module:: piel.integration.gdsfactory_hdl21.core + +.. autoapi-nested-parse:: + + Most of the ``hdl21``-``gdsfactory`` integration functions will be contributed directly to `gdsfactory`. However, + some `translation language` inherent to the ``piel`` implementation of these tools is included here. + + Note that to be able to construct a full circuit model of the netlist tools provided, it is necessary to create + individual circuit models of the devices that we will interconnect, and then map them to a larger netlist. This means + that it is necessary to create specific SPICE models for each particular component, say in an electrical netlist. + + This functions convert a GDSFactory netlist, with a set of component models, into `hdl21` that accounts for the + instance properties, which can then be connected into a VLSIR compatible `Netlist` implementation. + + Eventually we will implement RCX where we can extract the netlist with parasitics directly from the layout, + but for now this will be the implementation. The output structure of our SPICE should be compatible with the + `Netlist` package BaseModel. + + We follow the principle in: https://eee.guc.edu.eg/Courses/Electronics/ELCT503%20Semiconductors/Lab/spicehowto.pdf + + .. code-block:: spice + + Spice Simulation 1-1 + *** MODEL Descriptions *** + .model nm NMOS level=2 VT0=0.7 + KP=80e-6 LAMBDA=0.01 + + *** NETLIST Description *** + M1 vdd ng 0 0 nm W=3u L=3u + R1 in ng 50 + Vdd vdd 0 5 + Vin in 0 2.5 + + *** SIMULATION Commands *** + .op + .end + + Note that the netlist device connectivity structure of most passive components is in the form: + + .. code-block:: spice + + + + Our example GDSFactory netlist format is in the simplified form: + + .. code-block:: + + { + "connections": { + "straight_1": { + "e1": "taper_1,e2", + "e2": "taper_2,e2" + }, + "taper_1": { + "e1": "via_stack_1,e3" + }, + "taper_2": { + "e1": "via_stack_2,e1" + } + }, + "instances": { + "straight_1": { + "component": "straight", + "info": { + "length": 15.0, + "width": 0.5, + "cross_section": "strip_heater_metal", + "settings": { + "width": 0.5, + "layer": "WG", + "heater_width": 2.5, + "layer_heater": "HEATER" + } + } + }, + "taper_1": { + "component": "taper", + "info": { + "length": 5.0, + "width1": 11.0, + "width2": 2.5 + }, + "settings": { + "cross_section": { + "layer": "HEATER", + "width": 2.5, + "offset": 0.0, + "taper_length": 10.0, + "gap": 5.0, + "min_length": 5.0, + "port_names": ["e1", "e2"] + } + } + }, + "taper_2": { + "component": "taper", + "info": { + "length": 5.0, + "width1": 11.0, + "width2": 2.5 + }, + "settings": { + "cross_section": { + "layer": "HEATER", + "width": 2.5, + "offset": 0.0, + "taper_length": 10.0, + "gap": 5.0, + "min_length": 5.0, + "port_names": ["e1", "e2"] + } + } + }, + "via_stack_1": { + "component": "via_stack", + "info": { + "size": [11.0, 11.0], + "layer": "M3" + }, + "settings": { + "layers": ["HEATER", "M2", "M3"] + } + }, + "via_stack_2": { + "component": "via_stack", + "info": { + "size": [11.0, 11.0], + "layer": "M3" + }, + "settings": { + "layers": ["HEATER", "M2", "M3"] + } + } + }, + "placements": { + "straight_1": {"x": 0.0, "y": 0.0, "rotation": 0, "mirror": 0}, + "taper_1": {"x": -5.0, "y": 0.0, "rotation": 0, "mirror": 0}, + "taper_2": {"x": 20.0, "y": 0.0, "rotation": 180, "mirror": 0}, + "via_stack_1": {"x": -10.5, "y": 0.0, "rotation": 0, "mirror": 0}, + "via_stack_2": {"x": 25.5, "y": 0.0, "rotation": 0, "mirror": 0} + }, + "ports": { + "e1": "taper_1,e2", + "e2": "taper_2,e2" + }, + "name": "straight_heater_metal_simple", + } + + This is particularly useful when creating our components and connectivity, because what we can do is instantiate our + devices with their corresponding values, and then create our connectivity accordingly. To do this properly from our + GDSFactory netlist to ``hdl21``, we can then extract the total SPICE circuit, and convert it to a VLSIR format using + the ``Netlist`` module. The reason why we can't use the Netlist package from Dan Fritchman directly is that we need to + apply a set of models that translate a particular component instantiation into an electrical model. Because we are + not yet doing layout extraction as that requires EM solvers, we need to create some sort of SPICE level assignment + based on the provided dictionary. + + Note that ``hdl21`` already can implement the port connectivity directly from internal instances, and translate this + to our connectivity netlist. This means we only need to iterate to create our instances based on our models into a + ``hdl21`` module, then we can easily assign the corresponding values. It is also possible to create the assigned + parameters as part of the ``hdl21`` component which would form part of our module. Because the gdsfactory names are + compatible with ``hdl21``, then it is fine to create the integration accordingly. + + The algorithm can be to: + + 1. Parse the gdsfactory netlist, assign the electrical ports for the model. Extract all instances and + required models from the netlist. + 2. Verify that the models have been provided. Each model describes the type of + component this is, how many ports it requires and so on. Create a ``hdl21`` top level module for every gdsfactory + netlist, this is reasonable as it is composed, and not a generator class. This generates a large amount of instantiated ``hdl21`` modules that are generated from `generators`. + 3. Map the connections to each instance port as part of the instance dictionary. This parses the connectivity in the ``gdsfactory`` netlist and connects the ports accordingly. + + The connections are a bit more complex. So each of our connections dictionary is in the form: + + .. code-block:: + + "connections": { + "straight_1": { + "e1": "taper_1,e2", + "e2": "taper_2,e2" + }, + "taper_1": { + "e1": "via_stack_1,e3" + }, + "taper_2": { + "e1": "via_stack_2,e1" + } + }, + + We know what our top model ports are. We know our internal instance ports as well, and this will be provided by the + model too. For the sake of easiness, we can describe these as ``hdl21`` equivalent ``InOut`` or ``Port` `ports and + not have to deal with directionality. After instance declaration, and models for each of these components with the + corresponding port topology, it is then straightforward to parse the connectivity and implement the network, + and extract the SPICE. + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.integration.gdsfactory_hdl21.core.gdsfactory_netlist_to_spice_netlist + piel.integration.gdsfactory_hdl21.core.construct_hdl21_module + + + +.. py:function:: gdsfactory_netlist_to_spice_netlist(gdsfactory_netlist: dict, generators: dict, **kwargs) -> hdl21.Module + + This function converts a GDSFactory electrical netlist into a standard SPICE netlist. It follows the same + principle as the `sax` circuit composition. + + Each GDSFactory netlist has a set of instances, each with a corresponding model, and each instance with a given + set of geometrical settings that can be applied to each particular model. We know the type of SPICE model from + the instance model we provides. + + We know that the gdsfactory has a set of instances, and we can map unique models via sax through our own + composition circuit. Write the SPICE component based on the model into a total circuit representation in string + from the reshaped gdsfactory dictionary into our own structure. + + :param gdsfactory_netlist: GDSFactory netlist + :param generators: Dictionary of Generators + + :returns: hdl21 module or raw SPICE string + + +.. py:function:: construct_hdl21_module(spice_netlist: dict, **kwargs) -> hdl21.Module + + This function converts a gdsfactory-spice converted netlist using the component models into a SPICE circuit. + + Part of the complexity of this function is the multiport nature of some components and models, and assigning the + parameters accordingly into the SPICE function. This is because not every SPICE component will be bi-port, + and many will have multi-ports and parameters accordingly. Each model can implement the composition into a + SPICE circuit, but they depend on a set of parameters that must be set from the instance. Another aspect is + that we may want to assign the component ID according to the type of component. However, we can also assign the + ID based on the individual instance in the circuit, which is also a reasonable approximation. However, + it could be said, that the ideal implementation would be for each component model provided to return the SPICE + instance including connectivity except for the ID. + + # TODO implement validators diff --git a/docs/autoapi/piel/integration/gdsfactory_hdl21/index.rst b/docs/autoapi/piel/integration/gdsfactory_hdl21/index.rst new file mode 100644 index 00000000..dc5fe4a8 --- /dev/null +++ b/docs/autoapi/piel/integration/gdsfactory_hdl21/index.rst @@ -0,0 +1,106 @@ +:py:mod:`piel.integration.gdsfactory_hdl21` +=========================================== + +.. py:module:: piel.integration.gdsfactory_hdl21 + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + conversion/index.rst + core/index.rst + utils/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.integration.gdsfactory_hdl21.gdsfactory_netlist_to_spice_netlist + piel.integration.gdsfactory_hdl21.construct_hdl21_module + piel.integration.gdsfactory_hdl21.convert_connections_to_tuples + piel.integration.gdsfactory_hdl21.gdsfactory_netlist_with_hdl21_generators + + + +.. py:function:: gdsfactory_netlist_to_spice_netlist(gdsfactory_netlist: dict, generators: dict, **kwargs) -> hdl21.Module + + This function converts a GDSFactory electrical netlist into a standard SPICE netlist. It follows the same + principle as the `sax` circuit composition. + + Each GDSFactory netlist has a set of instances, each with a corresponding model, and each instance with a given + set of geometrical settings that can be applied to each particular model. We know the type of SPICE model from + the instance model we provides. + + We know that the gdsfactory has a set of instances, and we can map unique models via sax through our own + composition circuit. Write the SPICE component based on the model into a total circuit representation in string + from the reshaped gdsfactory dictionary into our own structure. + + :param gdsfactory_netlist: GDSFactory netlist + :param generators: Dictionary of Generators + + :returns: hdl21 module or raw SPICE string + + +.. py:function:: construct_hdl21_module(spice_netlist: dict, **kwargs) -> hdl21.Module + + This function converts a gdsfactory-spice converted netlist using the component models into a SPICE circuit. + + Part of the complexity of this function is the multiport nature of some components and models, and assigning the + parameters accordingly into the SPICE function. This is because not every SPICE component will be bi-port, + and many will have multi-ports and parameters accordingly. Each model can implement the composition into a + SPICE circuit, but they depend on a set of parameters that must be set from the instance. Another aspect is + that we may want to assign the component ID according to the type of component. However, we can also assign the + ID based on the individual instance in the circuit, which is also a reasonable approximation. However, + it could be said, that the ideal implementation would be for each component model provided to return the SPICE + instance including connectivity except for the ID. + + # TODO implement validators + + +.. py:function:: convert_connections_to_tuples(connections: dict) + + Convert from: + + .. code-block:: + + { + 'straight_1,e1': 'taper_1,e2', + 'straight_1,e2': 'taper_2,e2', + 'taper_1,e1': 'via_stack_1,e3', + 'taper_2,e1': 'via_stack_2,e1' + } + + to: + + .. code-block:: + + [(('straight_1', 'e1'), ('taper_1', 'e2')), (('straight_1', 'e2'), ('taper_2', 'e2')), (('taper_1', 'e1'), + ('via_stack_1', 'e3')), (('taper_2', 'e1'), ('via_stack_2', 'e1'))] + + +.. py:function:: gdsfactory_netlist_with_hdl21_generators(gdsfactory_netlist: dict, generators=None) + + This function allows us to map the ``hdl21`` models dictionary in a `sax`-like implementation to the ``GDSFactory`` netlist. This allows us to iterate over each instance in the netlist and construct a circuit after this function.] + + Example usage: + + .. code-block:: + + >>> import gdsfactory as gf + >>> from piel.integration.gdsfactory_hdl21.conversion import gdsfactory_netlist_with_hdl21_generators + >>> from piel.models.physical.electronic import get_default_models + >>> gdsfactory_netlist_with_hdl21_generators(gdsfactory_netlist=gf.components.mzi2x2_2x2_phase_shifter().get_netlist(exclude_port_types="optical"),generators=get_default_models()) + + :param gdsfactory_netlist: The netlist from ``GDSFactory`` to map to the ``hdl21`` models dictionary. + :param generators: The ``hdl21`` models dictionary to map to the ``GDSFactory`` netlist. + + :returns: The ``GDSFactory`` netlist with the ``hdl21`` models dictionary. diff --git a/docs/autoapi/piel/integration/gdsfactory_hdl21/utils/index.rst b/docs/autoapi/piel/integration/gdsfactory_hdl21/utils/index.rst new file mode 100644 index 00000000..864abb1d --- /dev/null +++ b/docs/autoapi/piel/integration/gdsfactory_hdl21/utils/index.rst @@ -0,0 +1,29 @@ +:py:mod:`piel.integration.gdsfactory_hdl21.utils` +================================================= + +.. py:module:: piel.integration.gdsfactory_hdl21.utils + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.integration.gdsfactory_hdl21.utils.rename_gdsfactory_connections_to_spice + piel.integration.gdsfactory_hdl21.utils.convert_tuples_to_strings + + + +.. py:function:: rename_gdsfactory_connections_to_spice(connections: dict) + + We convert the connection connectivity of the gdsfactory netlist into names that can be integrated into a SPICE + netlist. It iterates on each key value pair, and replaces each comma with an underscore. + + # TODO docs + + +.. py:function:: convert_tuples_to_strings(tuple_list) diff --git a/docs/autoapi/piel/integration/gdsfactory_openlane/index.rst b/docs/autoapi/piel/integration/gdsfactory_openlane/index.rst new file mode 100644 index 00000000..261a0a55 --- /dev/null +++ b/docs/autoapi/piel/integration/gdsfactory_openlane/index.rst @@ -0,0 +1,45 @@ +:py:mod:`piel.integration.gdsfactory_openlane` +============================================== + +.. py:module:: piel.integration.gdsfactory_openlane + +.. autoapi-nested-parse:: + + There are a number of ways to generate gdsfactory integration. + + It is worth noting that GDSFactory has already the following PDKs installed: + * SKY130nm https://gdsfactory.github.io/skywater130/ + * GF180nm https://gdsfactory.github.io/gf180/ + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.integration.gdsfactory_openlane.create_gdsfactory_component_from_openlane + + + +.. py:function:: create_gdsfactory_component_from_openlane(design_name_v1: str | None = None, design_directory: piel.config.piel_path_types | None = None, run_name: str | None = None, v1: bool = True) -> gdsfactory.Component + + This function cretes a gdsfactory layout component that can be included in the network codesign of the device, or that can be used for interconnection codesign. + + It will look into the latest design run and extract the final OpenLane-generated GDS. You do not have to have run this with OpenLane2 as it just looks at the latest run. + + :param design_name_v1: Design name of the v1 design that can be found within `$OPENLANE_ROOT/""/designs`. + :type design_name_v1: str + :param design_directory: Design directory PATH. + :type design_directory: piel_path_types + :param run_name: Name of the run to extract the GDS from. If None, it will look at the latest run. + :type run_name: str + :param v1: If True, it will import the design from the OpenLane v1 configuration. + :type v1: bool + + :returns: GDSFactory component. + :rtype: component(gf.Component) diff --git a/docs/autoapi/piel/integration/index.rst b/docs/autoapi/piel/integration/index.rst new file mode 100644 index 00000000..786a6bcf --- /dev/null +++ b/docs/autoapi/piel/integration/index.rst @@ -0,0 +1,341 @@ +:py:mod:`piel.integration` +========================== + +.. py:module:: piel.integration + + +Subpackages +----------- +.. toctree:: + :titlesonly: + :maxdepth: 3 + + gdsfactory_hdl21/index.rst + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + cocotb_sax/index.rst + gdsfactory_openlane/index.rst + sax_qutip/index.rst + sax_thewalrus/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.integration.create_gdsfactory_component_from_openlane + piel.integration.gdsfactory_netlist_to_spice_netlist + piel.integration.construct_hdl21_module + piel.integration.convert_connections_to_tuples + piel.integration.gdsfactory_netlist_with_hdl21_generators + piel.integration.sax_to_s_parameters_standard_matrix + piel.integration.unitary_permanent + piel.integration.sax_circuit_permanent + piel.integration.sax_to_ideal_qutip_unitary + piel.integration.standard_s_parameters_to_ideal_qutip_unitary + + + +.. py:function:: create_gdsfactory_component_from_openlane(design_name_v1: str | None = None, design_directory: piel.config.piel_path_types | None = None, run_name: str | None = None, v1: bool = True) -> gdsfactory.Component + + This function cretes a gdsfactory layout component that can be included in the network codesign of the device, or that can be used for interconnection codesign. + + It will look into the latest design run and extract the final OpenLane-generated GDS. You do not have to have run this with OpenLane2 as it just looks at the latest run. + + :param design_name_v1: Design name of the v1 design that can be found within `$OPENLANE_ROOT/""/designs`. + :type design_name_v1: str + :param design_directory: Design directory PATH. + :type design_directory: piel_path_types + :param run_name: Name of the run to extract the GDS from. If None, it will look at the latest run. + :type run_name: str + :param v1: If True, it will import the design from the OpenLane v1 configuration. + :type v1: bool + + :returns: GDSFactory component. + :rtype: component(gf.Component) + + +.. py:function:: gdsfactory_netlist_to_spice_netlist(gdsfactory_netlist: dict, generators: dict, **kwargs) -> hdl21.Module + + This function converts a GDSFactory electrical netlist into a standard SPICE netlist. It follows the same + principle as the `sax` circuit composition. + + Each GDSFactory netlist has a set of instances, each with a corresponding model, and each instance with a given + set of geometrical settings that can be applied to each particular model. We know the type of SPICE model from + the instance model we provides. + + We know that the gdsfactory has a set of instances, and we can map unique models via sax through our own + composition circuit. Write the SPICE component based on the model into a total circuit representation in string + from the reshaped gdsfactory dictionary into our own structure. + + :param gdsfactory_netlist: GDSFactory netlist + :param generators: Dictionary of Generators + + :returns: hdl21 module or raw SPICE string + + +.. py:function:: construct_hdl21_module(spice_netlist: dict, **kwargs) -> hdl21.Module + + This function converts a gdsfactory-spice converted netlist using the component models into a SPICE circuit. + + Part of the complexity of this function is the multiport nature of some components and models, and assigning the + parameters accordingly into the SPICE function. This is because not every SPICE component will be bi-port, + and many will have multi-ports and parameters accordingly. Each model can implement the composition into a + SPICE circuit, but they depend on a set of parameters that must be set from the instance. Another aspect is + that we may want to assign the component ID according to the type of component. However, we can also assign the + ID based on the individual instance in the circuit, which is also a reasonable approximation. However, + it could be said, that the ideal implementation would be for each component model provided to return the SPICE + instance including connectivity except for the ID. + + # TODO implement validators + + +.. py:function:: convert_connections_to_tuples(connections: dict) + + Convert from: + + .. code-block:: + + { + 'straight_1,e1': 'taper_1,e2', + 'straight_1,e2': 'taper_2,e2', + 'taper_1,e1': 'via_stack_1,e3', + 'taper_2,e1': 'via_stack_2,e1' + } + + to: + + .. code-block:: + + [(('straight_1', 'e1'), ('taper_1', 'e2')), (('straight_1', 'e2'), ('taper_2', 'e2')), (('taper_1', 'e1'), + ('via_stack_1', 'e3')), (('taper_2', 'e1'), ('via_stack_2', 'e1'))] + + +.. py:function:: gdsfactory_netlist_with_hdl21_generators(gdsfactory_netlist: dict, generators=None) + + This function allows us to map the ``hdl21`` models dictionary in a `sax`-like implementation to the ``GDSFactory`` netlist. This allows us to iterate over each instance in the netlist and construct a circuit after this function.] + + Example usage: + + .. code-block:: + + >>> import gdsfactory as gf + >>> from piel.integration.gdsfactory_hdl21.conversion import gdsfactory_netlist_with_hdl21_generators + >>> from piel.models.physical.electronic import get_default_models + >>> gdsfactory_netlist_with_hdl21_generators(gdsfactory_netlist=gf.components.mzi2x2_2x2_phase_shifter().get_netlist(exclude_port_types="optical"),generators=get_default_models()) + + :param gdsfactory_netlist: The netlist from ``GDSFactory`` to map to the ``hdl21`` models dictionary. + :param generators: The ``hdl21`` models dictionary to map to the ``GDSFactory`` netlist. + + :returns: The ``GDSFactory`` netlist with the ``hdl21`` models dictionary. + + +.. py:function:: sax_to_s_parameters_standard_matrix(sax_input: sax.SType, input_ports_order: tuple | None = None) -> tuple + + A ``sax`` S-parameter SDict is provided as a dictionary of tuples with (port0, port1) as the key. This + determines the direction of the scattering relationship. It means that the number of terms in an S-parameter + matrix is the number of ports squared. + + In order to generalise, this function returns both the S-parameter matrices and the indexing ports based on the + amount provided. In terms of computational speed, we definitely would like this function to be algorithmically + very fast. For now, I will write a simple python implementation and optimise in the future. + + It is possible to see the `sax` SDense notation equivalence here: + https://flaport.github.io/sax/nbs/08_backends.html + + .. code-block:: python + + import jax.numpy as jnp + from sax.core import SDense + + # Directional coupler SDense representation + dc_sdense: SDense = ( + jnp.array([[0, 0, τ, κ], [0, 0, κ, τ], [τ, κ, 0, 0], [κ, τ, 0, 0]]), + {"in0": 0, "in1": 1, "out0": 2, "out1": 3}, + ) + + + # Directional coupler SDict representation + # Taken from https://flaport.github.io/sax/nbs/05_models.html + def coupler(*, coupling: float = 0.5) -> SDict: + kappa = coupling**0.5 + tau = (1 - coupling) ** 0.5 + sdict = reciprocal( + { + ("in0", "out0"): tau, + ("in0", "out1"): 1j * kappa, + ("in1", "out0"): 1j * kappa, + ("in1", "out1"): tau, + } + ) + return sdict + + If we were to relate the mapping accordingly based on the ports indexes, a S-Parameter matrix in the form of + :math:`S_{(output,i),(input,i)}` would be: + + .. math:: + + S = \begin{bmatrix} + S_{00} & S_{10} \\ + S_{01} & S_{11} \\ + \end{bmatrix} = + \begin{bmatrix} + \tau & j \kappa \\ + j \kappa & \tau \\ + \end{bmatrix} + + Note that the standard S-parameter and hence unitary representation is in the form of: + + .. math:: + + S = \begin{bmatrix} + S_{00} & S_{01} \\ + S_{10} & S_{11} \\ + \end{bmatrix} + + + .. math:: + + \begin{bmatrix} + b_{1} \\ + \vdots \\ + b_{n} + \end{bmatrix} + = + \begin{bmatrix} + S_{11} & \dots & S_{1n} \\ + \vdots & \ddots & \vdots \\ + S_{n1} & \dots & S_{nn} + \end{bmatrix} + \begin{bmatrix} + a_{1} \\ + \vdots \\ + a_{n} + \end{bmatrix} + + TODO check with Floris, does this mean we need to transpose the matrix? + + :param sax_input: The sax S-parameter dictionary. + :type sax_input: sax.SType + :param input_ports_order: The ports order tuple containing the names and order of the input ports. + :type input_ports_order: tuple + + :returns: The S-parameter matrix and the input ports index tuple in the standard S-parameter notation. + :rtype: tuple + + +.. py:function:: unitary_permanent(unitary_matrix: numpy.ndarray) -> tuple + + The permanent of a unitary is used to determine the state probability of combinatorial Gaussian boson samping systems. + + ``thewalrus`` Ryser's algorithm permananet implementation is described here: https://the-walrus.readthedocs.io/en/latest/gallery/permanent_tutorial.html + + # TODO maybe implement subroutine if computation is taking forever. + # TODO why two outputs? Understand this properly later. + + :param unitary_permanent: The unitary matrix. + :type unitary_permanent: np.ndarray + + :returns: The circuit permanent and the time it took to compute it. + :rtype: tuple + + +.. py:function:: sax_circuit_permanent(sax_input: sax.SType) -> tuple + + The permanent of a unitary is used to determine the state probability of combinatorial Gaussian boson samping systems. + + ``thewalrus`` Ryser's algorithm permananet implementation is described here: https://the-walrus.readthedocs.io/en/latest/gallery/permanent_tutorial.html + + # TODO maybe implement subroutine if computation is taking forever. + + :param sax_input: The sax S-parameter dictionary. + :type sax_input: sax.SType + + :returns: The circuit permanent and the time it took to compute it. + :rtype: tuple + + +.. py:function:: sax_to_ideal_qutip_unitary(sax_input: sax.SType) + + This function converts the calculated S-parameters into a standard Unitary matrix topology so that the shape and + dimensions of the matrix can be observed. + + I think this means we need to transpose the output of the filtered sax SDense matrix to map it to a QuTip matrix. + Note that the documentation and formatting of the standard `sax` mapping to a S-parameter standard notation is + already in described in piel/piel/sax/utils.py. + + From this stage we can implement a ``QObj`` matrix accordingly and perform simulations accordingly. + https://qutip.org/docs/latest/guide/qip/qip-basics.html#unitaries + + For example, a ``qutip`` representation of an s-gate gate would be: + + ..code-block:: + + import numpy as np + import qutip + # S-Gate + s_gate_matrix = np.array([[1., 0], [0., 1.j]]) + s_gate = qutip.Qobj(mat, dims=[[2], [2]]) + + In mathematical notation, this S-gate would be written as: + + ..math:: + + S = \begin{bmatrix} + 1 & 0 \\ + 0 & i \\ + \end{bmatrix} + + :param sax_input: A dictionary of S-parameters in the form of a SDict from `sax`. + :type sax_input: sax.SType + + :returns: A QuTip QObj representation of the S-parameters in a unitary matrix. + :rtype: qobj_unitary (qutip.Qobj) + + +.. py:function:: standard_s_parameters_to_ideal_qutip_unitary(s_parameters_standard_matrix: piel.config.nso.ndarray) + + This function converts the calculated S-parameters into a standard Unitary matrix topology so that the shape and + dimensions of the matrix can be observed. + + I think this means we need to transpose the output of the filtered sax SDense matrix to map it to a QuTip matrix. + Note that the documentation and formatting of the standard `sax` mapping to a S-parameter standard notation is + already in described in piel/piel/sax/utils.py. + + From this stage we can implement a ``QObj`` matrix accordingly and perform simulations accordingly. https://qutip.org/docs/latest/guide/qip/qip-basics.html#unitaries + + For example, a ``qutip`` representation of an s-gate gate would be: + + ..code-block:: + + import numpy as np + import qutip + # S-Gate + s_gate_matrix = np.array([[1., 0], [0., 1.j]]) + s_gate = qutip.Qobj(mat, dims=[[2], [2]]) + + In mathematical notation, this S-gate would be written as: + + ..math:: + + S = \begin{bmatrix} + 1 & 0 \\ + 0 & i \\ + \end{bmatrix} + + :param s_parameters_standard_matrix: A dictionary of S-parameters in the form of a SDict from `sax`. + :type s_parameters_standard_matrix: nso.ndarray + + :returns: A QuTip QObj representation of the S-parameters in a unitary matrix. + :rtype: qobj_unitary (qutip.Qobj) diff --git a/docs/autoapi/piel/integration/sax_qutip/index.rst b/docs/autoapi/piel/integration/sax_qutip/index.rst new file mode 100644 index 00000000..407c94a2 --- /dev/null +++ b/docs/autoapi/piel/integration/sax_qutip/index.rst @@ -0,0 +1,93 @@ +:py:mod:`piel.integration.sax_qutip` +==================================== + +.. py:module:: piel.integration.sax_qutip + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.integration.sax_qutip.standard_s_parameters_to_ideal_qutip_unitary + piel.integration.sax_qutip.sax_to_ideal_qutip_unitary + + + +.. py:function:: standard_s_parameters_to_ideal_qutip_unitary(s_parameters_standard_matrix: piel.config.nso.ndarray) + + This function converts the calculated S-parameters into a standard Unitary matrix topology so that the shape and + dimensions of the matrix can be observed. + + I think this means we need to transpose the output of the filtered sax SDense matrix to map it to a QuTip matrix. + Note that the documentation and formatting of the standard `sax` mapping to a S-parameter standard notation is + already in described in piel/piel/sax/utils.py. + + From this stage we can implement a ``QObj`` matrix accordingly and perform simulations accordingly. https://qutip.org/docs/latest/guide/qip/qip-basics.html#unitaries + + For example, a ``qutip`` representation of an s-gate gate would be: + + ..code-block:: + + import numpy as np + import qutip + # S-Gate + s_gate_matrix = np.array([[1., 0], [0., 1.j]]) + s_gate = qutip.Qobj(mat, dims=[[2], [2]]) + + In mathematical notation, this S-gate would be written as: + + ..math:: + + S = \begin{bmatrix} + 1 & 0 \\ + 0 & i \\ + \end{bmatrix} + + :param s_parameters_standard_matrix: A dictionary of S-parameters in the form of a SDict from `sax`. + :type s_parameters_standard_matrix: nso.ndarray + + :returns: A QuTip QObj representation of the S-parameters in a unitary matrix. + :rtype: qobj_unitary (qutip.Qobj) + + +.. py:function:: sax_to_ideal_qutip_unitary(sax_input: sax.SType) + + This function converts the calculated S-parameters into a standard Unitary matrix topology so that the shape and + dimensions of the matrix can be observed. + + I think this means we need to transpose the output of the filtered sax SDense matrix to map it to a QuTip matrix. + Note that the documentation and formatting of the standard `sax` mapping to a S-parameter standard notation is + already in described in piel/piel/sax/utils.py. + + From this stage we can implement a ``QObj`` matrix accordingly and perform simulations accordingly. + https://qutip.org/docs/latest/guide/qip/qip-basics.html#unitaries + + For example, a ``qutip`` representation of an s-gate gate would be: + + ..code-block:: + + import numpy as np + import qutip + # S-Gate + s_gate_matrix = np.array([[1., 0], [0., 1.j]]) + s_gate = qutip.Qobj(mat, dims=[[2], [2]]) + + In mathematical notation, this S-gate would be written as: + + ..math:: + + S = \begin{bmatrix} + 1 & 0 \\ + 0 & i \\ + \end{bmatrix} + + :param sax_input: A dictionary of S-parameters in the form of a SDict from `sax`. + :type sax_input: sax.SType + + :returns: A QuTip QObj representation of the S-parameters in a unitary matrix. + :rtype: qobj_unitary (qutip.Qobj) diff --git a/docs/autoapi/piel/integration/sax_thewalrus/index.rst b/docs/autoapi/piel/integration/sax_thewalrus/index.rst new file mode 100644 index 00000000..bd5120bb --- /dev/null +++ b/docs/autoapi/piel/integration/sax_thewalrus/index.rst @@ -0,0 +1,49 @@ +:py:mod:`piel.integration.sax_thewalrus` +======================================== + +.. py:module:: piel.integration.sax_thewalrus + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.integration.sax_thewalrus.unitary_permanent + piel.integration.sax_thewalrus.sax_circuit_permanent + + + +.. py:function:: unitary_permanent(unitary_matrix: numpy.ndarray) -> tuple + + The permanent of a unitary is used to determine the state probability of combinatorial Gaussian boson samping systems. + + ``thewalrus`` Ryser's algorithm permananet implementation is described here: https://the-walrus.readthedocs.io/en/latest/gallery/permanent_tutorial.html + + # TODO maybe implement subroutine if computation is taking forever. + # TODO why two outputs? Understand this properly later. + + :param unitary_permanent: The unitary matrix. + :type unitary_permanent: np.ndarray + + :returns: The circuit permanent and the time it took to compute it. + :rtype: tuple + + +.. py:function:: sax_circuit_permanent(sax_input: sax.SType) -> tuple + + The permanent of a unitary is used to determine the state probability of combinatorial Gaussian boson samping systems. + + ``thewalrus`` Ryser's algorithm permananet implementation is described here: https://the-walrus.readthedocs.io/en/latest/gallery/permanent_tutorial.html + + # TODO maybe implement subroutine if computation is taking forever. + + :param sax_input: The sax S-parameter dictionary. + :type sax_input: sax.SType + + :returns: The circuit permanent and the time it took to compute it. + :rtype: tuple diff --git a/docs/autoapi/piel/models/frequency/all/index.rst b/docs/autoapi/piel/models/frequency/all/index.rst new file mode 100644 index 00000000..689eadfe --- /dev/null +++ b/docs/autoapi/piel/models/frequency/all/index.rst @@ -0,0 +1,28 @@ +:py:mod:`piel.models.frequency.all` +=================================== + +.. py:module:: piel.models.frequency.all + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.all.get_all_models + + + +.. py:function:: get_all_models(custom_library: dict | None = None) -> dict + + Returns the default models dictionary. + + :param custom_library: Custom defaults dictionary. + :type custom_library: dict + + :returns: Default models dictionary. + :rtype: dict diff --git a/docs/autoapi/piel/models/frequency/defaults/index.rst b/docs/autoapi/piel/models/frequency/defaults/index.rst new file mode 100644 index 00000000..b0d211e0 --- /dev/null +++ b/docs/autoapi/piel/models/frequency/defaults/index.rst @@ -0,0 +1,28 @@ +:py:mod:`piel.models.frequency.defaults` +======================================== + +.. py:module:: piel.models.frequency.defaults + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.defaults.get_default_models + + + +.. py:function:: get_default_models(custom_defaults: dict | None = None) -> dict + + Returns the default models dictionary. + + :param custom_defaults: Custom defaults dictionary. + :type custom_defaults: dict + + :returns: Default models dictionary. + :rtype: dict diff --git a/docs/autoapi/piel/models/frequency/electrical/index.rst b/docs/autoapi/piel/models/frequency/electrical/index.rst new file mode 100644 index 00000000..94dd23aa --- /dev/null +++ b/docs/autoapi/piel/models/frequency/electrical/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.frequency.electrical` +========================================== + +.. py:module:: piel.models.frequency.electrical diff --git a/docs/autoapi/piel/models/frequency/electro_optic/ideal/index.rst b/docs/autoapi/piel/models/frequency/electro_optic/ideal/index.rst new file mode 100644 index 00000000..1237293a --- /dev/null +++ b/docs/autoapi/piel/models/frequency/electro_optic/ideal/index.rst @@ -0,0 +1,20 @@ +:py:mod:`piel.models.frequency.electro_optic.ideal` +=================================================== + +.. py:module:: piel.models.frequency.electro_optic.ideal + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.electro_optic.ideal.ideal_active_mzi2x2_2x2 + + + +.. py:function:: ideal_active_mzi2x2_2x2() diff --git a/docs/autoapi/piel/models/frequency/electro_optic/index.rst b/docs/autoapi/piel/models/frequency/electro_optic/index.rst new file mode 100644 index 00000000..370fd25c --- /dev/null +++ b/docs/autoapi/piel/models/frequency/electro_optic/index.rst @@ -0,0 +1,13 @@ +:py:mod:`piel.models.frequency.electro_optic` +============================================= + +.. py:module:: piel.models.frequency.electro_optic + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + ideal/index.rst diff --git a/docs/autoapi/piel/models/frequency/electronic/index.rst b/docs/autoapi/piel/models/frequency/electronic/index.rst new file mode 100644 index 00000000..fd8c6cca --- /dev/null +++ b/docs/autoapi/piel/models/frequency/electronic/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.frequency.electronic` +========================================== + +.. py:module:: piel.models.frequency.electronic diff --git a/docs/autoapi/piel/models/frequency/index.rst b/docs/autoapi/piel/models/frequency/index.rst new file mode 100644 index 00000000..f9f5b8cb --- /dev/null +++ b/docs/autoapi/piel/models/frequency/index.rst @@ -0,0 +1,76 @@ +:py:mod:`piel.models.frequency` +=============================== + +.. py:module:: piel.models.frequency + + +Subpackages +----------- +.. toctree:: + :titlesonly: + :maxdepth: 3 + + electrical/index.rst + electro_optic/index.rst + electronic/index.rst + opto_electronic/index.rst + photonic/index.rst + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + all/index.rst + defaults/index.rst + utils/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.compose_custom_model_library_from_defaults + piel.models.frequency.get_all_models + piel.models.frequency.get_default_models + + + +.. py:function:: compose_custom_model_library_from_defaults(custom_models: dict) -> dict + + Compose the default models with the custom models. + + :param custom_models: Custom models dictionary. + :type custom_models: dict + + :returns: Composed models dictionary. + :rtype: dict + + +.. py:function:: get_all_models(custom_library: dict | None = None) -> dict + + Returns the default models dictionary. + + :param custom_library: Custom defaults dictionary. + :type custom_library: dict + + :returns: Default models dictionary. + :rtype: dict + + +.. py:function:: get_default_models(custom_defaults: dict | None = None) -> dict + + Returns the default models dictionary. + + :param custom_defaults: Custom defaults dictionary. + :type custom_defaults: dict + + :returns: Default models dictionary. + :rtype: dict diff --git a/docs/autoapi/piel/models/frequency/opto_electronic/index.rst b/docs/autoapi/piel/models/frequency/opto_electronic/index.rst new file mode 100644 index 00000000..31f58a61 --- /dev/null +++ b/docs/autoapi/piel/models/frequency/opto_electronic/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.frequency.opto_electronic` +=============================================== + +.. py:module:: piel.models.frequency.opto_electronic diff --git a/docs/autoapi/piel/models/frequency/photonic/coupler_simple/index.rst b/docs/autoapi/piel/models/frequency/photonic/coupler_simple/index.rst new file mode 100644 index 00000000..7aa28347 --- /dev/null +++ b/docs/autoapi/piel/models/frequency/photonic/coupler_simple/index.rst @@ -0,0 +1,25 @@ +:py:mod:`piel.models.frequency.photonic.coupler_simple` +======================================================= + +.. py:module:: piel.models.frequency.photonic.coupler_simple + +.. autoapi-nested-parse:: + + Translated from https://github.com/flaport/sax or https://github.com/flaport/photontorch/tree/master + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.photonic.coupler_simple.coupler + + + +.. py:function:: coupler(coupling=0.5) diff --git a/docs/autoapi/piel/models/frequency/photonic/directional_coupler_length/index.rst b/docs/autoapi/piel/models/frequency/photonic/directional_coupler_length/index.rst new file mode 100644 index 00000000..76732fef --- /dev/null +++ b/docs/autoapi/piel/models/frequency/photonic/directional_coupler_length/index.rst @@ -0,0 +1,25 @@ +:py:mod:`piel.models.frequency.photonic.directional_coupler_length` +=================================================================== + +.. py:module:: piel.models.frequency.photonic.directional_coupler_length + +.. autoapi-nested-parse:: + + Translated from https://github.com/flaport/sax or https://github.com/flaport/photontorch/tree/master + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.photonic.directional_coupler_length.directional_coupler_with_length + + + +.. py:function:: directional_coupler_with_length(length=1e-05, coupling=0.5, loss=0, neff=2.34, wl0=1.55e-06, ng=3.4, phase=0) diff --git a/docs/autoapi/piel/models/frequency/photonic/directional_coupler_real/index.rst b/docs/autoapi/piel/models/frequency/photonic/directional_coupler_real/index.rst new file mode 100644 index 00000000..b5b9b2d3 --- /dev/null +++ b/docs/autoapi/piel/models/frequency/photonic/directional_coupler_real/index.rst @@ -0,0 +1,8 @@ +:py:mod:`piel.models.frequency.photonic.directional_coupler_real` +================================================================= + +.. py:module:: piel.models.frequency.photonic.directional_coupler_real + +.. autoapi-nested-parse:: + + Translated from https://github.com/flaport/sax or https://github.com/flaport/photontorch/tree/master diff --git a/docs/autoapi/piel/models/frequency/photonic/directional_coupler_simple/index.rst b/docs/autoapi/piel/models/frequency/photonic/directional_coupler_simple/index.rst new file mode 100644 index 00000000..607d0c75 --- /dev/null +++ b/docs/autoapi/piel/models/frequency/photonic/directional_coupler_simple/index.rst @@ -0,0 +1,25 @@ +:py:mod:`piel.models.frequency.photonic.directional_coupler_simple` +=================================================================== + +.. py:module:: piel.models.frequency.photonic.directional_coupler_simple + +.. autoapi-nested-parse:: + + Translated from https://github.com/flaport/sax or https://github.com/flaport/photontorch/tree/master + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.photonic.directional_coupler_simple.directional_coupler + + + +.. py:function:: directional_coupler(coupling=0.5) diff --git a/docs/autoapi/piel/models/frequency/photonic/grating_coupler/index.rst b/docs/autoapi/piel/models/frequency/photonic/grating_coupler/index.rst new file mode 100644 index 00000000..0bfd1bcc --- /dev/null +++ b/docs/autoapi/piel/models/frequency/photonic/grating_coupler/index.rst @@ -0,0 +1,25 @@ +:py:mod:`piel.models.frequency.photonic.grating_coupler` +======================================================== + +.. py:module:: piel.models.frequency.photonic.grating_coupler + +.. autoapi-nested-parse:: + + Translated from https://github.com/flaport/sax or https://github.com/flaport/photontorch/tree/master + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.photonic.grating_coupler.grating_coupler_simple + + + +.. py:function:: grating_coupler_simple(R=0.0, R_in=0.0, Tmax=1.0, bandwidth=6e-08, wl0=1.55e-06) diff --git a/docs/autoapi/piel/models/frequency/photonic/index.rst b/docs/autoapi/piel/models/frequency/photonic/index.rst new file mode 100644 index 00000000..1a3b66ef --- /dev/null +++ b/docs/autoapi/piel/models/frequency/photonic/index.rst @@ -0,0 +1,68 @@ +:py:mod:`piel.models.frequency.photonic` +======================================== + +.. py:module:: piel.models.frequency.photonic + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + coupler_simple/index.rst + directional_coupler_length/index.rst + directional_coupler_real/index.rst + directional_coupler_simple/index.rst + grating_coupler/index.rst + mmi1x2/index.rst + mmi2x2/index.rst + straight_waveguide/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.photonic.coupler + piel.models.frequency.photonic.directional_coupler_with_length + piel.models.frequency.photonic.directional_coupler + piel.models.frequency.photonic.grating_coupler_simple + piel.models.frequency.photonic.mmi1x2_50_50 + piel.models.frequency.photonic.mmi2x2_50_50 + piel.models.frequency.photonic.ideal_active_waveguide + piel.models.frequency.photonic.waveguide + piel.models.frequency.photonic.simple_straight + + + +.. py:function:: coupler(coupling=0.5) + + +.. py:function:: directional_coupler_with_length(length=1e-05, coupling=0.5, loss=0, neff=2.34, wl0=1.55e-06, ng=3.4, phase=0) + + +.. py:function:: directional_coupler(coupling=0.5) + + +.. py:function:: grating_coupler_simple(R=0.0, R_in=0.0, Tmax=1.0, bandwidth=6e-08, wl0=1.55e-06) + + +.. py:function:: mmi1x2_50_50() + + +.. py:function:: mmi2x2_50_50() + + +.. py:function:: ideal_active_waveguide(wl=1.55, wl0=1.55, neff=2.34, ng=3.4, length=10.0, loss=0.0, active_phase_rad=0.0) + + +.. py:function:: waveguide(wl=1.55, wl0=1.55, neff=2.34, ng=3.4, length=10.0, loss=0.0) + + +.. py:function:: simple_straight(length=10.0, width=0.5) diff --git a/docs/autoapi/piel/models/frequency/photonic/mmi1x2/index.rst b/docs/autoapi/piel/models/frequency/photonic/mmi1x2/index.rst new file mode 100644 index 00000000..9a381f4a --- /dev/null +++ b/docs/autoapi/piel/models/frequency/photonic/mmi1x2/index.rst @@ -0,0 +1,25 @@ +:py:mod:`piel.models.frequency.photonic.mmi1x2` +=============================================== + +.. py:module:: piel.models.frequency.photonic.mmi1x2 + +.. autoapi-nested-parse:: + + Translated from https://github.com/flaport/sax or https://github.com/flaport/photontorch/tree/master + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.photonic.mmi1x2.mmi1x2_50_50 + + + +.. py:function:: mmi1x2_50_50() diff --git a/docs/autoapi/piel/models/frequency/photonic/mmi2x2/index.rst b/docs/autoapi/piel/models/frequency/photonic/mmi2x2/index.rst new file mode 100644 index 00000000..389d19e0 --- /dev/null +++ b/docs/autoapi/piel/models/frequency/photonic/mmi2x2/index.rst @@ -0,0 +1,25 @@ +:py:mod:`piel.models.frequency.photonic.mmi2x2` +=============================================== + +.. py:module:: piel.models.frequency.photonic.mmi2x2 + +.. autoapi-nested-parse:: + + Translated from https://github.com/flaport/sax or https://github.com/flaport/photontorch/tree/master + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.photonic.mmi2x2.mmi2x2_50_50 + + + +.. py:function:: mmi2x2_50_50() diff --git a/docs/autoapi/piel/models/frequency/photonic/straight_waveguide/index.rst b/docs/autoapi/piel/models/frequency/photonic/straight_waveguide/index.rst new file mode 100644 index 00000000..72c7fc80 --- /dev/null +++ b/docs/autoapi/piel/models/frequency/photonic/straight_waveguide/index.rst @@ -0,0 +1,33 @@ +:py:mod:`piel.models.frequency.photonic.straight_waveguide` +=========================================================== + +.. py:module:: piel.models.frequency.photonic.straight_waveguide + +.. autoapi-nested-parse:: + + Translated from https://github.com/flaport/sax or https://github.com/flaport/photontorch/tree/master + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.photonic.straight_waveguide.waveguide + piel.models.frequency.photonic.straight_waveguide.ideal_active_waveguide + piel.models.frequency.photonic.straight_waveguide.simple_straight + + + +.. py:function:: waveguide(wl=1.55, wl0=1.55, neff=2.34, ng=3.4, length=10.0, loss=0.0) + + +.. py:function:: ideal_active_waveguide(wl=1.55, wl0=1.55, neff=2.34, ng=3.4, length=10.0, loss=0.0, active_phase_rad=0.0) + + +.. py:function:: simple_straight(length=10.0, width=0.5) diff --git a/docs/autoapi/piel/models/frequency/utils/index.rst b/docs/autoapi/piel/models/frequency/utils/index.rst new file mode 100644 index 00000000..65b796dd --- /dev/null +++ b/docs/autoapi/piel/models/frequency/utils/index.rst @@ -0,0 +1,28 @@ +:py:mod:`piel.models.frequency.utils` +===================================== + +.. py:module:: piel.models.frequency.utils + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.frequency.utils.compose_custom_model_library_from_defaults + + + +.. py:function:: compose_custom_model_library_from_defaults(custom_models: dict) -> dict + + Compose the default models with the custom models. + + :param custom_models: Custom models dictionary. + :type custom_models: dict + + :returns: Composed models dictionary. + :rtype: dict diff --git a/docs/autoapi/piel/models/index.rst b/docs/autoapi/piel/models/index.rst new file mode 100644 index 00000000..02901f7f --- /dev/null +++ b/docs/autoapi/piel/models/index.rst @@ -0,0 +1,25 @@ +:py:mod:`piel.models` +===================== + +.. py:module:: piel.models + + +Subpackages +----------- +.. toctree:: + :titlesonly: + :maxdepth: 3 + + frequency/index.rst + logic/index.rst + physical/index.rst + transient/index.rst + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + utils/index.rst diff --git a/docs/autoapi/piel/models/logic/electrical/index.rst b/docs/autoapi/piel/models/logic/electrical/index.rst new file mode 100644 index 00000000..fce3722c --- /dev/null +++ b/docs/autoapi/piel/models/logic/electrical/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.logic.electrical` +====================================== + +.. py:module:: piel.models.logic.electrical diff --git a/docs/autoapi/piel/models/logic/electro_optic/index.rst b/docs/autoapi/piel/models/logic/electro_optic/index.rst new file mode 100644 index 00000000..799d50eb --- /dev/null +++ b/docs/autoapi/piel/models/logic/electro_optic/index.rst @@ -0,0 +1,68 @@ +:py:mod:`piel.models.logic.electro_optic` +========================================= + +.. py:module:: piel.models.logic.electro_optic + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + signal_mapping/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.logic.electro_optic.bits_array_from_bits_amount + piel.models.logic.electro_optic.linear_bit_phase_map + piel.models.logic.electro_optic.return_phase_array_from_data_series + + + +.. py:function:: bits_array_from_bits_amount(bits_amount: int) -> numpy.ndarray + + Returns an array of bits from a given amount of bits. + + :param bits_amount: Amount of bits to generate. + :type bits_amount: int + + :returns: Array of bits. + :rtype: bit_array(np.ndarray) + + +.. py:function:: linear_bit_phase_map(bits_amount: int, final_phase_rad: float, initial_phase_rad: float = 0, return_dataframe: bool = True, quantization_error: float = 1e-06) -> dict | pandas.DataFrame + + Returns a linear direct mapping of bits to phase. + + :param bits_amount: Amount of bits to generate. + :type bits_amount: int + :param final_phase_rad: Final phase to map to. + :type final_phase_rad: float + :param initial_phase_rad: Initial phase to map to. + :type initial_phase_rad: float + + :returns: Mapping of bits to phase. + :rtype: bit_phase_mapping(dict) + + +.. py:function:: return_phase_array_from_data_series(data_series: pandas.Series, phase_map: pandas.DataFrame | pandas.Series) -> list + + Returns a list of phases from a given data series and phase map. + # TODO optimise lookup table speed + + :param data_series: Data series to map. + :type data_series: pd.Series + :param phase_map: Phase map to use. + :type phase_map: pd.DataFrame | pd.Series + + :returns: List of phases. + :rtype: phase_array(list) diff --git a/docs/autoapi/piel/models/logic/electro_optic/signal_mapping/index.rst b/docs/autoapi/piel/models/logic/electro_optic/signal_mapping/index.rst new file mode 100644 index 00000000..638ed61e --- /dev/null +++ b/docs/autoapi/piel/models/logic/electro_optic/signal_mapping/index.rst @@ -0,0 +1,80 @@ +:py:mod:`piel.models.logic.electro_optic.signal_mapping` +======================================================== + +.. py:module:: piel.models.logic.electro_optic.signal_mapping + +.. autoapi-nested-parse:: + + In this function we implement different methods of mapping electronic signals to phase. + + One particular implementation of phase mapping would be: + + .. list-table:: Example Basic Phase Mapping + :header-rows: 1 + + * - Bit + - Phase + * - b0 + - :math:`\phi_0 \to 0` + * - b1 + - :math:`\phi_1 \to \pi` + + We can define the two corresponding angles that this would be. + + A more complex implementation of phase mapping can be similar to a DAC mapping: a bitstring within a converter bit-size can map directly to a particular phase space within a particular mapping. + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.logic.electro_optic.signal_mapping.bits_array_from_bits_amount + piel.models.logic.electro_optic.signal_mapping.linear_bit_phase_map + piel.models.logic.electro_optic.signal_mapping.return_phase_array_from_data_series + + + +.. py:function:: bits_array_from_bits_amount(bits_amount: int) -> numpy.ndarray + + Returns an array of bits from a given amount of bits. + + :param bits_amount: Amount of bits to generate. + :type bits_amount: int + + :returns: Array of bits. + :rtype: bit_array(np.ndarray) + + +.. py:function:: linear_bit_phase_map(bits_amount: int, final_phase_rad: float, initial_phase_rad: float = 0, return_dataframe: bool = True, quantization_error: float = 1e-06) -> dict | pandas.DataFrame + + Returns a linear direct mapping of bits to phase. + + :param bits_amount: Amount of bits to generate. + :type bits_amount: int + :param final_phase_rad: Final phase to map to. + :type final_phase_rad: float + :param initial_phase_rad: Initial phase to map to. + :type initial_phase_rad: float + + :returns: Mapping of bits to phase. + :rtype: bit_phase_mapping(dict) + + +.. py:function:: return_phase_array_from_data_series(data_series: pandas.Series, phase_map: pandas.DataFrame | pandas.Series) -> list + + Returns a list of phases from a given data series and phase map. + # TODO optimise lookup table speed + + :param data_series: Data series to map. + :type data_series: pd.Series + :param phase_map: Phase map to use. + :type phase_map: pd.DataFrame | pd.Series + + :returns: List of phases. + :rtype: phase_array(list) diff --git a/docs/autoapi/piel/models/logic/electronic/index.rst b/docs/autoapi/piel/models/logic/electronic/index.rst new file mode 100644 index 00000000..5fe874cd --- /dev/null +++ b/docs/autoapi/piel/models/logic/electronic/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.logic.electronic` +====================================== + +.. py:module:: piel.models.logic.electronic diff --git a/docs/autoapi/piel/models/logic/index.rst b/docs/autoapi/piel/models/logic/index.rst new file mode 100644 index 00000000..673eb1e8 --- /dev/null +++ b/docs/autoapi/piel/models/logic/index.rst @@ -0,0 +1,17 @@ +:py:mod:`piel.models.logic` +=========================== + +.. py:module:: piel.models.logic + + +Subpackages +----------- +.. toctree:: + :titlesonly: + :maxdepth: 3 + + electrical/index.rst + electro_optic/index.rst + electronic/index.rst + opto_electronic/index.rst + photonic/index.rst diff --git a/docs/autoapi/piel/models/logic/opto_electronic/index.rst b/docs/autoapi/piel/models/logic/opto_electronic/index.rst new file mode 100644 index 00000000..b8f9e55e --- /dev/null +++ b/docs/autoapi/piel/models/logic/opto_electronic/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.logic.opto_electronic` +=========================================== + +.. py:module:: piel.models.logic.opto_electronic diff --git a/docs/autoapi/piel/models/logic/photonic/index.rst b/docs/autoapi/piel/models/logic/photonic/index.rst new file mode 100644 index 00000000..576ba33c --- /dev/null +++ b/docs/autoapi/piel/models/logic/photonic/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.logic.photonic` +==================================== + +.. py:module:: piel.models.logic.photonic diff --git a/docs/autoapi/piel/models/physical/electrical/cable/index.rst b/docs/autoapi/piel/models/physical/electrical/cable/index.rst new file mode 100644 index 00000000..14488ede --- /dev/null +++ b/docs/autoapi/piel/models/physical/electrical/cable/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.physical.electrical.cable` +=============================================== + +.. py:module:: piel.models.physical.electrical.cable diff --git a/docs/autoapi/piel/models/physical/electrical/index.rst b/docs/autoapi/piel/models/physical/electrical/index.rst new file mode 100644 index 00000000..90daed94 --- /dev/null +++ b/docs/autoapi/piel/models/physical/electrical/index.rst @@ -0,0 +1,13 @@ +:py:mod:`piel.models.physical.electrical` +========================================= + +.. py:module:: piel.models.physical.electrical + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + cable/index.rst diff --git a/docs/autoapi/piel/models/physical/electro_optic/basic_heater/index.rst b/docs/autoapi/piel/models/physical/electro_optic/basic_heater/index.rst new file mode 100644 index 00000000..d8b0d604 --- /dev/null +++ b/docs/autoapi/piel/models/physical/electro_optic/basic_heater/index.rst @@ -0,0 +1,22 @@ +:py:mod:`piel.models.physical.electro_optic.basic_heater` +========================================================= + +.. py:module:: piel.models.physical.electro_optic.basic_heater + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.electro_optic.basic_heater.basic_heater_spice + + + +.. py:function:: basic_heater_spice() + + This function returns the most basic SPICE model for a heater, that can be closely integrated with circuit solvers accordingly. diff --git a/docs/autoapi/piel/models/physical/electro_optic/index.rst b/docs/autoapi/piel/models/physical/electro_optic/index.rst new file mode 100644 index 00000000..7d81fcd8 --- /dev/null +++ b/docs/autoapi/piel/models/physical/electro_optic/index.rst @@ -0,0 +1,13 @@ +:py:mod:`piel.models.physical.electro_optic` +============================================ + +.. py:module:: piel.models.physical.electro_optic + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + basic_heater/index.rst diff --git a/docs/autoapi/piel/models/physical/electronic/capacitor/index.rst b/docs/autoapi/piel/models/physical/electronic/capacitor/index.rst new file mode 100644 index 00000000..e09c8a2d --- /dev/null +++ b/docs/autoapi/piel/models/physical/electronic/capacitor/index.rst @@ -0,0 +1,51 @@ +:py:mod:`piel.models.physical.electronic.capacitor` +=================================================== + +.. py:module:: piel.models.physical.electronic.capacitor + +.. autoapi-nested-parse:: + + # TODO move and update. + The way each of these models should work is that they use the settings from the `gdsfactory` component, + to create a parametric SPICE directive. + + These functions map a particular model, with an instance representation that corresponds to the given netlist + connectivity, and returns a SPICE representation of the circuit. This function will be called after parsing the + circuit netlist accordingly, and creating a mapping from the instance definitions to the fundamental components. + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.electronic.capacitor.add_basic_capacitor + + + +.. py:function:: add_basic_capacitor(settings) -> str + + This function takes in the settings from a gdsfactory component, some connectivity node translated directly from + the gdsfactory netlist. + + See Mike Smith “WinSpice3 User’s Manual” 25 October, 1999 + + SPICE capacitor model: + + .. code-block:: + + CXXXXXXX N+ N- VALUE + + Where the parameters are: + + .. code-block:: + + N+ = the positive terminal + N- = the negative terminal + VALUE = capacitance in farads + = starting voltage in a simulation diff --git a/docs/autoapi/piel/models/physical/electronic/defaults/index.rst b/docs/autoapi/piel/models/physical/electronic/defaults/index.rst new file mode 100644 index 00000000..bd498b2c --- /dev/null +++ b/docs/autoapi/piel/models/physical/electronic/defaults/index.rst @@ -0,0 +1,28 @@ +:py:mod:`piel.models.physical.electronic.defaults` +================================================== + +.. py:module:: piel.models.physical.electronic.defaults + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.electronic.defaults.get_default_models + + + +.. py:function:: get_default_models(custom_defaults: dict | None = None) -> dict + + Returns the default models dictionary. + + :param custom_defaults: Custom defaults dictionary. + :type custom_defaults: dict + + :returns: Default models dictionary. + :rtype: dict diff --git a/docs/autoapi/piel/models/physical/electronic/index.rst b/docs/autoapi/piel/models/physical/electronic/index.rst new file mode 100644 index 00000000..f4b61b4b --- /dev/null +++ b/docs/autoapi/piel/models/physical/electronic/index.rst @@ -0,0 +1,67 @@ +:py:mod:`piel.models.physical.electronic` +========================================= + +.. py:module:: piel.models.physical.electronic + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + capacitor/index.rst + defaults/index.rst + resistor/index.rst + straight/index.rst + taper/index.rst + via_stack/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.electronic.add_basic_capacitor + piel.models.physical.electronic.get_default_models + + + +.. py:function:: add_basic_capacitor(settings) -> str + + This function takes in the settings from a gdsfactory component, some connectivity node translated directly from + the gdsfactory netlist. + + See Mike Smith “WinSpice3 User’s Manual” 25 October, 1999 + + SPICE capacitor model: + + .. code-block:: + + CXXXXXXX N+ N- VALUE + + Where the parameters are: + + .. code-block:: + + N+ = the positive terminal + N- = the negative terminal + VALUE = capacitance in farads + = starting voltage in a simulation + + + +.. py:function:: get_default_models(custom_defaults: dict | None = None) -> dict + + Returns the default models dictionary. + + :param custom_defaults: Custom defaults dictionary. + :type custom_defaults: dict + + :returns: Default models dictionary. + :rtype: dict diff --git a/docs/autoapi/piel/models/physical/electronic/resistor/index.rst b/docs/autoapi/piel/models/physical/electronic/resistor/index.rst new file mode 100644 index 00000000..9ba99a84 --- /dev/null +++ b/docs/autoapi/piel/models/physical/electronic/resistor/index.rst @@ -0,0 +1,33 @@ +:py:mod:`piel.models.physical.electronic.resistor` +================================================== + +.. py:module:: piel.models.physical.electronic.resistor + +.. autoapi-nested-parse:: + + SPICE Resistor Structure + + See Mike Smith “WinSpice3 User’s Manual” 25 October, 1999 + + .. code-block:: spice + + RXXXXXXX N1 N2 + + Where the terminals are: + + .. code-block:: + + N1 = the first terminal + N2 = the second terminal + = resistance in ohms. + = name of the model used (useful for semiconductor resistors) + = length of the resistor (useful for semiconductor resistors) + = width of the resistor (useful for semiconductor resistors) + = temperature of the resistor in Kelvin (useful in noise analysis and + semiconductor resistors) + + An example is: + + .. code-block:: + + RHOT n1 n2 10k TEMP=500 diff --git a/docs/autoapi/piel/models/physical/electronic/straight/index.rst b/docs/autoapi/piel/models/physical/electronic/straight/index.rst new file mode 100644 index 00000000..68653984 --- /dev/null +++ b/docs/autoapi/piel/models/physical/electronic/straight/index.rst @@ -0,0 +1,36 @@ +:py:mod:`piel.models.physical.electronic.straight` +================================================== + +.. py:module:: piel.models.physical.electronic.straight + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.electronic.straight.StraightParameters + + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.electronic.straight.straight + + + +.. py:class:: StraightParameters + + + These are all the potential parametric configuration variables + + +.. py:function:: straight(params: StraightParameters) -> hdl21.Module + + Implements a `hdl21` taper resistor class. diff --git a/docs/autoapi/piel/models/physical/electronic/taper/index.rst b/docs/autoapi/piel/models/physical/electronic/taper/index.rst new file mode 100644 index 00000000..6d579892 --- /dev/null +++ b/docs/autoapi/piel/models/physical/electronic/taper/index.rst @@ -0,0 +1,34 @@ +:py:mod:`piel.models.physical.electronic.taper` +=============================================== + +.. py:module:: piel.models.physical.electronic.taper + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.electronic.taper.TaperParameters + + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.electronic.taper.taper + + + +.. py:class:: TaperParameters + + + +.. py:function:: taper(params: TaperParameters) -> hdl21.Module + + Implements a `hdl21` taper resistor class. We need to include the mapping ports as we expect our gdsfactory component to be with the instance of the model. diff --git a/docs/autoapi/piel/models/physical/electronic/via_stack/index.rst b/docs/autoapi/piel/models/physical/electronic/via_stack/index.rst new file mode 100644 index 00000000..5f9cf67a --- /dev/null +++ b/docs/autoapi/piel/models/physical/electronic/via_stack/index.rst @@ -0,0 +1,34 @@ +:py:mod:`piel.models.physical.electronic.via_stack` +=================================================== + +.. py:module:: piel.models.physical.electronic.via_stack + + +Module Contents +--------------- + +Classes +~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.electronic.via_stack.ViaStackParameters + + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.electronic.via_stack.via_stack + + + +.. py:class:: ViaStackParameters + + + +.. py:function:: via_stack(params: ViaStackParameters) -> hdl21.Module + + Implements a `hdl21` taper resistor class. We need to include the mapping ports as we expect our gdsfactory component to be with the instance of the model. diff --git a/docs/autoapi/piel/models/physical/geometry/index.rst b/docs/autoapi/piel/models/physical/geometry/index.rst new file mode 100644 index 00000000..55025870 --- /dev/null +++ b/docs/autoapi/piel/models/physical/geometry/index.rst @@ -0,0 +1,28 @@ +:py:mod:`piel.models.physical.geometry` +======================================= + +.. py:module:: piel.models.physical.geometry + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.geometry.calculate_cross_sectional_area_m2 + + + +.. py:function:: calculate_cross_sectional_area_m2(diameter_m: float) -> float + + Calculates the cross sectional area of a circle in meters squared. + + :param diameter_m: Diameter of the circle in meters. + :type diameter_m: float + + :returns: Cross sectional area in meters squared. + :rtype: float diff --git a/docs/autoapi/piel/models/physical/index.rst b/docs/autoapi/piel/models/physical/index.rst new file mode 100644 index 00000000..dbf3a9ef --- /dev/null +++ b/docs/autoapi/piel/models/physical/index.rst @@ -0,0 +1,66 @@ +:py:mod:`piel.models.physical` +============================== + +.. py:module:: piel.models.physical + + +Subpackages +----------- +.. toctree:: + :titlesonly: + :maxdepth: 3 + + electrical/index.rst + electro_optic/index.rst + electronic/index.rst + opto_electronic/index.rst + photonic/index.rst + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + geometry/index.rst + thermal/index.rst + units/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.calculate_cross_sectional_area_m2 + piel.models.physical.convert_awg_to_m2 + + + +.. py:function:: calculate_cross_sectional_area_m2(diameter_m: float) -> float + + Calculates the cross sectional area of a circle in meters squared. + + :param diameter_m: Diameter of the circle in meters. + :type diameter_m: float + + :returns: Cross sectional area in meters squared. + :rtype: float + + +.. py:function:: convert_awg_to_m2(awg: int) -> float + + Converts an AWG value to meters squared. + + Reference: https://en.wikipedia.org/wiki/American_wire_gauge + + :param awg: AWG value. + :type awg: ing + + :returns: Cross sectional area in meters squared. + :rtype: float diff --git a/docs/autoapi/piel/models/physical/opto_electronic/index.rst b/docs/autoapi/piel/models/physical/opto_electronic/index.rst new file mode 100644 index 00000000..98714753 --- /dev/null +++ b/docs/autoapi/piel/models/physical/opto_electronic/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.physical.opto_electronic` +============================================== + +.. py:module:: piel.models.physical.opto_electronic diff --git a/docs/autoapi/piel/models/physical/photonic/index.rst b/docs/autoapi/piel/models/physical/photonic/index.rst new file mode 100644 index 00000000..6d9dbf87 --- /dev/null +++ b/docs/autoapi/piel/models/physical/photonic/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.physical.photonic` +======================================= + +.. py:module:: piel.models.physical.photonic diff --git a/docs/autoapi/piel/models/physical/thermal/index.rst b/docs/autoapi/piel/models/physical/thermal/index.rst new file mode 100644 index 00000000..fdaf5438 --- /dev/null +++ b/docs/autoapi/piel/models/physical/thermal/index.rst @@ -0,0 +1,20 @@ +:py:mod:`piel.models.physical.thermal` +====================================== + +.. py:module:: piel.models.physical.thermal + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.thermal.heat_transfer_1d_W + + + +.. py:function:: heat_transfer_1d_W(thermal_conductivity_fit, temperature_range_K, cross_sectional_area_m2, length_m) -> float diff --git a/docs/autoapi/piel/models/physical/units/index.rst b/docs/autoapi/piel/models/physical/units/index.rst new file mode 100644 index 00000000..0a2c2805 --- /dev/null +++ b/docs/autoapi/piel/models/physical/units/index.rst @@ -0,0 +1,30 @@ +:py:mod:`piel.models.physical.units` +==================================== + +.. py:module:: piel.models.physical.units + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.models.physical.units.convert_awg_to_m2 + + + +.. py:function:: convert_awg_to_m2(awg: int) -> float + + Converts an AWG value to meters squared. + + Reference: https://en.wikipedia.org/wiki/American_wire_gauge + + :param awg: AWG value. + :type awg: ing + + :returns: Cross sectional area in meters squared. + :rtype: float diff --git a/docs/autoapi/piel/models/transient/electrical/index.rst b/docs/autoapi/piel/models/transient/electrical/index.rst new file mode 100644 index 00000000..99b07461 --- /dev/null +++ b/docs/autoapi/piel/models/transient/electrical/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.transient.electrical` +========================================== + +.. py:module:: piel.models.transient.electrical diff --git a/docs/autoapi/piel/models/transient/electro_optic/index.rst b/docs/autoapi/piel/models/transient/electro_optic/index.rst new file mode 100644 index 00000000..9fc84c00 --- /dev/null +++ b/docs/autoapi/piel/models/transient/electro_optic/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.transient.electro_optic` +============================================= + +.. py:module:: piel.models.transient.electro_optic diff --git a/docs/autoapi/piel/models/transient/electronic/index.rst b/docs/autoapi/piel/models/transient/electronic/index.rst new file mode 100644 index 00000000..ea897279 --- /dev/null +++ b/docs/autoapi/piel/models/transient/electronic/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.transient.electronic` +========================================== + +.. py:module:: piel.models.transient.electronic diff --git a/docs/autoapi/piel/models/transient/index.rst b/docs/autoapi/piel/models/transient/index.rst new file mode 100644 index 00000000..3fdfb58c --- /dev/null +++ b/docs/autoapi/piel/models/transient/index.rst @@ -0,0 +1,17 @@ +:py:mod:`piel.models.transient` +=============================== + +.. py:module:: piel.models.transient + + +Subpackages +----------- +.. toctree:: + :titlesonly: + :maxdepth: 3 + + electrical/index.rst + electro_optic/index.rst + electronic/index.rst + opto_electronic/index.rst + photonic/index.rst diff --git a/docs/autoapi/piel/models/transient/opto_electronic/index.rst b/docs/autoapi/piel/models/transient/opto_electronic/index.rst new file mode 100644 index 00000000..cae56d94 --- /dev/null +++ b/docs/autoapi/piel/models/transient/opto_electronic/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.transient.opto_electronic` +=============================================== + +.. py:module:: piel.models.transient.opto_electronic diff --git a/docs/autoapi/piel/models/transient/photonic/index.rst b/docs/autoapi/piel/models/transient/photonic/index.rst new file mode 100644 index 00000000..5bed85a6 --- /dev/null +++ b/docs/autoapi/piel/models/transient/photonic/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.transient.photonic` +======================================== + +.. py:module:: piel.models.transient.photonic diff --git a/docs/autoapi/piel/models/utils/index.rst b/docs/autoapi/piel/models/utils/index.rst new file mode 100644 index 00000000..0a73a516 --- /dev/null +++ b/docs/autoapi/piel/models/utils/index.rst @@ -0,0 +1,4 @@ +:py:mod:`piel.models.utils` +=========================== + +.. py:module:: piel.models.utils diff --git a/docs/autoapi/piel/parametric/index.rst b/docs/autoapi/piel/parametric/index.rst new file mode 100644 index 00000000..7aadddd1 --- /dev/null +++ b/docs/autoapi/piel/parametric/index.rst @@ -0,0 +1,66 @@ +:py:mod:`piel.parametric` +========================= + +.. py:module:: piel.parametric + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.parametric.single_parameter_sweep + piel.parametric.multi_parameter_sweep + + + +.. py:function:: single_parameter_sweep(base_design_configuration: dict, parameter_name: str, parameter_sweep_values: list) + + This function takes a base_design_configuration dictionary and sweeps a single parameter over a list of values. It returns a list of dictionaries that correspond to the parameter sweep. + + :param base_design_configuration: Base design configuration dictionary. + :type base_design_configuration: dict + :param parameter_name: Name of parameter to sweep. + :type parameter_name: str + :param parameter_sweep_values: List of values to sweep. + :type parameter_sweep_values: list + + :returns: List of dictionaries that correspond to the parameter sweep. + :rtype: parameter_sweep_design_dictionary_array(list) + + +.. py:function:: multi_parameter_sweep(base_design_configuration: dict, parameter_sweep_dictionary: dict) -> list + + This multiparameter sweep is pretty cool, as it will generate designer list of dictionaries that comprise of all the possible combinations of your parameter sweeps. For example, if you are sweeping `parameter_1 = np.arange(0, 2) = array([0, 1])`, and `parameter_2 = np.arange(2, 4) = array([2, 3])`, then this function will generate list of dictionaries based on the default_design dictionary, but that will comprise of all the potential parameter combinations within this list. + + For the example above, there arould be 4 combinations [(0, 2), (0, 3), (1, 2), (1, 3)]. + + If you were instead sweeping for `parameter_1 = np.arange(0, 5)` and `parameter_2 = np.arange(0, 5)`, the dictionary generated would correspond to these parameter combinations of:: + [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)]. + + Make sure to use the parameter_names from default_design when writing up the parameter_sweep dictionary key name. + + Example project_structure formats:: + + example_parameter_sweep_dictionary = { + "parameter_1": np.arange(1, -40, 1), + "parameter_2": np.arange(1, -40, 1), + } + + example_base_design_configuration = { + "parameter_1": 10.0, + "parameter_2": 40.0, + "parameter_3": 0, + } + + :param base_design_configuration: Dictionary of the default design configuration. + :type base_design_configuration: dict + :param parameter_sweep_dictionary: Dictionary of the parameter sweep. The keys should be the same as the keys in the base_design_configuration dictionary. + :type parameter_sweep_dictionary: dict + + :returns: List of dictionaries that comprise of all the possible combinations of your parameter sweeps. + :rtype: parameter_sweep_design_dictionary_array(list) diff --git a/docs/autoapi/piel/project_structure/index.rst b/docs/autoapi/piel/project_structure/index.rst new file mode 100644 index 00000000..08a25c02 --- /dev/null +++ b/docs/autoapi/piel/project_structure/index.rst @@ -0,0 +1,44 @@ +:py:mod:`piel.project_structure` +================================ + +.. py:module:: piel.project_structure + +.. autoapi-nested-parse:: + + This file allows us to automate several aspects of creating a fully compatible project structure. + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.project_structure.read_configuration + piel.project_structure.create_setup_py_from_config_json + + + +.. py:function:: read_configuration(design_directory: piel.config.piel_path_types) -> dict + + This function reads the configuration file found in the design directory. + + :param design_directory: Design directory PATH. + :type design_directory: piel_path_types + + :returns: Configuration dictionary. + :rtype: config_dictionary(dict) + + +.. py:function:: create_setup_py_from_config_json(design_directory: piel.config.piel_path_types) -> None + + This function creates a setup.py file from the config.json file found in the design directory. + + :param design_directory: Design directory PATH or module name. + :type design_directory: piel_path_types + + :returns: None diff --git a/docs/autoapi/piel/tools/cocotb/core/index.rst b/docs/autoapi/piel/tools/cocotb/core/index.rst new file mode 100644 index 00000000..e4d03e46 --- /dev/null +++ b/docs/autoapi/piel/tools/cocotb/core/index.rst @@ -0,0 +1,118 @@ +:py:mod:`piel.tools.cocotb.core` +================================ + +.. py:module:: piel.tools.cocotb.core + +.. autoapi-nested-parse:: + + The objective of this file is to provide the simulation ports and interconnection to consider modelling digital and mixed signal logic. + + The main simulation driver is cocotb, and this generates a set of files that correspond to time-domain digital + simulations. The cocotb verification software can also be used to perform mixed signal simulation, and digital data + can be inputted as a bitstream into a photonic solver, although the ideal situation would be to have integrated + photonic time-domain models alongside the electronic simulation solver, and maybe this is where it will go. It can be + assumed that, as is currently, cocotb can interface python with multiple solvers until someone (and I'd love to do + this) writes an equivalent python-based or C++ based python time-domain simulation solver. + + The nice thing about cocotb is that as long as the photonic simulations can be written asynchronously, time-domain + simulations can be closely integrated or simulated through this verification software. + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.cocotb.core.check_cocotb_testbench_exists + piel.tools.cocotb.core.configure_cocotb_simulation + piel.tools.cocotb.core.run_cocotb_simulation + + + +Attributes +~~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.cocotb.core.delete_simulation_output_files + + +.. py:function:: check_cocotb_testbench_exists(design_directory: str | pathlib.Path) -> bool + + Checks if a cocotb testbench exists in the design directory. + + :param design_directory: Design directory. + :type design_directory: str | pathlib.Path + + :returns: True if cocotb testbench exists. + :rtype: cocotb_testbench_exists(bool) + + +.. py:function:: configure_cocotb_simulation(design_directory: str | pathlib.Path, simulator: Literal[icarus, verilator], top_level_language: Literal[verilog, vhdl], top_level_verilog_module: str, test_python_module: str, design_sources_list: list | None = None) + + Writes a cocotb makefile. + + If no design_sources_list is provided then it adds all the design sources under the `src` folder. + + In the form + .. code-block:: + + #!/bin/sh + # Makefile + # defaults + SIM ?= icarus + TOPLEVEL_LANG ?= verilog + + # Note we need to include the test script to the PYTHONPATH + export PYTHONPATH = + + VERILOG_SOURCES += $(PWD)/my_design.sv + # use VHDL_SOURCES for VHDL files + + # TOPLEVEL is the name of the toplevel module in your Verilog or VHDL file + TOPLEVEL := my_design + + # MODULE is the basename of the Python test file + MODULE := test_my_design + + # include cocotb's make rules to take care of the simulator setup + include $(shell cocotb-config --makefiles)/Makefile.sim + + + :param design_directory: The directory where the design is located. + :type design_directory: str | pathlib.Path + :param simulator: The simulator to use. + :type simulator: Literal["icarus", "verilator"] + :param top_level_language: The top level language. + :type top_level_language: Literal["verilog", "vhdl"] + :param top_level_verilog_module: The top level verilog module. + :type top_level_verilog_module: str + :param test_python_module: The test python module. + :type test_python_module: str + :param design_sources_list: A list of design sources. Defaults to None. + :type design_sources_list: list | None, optional + + :returns: None + + +.. py:data:: delete_simulation_output_files + + + +.. py:function:: run_cocotb_simulation(design_directory: str) -> subprocess.CompletedProcess + + Equivalent to running the cocotb makefile + .. code-block:: + + make + + :param design_directory: The directory where the design is located. + :type design_directory: str + + :returns: The subprocess.CompletedProcess object. + :rtype: subprocess.CompletedProcess diff --git a/docs/autoapi/piel/tools/cocotb/data/index.rst b/docs/autoapi/piel/tools/cocotb/data/index.rst new file mode 100644 index 00000000..909b942d --- /dev/null +++ b/docs/autoapi/piel/tools/cocotb/data/index.rst @@ -0,0 +1,61 @@ +:py:mod:`piel.tools.cocotb.data` +================================ + +.. py:module:: piel.tools.cocotb.data + +.. autoapi-nested-parse:: + + This file contains a range of functions used to read, plot and analyse cocotb simulations in a data-flow standard as suggested + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.cocotb.data.get_simulation_output_files_from_design + piel.tools.cocotb.data.read_simulation_data + piel.tools.cocotb.data.simple_plot_simulation_data + + + +Attributes +~~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.cocotb.data.get_simulation_output_files + + +.. py:data:: get_simulation_output_files + + + +.. py:function:: get_simulation_output_files_from_design(design_directory: piel.config.piel_path_types, extension: str = 'csv') + + This function returns a list of all the simulation output files in the design directory. + + :param design_directory: The path to the design directory. + :type design_directory: piel_path_types + + :returns: List of all the simulation output files in the design directory. + :rtype: output_files (list) + + +.. py:function:: read_simulation_data(file_path: piel.config.piel_path_types) + + This function returns a Pandas dataframe that contains all the simulation data outputted from the simulation run. + + :param file_path: The path to the simulation data file. + :type file_path: piel_path_types + + :returns: The simulation data in a Pandas dataframe. + :rtype: simulation_data (pd.DataFrame) + + +.. py:function:: simple_plot_simulation_data(simulation_data: pandas.DataFrame) diff --git a/docs/autoapi/piel/tools/cocotb/index.rst b/docs/autoapi/piel/tools/cocotb/index.rst new file mode 100644 index 00000000..c8bd82b5 --- /dev/null +++ b/docs/autoapi/piel/tools/cocotb/index.rst @@ -0,0 +1,146 @@ +:py:mod:`piel.tools.cocotb` +=========================== + +.. py:module:: piel.tools.cocotb + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + core/index.rst + data/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.cocotb.check_cocotb_testbench_exists + piel.tools.cocotb.configure_cocotb_simulation + piel.tools.cocotb.run_cocotb_simulation + piel.tools.cocotb.get_simulation_output_files_from_design + piel.tools.cocotb.read_simulation_data + piel.tools.cocotb.simple_plot_simulation_data + + + +Attributes +~~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.cocotb.delete_simulation_output_files + piel.tools.cocotb.get_simulation_output_files + + +.. py:function:: check_cocotb_testbench_exists(design_directory: str | pathlib.Path) -> bool + + Checks if a cocotb testbench exists in the design directory. + + :param design_directory: Design directory. + :type design_directory: str | pathlib.Path + + :returns: True if cocotb testbench exists. + :rtype: cocotb_testbench_exists(bool) + + +.. py:function:: configure_cocotb_simulation(design_directory: str | pathlib.Path, simulator: Literal[icarus, verilator], top_level_language: Literal[verilog, vhdl], top_level_verilog_module: str, test_python_module: str, design_sources_list: list | None = None) + + Writes a cocotb makefile. + + If no design_sources_list is provided then it adds all the design sources under the `src` folder. + + In the form + .. code-block:: + + #!/bin/sh + # Makefile + # defaults + SIM ?= icarus + TOPLEVEL_LANG ?= verilog + + # Note we need to include the test script to the PYTHONPATH + export PYTHONPATH = + + VERILOG_SOURCES += $(PWD)/my_design.sv + # use VHDL_SOURCES for VHDL files + + # TOPLEVEL is the name of the toplevel module in your Verilog or VHDL file + TOPLEVEL := my_design + + # MODULE is the basename of the Python test file + MODULE := test_my_design + + # include cocotb's make rules to take care of the simulator setup + include $(shell cocotb-config --makefiles)/Makefile.sim + + + :param design_directory: The directory where the design is located. + :type design_directory: str | pathlib.Path + :param simulator: The simulator to use. + :type simulator: Literal["icarus", "verilator"] + :param top_level_language: The top level language. + :type top_level_language: Literal["verilog", "vhdl"] + :param top_level_verilog_module: The top level verilog module. + :type top_level_verilog_module: str + :param test_python_module: The test python module. + :type test_python_module: str + :param design_sources_list: A list of design sources. Defaults to None. + :type design_sources_list: list | None, optional + + :returns: None + + +.. py:data:: delete_simulation_output_files + + + +.. py:function:: run_cocotb_simulation(design_directory: str) -> subprocess.CompletedProcess + + Equivalent to running the cocotb makefile + .. code-block:: + + make + + :param design_directory: The directory where the design is located. + :type design_directory: str + + :returns: The subprocess.CompletedProcess object. + :rtype: subprocess.CompletedProcess + + +.. py:data:: get_simulation_output_files + + + +.. py:function:: get_simulation_output_files_from_design(design_directory: piel.config.piel_path_types, extension: str = 'csv') + + This function returns a list of all the simulation output files in the design directory. + + :param design_directory: The path to the design directory. + :type design_directory: piel_path_types + + :returns: List of all the simulation output files in the design directory. + :rtype: output_files (list) + + +.. py:function:: read_simulation_data(file_path: piel.config.piel_path_types) + + This function returns a Pandas dataframe that contains all the simulation data outputted from the simulation run. + + :param file_path: The path to the simulation data file. + :type file_path: piel_path_types + + :returns: The simulation data in a Pandas dataframe. + :rtype: simulation_data (pd.DataFrame) + + +.. py:function:: simple_plot_simulation_data(simulation_data: pandas.DataFrame) diff --git a/docs/autoapi/piel/tools/gdsfactory/index.rst b/docs/autoapi/piel/tools/gdsfactory/index.rst new file mode 100644 index 00000000..3f96a870 --- /dev/null +++ b/docs/autoapi/piel/tools/gdsfactory/index.rst @@ -0,0 +1,100 @@ +:py:mod:`piel.tools.gdsfactory` +=============================== + +.. py:module:: piel.tools.gdsfactory + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + netlist/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.gdsfactory.get_input_ports_index + piel.tools.gdsfactory.get_matched_ports_tuple_index + + + +.. py:function:: get_input_ports_index(ports_index: dict, sorting_algorithm: Literal[get_input_ports_index.prefix] = 'prefix', prefix: str = 'in') -> tuple + + This function returns the input ports of a component. However, input ports may have different sets of prefixes and suffixes. This function implements different sorting algorithms for different ports names. The default algorithm is `prefix`, which sorts the ports by their prefix. The Endianness implementation means that the tuple order is determined according to the last numerical index order of the port numbering. + + .. code-block:: python + + raw_ports_index = { + "in_o_0": 0, + "out_o_0": 1, + "out_o_1": 2, + "out_o_2": 3, + "out_o_3": 4, + "in_o_1": 5, + "in_o_2": 6, + "in_o_3": 7, + } + + get_input_ports_index(ports_index=raw_ports_index) + + # Output + ((0, "in_o_0"), (5, "in_o_1"), (6, "in_o_2"), (7, "in_o_3")) + + :param ports_index: The ports index dictionary. + :type ports_index: dict + :param sorting_algorithm: The sorting algorithm to use. Defaults to "prefix". + :type sorting_algorithm: Literal["prefix"], optional + :param prefix: The prefix to use for the sorting algorithm. Defaults to "in". + :type prefix: str, optional + + :returns: The ordered input ports index tuple. + :rtype: tuple + + +.. py:function:: get_matched_ports_tuple_index(ports_index: dict, selected_ports_tuple: Optional[tuple] = None, sorting_algorithm: Literal[get_matched_ports_tuple_index.prefix, selected_ports] = 'prefix', prefix: str = 'in') -> (tuple, tuple) + + This function returns the input ports of a component. However, input ports may have different sets of prefixes + and suffixes. This function implements different sorting algorithms for different ports names. The default + algorithm is `prefix`, which sorts the ports by their prefix. The Endianness implementation means that the tuple + order is determined according to the last numerical index order of the port numbering. Returns just a tuple of + the index. + + .. code-block:: python + + raw_ports_index = { + "in_o_0": 0, + "out_o_0": 1, + "out_o_1": 2, + "out_o_2": 3, + "out_o_3": 4, + "in_o_1": 5, + "in_o_2": 6, + "in_o_3": 7, + } + + get_input_ports_tuple_index(ports_index=raw_ports_index) + + # Output + (0, 5, 6, 7) + + :param ports_index: The ports index dictionary. + :type ports_index: dict + :param selected_ports_tuple: The selected ports tuple. Defaults to None. + :type selected_ports_tuple: tuple, optional + :param sorting_algorithm: The sorting algorithm to use. Defaults to "prefix". + :type sorting_algorithm: Literal["prefix"], optional + :param prefix: The prefix to use for the sorting algorithm. Defaults to "in". + :type prefix: str, optional + + :returns: The ordered input ports index tuple. + matched_ports_name_tuple_order(tuple): The ordered input ports name tuple. + :rtype: matches_ports_index_tuple_order(tuple) diff --git a/docs/autoapi/piel/tools/gdsfactory/netlist/index.rst b/docs/autoapi/piel/tools/gdsfactory/netlist/index.rst new file mode 100644 index 00000000..5bcc12c0 --- /dev/null +++ b/docs/autoapi/piel/tools/gdsfactory/netlist/index.rst @@ -0,0 +1,91 @@ +:py:mod:`piel.tools.gdsfactory.netlist` +======================================= + +.. py:module:: piel.tools.gdsfactory.netlist + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.gdsfactory.netlist.get_matched_ports_tuple_index + piel.tools.gdsfactory.netlist.get_input_ports_index + + + +.. py:function:: get_matched_ports_tuple_index(ports_index: dict, selected_ports_tuple: Optional[tuple] = None, sorting_algorithm: Literal[get_matched_ports_tuple_index.prefix, selected_ports] = 'prefix', prefix: str = 'in') -> (tuple, tuple) + + This function returns the input ports of a component. However, input ports may have different sets of prefixes + and suffixes. This function implements different sorting algorithms for different ports names. The default + algorithm is `prefix`, which sorts the ports by their prefix. The Endianness implementation means that the tuple + order is determined according to the last numerical index order of the port numbering. Returns just a tuple of + the index. + + .. code-block:: python + + raw_ports_index = { + "in_o_0": 0, + "out_o_0": 1, + "out_o_1": 2, + "out_o_2": 3, + "out_o_3": 4, + "in_o_1": 5, + "in_o_2": 6, + "in_o_3": 7, + } + + get_input_ports_tuple_index(ports_index=raw_ports_index) + + # Output + (0, 5, 6, 7) + + :param ports_index: The ports index dictionary. + :type ports_index: dict + :param selected_ports_tuple: The selected ports tuple. Defaults to None. + :type selected_ports_tuple: tuple, optional + :param sorting_algorithm: The sorting algorithm to use. Defaults to "prefix". + :type sorting_algorithm: Literal["prefix"], optional + :param prefix: The prefix to use for the sorting algorithm. Defaults to "in". + :type prefix: str, optional + + :returns: The ordered input ports index tuple. + matched_ports_name_tuple_order(tuple): The ordered input ports name tuple. + :rtype: matches_ports_index_tuple_order(tuple) + + +.. py:function:: get_input_ports_index(ports_index: dict, sorting_algorithm: Literal[get_input_ports_index.prefix] = 'prefix', prefix: str = 'in') -> tuple + + This function returns the input ports of a component. However, input ports may have different sets of prefixes and suffixes. This function implements different sorting algorithms for different ports names. The default algorithm is `prefix`, which sorts the ports by their prefix. The Endianness implementation means that the tuple order is determined according to the last numerical index order of the port numbering. + + .. code-block:: python + + raw_ports_index = { + "in_o_0": 0, + "out_o_0": 1, + "out_o_1": 2, + "out_o_2": 3, + "out_o_3": 4, + "in_o_1": 5, + "in_o_2": 6, + "in_o_3": 7, + } + + get_input_ports_index(ports_index=raw_ports_index) + + # Output + ((0, "in_o_0"), (5, "in_o_1"), (6, "in_o_2"), (7, "in_o_3")) + + :param ports_index: The ports index dictionary. + :type ports_index: dict + :param sorting_algorithm: The sorting algorithm to use. Defaults to "prefix". + :type sorting_algorithm: Literal["prefix"], optional + :param prefix: The prefix to use for the sorting algorithm. Defaults to "in". + :type prefix: str, optional + + :returns: The ordered input ports index tuple. + :rtype: tuple diff --git a/docs/autoapi/piel/tools/hdl21/circuit/index.rst b/docs/autoapi/piel/tools/hdl21/circuit/index.rst new file mode 100644 index 00000000..675b71a8 --- /dev/null +++ b/docs/autoapi/piel/tools/hdl21/circuit/index.rst @@ -0,0 +1,22 @@ +:py:mod:`piel.tools.hdl21.circuit` +================================== + +.. py:module:: piel.tools.hdl21.circuit + +.. autoapi-nested-parse:: + + The way the construction of the SPICE models is implemented in ``piel`` is also microservice-esque. Larger + circuits are constructed out of smaller building blocks. This means that simulation configurations and so on are + constructed upon a provided initial circuit, and the SPICE directives are appended accordingly. + + As mentioned previously, ``piel`` creates circuits based on fundamental SPICE because this opens the possibility to + large scale integration of these circuit models on different SPICE solvers, including proprietary ones as long as the + SPICE circuit can be written to particular directories. However, due to the ease of circuit integration, + and translation that ``hdl21`` provides, it's API can also be used to implement parametrised functionality, + although it is easy to export the circuit as a raw SPICE directive after composition. + + This composition tends to be implemented in a `SubCircuit` hierarchical implementation, as this allows for more modularisation of the netlisted devices. + + Let's assume that we can get an extracted SPICE netlist of our circuit, that includes all nodes, and component + circuit definitions. This could then be simulated accordingly for the whole circuit between inputs and outputs. This + would have to be constructed out of component models and a provided netlist in a similar fashion to ``SAX``. diff --git a/docs/autoapi/piel/tools/hdl21/index.rst b/docs/autoapi/piel/tools/hdl21/index.rst new file mode 100644 index 00000000..880a9c0e --- /dev/null +++ b/docs/autoapi/piel/tools/hdl21/index.rst @@ -0,0 +1,33 @@ +:py:mod:`piel.tools.hdl21` +========================== + +.. py:module:: piel.tools.hdl21 + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + circuit/index.rst + simulator/index.rst + units/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.hdl21.convert_numeric_to_prefix + + + +.. py:function:: convert_numeric_to_prefix(value: float) + + This function converts a numeric value to a number under a SPICE unit closest to the base prefix. This allows us to connect a particular number real output, into a term that can be used in a SPICE netlist. diff --git a/docs/autoapi/piel/tools/hdl21/simulator/index.rst b/docs/autoapi/piel/tools/hdl21/simulator/index.rst new file mode 100644 index 00000000..1f44d9e7 --- /dev/null +++ b/docs/autoapi/piel/tools/hdl21/simulator/index.rst @@ -0,0 +1,22 @@ +:py:mod:`piel.tools.hdl21.simulator` +==================================== + +.. py:module:: piel.tools.hdl21.simulator + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.hdl21.simulator.configure_transient_simulation + + + +.. py:function:: configure_transient_simulation(circuit: hdl21.Module, stop_time_s: float, step_time_s: float) + + This function configures the transient simulation for the circuit. diff --git a/docs/autoapi/piel/tools/hdl21/units/index.rst b/docs/autoapi/piel/tools/hdl21/units/index.rst new file mode 100644 index 00000000..742dbb7d --- /dev/null +++ b/docs/autoapi/piel/tools/hdl21/units/index.rst @@ -0,0 +1,39 @@ +:py:mod:`piel.tools.hdl21.units` +================================ + +.. py:module:: piel.tools.hdl21.units + +.. autoapi-nested-parse:: + + These are the corresponding prefixes from `hdl21`: + + f = FEMTO = Prefix.FEMTO + p = PICO = Prefix.PICO + n = NANO = Prefix.NANO + µ = u = MICRO = Prefix.MICRO # Note both `u` and `µ` are valid + m = MILLI = Prefix.MILLI + K = KILO = Prefix.KILO + M = MEGA = Prefix.MEGA + G = GIGA = Prefix.GIGA + T = TERA = Prefix.TERA + P = PETA = Prefix.PETA + UNIT = Prefix.UNIT + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.hdl21.units.convert_numeric_to_prefix + + + +.. py:function:: convert_numeric_to_prefix(value: float) + + This function converts a numeric value to a number under a SPICE unit closest to the base prefix. This allows us to connect a particular number real output, into a term that can be used in a SPICE netlist. diff --git a/docs/autoapi/piel/tools/index.rst b/docs/autoapi/piel/tools/index.rst new file mode 100644 index 00000000..604540bc --- /dev/null +++ b/docs/autoapi/piel/tools/index.rst @@ -0,0 +1,797 @@ +:py:mod:`piel.tools` +==================== + +.. py:module:: piel.tools + + +Subpackages +----------- +.. toctree:: + :titlesonly: + :maxdepth: 3 + + cocotb/index.rst + gdsfactory/index.rst + hdl21/index.rst + openlane/index.rst + sax/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.check_cocotb_testbench_exists + piel.tools.configure_cocotb_simulation + piel.tools.run_cocotb_simulation + piel.tools.get_simulation_output_files_from_design + piel.tools.read_simulation_data + piel.tools.simple_plot_simulation_data + piel.tools.get_input_ports_index + piel.tools.get_matched_ports_tuple_index + piel.tools.get_design_from_openlane_migration + piel.tools.find_design_run + piel.tools.check_config_json_exists_openlane_v1 + piel.tools.check_design_exists_openlane_v1 + piel.tools.configure_and_run_design_openlane_v1 + piel.tools.configure_parametric_designs_openlane_v1 + piel.tools.configure_flow_script_openlane_v1 + piel.tools.create_parametric_designs_openlane_v1 + piel.tools.get_design_directory_from_root_openlane_v1 + piel.tools.get_latest_version_root_openlane_v1 + piel.tools.read_configuration_openlane_v1 + piel.tools.write_configuration_openlane_v1 + piel.tools.filter_timing_sta_files + piel.tools.filter_power_sta_files + piel.tools.get_all_timing_sta_files + piel.tools.get_all_power_sta_files + piel.tools.calculate_max_frame_amount + piel.tools.calculate_propagation_delay_from_file + piel.tools.calculate_propagation_delay_from_timing_data + piel.tools.configure_timing_data_rows + piel.tools.configure_frame_id + piel.tools.filter_timing_data_by_net_name_and_type + piel.tools.get_frame_meta_data + piel.tools.get_frame_lines_data + piel.tools.get_frame_timing_data + piel.tools.get_all_timing_data_from_file + piel.tools.read_sta_rpt_fwf_file + piel.tools.contains_in_lines + piel.tools.create_file_lines_dataframe + piel.tools.get_file_line_by_keyword + piel.tools.read_file_lines + piel.tools.run_openlane_flow + piel.tools.convert_numeric_to_prefix + piel.tools.get_sdense_ports_index + piel.tools.sax_to_s_parameters_standard_matrix + + + +Attributes +~~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.delete_simulation_output_files + piel.tools.get_simulation_output_files + piel.tools.snet + + +.. py:function:: check_cocotb_testbench_exists(design_directory: str | pathlib.Path) -> bool + + Checks if a cocotb testbench exists in the design directory. + + :param design_directory: Design directory. + :type design_directory: str | pathlib.Path + + :returns: True if cocotb testbench exists. + :rtype: cocotb_testbench_exists(bool) + + +.. py:function:: configure_cocotb_simulation(design_directory: str | pathlib.Path, simulator: Literal[icarus, verilator], top_level_language: Literal[verilog, vhdl], top_level_verilog_module: str, test_python_module: str, design_sources_list: list | None = None) + + Writes a cocotb makefile. + + If no design_sources_list is provided then it adds all the design sources under the `src` folder. + + In the form + .. code-block:: + + #!/bin/sh + # Makefile + # defaults + SIM ?= icarus + TOPLEVEL_LANG ?= verilog + + # Note we need to include the test script to the PYTHONPATH + export PYTHONPATH = + + VERILOG_SOURCES += $(PWD)/my_design.sv + # use VHDL_SOURCES for VHDL files + + # TOPLEVEL is the name of the toplevel module in your Verilog or VHDL file + TOPLEVEL := my_design + + # MODULE is the basename of the Python test file + MODULE := test_my_design + + # include cocotb's make rules to take care of the simulator setup + include $(shell cocotb-config --makefiles)/Makefile.sim + + + :param design_directory: The directory where the design is located. + :type design_directory: str | pathlib.Path + :param simulator: The simulator to use. + :type simulator: Literal["icarus", "verilator"] + :param top_level_language: The top level language. + :type top_level_language: Literal["verilog", "vhdl"] + :param top_level_verilog_module: The top level verilog module. + :type top_level_verilog_module: str + :param test_python_module: The test python module. + :type test_python_module: str + :param design_sources_list: A list of design sources. Defaults to None. + :type design_sources_list: list | None, optional + + :returns: None + + +.. py:data:: delete_simulation_output_files + + + +.. py:function:: run_cocotb_simulation(design_directory: str) -> subprocess.CompletedProcess + + Equivalent to running the cocotb makefile + .. code-block:: + + make + + :param design_directory: The directory where the design is located. + :type design_directory: str + + :returns: The subprocess.CompletedProcess object. + :rtype: subprocess.CompletedProcess + + +.. py:data:: get_simulation_output_files + + + +.. py:function:: get_simulation_output_files_from_design(design_directory: piel.config.piel_path_types, extension: str = 'csv') + + This function returns a list of all the simulation output files in the design directory. + + :param design_directory: The path to the design directory. + :type design_directory: piel_path_types + + :returns: List of all the simulation output files in the design directory. + :rtype: output_files (list) + + +.. py:function:: read_simulation_data(file_path: piel.config.piel_path_types) + + This function returns a Pandas dataframe that contains all the simulation data outputted from the simulation run. + + :param file_path: The path to the simulation data file. + :type file_path: piel_path_types + + :returns: The simulation data in a Pandas dataframe. + :rtype: simulation_data (pd.DataFrame) + + +.. py:function:: simple_plot_simulation_data(simulation_data: pandas.DataFrame) + + +.. py:function:: get_input_ports_index(ports_index: dict, sorting_algorithm: Literal[get_input_ports_index.prefix] = 'prefix', prefix: str = 'in') -> tuple + + This function returns the input ports of a component. However, input ports may have different sets of prefixes and suffixes. This function implements different sorting algorithms for different ports names. The default algorithm is `prefix`, which sorts the ports by their prefix. The Endianness implementation means that the tuple order is determined according to the last numerical index order of the port numbering. + + .. code-block:: python + + raw_ports_index = { + "in_o_0": 0, + "out_o_0": 1, + "out_o_1": 2, + "out_o_2": 3, + "out_o_3": 4, + "in_o_1": 5, + "in_o_2": 6, + "in_o_3": 7, + } + + get_input_ports_index(ports_index=raw_ports_index) + + # Output + ((0, "in_o_0"), (5, "in_o_1"), (6, "in_o_2"), (7, "in_o_3")) + + :param ports_index: The ports index dictionary. + :type ports_index: dict + :param sorting_algorithm: The sorting algorithm to use. Defaults to "prefix". + :type sorting_algorithm: Literal["prefix"], optional + :param prefix: The prefix to use for the sorting algorithm. Defaults to "in". + :type prefix: str, optional + + :returns: The ordered input ports index tuple. + :rtype: tuple + + +.. py:function:: get_matched_ports_tuple_index(ports_index: dict, selected_ports_tuple: Optional[tuple] = None, sorting_algorithm: Literal[get_matched_ports_tuple_index.prefix, selected_ports] = 'prefix', prefix: str = 'in') -> (tuple, tuple) + + This function returns the input ports of a component. However, input ports may have different sets of prefixes + and suffixes. This function implements different sorting algorithms for different ports names. The default + algorithm is `prefix`, which sorts the ports by their prefix. The Endianness implementation means that the tuple + order is determined according to the last numerical index order of the port numbering. Returns just a tuple of + the index. + + .. code-block:: python + + raw_ports_index = { + "in_o_0": 0, + "out_o_0": 1, + "out_o_1": 2, + "out_o_2": 3, + "out_o_3": 4, + "in_o_1": 5, + "in_o_2": 6, + "in_o_3": 7, + } + + get_input_ports_tuple_index(ports_index=raw_ports_index) + + # Output + (0, 5, 6, 7) + + :param ports_index: The ports index dictionary. + :type ports_index: dict + :param selected_ports_tuple: The selected ports tuple. Defaults to None. + :type selected_ports_tuple: tuple, optional + :param sorting_algorithm: The sorting algorithm to use. Defaults to "prefix". + :type sorting_algorithm: Literal["prefix"], optional + :param prefix: The prefix to use for the sorting algorithm. Defaults to "in". + :type prefix: str, optional + + :returns: The ordered input ports index tuple. + matched_ports_name_tuple_order(tuple): The ordered input ports name tuple. + :rtype: matches_ports_index_tuple_order(tuple) + + +.. py:function:: get_design_from_openlane_migration(v1: bool = True, design_name_v1: str | None = None, design_directory: str | pathlib.Path | None = None, root_directory_v1: str | pathlib.Path | None = None) -> (str, pathlib.Path) + + This function provides the integration mechanism for easily migrating the interconnection with other toolsets from an OpenLane v1 design to an OpenLane v2 design. + + This function checks if the inputs are to be treated as v1 inputs. If so, and a `design_name` is provided then it will set the `design_directory` to the corresponding `design_name` directory in the corresponding `root_directory_v1 / designs`. If no `root_directory` is provided then it returns `$OPENLANE_ROOT/""/. If a `design_directory` is provided then this will always take precedence even with a `v1` flag. + + :param v1: If True, it will migrate from v1 to v2. + :type v1: bool + :param design_name_v1: Design name of the v1 design that can be found within `$OPENLANE_ROOT/""/designs`. + :type design_name_v1: str + :param design_directory: Design directory PATH. Optional path for v2-based designs. + :type design_directory: str + :param root_directory_v1: Root directory of OpenLane v1. If set to None it will return `$OPENLANE_ROOT/""` + :type root_directory_v1: str + + :returns: None + + +.. py:function:: find_design_run(design_directory: piel.config.piel_path_types, run_name: str | None = None) -> pathlib.Path + + For a given `design_directory`, the `openlane` output can be found in the `runs` subdirectory. + + They get sorted based on a reverse `list.sort()` method. + + # TODO docs + + +.. py:function:: check_config_json_exists_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> bool + + Checks if a design has a `config.json` file. + + :param design_name: Name of the design. + :type design_name: str + + :returns: True if `config.json` exists. + :rtype: config_json_exists(bool) + + +.. py:function:: check_design_exists_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> bool + + Checks if a design exists in the OpenLane v1 design folder. + + Lists all designs inside the Openlane V1 design root. + + :param design_name: Name of the design. + :type design_name: str + + :returns: True if design exists. + :rtype: design_exists(bool) + + +.. py:function:: configure_and_run_design_openlane_v1(design_name: str, configuration: dict | None = None, root_directory: str | pathlib.Path | None = None) -> None + + Configures and runs an OpenLane v1 design. + + This function does the following: + 1. Check that the design_directory provided is under $OPENLANE_ROOT//designs + 2. Check if `config.json` has already been provided for this design. If a configuration dictionary is inputted into the function parameters, then it overwrites the default `config.json`. + 3. Create a script directory, a script is written and permissions are provided for it to be executable. + 4. Permit and execute the `openlane_flow.sh` script in the `scripts` directory. + + :param design_name: Name of the design. + :type design_name: str + :param configuration: Configuration dictionary. + :type configuration: dict | None + :param root_directory: Design directory. + :type root_directory: str | pathlib.Path + + :returns: None + + +.. py:function:: configure_parametric_designs_openlane_v1(design_name: str, parameter_sweep_dictionary: dict, add_id: bool = True) -> list + + For a given `source_design_directory`, this function reads in the config.json file and returns a set of parametric sweeps that gets used when creating a set of parametric designs. + + :param add_id: Add an ID to the design name. Defaults to True. + :type add_id: bool + :param parameter_sweep_dictionary: Dictionary of parameters to sweep. + :type parameter_sweep_dictionary: dict + :param source_design_directory: Source design directory. + :type source_design_directory: str | pathlib.Path + + :returns: List of configurations to sweep. + :rtype: configuration_sweep(list) + + +.. py:function:: configure_flow_script_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> None + + Configures the OpenLane v1 flow script after checking that the design directory exists. + + :param design_directory: Design directory. Defaults to latest OpenLane root. + :type design_directory: str | pathlib.Path | None + + :returns: None + + +.. py:function:: create_parametric_designs_openlane_v1(design_name: str, parameter_sweep_dictionary: dict, target_directory: str | pathlib.Path | None = None) -> None + + Takes a OpenLane v1 source directory and creates a parametric combination of these designs. + + :param design_name: Name of the design. + :type design_name: str + :param parameter_sweep_dictionary: Dictionary of parameters to sweep. + :type parameter_sweep_dictionary: dict + :param target_directory: Optional target directory. + :type target_directory: str | pathlib.Path | None + + :returns: None + + +.. py:function:: get_design_directory_from_root_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> pathlib.Path + + Gets the design directory from the root directory. + + :param design_name: Name of the design. + :type design_name: str + :param root_directory: Design directory. + :type root_directory: str | pathlib.Path + + :returns: Design directory. + :rtype: design_directory(pathlib.Path) + + +.. py:function:: get_latest_version_root_openlane_v1() -> pathlib.Path + + Gets the latest version root of OpenLane v1. + + +.. py:function:: read_configuration_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> dict + + Reads a `config.json` from a design directory. + + :param design_name: Design name. + :type design_name: str + :param root_directory: Design directory. + :type root_directory: str | pathlib.Path + + :returns: Configuration dictionary. + :rtype: configuration(dict) + + +.. py:function:: write_configuration_openlane_v1(configuration: dict, design_directory: str | pathlib.Path) -> None + + Writes a `config.json` onto a `design_directory` + + :param configuration: OpenLane configuration dictionary. + :type configuration: dict + :param design_directory: Design directory PATH. + :type design_directory: str + + :returns: None + + +.. py:function:: filter_timing_sta_files(file_list) + + Filter the timing sta files from the list of files + + :param file_list: List containing the file paths + :type file_list: list + + :returns: List containing the timing sta files + :rtype: timing_sta_files (list) + + +.. py:function:: filter_power_sta_files(file_list) + + Filter the power sta files from the list of files + + :param file_list: List containing the file paths + :type file_list: list + + :returns: List containing the power sta files + :rtype: power_sta_files (list) + + +.. py:function:: get_all_timing_sta_files(run_directory) + + This function aims to list and perform analysis on all the relevant files in a particular run between all the corners. + + :param run_directory: The run directory to perform the analysis on. Defaults to None. + :type run_directory: str, optional + + :returns: List of all the .rpt files in the run directory. + :rtype: timing_sta_files_list (list) + + +.. py:function:: get_all_power_sta_files(run_directory) + + This function aims to list and perform analysis on all the relevant files in a particular run between all the corners. + + :param run_directory: The run directory to perform the analysis on. Defaults to None. + :type run_directory: str, optional + + :returns: List of all the .rpt files in the run directory. + :rtype: power_sta_files_list (list) + + +.. py:function:: calculate_max_frame_amount(file_lines_data: pandas.DataFrame) + + Calculate the maximum frame amount based on the frame IDs in the DataFrame + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Maximum number of frames in the file + :rtype: maximum_frame_amount (int) + + +.. py:function:: calculate_propagation_delay_from_file(file_path: str | pathlib.Path) + + Calculate the propagation delay for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: Dictionary containing the propagation delay + :rtype: propagation_delay (dict) + + +.. py:function:: calculate_propagation_delay_from_timing_data(net_name_in: str, net_name_out: str, timing_data: pandas.DataFrame) + + Calculate the propagation delay between two nets + + :param net_name_in: Name of the input net + :type net_name_in: str + :param net_name_out: Name of the output net + :type net_name_out: str + :param timing_data: Dataframe containing the timing data + :type timing_data: pd.DataFrame + + :returns: Dataframe containing the propagation delay + :rtype: propagation_delay_dataframe (pd.DataFrame) + + +.. py:function:: configure_timing_data_rows(file_lines_data: pandas.DataFrame) + + Identify the timing data lines for each frame and creates a metadata dictionary for frames. + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Dictionary containing the frame metadata + :rtype: frame_meta_data (dict) + + +.. py:function:: configure_frame_id(file_lines_data: pandas.DataFrame) + + Identify the frame delimiters and assign frame ID to each line in the file + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: filter_timing_data_by_net_name_and_type(timing_data: pandas.DataFrame, net_name: str, net_type: str) + + Filter the timing data by net name and type + + :param timing_data: DataFrame containing the timing data + :type timing_data: pd.DataFrame + :param net_name: Net name to be filtered + :type net_name: str + :param net_type: Net type to be filtered + :type net_type: str + + :returns: DataFrame containing the timing data + :rtype: timing_data (pd.DataFrame) + + +.. py:function:: get_frame_meta_data(file_lines_data) + + Get the frame metadata + + :param file_lines_data: DataFrame containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: DataFrame containing the start point name + end_point_name (pd.DataFrame): DataFrame containing the end point name + path_group_name (pd.DataFrame): DataFrame containing the path group name + path_type_name (pd.DataFrame): DataFrame containing the path type name + :rtype: start_point_name (pd.DataFrame) + + +.. py:function:: get_frame_lines_data(file_path: str | pathlib.Path) + + Calculate the timing data for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: DataFrame containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: get_frame_timing_data(file: str | pathlib.Path, frame_meta_data: dict, frame_id: int = 0) + + Extract the timing data from the file + + :param file: Address of the file + :type file: str | pathlib.Path + :param frame_meta_data: Dictionary containing the frame metadata + :type frame_meta_data: dict + :param frame_id: Frame ID to be read + :type frame_id: int + + :returns: DataFrame containing the timing data + :rtype: timing_data (pd.DataFrame) + + +.. py:function:: get_all_timing_data_from_file(file_path: str | pathlib.Path) + + Calculate the timing data for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: Dictionary containing the timing data for each frame + :rtype: frame_timing_data (dict) + + +.. py:function:: read_sta_rpt_fwf_file(file: str | pathlib.Path, frame_meta_data: dict, frame_id: int = 0) + + Read the fixed width file and return a DataFrame + + :param file: Address of the file + :type file: str | pathlib.Path + :param frame_meta_data: Dictionary containing the frame metadata + :type frame_meta_data: dict + :param frame_id: Frame ID to be read + :type frame_id: int + + :returns: DataFrame containing the file data + :rtype: file_data (pd.DataFrame) + + +.. py:function:: contains_in_lines(file_lines_data: pandas.DataFrame, keyword: str) + + Check if the keyword is contained in the file lines + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + :param keyword: Keyword to search for + :type keyword: str + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: create_file_lines_dataframe(file_lines_raw) + + Create a DataFrame from the raw lines of a file + + :param file_lines_raw: list containing the file lines + :type file_lines_raw: list + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: get_file_line_by_keyword(file_lines_data: pandas.DataFrame, keyword: str, regex: str) + + Extract the data from the file lines using the given keyword and regex + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + :param keyword: Keyword to search for + :type keyword: str + :param regex: Regex to extract the data + :type regex: str + + :returns: Dataframe containing the extracted values + :rtype: extracted_values (pd.DataFrame) + + +.. py:function:: read_file_lines(file_path: str | pathlib.Path) + + Extract lines from the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: list containing the file lines + :rtype: file_lines_raw (list) + + +.. py:function:: run_openlane_flow(configuration: dict | None = test_spm_open_lane_configuration, design_directory: piel.config.piel_path_types = '/foss/designs/spm') -> None + + Runs the OpenLane flow. + + :param configuration: OpenLane configuration dictionary. If none is present it will default to the config.json file on the design_directory. + :type configuration: dict + :param design_directory: Design directory PATH. + :type design_directory: piel_path_types + + :returns: None + + +.. py:function:: convert_numeric_to_prefix(value: float) + + This function converts a numeric value to a number under a SPICE unit closest to the base prefix. This allows us to connect a particular number real output, into a term that can be used in a SPICE netlist. + + +.. py:function:: get_sdense_ports_index(input_ports_order: tuple, all_ports_index: dict) -> dict + + This function returns the ports index of the sax dense S-parameter matrix. + + Given that the order of the iteration is provided by the user, the dictionary keys will also be ordered + accordingly when iterating over them. This requires the user to provide a set of ordered. + + TODO verify reasonable iteration order. + + .. code-block:: python + + # The input_ports_order can be a tuple of tuples that contain the index and port name. Eg. + input_ports_order = ((0, "in_o_0"), (5, "in_o_1"), (6, "in_o_2"), (7, "in_o_3")) + # The all_ports_index is a dictionary of the ports index. Eg. + all_ports_index = { + "in_o_0": 0, + "out_o_0": 1, + "out_o_1": 2, + "out_o_2": 3, + "out_o_3": 4, + "in_o_1": 5, + "in_o_2": 6, + "in_o_3": 7, + } + # Output + {"in_o_0": 0, "in_o_1": 5, "in_o_2": 6, "in_o_3": 7} + + :param input_ports_order: The ports order tuple. Can be a tuple of tuples that contain the index and port name. + :type input_ports_order: tuple + :param all_ports_index: The ports index dictionary. + :type all_ports_index: dict + + :returns: The ordered input ports index tuple. + :rtype: tuple + + +.. py:function:: sax_to_s_parameters_standard_matrix(sax_input: sax.SType, input_ports_order: tuple | None = None) -> tuple + + A ``sax`` S-parameter SDict is provided as a dictionary of tuples with (port0, port1) as the key. This + determines the direction of the scattering relationship. It means that the number of terms in an S-parameter + matrix is the number of ports squared. + + In order to generalise, this function returns both the S-parameter matrices and the indexing ports based on the + amount provided. In terms of computational speed, we definitely would like this function to be algorithmically + very fast. For now, I will write a simple python implementation and optimise in the future. + + It is possible to see the `sax` SDense notation equivalence here: + https://flaport.github.io/sax/nbs/08_backends.html + + .. code-block:: python + + import jax.numpy as jnp + from sax.core import SDense + + # Directional coupler SDense representation + dc_sdense: SDense = ( + jnp.array([[0, 0, τ, κ], [0, 0, κ, τ], [τ, κ, 0, 0], [κ, τ, 0, 0]]), + {"in0": 0, "in1": 1, "out0": 2, "out1": 3}, + ) + + + # Directional coupler SDict representation + # Taken from https://flaport.github.io/sax/nbs/05_models.html + def coupler(*, coupling: float = 0.5) -> SDict: + kappa = coupling**0.5 + tau = (1 - coupling) ** 0.5 + sdict = reciprocal( + { + ("in0", "out0"): tau, + ("in0", "out1"): 1j * kappa, + ("in1", "out0"): 1j * kappa, + ("in1", "out1"): tau, + } + ) + return sdict + + If we were to relate the mapping accordingly based on the ports indexes, a S-Parameter matrix in the form of + :math:`S_{(output,i),(input,i)}` would be: + + .. math:: + + S = \begin{bmatrix} + S_{00} & S_{10} \\ + S_{01} & S_{11} \\ + \end{bmatrix} = + \begin{bmatrix} + \tau & j \kappa \\ + j \kappa & \tau \\ + \end{bmatrix} + + Note that the standard S-parameter and hence unitary representation is in the form of: + + .. math:: + + S = \begin{bmatrix} + S_{00} & S_{01} \\ + S_{10} & S_{11} \\ + \end{bmatrix} + + + .. math:: + + \begin{bmatrix} + b_{1} \\ + \vdots \\ + b_{n} + \end{bmatrix} + = + \begin{bmatrix} + S_{11} & \dots & S_{1n} \\ + \vdots & \ddots & \vdots \\ + S_{n1} & \dots & S_{nn} + \end{bmatrix} + \begin{bmatrix} + a_{1} \\ + \vdots \\ + a_{n} + \end{bmatrix} + + TODO check with Floris, does this mean we need to transpose the matrix? + + :param sax_input: The sax S-parameter dictionary. + :type sax_input: sax.SType + :param input_ports_order: The ports order tuple containing the names and order of the input ports. + :type input_ports_order: tuple + + :returns: The S-parameter matrix and the input ports index tuple in the standard S-parameter notation. + :rtype: tuple + + +.. py:data:: snet diff --git a/docs/autoapi/piel/tools/openlane/index.rst b/docs/autoapi/piel/tools/openlane/index.rst new file mode 100644 index 00000000..61751817 --- /dev/null +++ b/docs/autoapi/piel/tools/openlane/index.rst @@ -0,0 +1,468 @@ +:py:mod:`piel.tools.openlane` +============================= + +.. py:module:: piel.tools.openlane + + +Subpackages +----------- +.. toctree:: + :titlesonly: + :maxdepth: 3 + + parse/index.rst + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + migrate/index.rst + utils/index.rst + v1/index.rst + v2/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.openlane.get_design_from_openlane_migration + piel.tools.openlane.find_design_run + piel.tools.openlane.check_config_json_exists_openlane_v1 + piel.tools.openlane.check_design_exists_openlane_v1 + piel.tools.openlane.configure_and_run_design_openlane_v1 + piel.tools.openlane.configure_parametric_designs_openlane_v1 + piel.tools.openlane.configure_flow_script_openlane_v1 + piel.tools.openlane.create_parametric_designs_openlane_v1 + piel.tools.openlane.get_design_directory_from_root_openlane_v1 + piel.tools.openlane.get_latest_version_root_openlane_v1 + piel.tools.openlane.read_configuration_openlane_v1 + piel.tools.openlane.write_configuration_openlane_v1 + piel.tools.openlane.filter_timing_sta_files + piel.tools.openlane.filter_power_sta_files + piel.tools.openlane.get_all_timing_sta_files + piel.tools.openlane.get_all_power_sta_files + piel.tools.openlane.calculate_max_frame_amount + piel.tools.openlane.calculate_propagation_delay_from_file + piel.tools.openlane.calculate_propagation_delay_from_timing_data + piel.tools.openlane.configure_timing_data_rows + piel.tools.openlane.configure_frame_id + piel.tools.openlane.filter_timing_data_by_net_name_and_type + piel.tools.openlane.get_frame_meta_data + piel.tools.openlane.get_frame_lines_data + piel.tools.openlane.get_frame_timing_data + piel.tools.openlane.get_all_timing_data_from_file + piel.tools.openlane.read_sta_rpt_fwf_file + piel.tools.openlane.contains_in_lines + piel.tools.openlane.create_file_lines_dataframe + piel.tools.openlane.get_file_line_by_keyword + piel.tools.openlane.read_file_lines + piel.tools.openlane.run_openlane_flow + + + +.. py:function:: get_design_from_openlane_migration(v1: bool = True, design_name_v1: str | None = None, design_directory: str | pathlib.Path | None = None, root_directory_v1: str | pathlib.Path | None = None) -> (str, pathlib.Path) + + This function provides the integration mechanism for easily migrating the interconnection with other toolsets from an OpenLane v1 design to an OpenLane v2 design. + + This function checks if the inputs are to be treated as v1 inputs. If so, and a `design_name` is provided then it will set the `design_directory` to the corresponding `design_name` directory in the corresponding `root_directory_v1 / designs`. If no `root_directory` is provided then it returns `$OPENLANE_ROOT/""/. If a `design_directory` is provided then this will always take precedence even with a `v1` flag. + + :param v1: If True, it will migrate from v1 to v2. + :type v1: bool + :param design_name_v1: Design name of the v1 design that can be found within `$OPENLANE_ROOT/""/designs`. + :type design_name_v1: str + :param design_directory: Design directory PATH. Optional path for v2-based designs. + :type design_directory: str + :param root_directory_v1: Root directory of OpenLane v1. If set to None it will return `$OPENLANE_ROOT/""` + :type root_directory_v1: str + + :returns: None + + +.. py:function:: find_design_run(design_directory: piel.config.piel_path_types, run_name: str | None = None) -> pathlib.Path + + For a given `design_directory`, the `openlane` output can be found in the `runs` subdirectory. + + They get sorted based on a reverse `list.sort()` method. + + # TODO docs + + +.. py:function:: check_config_json_exists_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> bool + + Checks if a design has a `config.json` file. + + :param design_name: Name of the design. + :type design_name: str + + :returns: True if `config.json` exists. + :rtype: config_json_exists(bool) + + +.. py:function:: check_design_exists_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> bool + + Checks if a design exists in the OpenLane v1 design folder. + + Lists all designs inside the Openlane V1 design root. + + :param design_name: Name of the design. + :type design_name: str + + :returns: True if design exists. + :rtype: design_exists(bool) + + +.. py:function:: configure_and_run_design_openlane_v1(design_name: str, configuration: dict | None = None, root_directory: str | pathlib.Path | None = None) -> None + + Configures and runs an OpenLane v1 design. + + This function does the following: + 1. Check that the design_directory provided is under $OPENLANE_ROOT//designs + 2. Check if `config.json` has already been provided for this design. If a configuration dictionary is inputted into the function parameters, then it overwrites the default `config.json`. + 3. Create a script directory, a script is written and permissions are provided for it to be executable. + 4. Permit and execute the `openlane_flow.sh` script in the `scripts` directory. + + :param design_name: Name of the design. + :type design_name: str + :param configuration: Configuration dictionary. + :type configuration: dict | None + :param root_directory: Design directory. + :type root_directory: str | pathlib.Path + + :returns: None + + +.. py:function:: configure_parametric_designs_openlane_v1(design_name: str, parameter_sweep_dictionary: dict, add_id: bool = True) -> list + + For a given `source_design_directory`, this function reads in the config.json file and returns a set of parametric sweeps that gets used when creating a set of parametric designs. + + :param add_id: Add an ID to the design name. Defaults to True. + :type add_id: bool + :param parameter_sweep_dictionary: Dictionary of parameters to sweep. + :type parameter_sweep_dictionary: dict + :param source_design_directory: Source design directory. + :type source_design_directory: str | pathlib.Path + + :returns: List of configurations to sweep. + :rtype: configuration_sweep(list) + + +.. py:function:: configure_flow_script_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> None + + Configures the OpenLane v1 flow script after checking that the design directory exists. + + :param design_directory: Design directory. Defaults to latest OpenLane root. + :type design_directory: str | pathlib.Path | None + + :returns: None + + +.. py:function:: create_parametric_designs_openlane_v1(design_name: str, parameter_sweep_dictionary: dict, target_directory: str | pathlib.Path | None = None) -> None + + Takes a OpenLane v1 source directory and creates a parametric combination of these designs. + + :param design_name: Name of the design. + :type design_name: str + :param parameter_sweep_dictionary: Dictionary of parameters to sweep. + :type parameter_sweep_dictionary: dict + :param target_directory: Optional target directory. + :type target_directory: str | pathlib.Path | None + + :returns: None + + +.. py:function:: get_design_directory_from_root_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> pathlib.Path + + Gets the design directory from the root directory. + + :param design_name: Name of the design. + :type design_name: str + :param root_directory: Design directory. + :type root_directory: str | pathlib.Path + + :returns: Design directory. + :rtype: design_directory(pathlib.Path) + + +.. py:function:: get_latest_version_root_openlane_v1() -> pathlib.Path + + Gets the latest version root of OpenLane v1. + + +.. py:function:: read_configuration_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> dict + + Reads a `config.json` from a design directory. + + :param design_name: Design name. + :type design_name: str + :param root_directory: Design directory. + :type root_directory: str | pathlib.Path + + :returns: Configuration dictionary. + :rtype: configuration(dict) + + +.. py:function:: write_configuration_openlane_v1(configuration: dict, design_directory: str | pathlib.Path) -> None + + Writes a `config.json` onto a `design_directory` + + :param configuration: OpenLane configuration dictionary. + :type configuration: dict + :param design_directory: Design directory PATH. + :type design_directory: str + + :returns: None + + +.. py:function:: filter_timing_sta_files(file_list) + + Filter the timing sta files from the list of files + + :param file_list: List containing the file paths + :type file_list: list + + :returns: List containing the timing sta files + :rtype: timing_sta_files (list) + + +.. py:function:: filter_power_sta_files(file_list) + + Filter the power sta files from the list of files + + :param file_list: List containing the file paths + :type file_list: list + + :returns: List containing the power sta files + :rtype: power_sta_files (list) + + +.. py:function:: get_all_timing_sta_files(run_directory) + + This function aims to list and perform analysis on all the relevant files in a particular run between all the corners. + + :param run_directory: The run directory to perform the analysis on. Defaults to None. + :type run_directory: str, optional + + :returns: List of all the .rpt files in the run directory. + :rtype: timing_sta_files_list (list) + + +.. py:function:: get_all_power_sta_files(run_directory) + + This function aims to list and perform analysis on all the relevant files in a particular run between all the corners. + + :param run_directory: The run directory to perform the analysis on. Defaults to None. + :type run_directory: str, optional + + :returns: List of all the .rpt files in the run directory. + :rtype: power_sta_files_list (list) + + +.. py:function:: calculate_max_frame_amount(file_lines_data: pandas.DataFrame) + + Calculate the maximum frame amount based on the frame IDs in the DataFrame + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Maximum number of frames in the file + :rtype: maximum_frame_amount (int) + + +.. py:function:: calculate_propagation_delay_from_file(file_path: str | pathlib.Path) + + Calculate the propagation delay for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: Dictionary containing the propagation delay + :rtype: propagation_delay (dict) + + +.. py:function:: calculate_propagation_delay_from_timing_data(net_name_in: str, net_name_out: str, timing_data: pandas.DataFrame) + + Calculate the propagation delay between two nets + + :param net_name_in: Name of the input net + :type net_name_in: str + :param net_name_out: Name of the output net + :type net_name_out: str + :param timing_data: Dataframe containing the timing data + :type timing_data: pd.DataFrame + + :returns: Dataframe containing the propagation delay + :rtype: propagation_delay_dataframe (pd.DataFrame) + + +.. py:function:: configure_timing_data_rows(file_lines_data: pandas.DataFrame) + + Identify the timing data lines for each frame and creates a metadata dictionary for frames. + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Dictionary containing the frame metadata + :rtype: frame_meta_data (dict) + + +.. py:function:: configure_frame_id(file_lines_data: pandas.DataFrame) + + Identify the frame delimiters and assign frame ID to each line in the file + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: filter_timing_data_by_net_name_and_type(timing_data: pandas.DataFrame, net_name: str, net_type: str) + + Filter the timing data by net name and type + + :param timing_data: DataFrame containing the timing data + :type timing_data: pd.DataFrame + :param net_name: Net name to be filtered + :type net_name: str + :param net_type: Net type to be filtered + :type net_type: str + + :returns: DataFrame containing the timing data + :rtype: timing_data (pd.DataFrame) + + +.. py:function:: get_frame_meta_data(file_lines_data) + + Get the frame metadata + + :param file_lines_data: DataFrame containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: DataFrame containing the start point name + end_point_name (pd.DataFrame): DataFrame containing the end point name + path_group_name (pd.DataFrame): DataFrame containing the path group name + path_type_name (pd.DataFrame): DataFrame containing the path type name + :rtype: start_point_name (pd.DataFrame) + + +.. py:function:: get_frame_lines_data(file_path: str | pathlib.Path) + + Calculate the timing data for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: DataFrame containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: get_frame_timing_data(file: str | pathlib.Path, frame_meta_data: dict, frame_id: int = 0) + + Extract the timing data from the file + + :param file: Address of the file + :type file: str | pathlib.Path + :param frame_meta_data: Dictionary containing the frame metadata + :type frame_meta_data: dict + :param frame_id: Frame ID to be read + :type frame_id: int + + :returns: DataFrame containing the timing data + :rtype: timing_data (pd.DataFrame) + + +.. py:function:: get_all_timing_data_from_file(file_path: str | pathlib.Path) + + Calculate the timing data for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: Dictionary containing the timing data for each frame + :rtype: frame_timing_data (dict) + + +.. py:function:: read_sta_rpt_fwf_file(file: str | pathlib.Path, frame_meta_data: dict, frame_id: int = 0) + + Read the fixed width file and return a DataFrame + + :param file: Address of the file + :type file: str | pathlib.Path + :param frame_meta_data: Dictionary containing the frame metadata + :type frame_meta_data: dict + :param frame_id: Frame ID to be read + :type frame_id: int + + :returns: DataFrame containing the file data + :rtype: file_data (pd.DataFrame) + + +.. py:function:: contains_in_lines(file_lines_data: pandas.DataFrame, keyword: str) + + Check if the keyword is contained in the file lines + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + :param keyword: Keyword to search for + :type keyword: str + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: create_file_lines_dataframe(file_lines_raw) + + Create a DataFrame from the raw lines of a file + + :param file_lines_raw: list containing the file lines + :type file_lines_raw: list + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: get_file_line_by_keyword(file_lines_data: pandas.DataFrame, keyword: str, regex: str) + + Extract the data from the file lines using the given keyword and regex + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + :param keyword: Keyword to search for + :type keyword: str + :param regex: Regex to extract the data + :type regex: str + + :returns: Dataframe containing the extracted values + :rtype: extracted_values (pd.DataFrame) + + +.. py:function:: read_file_lines(file_path: str | pathlib.Path) + + Extract lines from the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: list containing the file lines + :rtype: file_lines_raw (list) + + +.. py:function:: run_openlane_flow(configuration: dict | None = test_spm_open_lane_configuration, design_directory: piel.config.piel_path_types = '/foss/designs/spm') -> None + + Runs the OpenLane flow. + + :param configuration: OpenLane configuration dictionary. If none is present it will default to the config.json file on the design_directory. + :type configuration: dict + :param design_directory: Design directory PATH. + :type design_directory: piel_path_types + + :returns: None diff --git a/docs/autoapi/piel/tools/openlane/migrate/index.rst b/docs/autoapi/piel/tools/openlane/migrate/index.rst new file mode 100644 index 00000000..a84d2536 --- /dev/null +++ b/docs/autoapi/piel/tools/openlane/migrate/index.rst @@ -0,0 +1,40 @@ +:py:mod:`piel.tools.openlane.migrate` +===================================== + +.. py:module:: piel.tools.openlane.migrate + +.. autoapi-nested-parse:: + + These functions provide easy tools for easily migrating between OpenLane v1 and v2 based designs. + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.openlane.migrate.get_design_from_openlane_migration + + + +.. py:function:: get_design_from_openlane_migration(v1: bool = True, design_name_v1: str | None = None, design_directory: str | pathlib.Path | None = None, root_directory_v1: str | pathlib.Path | None = None) -> (str, pathlib.Path) + + This function provides the integration mechanism for easily migrating the interconnection with other toolsets from an OpenLane v1 design to an OpenLane v2 design. + + This function checks if the inputs are to be treated as v1 inputs. If so, and a `design_name` is provided then it will set the `design_directory` to the corresponding `design_name` directory in the corresponding `root_directory_v1 / designs`. If no `root_directory` is provided then it returns `$OPENLANE_ROOT/""/. If a `design_directory` is provided then this will always take precedence even with a `v1` flag. + + :param v1: If True, it will migrate from v1 to v2. + :type v1: bool + :param design_name_v1: Design name of the v1 design that can be found within `$OPENLANE_ROOT/""/designs`. + :type design_name_v1: str + :param design_directory: Design directory PATH. Optional path for v2-based designs. + :type design_directory: str + :param root_directory_v1: Root directory of OpenLane v1. If set to None it will return `$OPENLANE_ROOT/""` + :type root_directory_v1: str + + :returns: None diff --git a/docs/autoapi/piel/tools/openlane/parse/index.rst b/docs/autoapi/piel/tools/openlane/parse/index.rst new file mode 100644 index 00000000..a1961bb7 --- /dev/null +++ b/docs/autoapi/piel/tools/openlane/parse/index.rst @@ -0,0 +1,287 @@ +:py:mod:`piel.tools.openlane.parse` +=================================== + +.. py:module:: piel.tools.openlane.parse + +.. autoapi-nested-parse:: + + These functions aim to provide functionality to parse data from any OpenLanes v1 design into Python. + + They are ported from the old: github.com/daquintero/porf + + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + run_output/index.rst + sta_rpt/index.rst + utils/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.openlane.parse.filter_timing_sta_files + piel.tools.openlane.parse.filter_power_sta_files + piel.tools.openlane.parse.get_all_timing_sta_files + piel.tools.openlane.parse.get_all_power_sta_files + piel.tools.openlane.parse.calculate_max_frame_amount + piel.tools.openlane.parse.calculate_propagation_delay_from_file + piel.tools.openlane.parse.calculate_propagation_delay_from_timing_data + piel.tools.openlane.parse.configure_timing_data_rows + piel.tools.openlane.parse.configure_frame_id + piel.tools.openlane.parse.filter_timing_data_by_net_name_and_type + piel.tools.openlane.parse.get_frame_meta_data + piel.tools.openlane.parse.get_frame_lines_data + piel.tools.openlane.parse.get_frame_timing_data + piel.tools.openlane.parse.get_all_timing_data_from_file + piel.tools.openlane.parse.read_sta_rpt_fwf_file + piel.tools.openlane.parse.contains_in_lines + piel.tools.openlane.parse.create_file_lines_dataframe + piel.tools.openlane.parse.get_file_line_by_keyword + piel.tools.openlane.parse.read_file_lines + + + +.. py:function:: filter_timing_sta_files(file_list) + + Filter the timing sta files from the list of files + + :param file_list: List containing the file paths + :type file_list: list + + :returns: List containing the timing sta files + :rtype: timing_sta_files (list) + + +.. py:function:: filter_power_sta_files(file_list) + + Filter the power sta files from the list of files + + :param file_list: List containing the file paths + :type file_list: list + + :returns: List containing the power sta files + :rtype: power_sta_files (list) + + +.. py:function:: get_all_timing_sta_files(run_directory) + + This function aims to list and perform analysis on all the relevant files in a particular run between all the corners. + + :param run_directory: The run directory to perform the analysis on. Defaults to None. + :type run_directory: str, optional + + :returns: List of all the .rpt files in the run directory. + :rtype: timing_sta_files_list (list) + + +.. py:function:: get_all_power_sta_files(run_directory) + + This function aims to list and perform analysis on all the relevant files in a particular run between all the corners. + + :param run_directory: The run directory to perform the analysis on. Defaults to None. + :type run_directory: str, optional + + :returns: List of all the .rpt files in the run directory. + :rtype: power_sta_files_list (list) + + +.. py:function:: calculate_max_frame_amount(file_lines_data: pandas.DataFrame) + + Calculate the maximum frame amount based on the frame IDs in the DataFrame + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Maximum number of frames in the file + :rtype: maximum_frame_amount (int) + + +.. py:function:: calculate_propagation_delay_from_file(file_path: str | pathlib.Path) + + Calculate the propagation delay for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: Dictionary containing the propagation delay + :rtype: propagation_delay (dict) + + +.. py:function:: calculate_propagation_delay_from_timing_data(net_name_in: str, net_name_out: str, timing_data: pandas.DataFrame) + + Calculate the propagation delay between two nets + + :param net_name_in: Name of the input net + :type net_name_in: str + :param net_name_out: Name of the output net + :type net_name_out: str + :param timing_data: Dataframe containing the timing data + :type timing_data: pd.DataFrame + + :returns: Dataframe containing the propagation delay + :rtype: propagation_delay_dataframe (pd.DataFrame) + + +.. py:function:: configure_timing_data_rows(file_lines_data: pandas.DataFrame) + + Identify the timing data lines for each frame and creates a metadata dictionary for frames. + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Dictionary containing the frame metadata + :rtype: frame_meta_data (dict) + + +.. py:function:: configure_frame_id(file_lines_data: pandas.DataFrame) + + Identify the frame delimiters and assign frame ID to each line in the file + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: filter_timing_data_by_net_name_and_type(timing_data: pandas.DataFrame, net_name: str, net_type: str) + + Filter the timing data by net name and type + + :param timing_data: DataFrame containing the timing data + :type timing_data: pd.DataFrame + :param net_name: Net name to be filtered + :type net_name: str + :param net_type: Net type to be filtered + :type net_type: str + + :returns: DataFrame containing the timing data + :rtype: timing_data (pd.DataFrame) + + +.. py:function:: get_frame_meta_data(file_lines_data) + + Get the frame metadata + + :param file_lines_data: DataFrame containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: DataFrame containing the start point name + end_point_name (pd.DataFrame): DataFrame containing the end point name + path_group_name (pd.DataFrame): DataFrame containing the path group name + path_type_name (pd.DataFrame): DataFrame containing the path type name + :rtype: start_point_name (pd.DataFrame) + + +.. py:function:: get_frame_lines_data(file_path: str | pathlib.Path) + + Calculate the timing data for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: DataFrame containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: get_frame_timing_data(file: str | pathlib.Path, frame_meta_data: dict, frame_id: int = 0) + + Extract the timing data from the file + + :param file: Address of the file + :type file: str | pathlib.Path + :param frame_meta_data: Dictionary containing the frame metadata + :type frame_meta_data: dict + :param frame_id: Frame ID to be read + :type frame_id: int + + :returns: DataFrame containing the timing data + :rtype: timing_data (pd.DataFrame) + + +.. py:function:: get_all_timing_data_from_file(file_path: str | pathlib.Path) + + Calculate the timing data for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: Dictionary containing the timing data for each frame + :rtype: frame_timing_data (dict) + + +.. py:function:: read_sta_rpt_fwf_file(file: str | pathlib.Path, frame_meta_data: dict, frame_id: int = 0) + + Read the fixed width file and return a DataFrame + + :param file: Address of the file + :type file: str | pathlib.Path + :param frame_meta_data: Dictionary containing the frame metadata + :type frame_meta_data: dict + :param frame_id: Frame ID to be read + :type frame_id: int + + :returns: DataFrame containing the file data + :rtype: file_data (pd.DataFrame) + + +.. py:function:: contains_in_lines(file_lines_data: pandas.DataFrame, keyword: str) + + Check if the keyword is contained in the file lines + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + :param keyword: Keyword to search for + :type keyword: str + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: create_file_lines_dataframe(file_lines_raw) + + Create a DataFrame from the raw lines of a file + + :param file_lines_raw: list containing the file lines + :type file_lines_raw: list + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: get_file_line_by_keyword(file_lines_data: pandas.DataFrame, keyword: str, regex: str) + + Extract the data from the file lines using the given keyword and regex + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + :param keyword: Keyword to search for + :type keyword: str + :param regex: Regex to extract the data + :type regex: str + + :returns: Dataframe containing the extracted values + :rtype: extracted_values (pd.DataFrame) + + +.. py:function:: read_file_lines(file_path: str | pathlib.Path) + + Extract lines from the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: list containing the file lines + :rtype: file_lines_raw (list) diff --git a/docs/autoapi/piel/tools/openlane/parse/sta_rpt/index.rst b/docs/autoapi/piel/tools/openlane/parse/sta_rpt/index.rst new file mode 100644 index 00000000..912a3ea8 --- /dev/null +++ b/docs/autoapi/piel/tools/openlane/parse/sta_rpt/index.rst @@ -0,0 +1,167 @@ +:py:mod:`piel.tools.openlane.parse.sta_rpt` +=========================================== + +.. py:module:: piel.tools.openlane.parse.sta_rpt + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.openlane.parse.sta_rpt.calculate_max_frame_amount + piel.tools.openlane.parse.sta_rpt.calculate_propagation_delay_from_timing_data + piel.tools.openlane.parse.sta_rpt.calculate_propagation_delay_from_file + piel.tools.openlane.parse.sta_rpt.configure_timing_data_rows + piel.tools.openlane.parse.sta_rpt.configure_frame_id + piel.tools.openlane.parse.sta_rpt.filter_timing_data_by_net_name_and_type + piel.tools.openlane.parse.sta_rpt.get_frame_meta_data + piel.tools.openlane.parse.sta_rpt.get_frame_lines_data + piel.tools.openlane.parse.sta_rpt.get_frame_timing_data + piel.tools.openlane.parse.sta_rpt.get_all_timing_data_from_file + piel.tools.openlane.parse.sta_rpt.read_sta_rpt_fwf_file + + + +.. py:function:: calculate_max_frame_amount(file_lines_data: pandas.DataFrame) + + Calculate the maximum frame amount based on the frame IDs in the DataFrame + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Maximum number of frames in the file + :rtype: maximum_frame_amount (int) + + +.. py:function:: calculate_propagation_delay_from_timing_data(net_name_in: str, net_name_out: str, timing_data: pandas.DataFrame) + + Calculate the propagation delay between two nets + + :param net_name_in: Name of the input net + :type net_name_in: str + :param net_name_out: Name of the output net + :type net_name_out: str + :param timing_data: Dataframe containing the timing data + :type timing_data: pd.DataFrame + + :returns: Dataframe containing the propagation delay + :rtype: propagation_delay_dataframe (pd.DataFrame) + + +.. py:function:: calculate_propagation_delay_from_file(file_path: str | pathlib.Path) + + Calculate the propagation delay for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: Dictionary containing the propagation delay + :rtype: propagation_delay (dict) + + +.. py:function:: configure_timing_data_rows(file_lines_data: pandas.DataFrame) + + Identify the timing data lines for each frame and creates a metadata dictionary for frames. + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Dictionary containing the frame metadata + :rtype: frame_meta_data (dict) + + +.. py:function:: configure_frame_id(file_lines_data: pandas.DataFrame) + + Identify the frame delimiters and assign frame ID to each line in the file + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: filter_timing_data_by_net_name_and_type(timing_data: pandas.DataFrame, net_name: str, net_type: str) + + Filter the timing data by net name and type + + :param timing_data: DataFrame containing the timing data + :type timing_data: pd.DataFrame + :param net_name: Net name to be filtered + :type net_name: str + :param net_type: Net type to be filtered + :type net_type: str + + :returns: DataFrame containing the timing data + :rtype: timing_data (pd.DataFrame) + + +.. py:function:: get_frame_meta_data(file_lines_data) + + Get the frame metadata + + :param file_lines_data: DataFrame containing the file lines + :type file_lines_data: pd.DataFrame + + :returns: DataFrame containing the start point name + end_point_name (pd.DataFrame): DataFrame containing the end point name + path_group_name (pd.DataFrame): DataFrame containing the path group name + path_type_name (pd.DataFrame): DataFrame containing the path type name + :rtype: start_point_name (pd.DataFrame) + + +.. py:function:: get_frame_lines_data(file_path: str | pathlib.Path) + + Calculate the timing data for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: DataFrame containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: get_frame_timing_data(file: str | pathlib.Path, frame_meta_data: dict, frame_id: int = 0) + + Extract the timing data from the file + + :param file: Address of the file + :type file: str | pathlib.Path + :param frame_meta_data: Dictionary containing the frame metadata + :type frame_meta_data: dict + :param frame_id: Frame ID to be read + :type frame_id: int + + :returns: DataFrame containing the timing data + :rtype: timing_data (pd.DataFrame) + + +.. py:function:: get_all_timing_data_from_file(file_path: str | pathlib.Path) + + Calculate the timing data for each frame in the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: Dictionary containing the timing data for each frame + :rtype: frame_timing_data (dict) + + +.. py:function:: read_sta_rpt_fwf_file(file: str | pathlib.Path, frame_meta_data: dict, frame_id: int = 0) + + Read the fixed width file and return a DataFrame + + :param file: Address of the file + :type file: str | pathlib.Path + :param frame_meta_data: Dictionary containing the frame metadata + :type frame_meta_data: dict + :param frame_id: Frame ID to be read + :type frame_id: int + + :returns: DataFrame containing the file data + :rtype: file_data (pd.DataFrame) diff --git a/docs/autoapi/piel/tools/openlane/parse/utils/index.rst b/docs/autoapi/piel/tools/openlane/parse/utils/index.rst new file mode 100644 index 00000000..8315394c --- /dev/null +++ b/docs/autoapi/piel/tools/openlane/parse/utils/index.rst @@ -0,0 +1,70 @@ +:py:mod:`piel.tools.openlane.parse.utils` +========================================= + +.. py:module:: piel.tools.openlane.parse.utils + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.openlane.parse.utils.contains_in_lines + piel.tools.openlane.parse.utils.create_file_lines_dataframe + piel.tools.openlane.parse.utils.get_file_line_by_keyword + piel.tools.openlane.parse.utils.read_file_lines + + + +.. py:function:: contains_in_lines(file_lines_data: pandas.DataFrame, keyword: str) + + Check if the keyword is contained in the file lines + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + :param keyword: Keyword to search for + :type keyword: str + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: create_file_lines_dataframe(file_lines_raw) + + Create a DataFrame from the raw lines of a file + + :param file_lines_raw: list containing the file lines + :type file_lines_raw: list + + :returns: Dataframe containing the file lines + :rtype: file_lines_data (pd.DataFrame) + + +.. py:function:: get_file_line_by_keyword(file_lines_data: pandas.DataFrame, keyword: str, regex: str) + + Extract the data from the file lines using the given keyword and regex + + :param file_lines_data: Dataframe containing the file lines + :type file_lines_data: pd.DataFrame + :param keyword: Keyword to search for + :type keyword: str + :param regex: Regex to extract the data + :type regex: str + + :returns: Dataframe containing the extracted values + :rtype: extracted_values (pd.DataFrame) + + +.. py:function:: read_file_lines(file_path: str | pathlib.Path) + + Extract lines from the file + + :param file_path: Path to the file + :type file_path: str | pathlib.Path + + :returns: list containing the file lines + :rtype: file_lines_raw (list) diff --git a/docs/autoapi/piel/tools/openlane/utils/index.rst b/docs/autoapi/piel/tools/openlane/utils/index.rst new file mode 100644 index 00000000..805fa429 --- /dev/null +++ b/docs/autoapi/piel/tools/openlane/utils/index.rst @@ -0,0 +1,26 @@ +:py:mod:`piel.tools.openlane.utils` +=================================== + +.. py:module:: piel.tools.openlane.utils + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.openlane.utils.find_design_run + + + +.. py:function:: find_design_run(design_directory: piel.config.piel_path_types, run_name: str | None = None) -> pathlib.Path + + For a given `design_directory`, the `openlane` output can be found in the `runs` subdirectory. + + They get sorted based on a reverse `list.sort()` method. + + # TODO docs diff --git a/docs/autoapi/piel/tools/openlane/v1/index.rst b/docs/autoapi/piel/tools/openlane/v1/index.rst new file mode 100644 index 00000000..2151d540 --- /dev/null +++ b/docs/autoapi/piel/tools/openlane/v1/index.rst @@ -0,0 +1,157 @@ +:py:mod:`piel.tools.openlane.v1` +================================ + +.. py:module:: piel.tools.openlane.v1 + +.. autoapi-nested-parse:: + + These set of functions aim to provide functionality to automate interacting with OpenLanes v1 design into Python environment, whilst `OpenLanes2` is under development. + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.openlane.v1.check_config_json_exists_openlane_v1 + piel.tools.openlane.v1.check_design_exists_openlane_v1 + piel.tools.openlane.v1.configure_and_run_design_openlane_v1 + piel.tools.openlane.v1.configure_flow_script_openlane_v1 + piel.tools.openlane.v1.configure_parametric_designs_openlane_v1 + piel.tools.openlane.v1.create_parametric_designs_openlane_v1 + piel.tools.openlane.v1.get_latest_version_root_openlane_v1 + piel.tools.openlane.v1.get_design_directory_from_root_openlane_v1 + piel.tools.openlane.v1.read_configuration_openlane_v1 + piel.tools.openlane.v1.write_configuration_openlane_v1 + + + +.. py:function:: check_config_json_exists_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> bool + + Checks if a design has a `config.json` file. + + :param design_name: Name of the design. + :type design_name: str + + :returns: True if `config.json` exists. + :rtype: config_json_exists(bool) + + +.. py:function:: check_design_exists_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> bool + + Checks if a design exists in the OpenLane v1 design folder. + + Lists all designs inside the Openlane V1 design root. + + :param design_name: Name of the design. + :type design_name: str + + :returns: True if design exists. + :rtype: design_exists(bool) + + +.. py:function:: configure_and_run_design_openlane_v1(design_name: str, configuration: dict | None = None, root_directory: str | pathlib.Path | None = None) -> None + + Configures and runs an OpenLane v1 design. + + This function does the following: + 1. Check that the design_directory provided is under $OPENLANE_ROOT//designs + 2. Check if `config.json` has already been provided for this design. If a configuration dictionary is inputted into the function parameters, then it overwrites the default `config.json`. + 3. Create a script directory, a script is written and permissions are provided for it to be executable. + 4. Permit and execute the `openlane_flow.sh` script in the `scripts` directory. + + :param design_name: Name of the design. + :type design_name: str + :param configuration: Configuration dictionary. + :type configuration: dict | None + :param root_directory: Design directory. + :type root_directory: str | pathlib.Path + + :returns: None + + +.. py:function:: configure_flow_script_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> None + + Configures the OpenLane v1 flow script after checking that the design directory exists. + + :param design_directory: Design directory. Defaults to latest OpenLane root. + :type design_directory: str | pathlib.Path | None + + :returns: None + + +.. py:function:: configure_parametric_designs_openlane_v1(design_name: str, parameter_sweep_dictionary: dict, add_id: bool = True) -> list + + For a given `source_design_directory`, this function reads in the config.json file and returns a set of parametric sweeps that gets used when creating a set of parametric designs. + + :param add_id: Add an ID to the design name. Defaults to True. + :type add_id: bool + :param parameter_sweep_dictionary: Dictionary of parameters to sweep. + :type parameter_sweep_dictionary: dict + :param source_design_directory: Source design directory. + :type source_design_directory: str | pathlib.Path + + :returns: List of configurations to sweep. + :rtype: configuration_sweep(list) + + +.. py:function:: create_parametric_designs_openlane_v1(design_name: str, parameter_sweep_dictionary: dict, target_directory: str | pathlib.Path | None = None) -> None + + Takes a OpenLane v1 source directory and creates a parametric combination of these designs. + + :param design_name: Name of the design. + :type design_name: str + :param parameter_sweep_dictionary: Dictionary of parameters to sweep. + :type parameter_sweep_dictionary: dict + :param target_directory: Optional target directory. + :type target_directory: str | pathlib.Path | None + + :returns: None + + +.. py:function:: get_latest_version_root_openlane_v1() -> pathlib.Path + + Gets the latest version root of OpenLane v1. + + +.. py:function:: get_design_directory_from_root_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> pathlib.Path + + Gets the design directory from the root directory. + + :param design_name: Name of the design. + :type design_name: str + :param root_directory: Design directory. + :type root_directory: str | pathlib.Path + + :returns: Design directory. + :rtype: design_directory(pathlib.Path) + + +.. py:function:: read_configuration_openlane_v1(design_name: str, root_directory: str | pathlib.Path | None = None) -> dict + + Reads a `config.json` from a design directory. + + :param design_name: Design name. + :type design_name: str + :param root_directory: Design directory. + :type root_directory: str | pathlib.Path + + :returns: Configuration dictionary. + :rtype: configuration(dict) + + +.. py:function:: write_configuration_openlane_v1(configuration: dict, design_directory: str | pathlib.Path) -> None + + Writes a `config.json` onto a `design_directory` + + :param configuration: OpenLane configuration dictionary. + :type configuration: dict + :param design_directory: Design directory PATH. + :type design_directory: str + + :returns: None diff --git a/docs/autoapi/piel/tools/openlane/v2/index.rst b/docs/autoapi/piel/tools/openlane/v2/index.rst new file mode 100644 index 00000000..8f903041 --- /dev/null +++ b/docs/autoapi/piel/tools/openlane/v2/index.rst @@ -0,0 +1,29 @@ +:py:mod:`piel.tools.openlane.v2` +================================ + +.. py:module:: piel.tools.openlane.v2 + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.openlane.v2.run_openlane_flow + + + +.. py:function:: run_openlane_flow(configuration: dict | None = test_spm_open_lane_configuration, design_directory: piel.config.piel_path_types = '/foss/designs/spm') -> None + + Runs the OpenLane flow. + + :param configuration: OpenLane configuration dictionary. If none is present it will default to the config.json file on the design_directory. + :type configuration: dict + :param design_directory: Design directory PATH. + :type design_directory: piel_path_types + + :returns: None diff --git a/docs/autoapi/piel/tools/sax/index.rst b/docs/autoapi/piel/tools/sax/index.rst new file mode 100644 index 00000000..437c504b --- /dev/null +++ b/docs/autoapi/piel/tools/sax/index.rst @@ -0,0 +1,168 @@ +:py:mod:`piel.tools.sax` +======================== + +.. py:module:: piel.tools.sax + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + utils/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.sax.get_sdense_ports_index + piel.tools.sax.sax_to_s_parameters_standard_matrix + + + +Attributes +~~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.sax.snet + + +.. py:function:: get_sdense_ports_index(input_ports_order: tuple, all_ports_index: dict) -> dict + + This function returns the ports index of the sax dense S-parameter matrix. + + Given that the order of the iteration is provided by the user, the dictionary keys will also be ordered + accordingly when iterating over them. This requires the user to provide a set of ordered. + + TODO verify reasonable iteration order. + + .. code-block:: python + + # The input_ports_order can be a tuple of tuples that contain the index and port name. Eg. + input_ports_order = ((0, "in_o_0"), (5, "in_o_1"), (6, "in_o_2"), (7, "in_o_3")) + # The all_ports_index is a dictionary of the ports index. Eg. + all_ports_index = { + "in_o_0": 0, + "out_o_0": 1, + "out_o_1": 2, + "out_o_2": 3, + "out_o_3": 4, + "in_o_1": 5, + "in_o_2": 6, + "in_o_3": 7, + } + # Output + {"in_o_0": 0, "in_o_1": 5, "in_o_2": 6, "in_o_3": 7} + + :param input_ports_order: The ports order tuple. Can be a tuple of tuples that contain the index and port name. + :type input_ports_order: tuple + :param all_ports_index: The ports index dictionary. + :type all_ports_index: dict + + :returns: The ordered input ports index tuple. + :rtype: tuple + + +.. py:function:: sax_to_s_parameters_standard_matrix(sax_input: sax.SType, input_ports_order: tuple | None = None) -> tuple + + A ``sax`` S-parameter SDict is provided as a dictionary of tuples with (port0, port1) as the key. This + determines the direction of the scattering relationship. It means that the number of terms in an S-parameter + matrix is the number of ports squared. + + In order to generalise, this function returns both the S-parameter matrices and the indexing ports based on the + amount provided. In terms of computational speed, we definitely would like this function to be algorithmically + very fast. For now, I will write a simple python implementation and optimise in the future. + + It is possible to see the `sax` SDense notation equivalence here: + https://flaport.github.io/sax/nbs/08_backends.html + + .. code-block:: python + + import jax.numpy as jnp + from sax.core import SDense + + # Directional coupler SDense representation + dc_sdense: SDense = ( + jnp.array([[0, 0, τ, κ], [0, 0, κ, τ], [τ, κ, 0, 0], [κ, τ, 0, 0]]), + {"in0": 0, "in1": 1, "out0": 2, "out1": 3}, + ) + + + # Directional coupler SDict representation + # Taken from https://flaport.github.io/sax/nbs/05_models.html + def coupler(*, coupling: float = 0.5) -> SDict: + kappa = coupling**0.5 + tau = (1 - coupling) ** 0.5 + sdict = reciprocal( + { + ("in0", "out0"): tau, + ("in0", "out1"): 1j * kappa, + ("in1", "out0"): 1j * kappa, + ("in1", "out1"): tau, + } + ) + return sdict + + If we were to relate the mapping accordingly based on the ports indexes, a S-Parameter matrix in the form of + :math:`S_{(output,i),(input,i)}` would be: + + .. math:: + + S = \begin{bmatrix} + S_{00} & S_{10} \\ + S_{01} & S_{11} \\ + \end{bmatrix} = + \begin{bmatrix} + \tau & j \kappa \\ + j \kappa & \tau \\ + \end{bmatrix} + + Note that the standard S-parameter and hence unitary representation is in the form of: + + .. math:: + + S = \begin{bmatrix} + S_{00} & S_{01} \\ + S_{10} & S_{11} \\ + \end{bmatrix} + + + .. math:: + + \begin{bmatrix} + b_{1} \\ + \vdots \\ + b_{n} + \end{bmatrix} + = + \begin{bmatrix} + S_{11} & \dots & S_{1n} \\ + \vdots & \ddots & \vdots \\ + S_{n1} & \dots & S_{nn} + \end{bmatrix} + \begin{bmatrix} + a_{1} \\ + \vdots \\ + a_{n} + \end{bmatrix} + + TODO check with Floris, does this mean we need to transpose the matrix? + + :param sax_input: The sax S-parameter dictionary. + :type sax_input: sax.SType + :param input_ports_order: The ports order tuple containing the names and order of the input ports. + :type input_ports_order: tuple + + :returns: The S-parameter matrix and the input ports index tuple in the standard S-parameter notation. + :rtype: tuple + + +.. py:data:: snet diff --git a/docs/autoapi/piel/tools/sax/utils/index.rst b/docs/autoapi/piel/tools/sax/utils/index.rst new file mode 100644 index 00000000..adb099b5 --- /dev/null +++ b/docs/autoapi/piel/tools/sax/utils/index.rst @@ -0,0 +1,164 @@ +:py:mod:`piel.tools.sax.utils` +============================== + +.. py:module:: piel.tools.sax.utils + +.. autoapi-nested-parse:: + + This file provides a set of utilities that allow much easier integration between `sax` and the relevant tools that we use. + + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.sax.utils.get_sdense_ports_index + piel.tools.sax.utils.sax_to_s_parameters_standard_matrix + + + +Attributes +~~~~~~~~~~ + +.. autoapisummary:: + + piel.tools.sax.utils.snet + + +.. py:function:: get_sdense_ports_index(input_ports_order: tuple, all_ports_index: dict) -> dict + + This function returns the ports index of the sax dense S-parameter matrix. + + Given that the order of the iteration is provided by the user, the dictionary keys will also be ordered + accordingly when iterating over them. This requires the user to provide a set of ordered. + + TODO verify reasonable iteration order. + + .. code-block:: python + + # The input_ports_order can be a tuple of tuples that contain the index and port name. Eg. + input_ports_order = ((0, "in_o_0"), (5, "in_o_1"), (6, "in_o_2"), (7, "in_o_3")) + # The all_ports_index is a dictionary of the ports index. Eg. + all_ports_index = { + "in_o_0": 0, + "out_o_0": 1, + "out_o_1": 2, + "out_o_2": 3, + "out_o_3": 4, + "in_o_1": 5, + "in_o_2": 6, + "in_o_3": 7, + } + # Output + {"in_o_0": 0, "in_o_1": 5, "in_o_2": 6, "in_o_3": 7} + + :param input_ports_order: The ports order tuple. Can be a tuple of tuples that contain the index and port name. + :type input_ports_order: tuple + :param all_ports_index: The ports index dictionary. + :type all_ports_index: dict + + :returns: The ordered input ports index tuple. + :rtype: tuple + + +.. py:function:: sax_to_s_parameters_standard_matrix(sax_input: sax.SType, input_ports_order: tuple | None = None) -> tuple + + A ``sax`` S-parameter SDict is provided as a dictionary of tuples with (port0, port1) as the key. This + determines the direction of the scattering relationship. It means that the number of terms in an S-parameter + matrix is the number of ports squared. + + In order to generalise, this function returns both the S-parameter matrices and the indexing ports based on the + amount provided. In terms of computational speed, we definitely would like this function to be algorithmically + very fast. For now, I will write a simple python implementation and optimise in the future. + + It is possible to see the `sax` SDense notation equivalence here: + https://flaport.github.io/sax/nbs/08_backends.html + + .. code-block:: python + + import jax.numpy as jnp + from sax.core import SDense + + # Directional coupler SDense representation + dc_sdense: SDense = ( + jnp.array([[0, 0, τ, κ], [0, 0, κ, τ], [τ, κ, 0, 0], [κ, τ, 0, 0]]), + {"in0": 0, "in1": 1, "out0": 2, "out1": 3}, + ) + + + # Directional coupler SDict representation + # Taken from https://flaport.github.io/sax/nbs/05_models.html + def coupler(*, coupling: float = 0.5) -> SDict: + kappa = coupling**0.5 + tau = (1 - coupling) ** 0.5 + sdict = reciprocal( + { + ("in0", "out0"): tau, + ("in0", "out1"): 1j * kappa, + ("in1", "out0"): 1j * kappa, + ("in1", "out1"): tau, + } + ) + return sdict + + If we were to relate the mapping accordingly based on the ports indexes, a S-Parameter matrix in the form of + :math:`S_{(output,i),(input,i)}` would be: + + .. math:: + + S = \begin{bmatrix} + S_{00} & S_{10} \\ + S_{01} & S_{11} \\ + \end{bmatrix} = + \begin{bmatrix} + \tau & j \kappa \\ + j \kappa & \tau \\ + \end{bmatrix} + + Note that the standard S-parameter and hence unitary representation is in the form of: + + .. math:: + + S = \begin{bmatrix} + S_{00} & S_{01} \\ + S_{10} & S_{11} \\ + \end{bmatrix} + + + .. math:: + + \begin{bmatrix} + b_{1} \\ + \vdots \\ + b_{n} + \end{bmatrix} + = + \begin{bmatrix} + S_{11} & \dots & S_{1n} \\ + \vdots & \ddots & \vdots \\ + S_{n1} & \dots & S_{nn} + \end{bmatrix} + \begin{bmatrix} + a_{1} \\ + \vdots \\ + a_{n} + \end{bmatrix} + + TODO check with Floris, does this mean we need to transpose the matrix? + + :param sax_input: The sax S-parameter dictionary. + :type sax_input: sax.SType + :param input_ports_order: The ports order tuple containing the names and order of the input ports. + :type input_ports_order: tuple + + :returns: The S-parameter matrix and the input ports index tuple in the standard S-parameter notation. + :rtype: tuple + + +.. py:data:: snet diff --git a/docs/autoapi/piel/visual/auto_plot_multiple/index.rst b/docs/autoapi/piel/visual/auto_plot_multiple/index.rst new file mode 100644 index 00000000..cd3a8f39 --- /dev/null +++ b/docs/autoapi/piel/visual/auto_plot_multiple/index.rst @@ -0,0 +1,41 @@ +:py:mod:`piel.visual.auto_plot_multiple` +======================================== + +.. py:module:: piel.visual.auto_plot_multiple + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.visual.auto_plot_multiple.plot_simple_multi_row + piel.visual.auto_plot_multiple.plot_multi_row + + + +.. py:function:: plot_simple_multi_row(data: pandas.DataFrame, x_axis_column_name: str = 't', row_list: list | None = None, y_axis_title_list: list | None = None, x_axis_title: str | None = None) + + Plot multiple rows of data on the same plot. Each row is a different line. Each row is a different y axis. The x + axis is the same for all rows. The y axis title is the same for all rows. + + :param data: Data to plot. + :type data: pd.DataFrame + :param x_axis_column_name: Column name of the x axis. Defaults to "t". + :type x_axis_column_name: str, optional + :param row_list: List of column names to plot. Defaults to None. + :type row_list: list, optional + :param y_axis_title_list: List of y axis titles. Defaults to None. + :type y_axis_title_list: list, optional + :param x_axis_title: Title of the x axis. Defaults to None. + :type x_axis_title: str, optional + + :returns: Matplotlib plot. + :rtype: plt + + +.. py:function:: plot_multi_row(data: pandas.DataFrame) diff --git a/docs/autoapi/piel/visual/data_conversion/index.rst b/docs/autoapi/piel/visual/data_conversion/index.rst new file mode 100644 index 00000000..6989c496 --- /dev/null +++ b/docs/autoapi/piel/visual/data_conversion/index.rst @@ -0,0 +1,70 @@ +:py:mod:`piel.visual.data_conversion` +===================================== + +.. py:module:: piel.visual.data_conversion + + +Module Contents +--------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.visual.data_conversion.append_row_to_dict + piel.visual.data_conversion.points_to_lines_fixed_transient + + + +.. py:function:: append_row_to_dict(data: dict, copy_index: int, set_value: dict) + + Get all the rows of the dictionary. We want to copy and append a row at a particular index of the dictionary values. + Operates on existing data + + :param data: Dictionary of data to be appended. + :param copy_index: Index of the row to be copied. + :param set_value: Dictionary of values to be set at the copied index. + + :returns: None + + +.. py:function:: points_to_lines_fixed_transient(data: pandas.DataFrame | dict, time_index_name: str, fixed_transient_time=1, return_dict: bool = False) + + This function converts specific steady-state point data into steady-state lines with a defined transient time in order to plot digital-style data. + + For example, VCD data tends to be structured in this form: + + .. code-block:: text + + #2001 + b1001 " + b10010 # + b1001 ! + #4001 + b1011 " + b1011 # + b0 ! + #6001 + b101 " + + This means that even when tokenizing the data, when visualising it in a wave plotter such as GTKWave, the signals + get converted from token specific times to transient signals by a corresponding transient rise time. If we want + to plot the data correspondingly in Python, it is necessary to add some form of transient signal translation. + Note that this operates on a dataframe where the electrical time signals are clearly defined. It copies the + corresponding steady-state data points whilst adding data points for the time-index accordingly. + + It starts by creating a copy of the initial dataframe as to not overwrite the existing data. We have an initial + time data point that tends to start at time 0. This means we need to add a point just before the next steady + state point transition. So what we want to do is copy the existing row and just change the time to be the + `fixed_transient_time` before the next transition. + + Doesn't append on penultimate row. + + :param data: Dataframe or dictionary of data to be converted. + :param time_index_name: Name of the time index column. + :param fixed_transient_time: Time of the transient signal. + :param return_dict: Return a dictionary instead of a dataframe. + + :returns: Dataframe or dictionary of data with steady-state lines. diff --git a/docs/autoapi/piel/visual/index.rst b/docs/autoapi/piel/visual/index.rst new file mode 100644 index 00000000..f9c3bf92 --- /dev/null +++ b/docs/autoapi/piel/visual/index.rst @@ -0,0 +1,105 @@ +:py:mod:`piel.visual` +===================== + +.. py:module:: piel.visual + + +Submodules +---------- +.. toctree:: + :titlesonly: + :maxdepth: 1 + + auto_plot_multiple/index.rst + data_conversion/index.rst + + +Package Contents +---------------- + + +Functions +~~~~~~~~~ + +.. autoapisummary:: + + piel.visual.plot_simple_multi_row + piel.visual.plot_multi_row + piel.visual.append_row_to_dict + piel.visual.points_to_lines_fixed_transient + + + +.. py:function:: plot_simple_multi_row(data: pandas.DataFrame, x_axis_column_name: str = 't', row_list: list | None = None, y_axis_title_list: list | None = None, x_axis_title: str | None = None) + + Plot multiple rows of data on the same plot. Each row is a different line. Each row is a different y axis. The x + axis is the same for all rows. The y axis title is the same for all rows. + + :param data: Data to plot. + :type data: pd.DataFrame + :param x_axis_column_name: Column name of the x axis. Defaults to "t". + :type x_axis_column_name: str, optional + :param row_list: List of column names to plot. Defaults to None. + :type row_list: list, optional + :param y_axis_title_list: List of y axis titles. Defaults to None. + :type y_axis_title_list: list, optional + :param x_axis_title: Title of the x axis. Defaults to None. + :type x_axis_title: str, optional + + :returns: Matplotlib plot. + :rtype: plt + + +.. py:function:: plot_multi_row(data: pandas.DataFrame) + + +.. py:function:: append_row_to_dict(data: dict, copy_index: int, set_value: dict) + + Get all the rows of the dictionary. We want to copy and append a row at a particular index of the dictionary values. + Operates on existing data + + :param data: Dictionary of data to be appended. + :param copy_index: Index of the row to be copied. + :param set_value: Dictionary of values to be set at the copied index. + + :returns: None + + +.. py:function:: points_to_lines_fixed_transient(data: pandas.DataFrame | dict, time_index_name: str, fixed_transient_time=1, return_dict: bool = False) + + This function converts specific steady-state point data into steady-state lines with a defined transient time in order to plot digital-style data. + + For example, VCD data tends to be structured in this form: + + .. code-block:: text + + #2001 + b1001 " + b10010 # + b1001 ! + #4001 + b1011 " + b1011 # + b0 ! + #6001 + b101 " + + This means that even when tokenizing the data, when visualising it in a wave plotter such as GTKWave, the signals + get converted from token specific times to transient signals by a corresponding transient rise time. If we want + to plot the data correspondingly in Python, it is necessary to add some form of transient signal translation. + Note that this operates on a dataframe where the electrical time signals are clearly defined. It copies the + corresponding steady-state data points whilst adding data points for the time-index accordingly. + + It starts by creating a copy of the initial dataframe as to not overwrite the existing data. We have an initial + time data point that tends to start at time 0. This means we need to add a point just before the next steady + state point transition. So what we want to do is copy the existing row and just change the time to be the + `fixed_transient_time` before the next transition. + + Doesn't append on penultimate row. + + :param data: Dataframe or dictionary of data to be converted. + :param time_index_name: Name of the time index column. + :param fixed_transient_time: Time of the transient signal. + :param return_dict: Return a dictionary instead of a dataframe. + + :returns: Dataframe or dictionary of data with steady-state lines. diff --git a/docs/examples/04_spice_cosimulation.py b/docs/examples/04_spice_cosimulation.py index 88e7ad84..d28252f0 100644 --- a/docs/examples/04_spice_cosimulation.py +++ b/docs/examples/04_spice_cosimulation.py @@ -161,14 +161,14 @@ our_resistive_heater_circuit.ports # ```python -# {'e1': Signal(name=None, width=1, desc=None), -# 'e2': Signal(name=None, width=1, desc=None), -# 'via_stack_1__e1': PortRef(inst=Instance(name=via_stack_1 of=GeneratorCall(gen=via_stack)), portname='e1'), -# 'via_stack_1__e2': PortRef(inst=Instance(name=via_stack_1 of=GeneratorCall(gen=via_stack)), portname='e2'), -# 'via_stack_1__e4': PortRef(inst=Instance(name=via_stack_1 of=GeneratorCall(gen=via_stack)), portname='e4'), -# 'via_stack_2__e2': PortRef(inst=Instance(name=via_stack_2 of=GeneratorCall(gen=via_stack)), portname='e2'), -# 'via_stack_2__e3': PortRef(inst=Instance(name=via_stack_2 of=GeneratorCall(gen=via_stack)), portname='e3'), -# 'via_stack_2__e4': PortRef(inst=Instance(name=via_stack_2 of=GeneratorCall(gen=via_stack)), portname='e4')} +# {'e1': Signal(name='e1', width=1, desc=None), +# 'e2': Signal(name='e2', width=1, desc=None), +# 'via_stack_1__e1': Signal(name='via_stack_1__e1', width=1, desc=None), +# 'via_stack_1__e2': Signal(name='via_stack_1__e2', width=1, desc=None), +# 'via_stack_1__e4': Signal(name='via_stack_1__e4', width=1, desc=None), +# 'via_stack_2__e2': Signal(name='via_stack_2__e2', width=1, desc=None), +# 'via_stack_2__e3': Signal(name='via_stack_2__e3', width=1, desc=None), +# 'via_stack_2__e4': Signal(name='via_stack_2__e4', width=1, desc=None)} # ``` # Same for the signals @@ -176,45 +176,12 @@ our_resistive_heater_circuit.signals # ```python -# {'taper_1_e2': Signal(name='taper_1_e2', width=1, desc=None), -# 'taper_2_e2': Signal(name='taper_2_e2', width=1, desc=None), -# 'via_stack_1_e3': Signal(name='via_stack_1_e3', width=1, desc=None), -# 'via_stack_1_e1': Signal(name='via_stack_1_e1', width=1, desc=None), -# 'via_stack_1_e2': Signal(name='via_stack_1_e2', width=1, desc=None), -# 'via_stack_1_e4': Signal(name='via_stack_1_e4', width=1, desc=None), -# 'via_stack_2_e1': Signal(name='via_stack_2_e1', width=1, desc=None), -# 'via_stack_2_e2': Signal(name='via_stack_2_e2', width=1, desc=None), -# 'via_stack_2_e3': Signal(name='via_stack_2_e3', width=1, desc=None), -# 'via_stack_2_e4': Signal(name='via_stack_2_e4', width=1, desc=None)} +# {'via_stack_1_e3': Signal(name='via_stack_1_e3', width=1, desc=None), +# 'via_stack_2_e1': Signal(name='via_stack_2_e1', width=1, desc=None)} # ``` # We can explore the models we have provided too: -piel_hdl21_models = piel.models.physical.electronic.get_default_models() -piel_hdl21_models - -# We can extract the SPICE out of each model - -h.netlist(piel_hdl21_models["straight"](), sys.stdout, fmt="spice") - -# ```spice -# * Anonymous `circuit.Package` -# * Generated by `vlsirtools.SpiceNetlister` -# * -# -# .SUBCKT Straight__ -# + e1 e2 -# * No parameters -# -# rr1 -# + e1 e2 -# + 1000 -# * No parameters -# -# -# .ENDS -# ``` - # We can also extract information for our subinstances. We can also get the netlist of each subinstance using the inherent `hdl21` functionality: h.netlist( @@ -245,7 +212,7 @@ h.netlist(our_resistive_heater_circuit, sys.stdout, fmt="spice") -# ``` +# ```spice # * Anonymous `circuit.Package` # * Generated by `vlsirtools.SpiceNetlister` # * @@ -309,19 +276,19 @@ # * No parameters # # xstraight_1 -# + taper_1_e2 taper_2_e2 +# + e1 e2 # + Straight__ # * No parameters # # # xtaper_1 -# + via_stack_1_e3 taper_1_e2 +# + via_stack_1_e3 e1 # + Taper__ # * No parameters # # # xtaper_2 -# + via_stack_2_e1 taper_2_e2 +# + via_stack_2_e1 e2 # + Taper__ # * No parameters # @@ -342,7 +309,7 @@ # # ``` -# We can now simulate so much more. Note that this API is WIP. +# So this seems equivalent to the gdsfactory component representation. We can now continue to implement our SPICE simulation. # ## `SPICE` Integration @@ -350,9 +317,36 @@ # # `piel` provides a set of basic models for common photonic loads that integrates closely with `gdsfactory`. This will enable the multi-domain co-design we like when integrated with all the open-source tools we have previously exemplified. You can find the list and definition of the provided models in: # +# Currently, these models do not physically represent electrically the components yet. We will do this later. + +piel_hdl21_models = piel.models.physical.electronic.get_default_models() +piel_hdl21_models + +# We can extract the SPICE out of each model + +example_straight_resistor = piel_hdl21_models["straight"]() +h.netlist(example_straight_resistor, sys.stdout, fmt="spice") + +# ``` +# * Anonymous `circuit.Package` +# * Generated by `vlsirtools.SpiceNetlister` +# * +# +# .SUBCKT Straight__ +# + e1 e2 +# * No parameters +# +# rr1 +# + e1 e2 +# + 1000 +# * No parameters +# +# +# .ENDS +# ``` # ### Creating our Stimulus -# Let's first look into how to map a numpy data into a SPICE waveform. +# Let's first look into how to map a numpy data into a SPICE waveform. We will create a testbench using the `hdl21` interface. So the first thing is that we need to add our *stimulus* sources, or otherwise where would our pulses come from. We need to construct this into our testbench module. # ### Mixed-Signal Electronic Photonic Simulation Methodology diff --git a/docs/sections/about/motivation.md b/docs/sections/about/motivation.md index 8797feed..cc24e4cc 100644 --- a/docs/sections/about/motivation.md +++ b/docs/sections/about/motivation.md @@ -1,5 +1,7 @@ # Motivation +## Open-Source Motivation + Standing on the shoulders of open-source giants. As scientists, not as software developers, sometimes we have a knack for reinventing the (software) wheel in our projects whilst not creating interfaces for utility connectivity of the work we do. I see a tendency to focus on solving a specific circumstantial problem, rather than allowing others to clearly understand the context and issue, let the knowledge from multiple disciplines contribute to a good solution, and generalise the functionality of our toolset to achieve more in the future. diff --git a/docs/sections/models/spice_integration.rst b/docs/sections/models/spice_integration.rst index bf15b67a..826454a1 100644 --- a/docs/sections/models/spice_integration.rst +++ b/docs/sections/models/spice_integration.rst @@ -30,6 +30,7 @@ is an input or output is essential based on the initially parsed netlist. A gene and the output module can be connected as part of a larger instantiation accordingly. .. code-block:: + import hdl21 as h @h.generator def MyFirstGenerator(params: MyParams) -> h.Module: diff --git a/piel/integration/gdsfactory_hdl21/conversion.py b/piel/integration/gdsfactory_hdl21/conversion.py index 750e7485..e5332a24 100644 --- a/piel/integration/gdsfactory_hdl21/conversion.py +++ b/piel/integration/gdsfactory_hdl21/conversion.py @@ -24,7 +24,7 @@ __all__ = [ "convert_connections_to_tuples", - "gdsfactory_netlist_with_hdl21_models", + "gdsfactory_netlist_with_hdl21_generators", ] @@ -91,9 +91,9 @@ def get_matching_port_nets(names, connections): return matching_strings -def gdsfactory_netlist_with_hdl21_models( +def gdsfactory_netlist_with_hdl21_generators( gdsfactory_netlist: dict, - models=None, + generators=None, ): """ This function allows us to map the ``hdl21`` models dictionary in a `sax`-like implementation to the ``GDSFactory`` netlist. This allows us to iterate over each instance in the netlist and construct a circuit after this function.] @@ -103,20 +103,20 @@ def gdsfactory_netlist_with_hdl21_models( .. code-block:: >>> import gdsfactory as gf - >>> from piel.integration.gdsfactory_hdl21.conversion import gdsfactory_netlist_with_hdl21_models + >>> from piel.integration.gdsfactory_hdl21.conversion import gdsfactory_netlist_with_hdl21_generators >>> from piel.models.physical.electronic import get_default_models - >>> gdsfactory_netlist_with_hdl21_models(gdsfactory_netlist=gf.components.mzi2x2_2x2_phase_shifter().get_netlist(exclude_port_types="optical"), models=get_default_models()) + >>> gdsfactory_netlist_with_hdl21_generators(gdsfactory_netlist=gf.components.mzi2x2_2x2_phase_shifter().get_netlist(exclude_port_types="optical"),generators=get_default_models()) Args: gdsfactory_netlist: The netlist from ``GDSFactory`` to map to the ``hdl21`` models dictionary. - models: The ``hdl21`` models dictionary to map to the ``GDSFactory`` netlist. + generators: The ``hdl21`` models dictionary to map to the ``GDSFactory`` netlist. Returns: The ``GDSFactory`` netlist with the ``hdl21`` models dictionary. """ electrical_models_netlist = copy.copy(gdsfactory_netlist) - if models is None: - models = get_default_models() + if generators is None: + generators = get_default_models() netlist = _ensure_recursive_netlist_dict(gdsfactory_netlist) @@ -126,23 +126,25 @@ def gdsfactory_netlist_with_hdl21_models( recnet: RecursiveNetlist = _validate_net(netlist) dependency_dag: nx.DiGraph = _validate_dag( - create_dag(recnet, models) + create_dag(recnet, generators) ) # directed acyclic graph - models = _validate_models({**(models or {}), **instance_models}, dependency_dag) + generators = _validate_models( + {**(generators or {}), **instance_models}, dependency_dag + ) new_models = {} current_models = {} model_names = list(nx.topological_sort(dependency_dag))[::-1] for model_name in model_names: - if model_name in models: - new_models[model_name] = models[model_name] + if model_name in generators: + new_models[model_name] = generators[model_name] continue flatnet = recnet.__root__[model_name] current_models.update(new_models) new_models = {} inst2model = { - k: models[inst.component] for k, inst in flatnet.instances.items() + k: generators[inst.component] for k, inst in flatnet.instances.items() } # Iterate over every instance and append the corresponding required SPICE connectivity diff --git a/piel/integration/gdsfactory_hdl21/core.py b/piel/integration/gdsfactory_hdl21/core.py index 0fa49540..a52ac479 100644 --- a/piel/integration/gdsfactory_hdl21/core.py +++ b/piel/integration/gdsfactory_hdl21/core.py @@ -187,17 +187,19 @@ not have to deal with directionality. After instance declaration, and models for each of these components with the corresponding port topology, it is then straightforward to parse the connectivity and implement the network, and extract the SPICE. """ +import hdl21 import hdl21 as h -from .conversion import convert_connections_to_tuples +from .conversion import ( + convert_connections_to_tuples, + gdsfactory_netlist_with_hdl21_generators, +) __all__ = ["gdsfactory_netlist_to_spice_netlist", "construct_hdl21_module"] def gdsfactory_netlist_to_spice_netlist( - gdsfactory_netlist: dict, - models: dict, - return_raw_spice: bool = False, -): + gdsfactory_netlist: dict, generators: dict, **kwargs +) -> hdl21.Module: """ This function converts a GDSFactory electrical netlist into a standard SPICE netlist. It follows the same principle as the `sax` circuit composition. @@ -209,8 +211,19 @@ def gdsfactory_netlist_to_spice_netlist( We know that the gdsfactory has a set of instances, and we can map unique models via sax through our own composition circuit. Write the SPICE component based on the model into a total circuit representation in string from the reshaped gdsfactory dictionary into our own structure. + + Args: + gdsfactory_netlist: GDSFactory netlist + generators: Dictionary of Generators + + Returns: + hdl21 module or raw SPICE string """ - pass + spice_netlist = gdsfactory_netlist_with_hdl21_generators( + gdsfactory_netlist=gdsfactory_netlist, generators=generators + ) + hdl21_module = construct_hdl21_module(spice_netlist=spice_netlist) + return hdl21_module def construct_hdl21_module(spice_netlist: dict, **kwargs) -> h.Module: @@ -241,7 +254,7 @@ def construct_hdl21_module(spice_netlist: dict, **kwargs) -> h.Module: # Create top level ports for port_name_i, _ in spice_netlist["ports"].items(): # TODO include directionality on port_settings so that it can be easily interconencted with hdl21 - circuit.ports[port_name_i] = h.Port(name=port_name_i) + circuit.add(val=h.Port(name=port_name_i)) # Create the connectivity connections_list = convert_connections_to_tuples(spice_netlist["connections"]) @@ -264,14 +277,15 @@ def construct_hdl21_module(spice_netlist: dict, **kwargs) -> h.Module: instance_port_spice_name_i = instance_port_name_i.replace(",", "__") instance_name_i, port_name_i = instance_port_name_i.split(",") instance_i = getattr(circuit, instance_name_i) - # instance_port_i = getattr(instance_i, port_name_i) circuit.add(val=h.Port(), name=instance_port_spice_name_i) circuit_port_i = getattr(circuit, instance_port_spice_name_i) instance_i.connect(port_name_i, circuit_port_i) - # instance_i.replace(port_name_i, circuit_port_i) - # circuit_port_i = instance_port_i - # circuit.add(val=getattr(instance_i, port_name_i), name=instance_port_spice_name_i) - # TODO Create the top level connectivity between the top circuit ports to the instances ports. + # Create the top level connectivity between the top circuit ports to the instances ports. + for circuit_port_name_i, instance_port_name_raw_i in spice_netlist["ports"].items(): + instance_name_i, instance_port_name_i = instance_port_name_raw_i.split(",") + instance_i = getattr(circuit, instance_name_i) + circuit_port_i = getattr(circuit, circuit_port_name_i) + instance_i.connect(instance_port_name_i, circuit_port_i) return h.elaborate(circuit) diff --git a/piel/tools/hdl21/__init__.py b/piel/tools/hdl21/__init__.py index 55c2c781..292c2ca2 100644 --- a/piel/tools/hdl21/__init__.py +++ b/piel/tools/hdl21/__init__.py @@ -1 +1,2 @@ from .circuit import * +from .units import * diff --git a/piel/tools/hdl21/simulator.py b/piel/tools/hdl21/simulator.py index 36c5f8cf..bbf57494 100644 --- a/piel/tools/hdl21/simulator.py +++ b/piel/tools/hdl21/simulator.py @@ -1,3 +1,25 @@ +import hdl21 as h +from hdl21.sim import Save, SaveMode, Tran + + +def configure_transient_simulation( + circuit: h.Module, + stop_time_s: float, + step_time_s: float, +): + """ + This function configures the transient simulation for the circuit. + """ + + @h.sim + class Simulation: + tb = circuit + transient_tb = Tran(stop_time_s=stop_time_s, step_time_s=step_time_s) + save_all = Save(SaveMode.ALL) + + return Simulation + + # def configure_ngspice_simulator( # circuit, # ) -> Circuit: diff --git a/piel/tools/hdl21/units.py b/piel/tools/hdl21/units.py index 7230113e..fd17b600 100644 --- a/piel/tools/hdl21/units.py +++ b/piel/tools/hdl21/units.py @@ -1,5 +1,66 @@ -def convert_numeric_to_spice_unit(): +""" +These are the corresponding prefixes from `hdl21`: + +f = FEMTO = Prefix.FEMTO +p = PICO = Prefix.PICO +n = NANO = Prefix.NANO +µ = u = MICRO = Prefix.MICRO # Note both `u` and `µ` are valid +m = MILLI = Prefix.MILLI +K = KILO = Prefix.KILO +M = MEGA = Prefix.MEGA +G = GIGA = Prefix.GIGA +T = TERA = Prefix.TERA +P = PETA = Prefix.PETA +UNIT = Prefix.UNIT + +""" +import hdl21 as h +import numpy as np + +__all__ = ["convert_numeric_to_prefix"] + + +def convert_numeric_to_prefix( + value: float, +): """ - This function converts a numeric value to a number under a SPICE unit. This allows us to connect a particular - number real output, into a term that can be used in a SPICE netlist. + This function converts a numeric value to a number under a SPICE unit closest to the base prefix. This allows us to connect a particular number real output, into a term that can be used in a SPICE netlist. """ + prefixes = [ + (h.Prefix.YOCTO, h.prefix.y), + (h.Prefix.ZEPTO, h.prefix.z), + (h.Prefix.ATTO, h.prefix.a), + (h.Prefix.FEMTO, h.prefix.f), + (h.Prefix.PICO, h.prefix.p), + (h.Prefix.NANO, h.prefix.n), + (h.Prefix.MICRO, h.prefix.µ), + (h.Prefix.MICRO, h.prefix.u), + (h.Prefix.MILLI, h.prefix.m), + (h.Prefix.CENTI, h.prefix.c), + (h.Prefix.DECI, h.prefix.d), + # (Prefix.UNIT, ''), + (h.Prefix.DECA, h.prefix.D), + (h.Prefix.KILO, h.prefix.K), + (h.Prefix.MEGA, h.prefix.M), + (h.Prefix.GIGA, h.prefix.G), + (h.Prefix.TERA, h.prefix.T), + (h.Prefix.PETA, h.prefix.P), + (h.Prefix.EXA, h.prefix.E), + (h.Prefix.ZETTA, h.prefix.Z), + (h.Prefix.YOTTA, h.prefix.Y), + ] + + base_10 = np.log10(value) + value_target_base = np.floor(base_10) + + closest_prefix = None + min_difference = 2 + for prefix, _ in prefixes: + difference = abs(value_target_base - prefix.value) + if difference < min_difference: + min_difference = difference + closest_prefix = prefix + + value /= 10**closest_prefix.value + + return value * closest_prefix diff --git a/setup.py b/setup.py index e61e3433..fe93fded 100644 --- a/setup.py +++ b/setup.py @@ -20,6 +20,7 @@ "pandas", "sax", "thewalrus", + "vlsir", "qutip", ] diff --git a/tests/tools/__init__.py b/tests/tools/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/tools/gdsfactory/__init__.py b/tests/tools/gdsfactory/__init__.py deleted file mode 100644 index ad35ab06..00000000 --- a/tests/tools/gdsfactory/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .test_netlist import * diff --git a/tests/tools/sax/__init__.py b/tests/tools/sax/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/tools/test_hdl21.py b/tests/tools/test_hdl21.py new file mode 100644 index 00000000..511d5fd9 --- /dev/null +++ b/tests/tools/test_hdl21.py @@ -0,0 +1,7 @@ +import piel +import hdl21 as h + +value = 1e4 +converted_value = piel.convert_numeric_to_prefix(value) +assert 10 * h.prefix.K == converted_value +print(converted_value)