From 37ac692d8e85eb857f473814caa41e8adbf9cf5e Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 8 Aug 2024 21:55:07 -0400 Subject: [PATCH] fix use with 3D conformer featurizers --- .../chemical_featurizer/generate_vectors.py | 26 +++++++++++++----- environment.yml | 2 +- ...r_table_original_chemical_ids_as_index.pkl | Bin 15700 -> 29535 bytes .../example_vector_table_smiles_as_index.pkl | Bin 15745 -> 29580 bytes tests/test_chemical_featurizer.py | 4 +-- 5 files changed, 22 insertions(+), 10 deletions(-) diff --git a/comptox_ai/chemical_featurizer/generate_vectors.py b/comptox_ai/chemical_featurizer/generate_vectors.py index c55c47b..c3bea1e 100644 --- a/comptox_ai/chemical_featurizer/generate_vectors.py +++ b/comptox_ai/chemical_featurizer/generate_vectors.py @@ -1,5 +1,5 @@ from comptox_ai.db.graph_db import GraphDB -from molfeat.trans.fp import FPVecTransformer +from molfeat.trans import MoleculeTransformer from molfeat.trans.pretrained.hf_transformers import PretrainedHFTransformer from molfeat.trans.pretrained import PretrainedDGLTransformer from rdkit import Chem, RDLogger @@ -9,6 +9,7 @@ from collections import defaultdict from itertools import chain + RDLogger.DisableLog("rdApp.*") # Disable rdkit warnings @@ -201,6 +202,7 @@ def create_vector_table( sanitize_smiles_flag=True, rdkit_descriptors=True, molfeat_descriptors=[], + dtype=np.float32, use_original_chemical_ids_for_df_index=True, ): """ @@ -217,6 +219,8 @@ def create_vector_table( Whether sanitize_smiles() should be run on the retrieved SMILES strings. rdkit_descriptors : bool Whether full set of rdkit_descriptors should be calculated and incorporated as vectors. + dtype : type + Data type of output df (e.g. float, np.float32, etc.). molfeat_descriptors : List[str] List of features to generate. For possible features, see https://molfeat.datamol.io/featurizers. use_original_chemical_ids_for_df_index : bool @@ -254,6 +258,7 @@ def create_vector_table( vectors = [] df_column_names = [] + conformer_3D_flag = False if molfeat_descriptors: @@ -261,13 +266,20 @@ def create_vector_table( print(f"Calculating {feature} descriptors") if feature in {"Roberta-Zinc480M-102M", "GPT2-Zinc480M-87M", "ChemGPT-1.2B", "ChemGPT-19M", "ChemGPT-4.7M", "MolT5", "ChemBERTa-77M-MTR", "ChemBERTa-77M-MLM"}: - featurizer = PretrainedHFTransformer(kind=feature, notation='smiles', dtype=float) + featurizer = PretrainedHFTransformer(kind=feature, notation='smiles', dtype=dtype) + elif feature in {"gin_supervised_masking", "gin_supervised_infomax", "gin_supervised_edgepred", "jtvae_zinc_no_kl", "gin_supervised_contextpred"}: - featurizer = PretrainedDGLTransformer(kind=feature, dtype=float) + featurizer = PretrainedDGLTransformer(kind=feature, dtype=dtype) + else: - mol_list = generate_3d_conformers(smiles_list) - featurizer = FPVecTransformer(kind=feature, dtype=np.float32, verbose=True) - vectors.append(featurizer(mol_list).tolist()) + featurizer = MoleculeTransformer(featurizer=feature, dtype=dtype, verbose=True) + if feature in {"desc3D", "desc2D", "electroshape", "usrcat", "usr", "cats3d", "pharm3D-cats", "pharm3D-gobbi", "pharm3D-pmapper"}: + mol_list = generate_3d_conformers(smiles_list) + conformer_3D_flag = True + + chemical_list = mol_list if conformer_3D_flag else smiles_list + vectors.append(featurizer(chemical_list).tolist()) + df_column_names.append(feature) if rdkit_descriptors: @@ -275,7 +287,7 @@ def create_vector_table( mols = [Chem.MolFromSmiles(smiles) for smiles in smiles_list] rdkit_features = np.array( [ - np.array(list(Descriptors.CalcMolDescriptors(mol).values())) + np.array(list(Descriptors.CalcMolDescriptors(mol).values()), dtype=dtype) for mol in mols ] ) diff --git a/environment.yml b/environment.yml index e326873..79f3e6e 100644 --- a/environment.yml +++ b/environment.yml @@ -32,7 +32,7 @@ dependencies: - scipy=1.7.1 - tqdm=4.62.2 - conda-forge::molfeat - - rdkit=2024.03.3 + - conda-forge::rdkit - conda-forge::ipdb - transformers - dgllife diff --git a/tests/example_vector_table_original_chemical_ids_as_index.pkl b/tests/example_vector_table_original_chemical_ids_as_index.pkl index 80d69e966d92fe38a08cc28eeb6b7f990ef51cde..61cf0c465fc84ce3df850141c6b1e7b38bdbd8b7 100644 GIT binary patch literal 29535 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 delta 2715 zcmcgrc~BE~6wW3jL5u=I0tg5w#Gr;IQb-C3`;Z{WC5VVRSdB)ERH}kU8*77#SBG$P z!6{(tfm+0ZN6;#WNvn)yJX!%uZ5=>P4{WIjZPaQL$o{ONcBX%H|JZ%+eee3-d)v~5 zHLB_5a2 zLM$rq73I*l(Y*S|Ray@59r|wu>&oz_$;pdMy8xDXUx1MtWRMWsoB)49?(}5_fmCfQ z=0YW6vABQqguI3`A8s*C*2w7@(KFW-qY_s0r0TmfJ~`<>ay&>ndRv?tc<{1r*<OOZ+7L0^6J zVwPt-qH1JMb4i28Y6YF_R85edyF z@Y1ct<4zi`)pO`cJHDHN z=_Nkcv($D804`%JLRLk>*0v#)CdkDSDLa#+m>_|0IP{N~C0$xC()YTP)_yvG&szW^ll( zrpD&8-|XN+e&fVqz8!KVbwZxxuAb!6EQ#AT6=JDCTOSw-A9++_%A6?Bln6t#Ux-1x za{i{mRl(pku=7-EIS;ahl>yUn9%Oye-4WR31(RCSGuf&3uqvj*^Zx!RAiF=%*e{U4 z)5_clC3*oWN_HBXFQsTMpw00~InhkgTuu(gkfg4hkjSWlD1|dLcVGB{H7;ezvfHmU1jW4N=0J-Q`PyAnwXB+xhE);Kr03D^2%I zI6vL+7T>`hC3GpAFRIo1c)2jXuF(Opm?C;$-I|%&3sR!a&Qsn0@UqiU4PYOVqlkvIt5nBZ8 z`eELIs#$EPlaC7*xjQ2JH+REEuCn8b37L!uC*k3 zawzaqezd48rUR##pCS)SySp7-x-+$Fzy4Y74*Bb2I&V@0P*T7Ahzrxg2K1W34V`Q~ z{ubfFO^xt fvuI1xw2{k{BP~HWZDT%9DI==W0COXrq%HXyz6*Y; diff --git a/tests/example_vector_table_smiles_as_index.pkl b/tests/example_vector_table_smiles_as_index.pkl index 87b809bb0d65025e109eb168d073a01277445e8f..de3745d193c771cb371d480836957b7167e0c041 100644 GIT binary patch literal 29580 zcmeIbcU)E1)~Jmwc8wZa)VN}-i5fMD8rxio1$#HKg|!6~l%jyfl9*+0*pb+x%ia|g zRBUsJAT|^P6qT~*RitD08)M83YJ6|LbH4B1d)`0Z{X0L$GoLYLS#y=mHXgQGZqouc z3wn9fm~L{mHMzC5adEY4JK5FbWasHovA4X>_2J335qYg^LA)1$ieOy}ti zHq#vKtS4a~EUxW5(`ot~u^6YBj_wX7S69;<7}eU<&c?;r&E0jTjXM^Wqe4%Q^00U+ z+2}dYVu`0^sY#y8JV$u899U{#*@2~(dfHd_C}-okiUi8O6=I%LZ#YE4R@V|aycPuRa2Vf`uXA}OvZvx8}m(qWD4?kYU$EM_(FG+n2 zB{e1Ruhe{8Tw+R~WSo!9zmod@SyM7;36u=@F??K8VoKm2dVO3|VoKm2x__Md2lEdD zmh>vADS>}0RZ{#h{KJ4H#UIy{q&|j!tN4H2-R^%L@nR?c!%wA>)A=8PlI!C?GW&o3 zNk877kIlbz6#vluA5tY#{3|sj#s2^wkMptlhwlH7`gojw#r#_Xeq3BKMG2JDl$a7I zNtHlJ>K~w__+u#PRg(G#^AD+yyZ=LRN$O)L9)}+Ba`nS+QS@WaR}Iz>cx3J$5`tVk zd$Wqbp5L!;An?R0eI*20>e50dsAL*pAn=rjM+oEw2ga&s1*S4QXDSGCeb)q; zpxh%H1%apT_}T!V`S{W)0XkY{)b0Qg(rGR74KkTSZtG+Mb9Sm^9^d^=BG_ZNL&Oy% zttMditSif8;-%AMc-)_E3Ym?^X9+lUrj$<1m^za zt}v13$_hyRw4P3>n?{s?ME6z(8lKZ|jD*0loO;Lvg$=r>2>gC-1%n{oXPu0|;!~2z zu)GFh9R6yf`EUy4A}E2H#2+&x1fJZmoG{tn)ezOSbnDl20@%_fP%o2zPch2 z+L1cJR`Su{d80rEEfhAoZtr5hpJFg({q{h!B zGDTSrA%cnOF+nG@EO(4bkX8PohQOa6j#J1amQI$)ycy9-CrE6zR7GG$i#h_HKJO%< z;f25K5T@u}9s$ptKA2K0uH6ig^6izQTVVI-&esfr+w-hcf*U?}bp*b!pSZAj+WmNq zO#Y!#B6Z8VtuXQB%0UK-3mT6kU@vd{ppZ$PctJ;C`HuBe0zZ#Q1U%}<1Q5{c@Y`Dw zLHt%jMPM&0UQ@^%`MI=4CgO4nGP*_0^AeeYDXuaC&mEXYz*2wuOd}I8aixO5&W3Ly z;5VAsOK7;a>S!Ra?DD4-GTCGPR0-k~aj~%wM<3aG8vd$l!6g`R4m65Mb7LP1~;wGe|Kv~*dBU}7949f2oaovxCJ*s+`pGY+^Z zWKu78mk@Yp*FYUXFI^>`40}B5iGqd&*Xg1m@H7^wlDRj;e68LHa8bx4ly-m!-Air$ zQb*t$8>$eY`-*0<3PHpV6UgvqHJ|8Y@)b=Yxbw?+1%anTr^^IMua{^DEOi#w5qRu^ z2$f7ism2PyHDA#k9?K0tKuzxWHU#X|+9?Ve7S*7tN?-(zf(SJs9mEB|bH+5t0AyiGsMlva?6|-=3b@Mkb#kl63jPj#Gm^VG%V6O zUna=+K5iiJkWc?o$vo+otr0|hu~C?W?|%dVHCaRFNCYV-i(~{A^8KGW!NxN|5TWL7 zn^p!v?#_-fL2|p#RD!g7XUVXFUNsFgEWAa!M3C2@o<bf)m(Q|7`X!!L3=QM)C#^Q;@VzYu( zG6~E3Xb3F(=1K#B2aPhHuf(s*OJw5CbdnKRR;e*$*sF%Ubut;-{tzbh{1byr%wqHX zmHL^uwD{IXt0={vKG-T_4bRnGBm|byyr)X=v{5+)fnV7BLO}ej6FQmL<|dUOVWkg5 z=yk1WAA=xnH`fCS%b_h|nvi z=`({&zLTX)5O7Ca8~o0_4GJ2b>U>fq2yj@gA+W3|E;>Pe#V2HVnDbi&4bLmJQ6|Vy zx~K%V4|FyN(mpW{_;Bze4Gl}kX(drAyWb^<&^>cvf==N5=~M%O6;-XH5aa}iedhf7 zK8;M)MDZwKxwDUezyV7QQ4x4HTO%NPnfO_h=WWzAOtG9s!*v86vo=*GNGo&4KwwEd z`)g!UvQFy+TfSeQ5`=BBQv~c-3lX|!988u8!mkb>U}58rt7us8iUv9Y-`9GYOptNt zAVf&rb82o7#O-(_A@KNTJB7Ktt}Fq6wzZ*18KXu)3Di6r+s_~fN$L&}#z|qm0$#Sb zprGNIlS2&zcIwNgGMT$O%=;W4ou-pXUDHoOU{O6P%Vb`+dJPe}-}~cRjo^M%pn||s z17i&`@o%O`WcDUjgb1m-UycywS?Ovr8lE5DUneM9umvKR+^lF7fjyYv{wGO176Lxh^dD>D=_>7Bz>f`_fXl?j4x)-VVn>Sn13EZO!Z0Z+_{k;$a* zGf4{W_@`86vL=E%-92BmK1mRAWLPKlEc*dAv` z0dYqXbu>JwYp6zW^|wJP0!v>x8X}|ubB^j{;;J0i2wqm52@z5=)0j^1ta`qHxJI5J zpnL9l2LplM%<)mlq*jwyNr_0*>Vax2`{(Xja3 z4H`kdHXb6F*He$G2t3nglR*#>vs*%7*JeL}2&qM<{!qxo9$qdH7;}aPDxCjKFtK`9>$WHerK;z#ffh2oX||R;3Jr z?KOG|co<;FXjtyl))GOo?F5yeP#GW~dCd(FP*X4=kAPoay3imK?r=>*;904uI>E!# zd>Mfi956p=jk>-Pnb)R)5FvGU{Y(NLu{J&nxI;jLnrT!q`8BfRRX!y zEsY>2AxR|&nZHb!py-yuWKQ`_fd9xgk_C2ux}>H?aIuVog20jno`wjJ(0;Ov!1JG{ zssyjrRu<;sg943A?z7=K!Tr5mRRk8^^tnbR@a$g_fpK?^g248i-av+3E!9_;xcmMF zrg(D9IRUZm%{4O7zkaJAFyoeZ9`dUTj;mxY)-)hOs^GenM&MiZl|=Aj*I^Zb-;5YY zhUa#Q)5#de7Lj2m66(olSgI1BB5>boKkEoA!D_8ckofwPLh$U(LYW}3{x=FiPSI}~ zL4MM9mEf88Y6F2kA67vlli@WQ`;00AcD-f@EgLiB8l|p% z^-L#t`?vu_7&-N~*AkiApR6(nt`_uB5Lo`UIVwSXUN{+^xx&1wkAfuwQ#>qayoA8w zt>;Ibol_L>kL}bYbJS6A~gCKv*8375W*U4mdHEty#uq~@E8)QOH+ChX~X+vyP1or3F z_7Vb*fBCsE>2|>e8Wul2TO$a#a8N-0{eC)`+&V2FLQTpUe+7YuRNttRNw5EzfRx7f zRWf18O@)b`+eRZ3Ub~w?kgJ*x=W*;#84bU)@hL=r+^?r=1d$_d=?JXg$UR}6UurB& zR>lwmQ#|g;JOUObYmzYgJY@uy-mQ{K@TOrM1A(V~WuG`}BV^1v7B{VFl ze;Wb*HD7CF?)N#T5wFLWM>W$dObW5Bq8t@ZssS_9J}5s8kV=qLqKAu z3I>@-B}PHu=}H1bfS6kK30Qtv7ZnY2S&(EP@c8>SGQm;T4iZ7Z${P?NmA9)J85Z&~ zLnE`jcQqA(rEULAfd7o`8XBIfek&0?%`opqwC&fz#NT`-px~=i4Qp6|r>jAb9&(R> zC*~I_WV{<4f(Qc^EgoPHJo`csaHmTT0u~k!A|SbSuxf$D$A%skCSp&FjE04@`c)!` zO0K9Pz^Qz#6FiCxP!ZVux5Ei|{Hz)>nLAgrbp&2`atcJKNk3&?b4!2YlO*I)m}hq@Ero47t`0Uz+MlX#6`=)JH{($c(&UC0+x7Z zxrTc zsR%q~^#K7724oSi{KF>60#j*xkW3K&SCN3A7T>63&i&R?BS=W^q7eA|SJMgNcBQEZ zEcKxIq-17wlqglOa;ZY8M-%#}1mRVffxypBaFqx$25!~~u64MrBCybnN>K=M580^*JVCCg6NDw!F%a0j5v3(E5#d8+f)pR~v0wSLGZ~isYJ!F- zc5~Y*0dbp`>u7lFD;o)cWq+5Ul6mslUcmF7TXi%nKiC%{ZswIKDw&5Fr6R)5N5 zZro4S335NLDIxIKhu$(lNQFF=;AyiX0+LhAr{Lkj5s-o6#GJ=ELEIWI34!s~G8yJm zxv7ChFOwK5Bd{lae`o}EoSX&dp`XiW`2AUP$nd1FilOFO#`HK3E}>+#nSq)M%C_0r966 z8Dx@LW)kp-$TS5Fe>2?co_tdc{eo#{$!rJLXfukH!`fKz(GgDA}@#oWcS-X1Odjc`Vbj`C;aqO!1)S> zLMChF&jvxr=17fTQ(zaFAa-aai6DGmO9O#reQHUDJr3)pqTyNg$pq|f@L~{9le#8J zAt-D*Nti2JhYORJTiyT#KNhd~QJ6T#>lzv!GkBswkh0$Vkcrz+K_zo9I!+?E^=p49~Q7G|;fWxs~>eTH-}x6$=rWiAdyMi7AoNRC){kRYdWPo9{I@x=?)`R1fJr$ zOCxxc4xsCX;nB9wMY-m8k{-%l~bQMkb2G>WTNfnLxkdIkzT^&hiw&*>v`Fr)RP~UNC-Up%AW+R zpi-oahF!JcIs#893?swucRnSNiQBnBMPP~fz6L?guz4B+H@X)p1ZkaQVY2g>Fxn4} z!la$qZ&+Y)#MYw_0rpreGYB#&m(vLz-VG2CP`9&!hP@~&E+m#4REAP)^O?SofmGz@ z!5Tr{Rz*VKej6YlB=#F65u~&?pZDxx=^7dqb7HAT?f!0niiXFHODDrp2XmQB)Hw4= zNqlr&n1tYT0gpWgb)!SZtg2I+=*Gb0snX z?cT}+w<9ccf}A0XAmZ#@#WlurnzxgM**{VuIKONj8FsyYTLTS?JZyfu$!nRbk-1ZM z2}DRGXJpF+d$SrF!qlk+5vK6nZm*NsU*j)@AlActfR|gulHu_eI|{fqy^VnD%3#d` zM^31T2_AOsrywvt&lM^`O3hJI? z!o+n+GAI?=e!WDna@Zdbp;zjqaFyWJfq@zVPwW&VlgX)gUYMezHzYFme0D>GUQ0Ir zB_L$QV3kaPOMQdDD0)PON1b^J0*dbpXe|?@9O6as4+knWr&*B?MlSm#q;*RN6^~ z`M$9P0drlO|Er9^pA0@JOvH}8DjL?`{fL08T z5hm_#p7-E}iYfMRrL6GfOoeYm$ZC+1Mvwgy(*8fSTnoCb40a;!_Dw*gf;_l|@ z+dL`7&qgd2sn8mhWLSKQE}8`{<96w>20?s}HVOg@VRjNhK({o5U~!Y08UnxPbyz2p zKQ~w*NE>ZF%NhOBH8NRQIS^r-wEeAB1Rhqiy+$VB^-nUHr!gHQ0^@E=4S}VE)m8`s zxh+I6FV0pG5He$-Mkd^5GZ}tYJ0#4FrQHomMNiBWreH)P5YYWun-m#=>+KKfWQ@R< z!bF`A?;!j^o8<3bSa zh+xi4mkC(->;_2i7Zk6S=>+kwZU_^vTm%8B7Y(c=f|SGaWrDOjzY2(2SYIPkRO4F( zffo*JO~6uL4-)2Sv%3Pqv~b-5YhF0Ckr7zb;4>1Lv|n~91mSg59f4(SiXQ1Ja zRqj(YG%RIqdouh%(j1+P@4z&LfIqsZ5u6WOArTl2qh*4?lg$hS9{)va0v0vu1PB=L z=G-7*vO9^>%`>O9p%lOMXM_p_{}QFb4vpa2oGuE%gE0*Zg6FaKG=ft-RuZtcCgqGB8FpY-ePMj}E`}1QNzEN25o8>Cp%EC@KNFBT-$cM3 zy&eb|m?D1g1{Hz(2CPuXa}_v@T4QK?=ds3&#Z9^JqoD&wC|71_sO??xPVzg=|s~SnAP{5Fu5RC$0^ad+i5d zp1cgyF~#l%4Ob9&?DCZoncThyb%M7~cNhr#?3raUnX7wh>11NQ%Yq2qlj@moqMVKO zD8;-y7ps(t?s3QCFNGF`d#SG(7f~?ixXAlu0HC>2^vYh@VwoB`7@qrH;UITWA_VMpkt) zJfVMvfrdwZYktJ#)tjM_DV#77BBYFK=J&z)<2z+EEUsppMyZftl~pp2CoU2Y)uFXP zChWIc8UoMle^n(ger%>7Fr(6SnN0AQWMQIiOi{_?MpcmzSW2C70<_VdDjL4C$r%NK z?PF%6-{~S#Dy7v~jleJCxq-k^AG{{ukEZO_(eOJ5*J=crr3(}UW-Q+>lgU0X#~|~t z{SArWMX8ZGf${xp0V(dgWisif5+OqOlc#4G2)uC2C}C1sSgK^6=4~Ux)0Wjz(6Epl zKN|$EhWqLWJp0uEi6HNIrVK#;KQQJqMjRx+-e`w{X?CN@15Ed07bgtR3AVlcRYTyn z#{FOrT&OyMfO)T-t&#C9yeG_lmqjuf7I3YRgus1cCTL_fw)j;hbN%cR4T0@UnQb6& zr!re~GT}!jDFo-Mm>&mz6Pie9_?4jxAp#u#`kacu!s_lK!w!zr4K)0E!_mTQXdf<- zv8irr5Nt{AC&0^N7y916xtth>uWi*-B6Dc?5QQM{hn)rj zzrJ!V89w#qD>5vw-Jb&Z@CeNU2R!@TpDF@hJt$r$v&*uzfKlU`OJw{P1hV zRwnovXxOa_uM`A+vg3S}VDFz|cDA*Fi-v}s^)C+*YEJbP_Yd=voD?$Gzjn|GuBOx@ z!%o&;X^^>dyorp!>^GJn;3r4)6=r){H^{(%uATc!1W_l;kzsyYR}=8CsjY=MwzjST z)Q_pd-{=IZ7Oj^N__;lMAObi)4p0fsp1(lAPPXl+knzahDiPeRG#es}Gv>u&onZg? zJTm8~e)P<69f9ek-DQGP*DD$Xq5ZF@2;4iPiAKi1`#OnCphZUkUN71iWDXQr zYXmo9_6RuAW|4%3otnK!n3V-VAYj1jli$h+Ea>;48X2!!^9+KWZsK0$YQ0^QV!J%f z=#)BKB~c>yYu7E6!1v;M0hg@Bg~ZoA@D|4Jo3ACTVSAT57zD?fhCqbb4~2c95iA)$ z!a!i*4eyX)iiLOvu}kY)K?aI%%?nfzm}~XTIzhPIHjUtFi1~`zlhHvKUc*(Ul-Hrl z62ZArZV+LdrQtUe0&T3gM0r5v)fyUhcx^L?0LxOu$b4DyaGA`Sn63sv*u1hj!R&*f z3Ig|UU)CVwdr*?dT&`A8Czw__PC;P%gAId>Nm{Fs3EI?6A#-(7f1SX)_F!^mn_s?`O$Xp6Lt`lenb09*>=U`Pb z{JfQkfSq4vE?(-`PNkalKUXDSR|nV$<6rTKPN}N{epCqb(KZIbM*HeA!Tt)fB?NZ! z!dn8qI8?k>@_}W0FCzz_up=yW-y+1PtgrNLL9? zkNsXJ*wo_>8G$>c%oipoVz5T$&z<9B0-sjmmf@%GHk8n?;~U56l-hRjAw=lz=QLJ; z|K;@(nI&u283aLHUdsq<%bCRznMHazgN)C~mk^=5UcZ?}u&4JP6@l$7h>*zye?D9z zI8-=5LSU!j>g!}qu4=83S@|ehA#>WVl};vfUH0;dwIx@j|_W}VI?8mEQE*^D)2;HyFcqL#!gZ&DbLnll!fm@ID!Zfwf zL16J`3nT=#qg@RRf&0wbAQN!?8X2~FXSjrhg>3#(zzXM{Ai(%ljMoT!j_nn2aN^Gj z8tz$hxq-mEoEwp0KHkG5G+cjC9wNZ`+b<1*L$6E%tR8fh$oS5`q#>|VV?$Ij*OM$I zG849m4dg1(w3QU{J#SJANjeiaOYO&xB_1b0J1H3Gk`Zv||(>LH`yXV=a# z2>d#Kp%7eX+fOC%es)trU|V`F)5t98-cOiS`+6y4ysevS2+XHpU5SiW)dZQ~z|N%t zE>=h|$oP*aLxu&6%2mLK-%GG-|3Cv8{rJ|rff9k`>d9I)S!}mID9ceR-rX z=QjmvnBoB!M+tN4`BsC>zIDG5u+`Emjm##8@e%?H9Jt6JxRBr{6a4vXHbfX_?ifWU zxYfsBLtxu(mQx7)=f)ZceA%n65COhz`Kv~-^3-!-X1pz}pkcm0%_76X9o7kR!MT%0 zsriFziPUv%lYxd`I~t%MFyEo!GQrqcZ!`pcu*nmh%-lb`1?XQ5mB^gRX($tH&0b;< zc-pHv0{5HT4kEk>aAHFZfxFD#V-N&atgREA@lI3;*4=TO z!(&(0%VYv(&s7oFhJ~dSf)k6)Zw!9ZI>}^?miJZ>xPQG73YjBue`o~94|wVbe8I+b z5`ouWr^v7~Yh5%n?B);GRf45@K13*9Qt>qz?p@SdLBlp=tQRnI%yNm$-k=m2fgfpY zzM>9XsHl-yym-5Wz^=8dppe;>Szagbo6`y+r1aY6o7$m!RgF@&8t))rr=R~QVA{(p zk@B;(RV{F?pjE#^1Xx~voJ26iYk-2l{5`8_WVU)jz?xmhugVBa@9NZM5tL5a7rSx+eciG?9i_hMe3Y1%)k`$S-n-jwaJG>YR@4jnNpWp-qZ;G z+LNXbY)5T>g+pw#PLU6Q)CSd);Z5kTxxP3ZAsJXMEz#y2~JeB}H zO$}7ZZ0b53A{0-xE+b&=q`@+orBip2VQ2du5O6;3o`NZM+$u#FZx=@$4G%eVL_=VM z28k5k`IE0f#y6pvguwT%D=pyQ=!zh~tX;QRB{&t(P9iuk>4lEKb|>wS$y_NChr{kV zaEVgunm5rY6>#tyVOBmIEX=u0k&uDz>n}|bsX)t(8XCUp(03{V+t}$RVV2r|W03Lc z;3^~Vqjf?cLXD?e4TX$dIZu_~eDg&b0y`dIC6PJEnhUeN%r`0;c5=;434#A%cU~q4 z8fQMa2S4AWp<(`(Js|?@8hJ?}Sb9n!;NEYJ3lmmjtbpauepM~7_=KsNM6fi{e7~Q# z@+k`g?*uKjl8X%z8*6-Iy1U^&zGz7MP-36Io$4ha;GT*!6QfC{IhKd?L zi&_%Z9DH~KB8;Pddrv30^=PPpz_g8S0;YGK0s_p{-nkM2ziGWeCs>eiUcjc6omDbB z9$b?Un9r+th0OWri87f(rm1M`?BKWhdQ_M+(*b^)u(KQd=3qBR2OIo#zymGdR|J>B z-v&IeH2!H{*`wxrzkV3d&eg%j)1$KWWLFobNi!!;wsVDUExn|wFs^v%9V<7H0gd`$ zEiwMRZBchZFas~SP4>oE+}11)Cvfzar>2l!ok>x4nM;olW3UU2r+oUxUB-T+`nX|K zE{>z9^|N%vwtg>{^6Igkvjc=TbC@rJ^qjzZ?qI$hQ<+Xm@>Z6yd z+t#IMntOxRr^H|4;I)qZ%c8dk9!*hdtG&Uzy!_MBGDIWAv2e7~)An?>tXZq%ql zzS$47{^GW}dgQ0*^;${QFd74T*Lc6J>EF@*8XXr?R2`R>r#f?6S?gbb$E|j+R9=TD zv)ZM5VzkQqgyP^=?PY8q|FkVeBero9jMCFF^)M=xeyL6Eg7P%39%PuXEgxR5U^IT; zNBy+MRldS@@k`y)h{i2$|GQD&qSAgyo1fN_p|iBD4aMSd{@yP3e~wQiy;LonJ|euq(tSi>+DzqFc{#d^9`94Qye|0=3)X@6wf-gJJ7_e+lF z@kL6EPiRd>wK_IqnRz;XT|yAsJc3RE<;0_u(%UO zz4VuK-<8ZacR7u(JeNP%7b*2*1FSE8=>?W_Jrp00lsAfwOB-3GyIfoZQETW+=Ur=c zgzm%Qly-guod>y-ME6axH=b{z^=VgY)A)L;J9HgMQB7!_O4B;@ypsfi zOvd|Ge`KQPhY@8V<}F|LQyILPR9nY-$!$<0Z0l=(D|){_sNxqrw=I%>2r%bqpCDNr zX?|#DoAWe2w2Nc$IR9!a9_R1l{@quQ#fZi86vw~!E54qJ^G*KNPmJA7k#%cz20R@VQFQIE(Pjq$&Dl^lmT_xJXH(d7g6uh##ob;X1Kz5eg*;=2FWD1TV- z?~e2D)_*wL|M}Mc?)8<7_qTm3K9b^maV+-#x8i@7dH+-E_}{h9|6SJq-(?;D{=RzJ z*YhYn`Gc=q>Grp;T(N);X9Mry7qxhlvh;MvPhnrfr?UI+e=b|<3BRr1quz&KJY#D& z+s>`+B$FF_T}>rxXS-jm`#Xb!&u8|%JjxaG@A$27kj6Ek~M1NVWbG1$TR<01#=4~ojn zu(O3_j2t!+KBf+Kas0{M)1#V|ooUvbp6)JAW>KlnY?F<M>}U5yFQL~ zHtw$Q9XXyJXh)cA9c)aF@7YgbO~XvC@SQr2mi8vsDX?>&!m9qJYKf!y$kOuvW-OwR3L#J{NyAFJ=+BXuv!(W5%_wjTVGRe$`-pyJk`p+CKAT3Ypc zKMT!4Lp?pJnu`Yw?Kce5)!u7U_mZ(kyx)892ugm^bJmpp)8RvXgp8L~@UT8Z`&f?|*%K-& zl`t&!UE_lcjPou7W4&v9|K4CwRWdM6SUm9iH9x%PJHE%A-s8^i@sF^%BL|N#ueD+^ z!cvPh%vy{vX)(f_#RyXtBg|NgFkvyme8mXURT}B&GG&-~!piR&Fy(tK*q--VxIZP8 zA2e{YN;0shcMVw9y9O-mT?3Z(t^tdC*MQ}f9W@NkU}bTuo0nPTy%wzV{U$E-T^82% zUJDlYUJF+DUJI7@UJKUuUJDlZUJF+EUJI6387?eqF(=Gk<-Hc};kza-=3NUH^R9)9 zdDp_lyldfN-nDQs?^?K+cP&^<75L^c8+Qj6XUmbpV2XDSKuedI&hBuf4Y3+(W#;lj zhMK7^Jo9=wI>4Rf?qFkSa-HO2Gsni!&dt-K-uoFVJNU}7l2ncNQzPJM4&`;w!C&}& zG!D&RPJB4br|)$!k5UzsRZklmyXo#O__b)2u-)6mnHtrwK?^a#a~-m{ju9^K{$ZNr zXxGcd*%lm5H`3%j(-q!TY(F}nlFWxI!GTIr=A~4`SiE2GzA*@H7I=CA4ITlzIoZ{^ zr=zvyPpdD;WmSZ;^mkh&Uv7H;-8fJ92FUHAm0m7RYPCjL($=Sgc#={02 zzsnRmbH?7*b#BR^*l@u$;x;?LM!*_yn{f_o0^$G;Zg3mo(6|-QaJP3b3%n$!*}2mg zc$|W*N4ZRQbZ~<^1M`mXh%h;ck&vkvhsFJLnLP*IZn5FwI^Ety>^LT!9o$_Vir0b- zI2f!Wg!AD7Bi8w#4Ob`JvoNHXiVEG#4VT&P9T{vSesyAP=sn%!YO~WaAUBJ&I}IvUZ>(*$+>__#0i#X=ROC1 z=ro^WcRP1i^G@I-a3Vi!nNKSYjVBoo9eREW&6&=VTy5;}jxwRbhr~=*JCi5Y?2;O6O4+usJA;kO^;_W631`wlD_qA)f z0jF2I2P{LKNz2=7xX9jsp|GJf-rTH4i19JkmzkcDO(J2C(r`}~lmJ0UFwu7Te`u2= z!7w}H6N2{+88+$jhCLXe0oqDjUs$-$m;lU3+N1?d#8|-igdhu!Xd?ktLlz{MMk9RN zwHP`H#UkI8oSge$AOF&c(b#6pFTltRGDwJRN`OBjcltU5f2t-L zbD|Q_Sj<0qLS93e549L4YvA;P=$_+@Q3;E=Qq{xh+fVrp9}AL>o)(7&9=xubck6pN z3D@!C5wj+yCLYI0y{NBle^6PwwoXiUI-k^qS8rkIv%0%*am`PWE7CpTOOa9FL2rHJ zVyow?!2b4)-(rJP;jaGkq;vC9;m35_ijbfb76ga2pR9kf3L@k767_RERJ_`c!s41w z;-#C4$DGpN!bSH=n9DGO)y13^0NYVGKy0u?BvVMiLo?r@Lw#HRh+IN1HZmQ}Wg z0u;N$87pX1_`_b=daMG|iMIG%%$$emE;po$);_}^%~JjN%q;_s(JECks*XcX*m`9; zrjvN>FAkA7z@s@lKTCxj^t)9H-Ng_Efv5aX0Tt_orw@E z%3JIl z>B^m&0-ZMlc3Q6M^vz^IGPP>shg+FQ*Y)uda=z))S~Qiclv*%#_VdlXaW*y3?UAEE z5!%fNbT6uXFY=iXl7{u-6;@tQ)y!^caTyC6Ts+-=nQaf{3ie!!1#D=i)p7fnOek_7 zZd`7agVJNOpe%0@6sa#Ytvloem7+g#U0CB_@SmhmN{OWG5@#V0F^k2#*_J+|hSE3W3qGYGh`BIAd66%~#CRhuuI5@I$=L5Lwu67E7ydlwPhWo8-9L28BX{s1? zJ`m1S#a2p&#e$)6d)3F~$Cw!}IH3ME-d`bO1IhYk4_(lv<)C1)FzG+BzCuyqJs#ol zEoJl<2SQ*%Ri-revInx0QzGNZ@2-Ufw4~#HDu@u~>@Hst05R8(ThB`ifZLODEYw{y z;Nmp>WWJp(O7zrH!jHJ&0r&TQe-(OO79bPOJTqp~BVi~QE~crZH5$bwl z=TP8>{76w*R0mEmJw5>0prn5JQ75LE73kE3YdhIG zd@|w0O^tAdqw)UQoX>v44F|$uwBiebJ{_THUucWDwz)Ib7X*z2#@N65SGTfYhG<*h zqP#h9;Ck7&w|