From b62e022ae351e4564abdf06b79adacce83804725 Mon Sep 17 00:00:00 2001 From: Christoph Knote Date: Mon, 24 Oct 2022 16:55:16 +0200 Subject: [PATCH] Add high res option --- blueprints/highres_chemistry/VERSION | 1 + .../WRF_DOMAIN_PLOT_COAWST.png | Bin 0 -> 82614 bytes blueprints/highres_chemistry/config.bash | 99 +++ .../highres_chemistry/emis_edgarv5_mozmos.inp | 29 + blueprints/highres_chemistry/exo_coldens.inp | 6 + blueprints/highres_chemistry/finn_fires.inp | 30 + blueprints/highres_chemistry/iofields.chem | 20 + blueprints/highres_chemistry/iofields.met | 4 + .../highres_chemistry/megan_bio_emiss.inp | 9 + blueprints/highres_chemistry/mozart4.inp | 86 ++ blueprints/highres_chemistry/mozbc.inp | 60 ++ blueprints/highres_chemistry/namelist.chem | 44 + blueprints/highres_chemistry/namelist.wps | 39 + blueprints/highres_chemistry/namelist.wrf | 160 ++++ .../namelist_timecontrol_chem_patch.wrf | 12 + .../highres_chemistry/pp/plotting/crontab | 34 + .../pp/plotting/geotiffs/run.sh | 37 + .../pp/plotting/maps/plots.py | 197 +++++ .../pp/plotting/maps/pois.py | 268 +++++++ .../highres_chemistry/pp/plotting/maps/run.py | 110 +++ .../highres_chemistry/pp/plotting/maps/run.sh | 50 ++ .../pp/plotting/maps/tools.py | 68 ++ .../pp/plotting/meteograms/plot.py | 757 ++++++++++++++++++ .../pp/plotting/meteograms/run.sh | 26 + blueprints/highres_chemistry/waccm.inp | 67 ++ blueprints/highres_chemistry/wesely.inp | 6 + tools/plot_domains.py | 9 +- 27 files changed, 2224 insertions(+), 4 deletions(-) create mode 100644 blueprints/highres_chemistry/VERSION create mode 100644 blueprints/highres_chemistry/WRF_DOMAIN_PLOT_COAWST.png create mode 100644 blueprints/highres_chemistry/config.bash create mode 100644 blueprints/highres_chemistry/emis_edgarv5_mozmos.inp create mode 100644 blueprints/highres_chemistry/exo_coldens.inp create mode 100644 blueprints/highres_chemistry/finn_fires.inp create mode 100644 blueprints/highres_chemistry/iofields.chem create mode 100644 blueprints/highres_chemistry/iofields.met create mode 100644 blueprints/highres_chemistry/megan_bio_emiss.inp create mode 100644 blueprints/highres_chemistry/mozart4.inp create mode 100644 blueprints/highres_chemistry/mozbc.inp create mode 100644 blueprints/highres_chemistry/namelist.chem create mode 100644 blueprints/highres_chemistry/namelist.wps create mode 100644 blueprints/highres_chemistry/namelist.wrf create mode 100644 blueprints/highres_chemistry/namelist_timecontrol_chem_patch.wrf create mode 100644 blueprints/highres_chemistry/pp/plotting/crontab create mode 100755 blueprints/highres_chemistry/pp/plotting/geotiffs/run.sh create mode 100644 blueprints/highres_chemistry/pp/plotting/maps/plots.py create mode 100644 blueprints/highres_chemistry/pp/plotting/maps/pois.py create mode 100644 blueprints/highres_chemistry/pp/plotting/maps/run.py create mode 100644 blueprints/highres_chemistry/pp/plotting/maps/run.sh create mode 100644 blueprints/highres_chemistry/pp/plotting/maps/tools.py create mode 100755 blueprints/highres_chemistry/pp/plotting/meteograms/plot.py create mode 100755 blueprints/highres_chemistry/pp/plotting/meteograms/run.sh create mode 100644 blueprints/highres_chemistry/waccm.inp create mode 100644 blueprints/highres_chemistry/wesely.inp diff --git a/blueprints/highres_chemistry/VERSION b/blueprints/highres_chemistry/VERSION new file mode 100644 index 0000000..8fdd954 --- /dev/null +++ b/blueprints/highres_chemistry/VERSION @@ -0,0 +1 @@ +22 \ No newline at end of file diff --git a/blueprints/highres_chemistry/WRF_DOMAIN_PLOT_COAWST.png b/blueprints/highres_chemistry/WRF_DOMAIN_PLOT_COAWST.png new file mode 100644 index 0000000000000000000000000000000000000000..9c845e78a3e46eb964a687bb796fb0db111bcfbf GIT binary patch literal 82614 zcmeAS@N?(olHy`uVBq!ia0y~yV15C@9Bd2>48Du6JYis9uq<(nC<)F_D=AMbN@eg( zEGfvzFUiSFQYcF;D$dN$GuAWHGtg1UC@Co@w$j(ng)7j@FG|<9T@=jAz`(#+;1OBO zz`&mf!i+2ImuE6CGB9|$IEGZrd2_eCLL^lD_{aCxa;p3l7OJ!e?dpgX5f$BiV?+1e zr1!F{yOR!gDSf-n)y1@^Nh!iXWNE8h6xU1Jn{UqTtLITUA`<0c_Tjh9dApl$&fM9# znKR}5o$B)&f7IB?D?z}eRcqGXWfX*fzy>{t=p%8F1>GHB@Pm={1w>G(&Vg|kSgfN% zJ^-$ieN^da2#kinK!!l|-cDilq>T|9B6OB4U%tJp+{ML3Y6(NEi%V4N_1CI8Iy~J+ z5B>Z7{{EAFcJupRym&E-A^T7Zr|-M}?{>ex_U8Ak?Dbb~mR$*SznXLVTjJ)M9bH{X z4-Pcmsrh_XCvsED?&}6wS5~my&U&*^yYb=D>2bFbqV=YC|M*c+_2tDu$@Dn~llyIt z#n=DcdigD=)c6lB9M&F6+gx}fv7Pb5dHeqXF)?>u?DL+cqiAox|Jm>Ox}Qr=Zrgsh z?#V>=cLDW0hZihZ(6ImCukPt_Rh|F-{{H-Avj4ja8`myewW{mvZ1c@YN4eDe=bd5Z zw>fa2k=gRag60{f*C?MvrMyR*i;(H*Zok8TR*+}{od(Q zrih%gd_L!G-02ohVT%t3m}lQnH#98V{nq5^?)UqY6%`o`@-;-n#3s$1d-nbQ|L2~Z zoE*71jra5O^UrT2_dji9mwPbLUGC=E&u@M8_I?S{+xz9xwRdeD9UhZG3B+Ud&9ai} zZ*Ok)vc1@xexB{YoZ@p2>;M0jUmd<)O<8%dTEyLJ*8)=;9Glq^H%3U=*3Y-AeO0sn z|G(eG-)^QCe>liqeA(BW@xuw_{x<;)^XANnS--F~+*9r*=PJFgl^PQ5?r7S+14-PSU;upSb`MUP@ zIlJFEK|w*Y?$n1b+y4JLulXH^<$iM+imPhF!mjCUy*z16nD+G8GRgb3-(|~oSN{LI z?RK8BvGL}q)oMygO4eSWdST0~h6V;cs}~9k&(6>H4-F07TYGI??CE8`vl)tAYA!5r zJTQ;{j59O#=HB9U$%rvhQRiFRoV&bg6seNd@gaFAW1?c$4#(UY&|%3eHw>eQn?>vs#PzrSN)Wt})<#)%IP z55HEu?d|XXeA(>0MIdoDHX(WW^R41>Cth7$J$ui(qut`hX=fzb_+-7>`D8gbI22S= zTJrAhGE6$cQTPAvceVceabn-so@DN~dZoc&mV4_+?)JNG*Vn~z^6;owSvS`;cdxAQHH-Cbre*YD8b!!NI`m3D69dHC_TeEQ2vOMSN~Dk=RonBURi zpX?AxXt(P*Z;r!z>eSkPr+Hc&1q+|emRw2>=0DWI=8Xx z?JZfWw8L$@cB`*OJ+J+}erxviUqQja*|+ju7-n2hh>weloBa3Hot>NWA0BGmSN8Un z=?%Anf(`Gd$Jc%QSz~v<-~QhVZhrp!g8e5>c-((sd}}tV(&e-^PzEZ=OokTG~Ryu3=|XZ?(F>Y@Avy2DO0ZH zmpvmRCB@@w3|EJ(O}eomv8Ao;)1z+vPru*qH%>n%lehP4n2s1XD=TYE;ZafEd50f= z6p)cQ^Wov)%D-Q)|9rW8{*Tw|_s_7awK{M6J?8BB=O@+YKbc#8@8;U?dd9|+6A!l~ zZjGw^bW(k$aXR1UXJ?b&+}P;i;=)kye(!g)h_?JID*{dTuU|f=h)cfyk74oibEyZL zSbb)j^&Xe6pL3Ycdd*oJ( zx8$<#*KOr*Zd_#lanA1d8@J!DKL3=OJ5@nRX^~)wpkQXGqM{;?gaJbXs75)L@wVQ0 zQ-0}>hwaQ?-S3pA|J`}}t(vZGull@-rf&Ux5)BI$D9Ba6*(huE@6&1h<@xvb_1Zl< zKYxGl-nl{C!?*_*5@#=U;uuPk5b$H#iJKgBF| z?_cM6Z~NNQ`uq2&aVGfr@#*jVBD8Vi#;@OYzuWaXYo57Dx00ILva~O|6#bS@PM=rF z)=>KT+Qx#1htz)Ww$I%=BO9;Ok%R2=cQWj^p9`^g)S)~p$6iY-Yx^&CC8cV8 zP&4|{t8HwTRaI3>n^v!VdiBxc$1ks~jXwK2y7}wc+uLtRne2>N_x73!d)B13NF6aI zCZ-oRH>-cYTQ2|f>C-p+|NlEP!*H>hLUy*3lT+5b=~Jd$v5DW1z}VW_+A#CQ+Ks6U ziHV6k@^&%}OTDL?&Emb6wDHQD@9~X|ji&b7Pn_^*FJEn+foKk)qQZ1w{O+2wmK zzr6GGpT%6ibvqt)&6@a2)-d~;PK{ms;{LTa4@RHb=2#gK5pnkO(QfhUHuvwHZO`4F zUwvm=Qc}_^8Nqv2pYCqWzOHsXF8^-+?YjKcYu5CDBL3gs-@-C7KF`n1eR+3x`B|RU zwVMqXii(S+ZO?xzd3}v{_12I5?$PVFF0AX5Fk~`FZ&FcLH!gbOq2@cw#n11Y-gkEw zmv6dU7hGMIT$L?6B4~Q>b|1@&-|zR^J32asgoj_Ba($M4z1`HQQxEj{=f{JZ3(4Q! z-0YDy@0&73;M1VesW2v!&%?iu^Siv%~`>6x0&DW#M9~VeMgfL zKR-LW=hG?eIhD_59yxmS;&Oj^xw;>Tn>KGQ-V&Ay(rF=EG`Pp4-ZCbLPKH7eR;Y2YMgiV%caw^mL<$DJSJJX?d!|S z%b)#}um5u~#X9=>m;c{)Oxu#X_ha#S+wB+s{`>R!{InP6{EBzR$W*`C=rhA$VcJO- zS69~iHJ^R8zx%kj{Fw-G$!$OH`L@+%XFGn>FW;VD`eI>w(&n2Q+Sv;59vqm}lJkDw@4V*hl?Q#A zzP(&NpXpi0hig1fbw}le=dY{WyOZh5l`A3VY(D!iJUch{G^m-d z^senu10FTMIVUbGbk1(NB_3Zh@yCxJR=-(USPGs_4QEPA`*v}$`}OS8&p#U$JvlK; zq3FqpiPby4_uk&N=iZS{Vd*>1w_cCS{#ttX=g*%$GmVy>{QBNF?aYeGd2{C65xOfR zIMM9by<4&Zf`T_+btv~Ge0_B_=hhZZhTV71DYna8dhxHBjW_Axp;lAVm21PY7c0Np z{b=9scaJ}xw`V^S_+@dw-L9Lr?ulxLty!>Ti--a9r$vjDHf`GU<8izK~W zwP|9IGLT>kD( z*z5GdLc`^A%cML#Jwe%9rsl)Jl6Q9`ci;6(OH&J8=JRmv_IpeUhK3V^{VbPW{iUU( z^bZmxy~_PIo6c#xY+z)brBiL1aY5l&uXOn5+WY%zvzO(Yw=*)c6l6G#+ z$@lyJ-+RK_Y@7Sy!ou5kpD$?Ud-QVo{Im}b4)(qimXbQvZ~yN^r}{jPs3@uUnvbmU zH6LB~{^hg(Q?T#fuh(qF3|mCHj~@E{e*byH<1)^Uj*Ro`er2A$@_X&CZ*Nbh&#!fJ za&prCx+$!x$}0JIUv5eD?{9B^zFNJWgOfA!U|eU1NAyBa$Mesz`sK^>^G*KjzkGjo zcGd4~@Am(%Tjn>H>%fbPi+_H*oj?1p%o41}W5$XV8f-ig2S9ClR`HmC&3yY!-)_HOrxUYd z0;pcdyu57U#EFg>85*&>%Tj-QczCDaFz=3-bzyIlpP!pM(>z};c)8!x>+$uecXySh zq^Ac*MMZr!w)%P{c;~NIt2w#3v#;*!>gf2t=||M+h!xPWt}7XTZ$E+#fh_|0&BevV z<%qlnsFVYZn|)*kRU{xmmp=`ltPBzqv|j*M%D;kd*NM0#n>Gn;zkT=CT>(MCiFGJ1%Rg-8+GD)j9K7LPcBT zMg4wUeAvRzbv!G7-__RE&D@dSA6Q8kOMbK7b@P_!%H?|`+RB%#TII#K>xA4ghS-#R zVG*{2To+RHCz$m=h+||qGE1JV*Q?od`?~fM6+1rXzPPl#?7pJ-gW3OOr@q$ae0TMi zFYo`qZaVzn*TxTjN?E>h zt38|YZ12w`3AW1MPiOM2zJGfE-O0tJY{sM`ogE$ZTDphiBCF*si=EWmR!YnLl9#C} zx?9U{E!uGBc+b6G>*p4kz9|=x ze7woCUP1P-!K|ktPgkFcEc#^R^?d4~o7)}Q^Uhvc*U_=X4%D7}RIhdVU~H%DDl-TE z7duj;p00I2d{OMP;VYRLpG8BaHC}ctEi2V7tvDXKX6=Hi;;oVv_iI#^oV~wUT}PK? zLBX`2QyUiSy6w&N;I{cj77Gr0rJD2KQmw;cb_>1nvq(<4%R4*l@TN+axk7#)_auGZ znwuW5W!p>PhY{9uB$&R><&w8yvz&b(tJN_6Am{W+_PX<3kLxb|GXK(DtEmqSBkE3O ztuhZk=sf=b@A>O@55}_E*Rt8y-}~UpEGYOf8fq zGHi#fn|2Gi&sp4RwIjQSt9c7|_`{Q*uk4eM+@9`Vb;Yvak7~v3xBRwzE%(~5NnnN+q1g;%;@0@M< zpyG3Os^m1*;D>YDAKvLJ_@B92-;p^1uv;O7HJtwy5>B)c2ukvfY z#8jm0sQjGuNqcvxoSJecpVyVSBw@ zcEaB{vm>P~!g_1>e{AP3JaV(p&2r_f7j5f)Z!P&gOKdWOu$Xg>(!Q(>ED>iif9&^b ztoAcwL?%-&$Kzy>|7?FYoL9uisDnIp0EfF3XY~56)I6 zT(#d_S*WCRY0?xGKNpuj{*{~#e+3KYpO4v{yU`)U`m+cz`N;J2gQ1=r3# z<84~oXUYHl`FY{mER}b>M}Mrl#UI4q@-24TpSs91>klSQxFIUEduH~H+vSYQHx+kx zY%%-)PeoZt>9<<{&S`gE{qo=N%=o~=Kj*XUe!O;P63WrNvh%L^l&o_+9QG9ea7oU+Y|e5?)`35Sz^@fAD_0a ze1Gcfm2al^xA|(H{QWBXO`xArU+2OP&+9*==1F>f&;9vmV?s#Pfg79r?k2T5Er3Yh8ZH`q<&j>rM$AC2tbh zetQ2uu;Xh+&n2!GLX6k#c*X4*-uEy2vibSX@)t&n{CN)xzFuIpde(`B6I*1rBsb1k ze#QA$^UEn`)*lIfX_&v|&-K)Pr=t14*5}`AIQsH{T$=jx-7=rIrr3K4Y`66jxA~)K zlX2j_apI@d2H&;K>SuHZW?pzX&+m5r;)Q9qtvMwnJYJgT&+2@%?cNS9j+Tp)6VI?# zr2XsP;C%Q+N&eyI20YEDM5j*C(^>jueGpguFR6954DFyPwyFI$Y@#EZMbQ_}YPE z!M8&4R;avP6e^J_CsAa#L@s69`;wX0U#v5^KIOaBj)!cYj5o5)IJ|FZ{nT06>#di* z`?2*G_i9l#xoo>4vxC{&C;mSA+-07GXU6{ko1=1T9G~?x$%t@9|8 zWcCKO+Z@tYe)x*4zUmc_CE&Qy@yJ|p_ltLw!tU=AJ9a;Nnz4xBM6u!Dy)R7 zO=-tF|`;lmrsZ&Undu&lq6bS?P)UDG$r z?FYguw_cvN{neDLzE#h1O!o74HiYLZ|G&Nc#QeCHqnXE(Si5<3^yEK^9~G((v}sG+ z@M+dni8k(IXESU#@_o*^&G;?KsQK*twxrP3oq4;~uAkcH+hVPLK>qR#lQQAh_*bX) zAOFMMpnAcxJ^FE{?dq3HYTcGPUVMKvEg`S`+WmuBN2M}uuWYdY^P#}$JO7fDcj0L( zox?AD;};T~n0ED>-Pw+g6ZcNOZoQsoEPQ0C98c!w1MgHGPv!A=l{;zcOw zWRbsE#?(2<-uuLVv-y+udl%-fY4fu^6LoXGEr0R;CTG94o~vmEa?cM0KS@5To84ij zJ?q@}(sh@^9`SbWFuo(=BgJmmS@7@fZuuqVVf)S`8E#&aUwXX4;&0WD*X}i}H-Bh( zEnLJCrk`^8bN7iVZT9Zd?dr>=+-f&`K4^KM+q_}>tS8H>7#^H6da!|cTXBH2pahS4 ztmDrmg*g>f%|B;dZq=`}H?uM9@0u$5b=iLDyyjB=^^1ROH`*iGwlnX4hw+0W2`}yl z=he#ol3_Fc&wl#ff!8;F?&0}3{aEm)<61wGS5*f4xVS`30X23%^6TGAP-9^>cG!9| z@dInYsnBO7In~Uj=dSBB`jkTr7}9H)7cX)6lzei>=DSmR_lwv4K6d8S-Hq)#+blFn&c}sp zXMC0%9et|1(!O5KEWaT-@BUVY_tQNMzGpwu>rqxvZ1^PlRN`r#MM1{rFL&kVl*!io zV`9C`edhggky-Kc_jcVme{XqGDeK+1cWqZwj|M+Ty!rF=%5#N>6PM4J`G%dhd1?KO z_g8nN7MxBfe%Y{FsCvufCx)f@FC^L=e=aJL*~rHvBsH&9pe#T_Y`XCMCV9{Z*cK*G zQ|!{Oy17ij_g4J1+o(Nd`k}U`&vt!2Hbsm{;KITG%WbMZ*`yWJedxUK+raqa?M0T) z4ksz*1W3fjzwtVkZkbb2CA{QIdvttrbidk@0|JlqyYsia&C4%Se%-5MR&OHzc;drn z-D2E4vVrO^=8xR<=)J3c49uj01svy#&8qi6oy)110#`}_2V4~|+qUK{fK$A`q`Hn{@Ddq=egthe=a)QsC%JF z`IeW%at5Yqwnttif%_K8%s;+jeovr_OH>OeWn{*_)7s24^{i9De1%j0G@H5KwJzO% zc-8*dcH7oSFt~rwWAo5GA^G}<*ux{gkDJUemv!GW`5S+UQci$G*mBY89Y57Azs-r* z^EA#V?w=f&Idj0S1#_0BFBQCUw$=KwZ)u+CJRxogyIuY-oC>lGIIpW-csHvoWZjA- zIi8ZP#a$Zz{xSdfSzJ+A_IF}leQ03TKRc19m!7T_Srh$gk@(*rrn~G;DKW3V=05Z< zczyA~mSpZN59a=DwM?qLH`iBwd)daFEel`Q8N6XL=BR(JxcS)cYmv%@bF-$aN9Yt> ztbJD0{{H^)zsEx)w#<(_wDxt~Gdp=(&f@)QpISWTaQZ#c>swv9ew)!9woK(|!8;c* z-70PC)-%0-xGN}Pep~tBqCMH-!9QPnb=B#uvNhPLKd1QiyZ!M>N}Dc&5|qd5S^s6H zh+TTRQ_teIrRVN~oip#=77a1pyE{;B`_IzjpA)vOTBol%`FpP1MRj-KJG(y$o+?wm z)yOEherD%k1D-ptwF}p;Z~5UjVFpwEd8Pw!3uINO}?JtI((+@NsK6C$S=KC3&ofh4meOijayWy^mZ{4HRXaA-?{qUT};)TnL zTlZ^XzUTZcyDZKqQ0T)l(OKzru9+6kv^jfwUgem_*o&Q$xcS3lf8vbOf?Vd#B~3Gr z__?@5xk~@^P*zf^UOQ7hxzJK$PNc`Jj!*#+rsnfa7d$jhm|Zt9S6gb&&}uKX%_qJ* zxZr())!nNrPd=zwT{eB|;@>|+4zaZ+_Lt4d{-i6m{GcHAgz*DQzzWwes}_R*?XC%s?R#U{`j46 zYIa)C?zw_OjEmJ1chu_GX0MF2dV9xO>i+-!%!2ctH=6f;nR##W3Ss5MPud^8F|)jv z_qp`gv!rfC^UnAGjvrD#f2eZq!-K{Te!iad?(~Fih7%RGn-8ANoUXUr>NxjeyY}L| z+$yPkSF`#yESFpHAjW0MR8XUB;NESy5gc@zK2I!;f$NRu3I3l3XsEyM1dpf9#O|e4+9>lfdIw*Uew&vwlg| zT&-s+$=q%Cc7N}Z9U1rs4*|UL^&%%nh@WC7QCX zIDYerkK69cwwfMs+{e88qUWzxb7Dy_Vd}hDdu)m-Or*^V&MmOpFSfk z-D|np_DTB8;5F-O)}&rr_uo|boyD{T_ZpY%n;n&Yxhp$7VAlpIyW1J}cHErzQuyK8 z-wR@emYg+D=e_aPV$s@`FZ^n+rf4|v^Dcce-{{(%oqYL?(&u(_uanqZeDdBk-DbYK zXJ+#Do{Y&}XZrsi^CP{^#fQ(zO5Mr5c+z|2y%^p$@$3!Fc9*L^y`PYJ;VnZ&kyJ~| zb=!o`Y!=&v&#|c2F8i`_^U2^hi5EFfe^C9}9$v?O``q*>;g!qRNceFsU$LTNgF)>v zft!=Rz4JFxQhIbhtuCj|_f_t?iFc=6pmb?5I*d{A@M{#o^;`JKw?jDqg16aM%Z{r-Ec zeP8hJ34dIS9=5k9Z;j%V74W+MaxaIp2-|!cX7Q57_xEmptSf(av!Ea@Dn-qXW%HH0 zd*3^rZ$5cH%4;p7t^I4i8xIe%eB)Vidv@#w_M4gYt~^W5HcxDy#aMZEc2KU`YUVqV zd0o%Mu4ZO`UAy{YWlh0%7uM%WO1TrzCg; zGmrPfr#ZWB*Vswin|NSFO;z2U;{MX>@)B~*t?mD~+ZtG*RnFp_(~gg-#^w&iRS(%_ zd}6azD_gtWtp4)q*(d6(rSC;DdG4K+w|tGnI;n=O17u{%Et~=l$oKU;gAV zUU*A1`N5*!Udq|K(h3?(e*1*N z^cq<08N`aSY6In_JW1{@5UO$zxF@8q`q}H@r1n|=zN>87Y|^B6DaoWsPf2NQ^1JY~ z0zLtOD_{1NvCEXL+Ua-Q;8ot{hz0KzRvGQ7UN*n(NY?fwUK4j$*+9Okx*NQ+*9tMr zzuxrm{`Y70LhF1P){CdrUi#s8j=|!+-yP{YH=J_5%)UAK#AD?%QFpJ)am)@gzy5Sa zsIPm``zvPSDik;-pYPp&&y|@H)Pb@TUKwz+bJRA`09v=jN{P{FO6?Z`|t82aG}NHw;M7= zZNAv=_-?zWuvT+UsMkq()q-DN3m%rGd3JPk+z$fv=+-_y-oK&MYNNa5*`Vy(m-TL* zITRZgR3BX=-_x~Ceu1Yl%n?384X0CfYX~UCs?d*Q-uXLZj z-B-svZ)Z`s-qkG++&_c~S30RoeL3~3S@^o|hZv7vzs8>L6KUvE+5DhR?-1XuuNU_& zQJ;JunpfU_=jmJl39o|v32z$T>2kh2<`iPR;@bnwyFYb)Ij(g4@^_i}@BbJ3|84#? z;gb*7-hFR6b+0h?$MdkyWyt@-X}l^SOY@EmpUk<~_xn3KwrGJ{qMy2o5)bmX$O*NW zHr%Ru=F7=tx<72nwfozi#jjbnZU4Qpo2r>9`=|S+7K+TazvFYOQv20g;VZ}ICyh{TV(cmDg?I)A}!2CeI1S8war1mwEC|Jt9Qbb0k` zhT<=^CpAw;{C`n(?cUC5^?dP8w~l5`S$fr1?)tw~-_jWV{blzpKatk{+rHs&`$SvC z_MVTDE^`H3PaH`2k-$@9EXQYg^Un9h>Way{GP#W>*T4JWI=@W!i!~EN{8D!Rz_%R5 z_ohd0y86ES%eUK{Ci(Y5a@YK?d%I?d`y>YWm}}B;`) z&cD&sg2RXN$n$M)BHG?Pu}e!@BfhSEef;{fId8u@l#1HrKeqJW`!r6=JnWI?&7Ydb zbX8xU)%l!u_~G)|H!p|ls(iU{YwORO@@bRHGNtAn(!E~r?{2{d&y@Xh&&IRsr92e; zA2c^uddbf_SEuOfrvL1?`o!<#+RD3fdBv)=iBYaJ>{2PUw+4;_H#qcZ>t_Vc|DId&3rSN6~AlJ zYJYCNbvW}`^#dQC1FwwilS+537LHgmVM0?Puj<=Lp;P|cJz&%uD^TsH^LAZdv;BVa ze3gz4kJ;OcBSSz72*V={|5&$gSoq9igXxVX!^gG~MRjL0vYK_oDt=i@RO{}s5Sq82 zZ`V8a_IXT>i51#huixZ_NQ#`(Q7I47TUtL=$VOqtrv0ZjxZf^R-C3ZzlfzP>rDL(u z2CL}rbz2{rotPcO@>`ZQ_E*#0PTO5wdHSWRZ>m3@diKYvRgwEM_WpD_-~4cu`k9*? zmeOY)e4K5rm~49RH*4_5JyMGg@yhYPc3-=^CeyO;`LRHg-5jgWGTnT=P~mor{9TcD zVYgaFem>>LQzav0#D4j_bUoQ5v}b9Y4XfO>{y6^mcI>j%2il$*hiSB zdne!cyy)c53R4+V8L{)JS9@Q-u-|+=@Bh7>#dn_6%*ns!;dyT-&qpPtNAp9{d{gun z8f9Nf`(w!a&a!h#co1j=w!Ck4>hpC6qS@vYtdv}`{7d^PE)C6wNj1e=?mRYIE-+op z>0p|1cj-H~V)+A)HVG7#u=IJbyKQwm*u%8PHO`5xO`z0C!CqY<6Muv z;?fEaPvYJ#SX*Rrak;zj4bu&-_qh%mfJTLua(k_e2u$n?OKyCnRq;sZkzU{8!@9Bt zJk71`dQAP-=Xe&}XTPwu{x949I@x*qTn+cdC$0iP~JbH!f#3 z>@wCkHEqhqKa-vsyfT)k`PTQ9KjE#=j)wv{jCsH6E^}ume7;+u`6ttR!MxB^z3mbk zRRiR!b*IVSTm0X@Hp}g-^rl~ZS4GaQS{pgf#Hw?}TbN%o`Fp8cVtdQRk3V}u)_r}n z`p&_x`~C~s>dfkzDk|}m&9Sz5gZqt6NwMbDn^#{<*18@x>36B#&)`oVMJhPn2zq$@ z7ijv$B6!DqMnfNC#J1^cuk{+qd1{*T{Q%Bin6*Q`=H@$k&*~*s;yg>v)~fXY;;i z6_>H`&;9!^e4NLUbiQlt&6E%c0fw;EQ@03aPSMvhXTDLbb}b*&u6ogZcCPDx`CnIV z?|HYe^qJI`la|)o{v<}%pKr46KQ5Q5`m{BrDR{PdVbsAhOlEeo9ZSom{*;rm5ZPDT z-I1*P;#0_Uwf?`~f7E|`GSgc`DBoA*-=ZI}ubf{l3JQzcEEew|Ve{LzM0$hw+m1H| ztS^*w-9WRmPK>*@Nao+=pKt5^=jg^uFs*KIeFKmzLLmy`?3ND|f2x z^p3aqKTlWrMQXs#w~J-c>id?i>R>E>#a?B7YK57`ucaM}=67jC$GBa!D%Rbud&jNd z{exKzwmZrVzI}KWDZB04zpWxZ`UdVv&dLv`-ae4taFva@zxC(+#KMTeZRHPi4G*L( zJ$-p@WbyGRn~%Q_uil^kUuC~f)AMzWtBQ7flQh=6{qA1D3XSI7{tc@8FTQMaN%Avi ze$h0OHD%AV&g#jH>$6V#PP1!2e7ZQR|8MoQnO|*l?NZh)d%fcc+v!ERa@!=fua(}j zx#IdSi}X!1@7{U7__3{Qr>%O~?)Eopn&h{$yqcYT{qKA8`u%F&cc1#7RsVaign=oT zIeXc~_dSbtx~|z*YwL34@Qs-l7T*5GFLX1O>w;@k4`}wgg{dUdIBplG+TI*H`zI+o zN<{8hUYT<$uATMVKGt=$yVN=(n%%w}N%dZS{rTQmYrE$q@jvZ8tr;B?_W6U@%*7WN z=Q44;OJ;jJ@wm&Qj=MYGd;|>)znVJbZ!FvL_;j_l*`L^2TpbJdMZUMSmTimS_&M|0 zZ=u_a|NgS>UOi_)i1^X^s)Sp7YR;dl&K|gbuP5@|Y3~Q;9w+{+vAQ?2VRd)+)a&b8 zKUheZoLLjQ?|z_wP~7(&%k|n{zGvw5|7Zp(C-fUHyB*?9F5lZPEZ6e=_=U%Z<<8o5 z?OXdt{*&kadfAGaFTZ!nf19u@|ACHWwq)o_Q3jWJBA%aKJdw4VZhiUeB;)CiyS zZZ6Yloaa#-(4coI2|Pm=6?SwQ&$Z^ZgNx&5Den@VKFf6D+HJSom&@JuPhgucy>YSs z=V=j}+i!AO>-20me1?CK-TeMly`fX|SMlEBP7|5%wM^`8+)KBF?XvN^_x*ZyHLbwz zkz$02xY)mxw4ZvqM}!g%ii>1Ti>j{Yk*QI-^Py>{-v8a@A8kq{m)2Ju5RBWOSiW>8 zTlL$djO&tB@@Z;Dn{PIxtrL_N$x?f>`*DPsjphBCwXx|Hf6p&lzU2PDHp}P-n>VJ^ zPw+j$DfrcG&gp+T%;jJEuG-%}^}1C*u7zKYIb2{zlVY;zxjx2f6AShZE3>W@$%_qm z7N5NMd2LnQrRJ;K*Dg!R<75ryE=b?`(s18#zPZ}9Ay#(tMd!^~_8`V3MSm%1LLw?G za^ugf$^ExpUJLwKaDmhM{@k_tGu`M#fp@#r?kBaA)9-C~aoff1|Nmc)SS#N0F^*?2m#smuXbFXzIAn(iUs=y&;;&EY0Jq)Hw@C4Q|qU0e0I*Xq;lEIudnAR z@h|1pe)wdyqTy1@T{=oibsnIFTU*uy8Nar2TlBP1*WOot&?9|zQ?cjXgvVYp{Cz?ei0Empdz-G= zEOWm6`|S$8yDLxqT3dPRmghP>J+t~vlKzeC)hT!FSGw*OnfNh_O?0*P2KQTqF4iBW z%#hr(QiFB*+#lYLGwYpy&$@X10^`CjGw(?IuWUanpR+70R@7~4<3qC*QLm59jZ9-Z zn%-mL{?PjC9i!I2_PcluOp04wUud<`E9u*^@q1w zs@8|ES*!5(Ux}7owOraB_UHFl59hD8Zndq|tohV4GxzTq>4#_cKUlc=!7;~z*V(<( z)3Y<#d0AIao#S7W#q{M-eAmHXUgol-zm^9wuP6Tb#=Cl5yzBMC*p0VtyG_XB-<-@_ zmM|r>`Dl~zwVMy>ZVGSy7#e!`!|muD?YU=mrGB`(`@`w!6J|3O&VBG__rn&!wRepL zC(14Z=h|!6OkapDJ$w1y2I&Wj)jj2>`n|GVdG_)%zD@48UVilB|FrB$;uPtKH)1+v zARkXW?kZFoBqFwZ=ed2yTV%aiu1z`c#G$J0%4MC*Z&_-g`S+Oj*RkrKStsi`-&}T? z|B**U4}SkNw)p0>IqX~Z_QRK_&knxlzAr&-Lbk7>;Dz4?UjOEVe-8S0rRH;*^Zdi* z>((~=w|Kh;S`~_L^T)R6-e}vrw|7PG;tpH=Yx(Y1?^@>dcri0%H?T^*NQ;b;ocXwT zL9zae;t1~V8+bL&nSZwQna!Xr)^OI(fnA!Boh9JY@uC|4ST4=KA=+^+w|Kz)(@k32 zrm$zPW3aVhJGXc8Cw{rx@2u|GDz0!BaI|fT`Z8zYaTlRV9~H^`lnGy-t^e@d$KruS zacuS0$mzR}-`0FmGs*ehlzs&Tj=Xx|Dj5#_UX$j>tL5@9+L^z&5d3k^SM7O9{ND|aay)%zhjvkotNZZ_%TskB4vtirW!CJTSJCzbwk z-w|MU?>2Uv;Dhu;vtNsRf5vs; z;GAQ>-p*bly?LJ94{F;TYk^mtsj5> zd1AhiT%QfM-`-n3D%UqwXP4hCIdSsCv%4vK=ej<*;9*lKXYu(;Z2tP^j?b9Sq*T?P zKV<$>lq=nD*@t$g4N)7}Zg$GbdH#NVYx}JeyAmbV>?@VsccJXVi)w=h880sJzq4lb zU${JN{?hd24|UhIJ^#->v2g9B@cqG2EameVyz7q(y->*sFnGH@-#_5`t=U%6^X@vF zJHB(n{e&IwnK`<%j`DSPypj38qgO{s={Mi&X)ABo#ed!^DZ!I|r=vR9^j%K*=dG`w zuL;wZ&C6py{rs?d|6_&bzV9VV?w{YAb?gWno2UI+9DiW?%@1dIc6^KMSqB_J3uuerw7Z#phxz*RYUWR3n(=X;WW}@82L8?O z$`UwaEUv_a|GocmpZgrne0zs~+kbA^z2~mnUY2?xYny2&9xH8Zi^Cyy>WoG25*}wMQ2z_YyOsIjmuX%HRJxl7%>3>vSK`&WaQc>r{kK}=?U@dH zAKP*ESxC9UuPHBPxiq)hi_J2(JGW2tkIDCj4v%0+JyB$_fa%2zk4sxBFF#ypd@#0C z_ei7ah4!ONcIFa!+{eDl&+uF*H$TYS7 z7tWo(_PEVu#?5EZT}PSP=W?;j@K26gR`f_?+PuwkJ{(k3>G#Vs*<4rLZK>S0;_~8% ziU&@`vRkh^x8DxV+7|sbY{Ski@BZv>I<#O5!?~Sj_auHl=N!SDRiD=9(f)JE&Q&fQ z9a{|UMu`YcoK|`+S3uy#hb?zqiy!{GyrI3q^Y04wzxA)2_h;6=wBD-!x9-L1y3M}@ z$_r)w{L}sOqwsEWcM;=_KlYpTc3$a{7tBv{um9WkEH>)GG)v|OcdQ>AzFKf7RphKr z+C@+Al@ZYwlVVTQ+}*RXqEx{rZO0^ILkg59A%c zdUwv>1PM0Q`}vXEHhfrq?e*f06M5j}F}kmtsuQzTTE4A_wv*peqa3FGW!9W1^@y8c z?a@{V{Y3|k`(L|T@ItfTP3x3DVaN8X>#6?V{l~V1G1vdibvtabsbcpg)l`YLiw_K4 z_lr-oH5BKw=jF5Cd#_hGdIfLS=dz!hzH!C%@3gDG{e79U`R9+PRet0A}I8*=3SSTaBJZ{PCsSykz7 zS)1szyCv^9lhd89?3;Yt$>mS?(dUx*``d4Fl4*3|mb7G> zB8uNJwqjzgPo&`-A-}*t!NkO0J&K#uH66rndTTgLH+#M_`@wAUv(ML` zZWbUO_(H2=DpWWKGH$K~D8Y0Sacu7uiY-#eIIEi}x znol~{64X!nm#X}^@L}3cGy8y@>n1Ht*E8L}G2*OXTsP}Cd8W6!51f5`;9bUDzh9eG z_aBrlKe)*9hSOY?I|BZ1EH_HXH7`xqKfHINl-{1}Jm;LtK72oAut4Fq%-p~EpSJIe zKg_&bxZc&K^SXLch?I`Z7yUaQZ03{(e~zDT|N8@H#p`{$*5^tuc%IYpP_}cwl3ep zS6*r#ds9)s_v};Oi*LN?Y4&eIZq#$kzJLBWWL+k2$$?u(&zAemIG(4vAo#Gi zjT1k|QMtTk*ZprMdJ7BQlv@kh06WdRP~^rM728{#Uw&Ud_#`~x$J?#9Cs)m6oNzsR znl~3$Yme!MEX5<`M((%EL-s2_cvo(aXWh2OeDk-NrZ2;$Pp!LLeZ5lm)e;S}zPla| z`CHQ#>1NJ4%EUf5VOq-Xm%)1`ADj8~&$~*AzP$^6o-cju{bSvW)2Fh-E`2^c@5Z58 ziEMGx_m#Jrc(u>07c5M>R%VbcpA(aKE+^uXG{ZZe?UB4mhq=~>T1Mp9C7kx%(SEK) zf7641{2yzr<<{S2+$p&si7~Og?LkkeSyh$$8s77(TC3lDa&egj-USgAwpBXqAAfi{ zd!X~;6EgE%ukP-j)w#e)`SrW(%`*>LIyi}c-l)wc!yEf+qP1r3e9jBfk9x|5u4td& zxv)BF-JFQo>01vOKA+idtGQA<#(Y{=c%EW?mfbc5?W<3ZR)3rG@7VL^)aa&9r-DwL zZ`yc$mgKeVd&H+Xs817+c3UZ4WbPQpmU!GXVCy~Kqn~oGEsQT$*t1`#&t~(tt?BC* zRs6E9;Ig@){JNf}EPdC?h)`bjxm(rO2e~W>ob^agNlEwg!~g}rSzNxJd%0Z+>3^w}G4Y)g^5KmAGG zDqVeX$$Ylw#rvDOl7!sUEfzgb8i{&gx%kD>&(r9kImJOUb(nz1Ml_OvPb)v!}NVQHG16P;^GH? z?|jfLen!Zn`qW18hPyW(uz#-gJbUHdr%Bh|c9@)b*RVN%;h+0OTGzwgRWttjWS>31 z+@2w?mbXf-NB4;5?$fs(=H&nT7qvD_DBn-zO+vBluJZM$P4%BUgE3&8?e20 zH}i*?mmhC`c&>2slP9SmYt|TiPB^0WZsKWB5(al)KE2_S_$lNzbN1Hq^{PKVrfmN9 z@hkiFHTt<_ih>1Sc7o=}KfJL%`RLV6tJT*(Y|AoV!WrJvICIx%_oMsq%YtzB zpg2#(r!z%r@>b7u$cv8O$5Uo4`~F?T=b)pvxTf($`;~6wb@Oj3&dXicEh@OuKO3}@ zv-FL*#JPQ~i_XU{s8|;{dq$tF!pic?$KPrlZrG4f^A5BoSEw}R$~?>d`JYAdBq#E& zicj+T({h!od|#^FH`D0V)^}|9s^n7a?7wEs_-i@){_Ob8(MP#HtIgIv2^v$rwnwf! zFXrs$6Uojee`iVUspOY2y)(!3(@Eoq=G+}tyBQ3$c&5eglA3SK6E`pU+9q+qOjmFx z|7(oBm{8D%wLiGq=I}H3t&H|tX=z(v_2(Ne!)v$HNng{n>NB&X_2x z@O7@-j?Z^R{>Stzp4)t2U1O=&8qxn@JnIr(*jM<+c6OZb10NssyKVXY=0h?s%ns;0 zonkisto-_=cbC51uWe0QDozwGr{?w_^uEqU*=e@3uH&be#3wL&Oyt$oZJ>#I|jDxpi9~+*s z)sfwoGv7-pd|!_D%$;SPYj5@2=KY-i;ZkqG)qe#s3_UhH%l0yhE?s+f^R~plMH0n| zYy7j{&bu;ouiUYi1h(hk%^~lv8BKi=yq)Fge&5Vxd|e%HxzpPc-$*-Fy*w0TEE%6rkX@d7KJt_Fof4Ls-)!f)R9oa89om-3Xj5y+ z)7`pUui3RYdiV5y*=Lm`CUV)=rKH*Bdw$=`Z@wqs|JO@SJAQgttT+DiMe^d|MK|;F z?1l1g>@CVTxVL#@tM$Xx;b&)xDJiY>3BKd%vgEDysaDPW1Go7drq_M=W^Y|~XTs-& ztD07&uS@uO^z_S*b^L3t?frgltMzf;t7`l_^4D&~-YgFL&t1-YR4m~_b67Sj3o@g@%)b@;6JW%2(py!z+6=)DgjAFXVzrYXb* zCDg6eFg4!D-Zmrn1b4B5A#09r%^#b0i`wG<|HzE^qkZx4qRjfz>Ny|JemCyktuX7% z^=F6gtWUh~^6a&B9Vgap_))VfR%4U7hMu09jg8Dc&87z%uD$E?IIVG}v0ScgWq$KR zL+_Q0XKtOe&z*eiptm__9#t;?YsSC2U!6;z>n=9B+rS?_Gx*iF_UX4Y`?nllHe=~omOG&ZSu6{gWsl4gK0V9&5+gT{jaZc&Ppa!y z$BK{Bw%%UK8W6?u?$ochJDVPK7$=@fF;3v;XbPNvP*Hv6ZSU>}v&|FVCVAL$`0ZX+ z#}NOvZS!qsPrHb>5p%+J?VssWu>RRh)+7nG?smPy!B3mK^D0lTSl?N?*-rk? z&%KeGR%(dvk$X|fp);HP{(k=(6BA2n_hp}sb?1&OyvqgJ@#U+(J?7b;Y1{00-M*;2 zn`B{iXU|`00m=306HM*6-_^1E?I=0_eZ6kP2j)A4GM@fwf~7GcPgkEhS*6`Q>Hg`D zVZS!qSR3&sp;RIw7Br+LHk&nlk+Ay|=ISZ3)l+2M=P-AlJ@l;KEO_4*Dfcx~XIx%< zV%CJ-MBYaI%?~d>e{lHtf>n#ks(!Y(PPnr?Z~ir%ChcD{D~0=Pxa)oheA>)msnPOo zeQEx*)9da8oII5s9z6FcTTQ}7r|J6&?rwf|wzGCFQ^`cJ#SF12`U@FizgZr(PFj0r z*>USwP9Hv&gohKm4fyQ1<^Jq=m>l+p^?VHDYO$uvjiv{M+IMuh z&cRqI9{IIquXEqOerGFr`u_dP^?vW)>V4Ok5qaQN^|j{f++y0_JggV8vpjzF>d>nV zNt_!JN~6x!r#t*B|0!}_w~@Key#D^bd7cSb3UlS(oH;dd^~W+>wt4gJeK=WU=IGNj z^MRqZ>^c8qa!(iB|6V)$>!;O5t2E|C``p~0D)Kj|Yx@!2e*Z>i|IBNjw^)K_xvnkf z?(n!BJcZj*x>HInSa?o;RjROCq$!Wx@`uTno*m9Tp0Kd%o3e0+v|zY!!VraS)YN!oBD;YoMFHQ%k)KWd(Bd1Rk{V9(1B z=W{r?T0g&Q`ur}ZI`w3Y-HeZN=U9I8u|H=xd0uVfpGTnvg(5vQiT$PPeIxcU)Xn$$ za?_BP?RndAg||&lcNp`oVPu<^#GJz?VI#w%Kd(uLt8NCfF_%={{j_#xzqYIY9qQCN z&DB8-9ELs(>3gBvXAk_{Z+d|-X}c%ebv@2183tDC8QDqdEGjIZ-9NuJ{&;6IZ&7@Ahm6q8pztlXZCK@u?w?zdRLUCq zGH+F}ZNiTSCyXEd+9+_J^V8EFqE6N2FYn`QRbu3J0TySpI`1vW-;^(PfmsfvR zecyLT=)r=+YrjrspR#=Fh78nW6pbfR&FTcWVoiFzD}=9NzYdyEy8E6;PYPn zoRrV)@dw(TrhVG-!%w%~aJSN#m`MpCQcLDWo3lH9$-G!nx1)G*yPEyXGmDa^KddfP zv9VwM_N-h6-)gZ#`S%4%-Auy5|6cqo8oqvItopwf)6#ezc;*Gvyt{teUr*6UCAtU5@a3iZo-B+nI75siXLH*h@a`Wf&o{!_)Uz^-F z?|J&ci_fpgWcO#?>)$*tiGSzh;*Vk#g=Hl|r9l=y@B1|D=qvc98^xulR1My%k~v#% zkGRs~4@>o1m&Bz_T7T@6dFa%`yHbDH+?zF>=WxPb<<~3Et!b)0?wm4b=fU9Iy4>W= zx0U<)7kpSQRD5Mmtk9pYi+8Hse$3X+oW5u3hRw+xmg;Q_);acWyZmq(AIn!xrN94F z3;rJb@X~F=&8T-yWmAtbz1M4gZ{M&!zBxLsdCI>Jhe}2M*-SrnxOfBm&CdNgv({X% zZ<}x5zE~Xp4V3V-k|xjX?Irh z=e2SBByBo~V>nVFFTF*@n< z(kLyXNrcZf%?n_dL z^OcVaMQY-E0s~_==f6^48IrqZ(VM&O5AM1@_$zv0;cdV9!7eH8;MV1~lSzilRo-_T z5HME$+{LP6nap|5i+M52XXhUur(apS_s@0ygpC4a5x2csL`ri+64~1}{`>e<36;O_oIzZY-ZA@f6PJIf|BX`iZ{dAr~Dx6M92 z^L+Q`huiZxUfnMF`)R^H#U=Y@pIS6|dO&W)8EHoQI-e^i166EiwIoV}q=!E4C{Eb= z{!i?duB)PJq;^hwB~$)(Mg49Siw6lB=ak>SmOnGo#B;CW-8qGzs5mlD*!$)oBV&X9 z*E=ph7Zto22r2|q-luOopd5doy+3$sgr?;D@`_EGn#T zLlzm?z?^`n}mw3KI^W(cK5-$rrB%O_oWqg|pmm~ut_#-!}4J0e+Od_8FDw!TY0E4Tiho<1vekKfK!rN3@ps@B%* zbAF@X;su*{>V62kmoC40|Nmb1gR!n3>KvEsnQ>@;^M6$X(+N-1C!d@@&;QHGi#M2Z z*VJd(woZ<3Y|6=)o^$WVsTbH;)(uf>SyWiw zTv|F!S2y{mXtsia$U0eOTfUZczpsYbeGEAq{r#}|`712X8J2$bKKsB%MJR6e@?S5M zHo0%z>o2dQq_kUUpYWY;Re!J7+WmOpIpc#uguG`b2&UoP+cmG4PTvdAglwK{-=<#Y^(;1nve>=ndsed1y+n#vh=i0k}cj;BLnCUGq zc`5&3ok_fO#hl8+X|Gq*r&{L3@khQ^C>NF~3VQu@`_jKwNB3B=7JLnUP%!J}sq?!p z%V^5w{|v22ZF7?Y69mfd@l7qZXDKJokS9scT$pM^#bSGCMan=I#_^z+!$kUxJc zr!lC9EpKh97Mc|kw{hxDwtMMp=Zg0qlFQ62i2ZX;!(Ti7=+tZl9lp4E$$hi_Pd}Q( z_MG8wpUL%|^*<~`(q^B2-*4&v`n+pOKX^{Ej0CQzW8w9EIUa^75{r_Fg?O`tf8M_Vttv-%9{hwnbd z*);(fm(?>h-+5WowalDqx2yK>?;TBNUVfY#6um8f?b=N;au#=M`yY?_duiK;q$iU&uiQ6Cg{DL@zHKiMf1;DtREQPzK-AD z;ZdBOtXbgV;xfy#(9WhxujZ%F#N+OhtPDdB{xq9oC^o}R(5{Lpd{O(3?#C~_MTPI$ z8&co3$@rS*`t{X9rCuUFvl-I2Ha}l)Y}~xPF|g)uL~e=h!sP7|s{ZY1{4Bu)8g(_~(m19?#jDKfm1=wboj8PX5)G z3t1wz^9Th!IJdpeE~B;`H;7&Xxow9c(YgmW1{kn@6f9Fos z)jT{mlGWUnU3T~T8z+;69$dTraQ^(WQtzXuiobt!wWH&WMfdsVmunp-?sb4o6$IuU zlAc)W=&HG=PW_9`k(z(EMSfIIi;O#yX6}AKCt+j6nU$-=HrzUR^{n6V+txx;cJZga zzUTOQeoXx2v$y5mF1g=hXMMLVFmr;X-Q+#%xj#JFeKzyS@&1P3^^NQPmhUZor#0gP zL(Mmv2pyKP!UW!}LEpk7@BYmxTjbBH{$)YHCHV+`_xbGK>mSJ9eD?R?bNxfBwaA_t-?eMz&se-wjC-2_`@!~|9k#2L7q+)4efq&pn0{k4Ot^{@mTtGu>EYw$;5gf%j?^?)+P3xoe;CrfUalmpl9la^mM( z_W8xRuhUdR@>Zo>zTwNVjBV1_s%bOd=&dxr^K)9$=e2v{j30dc`Ju95Uvt)W-FSuu zG)ai`y}+@692V4&TICSVm-fpKmR|$|JU7@3@LkdN&4rhF8R{#c(}|~ z{m_C$1MlQWrAtL7O?sQAU*OpFW^z~2!!_Sp+w&HbbK z6EyXAFSg+GM3sAUJpQPjH8#Do!r(-W@#Hz@KN;>Rt9bHR_WX=}mCSc6IJk^GrKWmZ zxv)a5{JTiSkMB3?&*sPdJ-p_s-m>}o8v@g3pRbnBQuEtv{opP8gXZHKT3IiYXZf#b zTw7n9{c(fp4)c(in-llQdAwx*+ux)ge@N=hfvZOyuZ!;v`r=`|o=+zF|M?=pxUzakCTSV|< z@xPDz*LQTBSa(D1<>bI;X=ih@e|*28y7tDxZENpNeY=6>#>3Oo6P~HJ@RTHOHUIC< zTD@ehU2xUISFemV@7-V7ANgsWqGa}iX$L24pP08^P4JR^O8a@?E5;|*e2iTwZO)Jr z!>P>Q+NHE>|K+I-dW;`FUVg?qAv|AM;i&8O>AQYj-6W8{XR@AusbYnLL4?AJaDkft zay}Io&gdJKv_$f~yOn;%>Yc;Orl12dp6|bTnJ1m=YMj&i>@26Cp#5|E|IFPT9dC5X zRa=fk-R}9}?CgL!?Du=jU*CxT z$}+F0cxLy}B;~i0Ot|Va45UBqi2lgs;!@TFI`PNj_7*$db(Rb^p)BvkeSSPBh?yI^ zJElBR;s5TMnyJrt`+jsMbNF!HS^Ru+)Y>IIzKM^yrEmT@m~QY|xZ`!kI`eZe+zt+t zy7Sh5KOnjLv;FlBN5M7eduPtH`FbGjU9EKB4CeKBxa?~>bkBHx|GxX$pP1E`wzI66 z9M70=RCINrs&z)aZ}lO*PxniYeJikzo%f2VVfhK?d*+oX`*yND{@DFsv1!4hrv{(v zE1uW8SN=*W_WI*`-7)EU*t?w_C%$QV&N&h1k-+!BiZ z-W0gzpdCB^z1Pi2Mxa@-t8C^E+uJXGJlMDP!ppnDGh{q|2r7#BRxw%Kfkun_?Bne1&i%{@N10}PF)EyXB$@xx{G)q)9oW_9P5nP(@j@~0?DF*UC(k$C zZco^{>!sPc>g?~!u0E-o82#Bs;bg0}Wy7LK*9}#QQ^Xuk@ST|y`AOQQ+;mN}*O{G$ zEMGa2{w|h&aJ*lkT9#pEewv`6Nz;trlyiLSdP!R{^4I-zvb7`ci|fzRNvSjlYX4xm(Q!KoBmD{+xYQl zZ%$plam_r&i*KWMTc17s-1znE<#HVTu`Kme(N$aE-0*XWM)`ZL3*Da|&eTpkr}E;4 ztl63aHxG82I=pP%rdQ7R;#(D$<@~1)biW3fWE(934aQ8E&s%@ap!rkfxz*mWY#N%@76^@Hy#3*MhR5-a3>sF$-e%jxvJ%)802Py9CGS9^X< zFF#{-k@17`@6Rsy)W0$ylIzErNag4jIVrF0g?FRY_t%{Ye)sTx^0Y%2pC7*9{qUP2 zLqzkO9YJqg-6=6A8!gyXBWI-O}O2C z?4Su~_wBbu|1DiyT(&Ltj%TR3YRCHgH$(Zd*?;o87T%wjYizN8RYQH+Y~{W6KCNFf z9dZM1KKv$f&2~%Qs;{A@?JfL4s!eS-n%}s{h&ny&`M$8*^3YqKl1tBD&(%MeUK;uG zUs`#Q-C59LV2$Vqw}9^oRlcvzeew3QwO`B``Q zrcOT)JpJGs{SB>_oG%iNKiU*9_cQ-J*8d41jpt)~O)oUA?w;G>E!-g~)@++|+-^}M z(;0{J8phi;FK1v`&UX3v?2v2yk^Re0I3Kwvxcknu?HB&M%89QpvHabfv$?9_EaN?0 z<1(YL!;7EKGEaIZ@jgEL%H2?dN|`;sIYOohR}~1H>{m_ZH~;-Y_v^MIcGqvRbzkh8 zJ34-d9&Xs$t+;P<KvYgDD@4ghxf7DZW>1*q{-B;ay zb`{m+8Gp#D?~RmIsL!&iy!_ciZm!S4e%1#Z4f;k4H}S~XNr&kud}(m-+E;yjjmF0Z z#~<+Ac>DUMuATg!FOqxe*q`L6EbwNCo%g~o!Rx`de$k1xPLf3~E=v+Gs~wp7_u&TIQ*2^nyW45srby8mGQ!ZQ|DRbs8*E?HDEwAYJPGbMLuFLcE&+EQ>V%h1>C%^pL zGQFvIVixpQ_OKc~EP+Ps}}y0&mJ9O~yt{n>Ff zB-Q%iu5`tf;-cDGCn^ku*O+;D81i#KW4f07oHn<#CIv5YqVa>l~*ski+6=>!3kCY38$Nf zjP68Ub(t^3sQtffHk)JIvw80;3hnk3N%wfP-d6*yX8&9F%Jq+`*DTFP{@@kBkE>*P zw(nv3ws*l1zw^xr{}rFqL^eEJ=er`*WO;{a`P#&f8;&mN^-%u5TTJfkq}XjATYE#+ zu5Ouq-0}FkwRdGtoNY*7XR@3(U+_lhd4F*}dzCqV#oze<*1rAzV=?C!iTiU8$UQrM zRm1qft>ube9e$(=F^Fp4O)J{5xc$1Vfq_KaJnr}F8-A#GiA}libf({gjY4j6Tr;!3 z`?RmVn|5-`=gALGPv?+)vFQGmxRSaB#$mgi7zOJW*H2Ya+VpY9C(rmgl-Ap*1@G%#J)dbo&csRE-}YA3U736!E_zx}iI?f*wUTMeisP66ORL-;o@Z+O!`_fd zZEsSVm;cLjHN!jk2J@7-1)G&$e2X%g_J?Q3KY@tdODe5*eNf-A#ClJaHRH#;Ap19N z->>gV?hl!lAy~h(elEztFDeD*lvuI`s|S2=7IZmsP*!p+$-&r~Vk!eww;q^a796>zcXiV-ATFB(x{ilTh-sL&+gw_rM#zh zzh&>;B*xv%4Sjsyey=p2`|j?fgZ4)2zCAd#$;y0M(=PUlpC{)<=!zD+4*YQaOzis^ z=h@}$82jUUj4%4#U%6LwPWKkbC}OR*i%!iJwl&v&9lYx~-T9XM6MxD6?Pt7C8EdY+ z?7ng%Xl}39#C!SEbjOIbvZ&&-cJ{_danoMy|tKTjQhxH8iq-6&#B z$&RfbcRk(`C$voDjF=my)YrM-&3U7qti>0%ttrzMYi~WVP>@07{9nHJ>w~54-Ap@ zBp2}SW_-Ll{N>NY^RwQDt)6$^&ICs?VItV8beBvo!kJ=IDb- z8xuB0tT?wm?QHBzk-uR*+Yj8i_ij>I^|MDVDgBq@1q1~%f3MOy^FZdo^Ydp@l6EK8 zN--Q{ZYtlLylM5V_{(xKd_R7yyqmpZ)uEW#)^BAu>wR78emFC*Ak5mrn$c{{jXG(D z;{9#E{f^2p{!RO$QktZd*nU;7-lJ-fuw!hq$QKIWD2qBBo2Ckq`+yS?&pZCk&u zelC;3pA8>oU4J{VEJil=nes(f2PcMe-~6uKnd(=%Q8<5hV|3Y_ou4~9>Mw%In=Q4B zjTd%`uZhl@roU=cM$P?GML)jj{`h68aiT5n_hHTO!-3DQOtX#pWH_gHQ{N#Wbdu{XXS)Xu1|mPoRFID`_R8t#deZQ!1o1Jxhy4o z2jr5Eho>I>{VVo?u|dPv{&o2~CYM<+WM`f9DTzz8dm3X7WHlr&MXo8mjQ7v8%2V}IiwAB*+Ij(263?3*9;`O`9S^ND{0Y*3{?OW{a&_1HT8np!ep&lf3LlGeesOT2i;VQaw&P}3Zpze! zSZJPK`sUeGujsIOVdp++hdo~X?cmDm2UhJ*{J5S)W%moieb(Pj>`G4h8T{F^K123K zj>RG!iBPdUOYhyf|8a)PiyO@U=5aDQMy!>qs=d4SWTfrP{Pambv()xjNH-lm_}Wl@ zUe@RAQqe!3RDCL&Z+uQZ`PWE1erkW7@Giky`(K)VyceYZpXXouB8(++o0^Z^Wtx2a zVs;RJOy^e4Lw9E88QnXvAS+gs(_B@+YQanXHJ3K^cr_ogY~5kCb3^;>$eK?7JWXKd0)qKM_v9%mSY86MUNabV+Xnr~CYTwwKXU#b#Z;-RzY3XYYrX z#a|~~WBtalU^t4Mv!gq{b)@%BfUPQ%yJ4?lJ*lq=tj^HlrNFn9k(p(#==M-z{W?>gJl z`StYKmZH$7AI>H1_$F!bQ!8TY1s|s$Cygg;7F@jPV^HL#d<}o?^}OeD!>aaN?tO6Y ztFX_sGun#DHEgNe+6s1@a({(xshi*Zp&5Rd`})DP>x2K^xw>Xop6K2CFZddkUvd6t z{xhZLc2D3#v-GKVeidClSotgHMAY$Z+h@*sJ0;us$b4|cQ0pCHZSh&{lwECK*H%#$ zwbfIiqD5|;_51my)1X%A#@muQgTm=epQY^1Bt$u?cFnB$ zu;QVBD1Z807Uim>jmyl>vwF_nTFPt55ZCPc*i5i8N9F45)rIN13e$IL#=kqJQ97Gb z_xujQbrn2Jutqy;TXGFmpJ)B3mvxXUt_yE&-ZwEWUgOp{fqhuSES$c zExUdD&-|?~%c^rdodrK~&w2!!%@Qe}I5%Jl`}0zz4cuSur0MS3BHMO+K|z>e=<8J- z7FJCMrrh0qanqY76Rl~}uh-=B7ESt97jASsJ;-3Mz_vb1xe_HCJJvl{3z9e{9&elY z=SZ2GW9s_pri$G?;YP3WH$*6?T+-QD_UCB9jm)%p-E%+QG5v5nKc7GqIlB zPlkKGaDS2A^7w7-zoy6{10^wUS3~Byw|nn8n;eZ@@>Bz|lSurgr?6ZTzr6C-zwcO< zzI(!+cJsAFo8!6vMFr_QHd?JY5-$`#`NnDR{*_5T-PCRhn;pJse)ymBgMGm-jkbZ> z@=@DAKN9CTydWn~a`n3C=JUyo{9%qci!8s^l&|?Cz3$$99rlV(Q`0t`KDz(V`}d7Orw8nbD#7x%+EemjJ0zx$8w=Km49~{CZdMN2plj@7|{Za(8WH=YF)a zDde=Zf4}qYQai2-u2Fse7Ik!-*r%z&bZ-CbQ=y?#^t5u{-t&;Y`1GV6%lrIwvfEgr zMdx_i8m1o+DE2e?^FwgXe3tKXSbpBzef`DO^D~xSI(C2eZ`nIrxWxYPNUml)F?-7P z-??2Ln=isf0e3Ih!*cGek3)&&-u-v}S@}#{d*^1}n}=m<^jKe9+OTM+>yx^P-WTr} zaqu)(-*0vHzxkC-y|;OKe$#ew$4_~G>Ps&RZph$cxF*0pSN@g5lL;r(_%Cwo@;H4l zUQ|%uUn@|Z1^R=rZLRQ{?g39b?|%_;4OI5 z`lN1}|GV&=Ywt=6-aO5+jOEhv-El5*@|^egFfMO7SULCM>FMQb7}vAA$)(AO3$WDt z7@uZ**Y!m;AkOJ`_HE%>FXOeT;uF)r%LTvXigDlhDfY!;!q;T8jsHB0Rc!0C?Edq` zp4r4bZQ|cRv$n)7MeeRk)^3Vgt71RVXM1>1hmD;~yYA^Z>*}s^79219@bPlMMGw6m zdAp{i`-QLQb95CaUeqt}vba+(wI+5`vFy)uvj`oR`D-4;9Es251&zaIUr3$*{AIKh&c=fR7X5Y8zZjFDdSayhyUpc9O z<(k9Y|6&u5Nwyta^*StYURdwZmq()?u!eJ#+`qr3Fi+xv@d6ETv$cohBpvq4SA9Oe z@&6;;4_C}mwjR8E|KI^d>#|4c`bVvvCx4s0_wS{w+n1zDCQjQtyH(QF#U*ND;sNu= ziI==L*uzLig10eXJDV-@qF|1g;lyX-<6M)wy@ei`2EGwOZ+ca zj-==Mo%`Q1%RkUlt;=4^{PiiN(Z(s3l$1KweZH6Bo%JN_MY_yRr%WOi2{bgu+-E@AX zPCI-1!TI+eca#emDMcNJ~30IycY<~N*E@a9f_I}6n&5AZ+%l5HeR!=Il z^r$NNeRHC#%eM5(-Lp^pQ(za`eX#9m!GVt-p7SXAcPvS$YOGBD^d|bu|Mpq4TuTlw zys=sQLcZJmxmNo@Gvj@3pzSknKmL3$vG~DydCwh+jb+ofuf93uV-#CtemyJyT*mM9 z8GSwP-|aM8)4*zfV7{?Ju3X6OvoDvoU9X9YO?{WWb>@1;eW$Xn-P=6xllN)QJ&J|j ze<>*aUNh%>(TTczZ`rSP?z0$wJ=z)3Jh!B7iE-HSse3Zx53TWkFk$k;hyDjeuM{LZ zyFaM>SI(6tCQ#XvC)f2uxpzVL8gz28&b+qWFoSNhjgA+&zI{GYTv^Bk|;w!E;B z-R6T}$=m(e&woCN{E?&cB(>>ilkO2mhe@*83$D&-%VO?6>-1*lMo_CUDV24bfV69I z_s5)dZ9DunRN5|VZ=3Wfh%0RMvOV1=&aJ!?aI))k*dxtbo6KZ6Jjy11N)nIhd=?~k zIC+AhUh`S`XO3R>7H_ROI!yobd%cXep1tB0uXyRvhqrz1zqF3?j#Yl4r0Whn3+heq zI>`>(a>Kv-@@*~#K0M#LW^Xz3zExQkk9;hCdcCOCXmK&Aafme3`NR2dZf;$CC}aFy zFNfm{O8z}6&(=uHF+3;xYToiIhaXM8WYBbbX0X3~C0q59<{6t8WtL}Juk{t5I5#as z>PgM4!^_0YFV_3j=QMtu{^5!L+4Q@~l0UTWZq;XNJ=Bo=;KAevM@}a^`~RTR`^A?4 z^(4Rkn+uDz9mF$1E7HFSaa~BAzp>7;$3ykqAq%TJ*A||P?d59b_0LzRuQIeNH%(~t zvt95%;l&;9J5vKD@&EtBlKJ`UMa|{R-B-KLXA8`DwBY#fyXBcrc4znruFj8So^H!E zx9X5J|G`~LZzwUn`2V=CKc=%ICv?+-mZ{kK^(RlNGl@Twlg775Nk3 zaJ0z$-lQy#cf9_-#@@SgV;ZkMeenOy-SQbRp%0IJe82Z{dV1Nm?{`z8s~ox-IuzYAVsWU^CfG!c;mfl`=aFcMaj3S zi!jZ+_;s25nlo?a*Zo}l;kvaa|M$bq`xksazc=baP|BnLM{&W4E1ynXUhvGSAg%vj z_>9b1Eqq*pRvIRK2e*a&{wy`Eu159GrkgFVm~<1l+ik_5hwbD61oZc<@U z{|u{OL+x|x4@`X9_WE4QCo7HB3%}>rmK_(GsCmMG_tbgK^pu+%&iZ_BuNh{oUwO1Z z>cd)P1*v5Zf>~$yg)&V%>Gb)vi%Z(94+?847^m5?Z=85$)w9MJj%QAJf;x5bHdV$k z<=3u#w|%kr!(;aY>)sxUt7ntpE9yJ3@%hK{=FC|kwae#}imz+6kL7-EKk>)jaKZPz zkIzZpUG+gpDW7wnb;tH=-q&kmQ{=b2=H6z>?5A~3cj3?FXJ>LxN|p(5`PRX;tK)>v zr(gRY{NZ<0V&hY9yWBX{%kfk0`wMlSEKK%n`}zE^9qV~pzK|DTl>f1CT_iRAi! z!s&gTFXu%qw%ytO{8HF`zb}2>4_B!_oTq*B!(rYlvBBx(CW14Qcn&Z4aKvfW`V6&u zV#i~5y_WwXIxpbFh11SFHpV_59&C)12zEKv26912dgO*W)*ha;a~HQ=n&6kZjc4t4wO#Mmd`@Q@#?tpqrz{K3@diXNvZl`bdzi6} z{lG(p_yhBvTi)RI{^xs5v94OKp8slW?CDF%;fI>{H!QY0|6p?YBpHuKJTJpHcD$Lj zr~k>tqFU~|{N=%AZa4E}7eDKYjY;)$QERy;+R@>Y`qHH4xAKQe@#QtUFRwo_<=eq| zXU?xQ@x7mS>d#GshqcEKPS-m><@5HMf7Q`)$_5*?7vw)(dEZ&f^XAOm-_x$-y$dq` zDbIcJ^M$a$$J8_b56j$Xo%KpjY4P(9)*Sn+J%03VxEtt_(z9|wcZW~v z>uHC)>s6nhkWtEBbY#||+xzZ1n;($XHd5W2B`5Pku;Qm@LG{8aL6K?wwcDn#eMobR zT*>7vF4@y&oH}J zwEnK3Yf4wa)7=u0c1h(tf|AKvFO-xfyVi$4JN=Yxx%KC}Pfz~2`L^-e)`HtdFKl8v zmG$uQb7!sMcNOOzTJro^%_}CybG(+fsdDDZHy<;eW&dk@aJuPyZTjcOvY$FXR>~WF*_uI6aJP!^hYP(Q*8fht zD(qzJ8z2(Ek7ajnpk`&V0*~zMis=ZFk~D#SIS}3UZ!@ zpLk!-wcghE!vO_neV){L*T2R$YyaQ&+j8Cx**Sh*`wX^nTcs@9b$;j8w$SCKheYE~ ztm&%1#9DB@U$W|lTUcEhZ@1j6{Bj?`nNNJycZ%Nqy7z)>N>Q+*xZuXar~MC=#y9t7 z7l>JWJoov*{OFd|2acXtCAi2p@R9W6C2jX*WD6@F{JFhgz4B(E-`w?Wd+$w;{PXtM z^M_NHADGYEF1P=6qz?BlD`Vx)($`a#Ez6H#mJV~sRz9LMJ3o8Y%+L4!I$Ats0prrzg{(& zbGxPV*uR3G$sfMHRuoYB*RK7hPhBavLHU7#ob&V6%g5gwKCklmnO7Ul znV;G4;`X`ZlHG+B2WO@~sNBvTA8Quby_w^U@PRKgzu4XLK0m*@W6u|Zm&^Zitd2Xk z=GVVzr{x;fJv-A>^4?ysORN0%daj1Arxk4+-c5X5FmF$96FW=fj~6jvb2iMn^4*TJ zd~M@RZpE1j*Q5>yKig=%sKX~|os;;>i6$!xxZI~5erKU%&m>E~>&JY4zP&ZWvaXz4ri^J$VQN~*Z{3Lx&s5&lj>&e{j?Pw0EDyrgOKS zKQJ@-!M*Ff>(_OxagAj8&im-h-H+?rnjUj$Sgd1c2+|P&oZfrfj;i>m|KQufjp>K}FdN0k|N3}sd$0S$c>V*Aw;!BTpC84+ z$8h*a!EOUvu|5TfxaJ%3>)YmCJHu4iyFUHYkG9a6wikSb-KPnc?`&SfFCuWm+#z8< z!@E7U_pfQs^-ER_n#nJGEI36XVY$4FPw2iZ`Mw3SuN3zmjB95SxGSLAa`yJE&J#CP`Z5LOU-s=B_qLgzol$y9$%Z@{%PSFzOHmf$I3MB%}rfrvYuH> z#l~&tk=x7puS&g#=Ml#)PMKM)+i!KRzt*0=j{m$4|FWG=D{u6QuS@+9&!6!3ah%V7 z>2Sf6T9x)U&YMqKs-)jJce~I0xbf|6qCKCleBN{BP{Bk~!8=DU7w<3lpTzI1|DX5V zE;bpzL+jfg8ka2>nt1X|fdr@`Ust{R#P0&Rf0lK-l{-&JfSMgQW8LS^l3Z%{;PA|s zFIb;W2;T8Du`s-kME{_o<6_jynq_^m(&XQm$c@+}n-TeH}fFpuBx|<0sXMH(_@UCT9GQ zkEttqwkb9-vf%&Mf{Vus+I+-p4EUGVXZhx=+OM^XJI`_G3LXFsg3m*3BR%X)J~ z)cePKAAgsa?C{t3>kK<_hLi6sPWQ$8?a|#gxw`X&PxzOcN{g}=m;70G_??E*rgl(1 zzjty|!r9dY&-ovoVSczn$>J3I_Sj87%{D(fY`I_M-qV&vksmhiZz>lTdr|pBZO3PJ zmixjf2W>wWrupwJ`ZsNsc6Py&9S<%EFR1-{?)?Ox1I_ze@?|;W@3H%>YtKI4bWe8A zMjlazxA%DdRsZT+z-+qeKtahxfD>F3xa6cBbs|efDn`-=oAI?=~9T+5g!3&ztTK z-J1*7)w1~)vBsTut9T=}<45w${qx^i{t6L_^*p3~I9am(5~r+?()$-O60e$F*_|)u z?0Ww;?c~JMk`;Le-c=|Wc}}g{Dsnm7=!5=VzYd?&w$wO zmd{!Fa(4S+>HmkqpDTS|5fjv``D?zM!Ztg;mnKid4sZ2$zPjhGbzO?Yx!($Fs%EaK z{d492D!I#+wRY-n|9b2D-p_5DqqO5k`R#i_d3TL0as?~p&nAE4Ps`u6PB{+ksuGjmG%YumOH6|;5~Yq`1{ zn{~PQW#i8Mv%P=ozAgFl?5yVX<#Al{*0P_xzrXph--11CztdIKsUkAr8;%#M&)&26 zbHVgok;T`d)^OYN@RvG1kX?Pz{=dZxJ}tc!Hy%A|O6GpCWB246bL~&$+zi|C^sB?O zh~@E)Z+@-6_}|Cgvi)h#{mC;~(&Ei#cYU7p#pd4O6PpBo&68;f=}O6;GmpLc#lu`} zGikN9+nz53>_exA`JVjB5E|D~56s+_jpIH%9r z+C2W>I{r76mh2Iqx!x5W-=gz8pYx6E0sH&ReCj*yMBiVKtGn!ar}2i;#x;9au?Y!U zyte&tB!8Rj-M`84Z3%K~&9~;(-Zgo`W2yPi$MCBCy0nXrKYzSdX&fGM)1#p&YM=DKOn%`b@cz=HNlL*}xpsB<#P{YO$UdL4 zYmB#p@17dZ>t3f<{L`FIdbSPsedj%@CwFyUpC~hPUv-T7uE_%Z2g3PV z_Wvn6t!-_V@N3)O`-iPhd%rc^TyT-q-kR5MO~ZRR_WgT#=GAiCntkA9Q~!LwErx!Z z@_+r4&FkKM;cQd2ctB;MYTEm%ABROhbgxhUx9;Ds=np?0-q^h15$CnoO$XoYP)cfE z(;CUpqa(S|va{oj-rQzABi|P?U&=G$`Tv_+e}4Wc%HpNdj|~A)~HeBIz`TXy-J}fkP|IVuB>ONchcPf+nmS^tW zICb9fYR|7rA70OQ_&WP}&-|GF>)R)?e%HJ4(6DO$o28HY_#WkI20b)Uxv%q>HMQUd zXTkqcPz7|;eva)v|1_cQ@*^+*r`tR0^9x4GDqhS^aDCL!`mk)%cjIn@yT4@OQq(r; zbU&RRxg>@$6OVwVY0C4AKyobnsstkv$ya0voa)&dv*4?7WcZT zJKrp_Hhx;WXiY3r`rh_6KMlTb+bR5ghp^5)vGkY6r==}RkpFq}OntY1c;JVZOsn)( zNPR85^wMPFR6(|XrVj7t|L)j+grR^X_RZffk3M$UtE#e3;@NBC^1;?|Zo8h5bMBrp z<-PUqQa{FvCC@lELnfFtHs#Ta#ifEX=iQOpQ7k&AQ1whz@s@8(xQ(95B)r@_^L^;& z2OIo-bGFSo8W7>PO5b#2zxBbk`x58=D6UueTziz8K}0V8#DRLYj9+!a7ni;8>rbAg z7RkLy!+LR#rTO({<wmoecd*~9cY0R#c;#x= zcl*tZd-v7FS3K3si1YpSysND0`pT>aKN+w6U!b~K>i42%V{td5*4m@#*K%fUy7#|7 zQOw4Mz5Je;*p%w_Ck2z9s;_0c%(_xy->#SCRSg{{=AF8w&Fy}|@xSrk6y0;1tou6N zD2bK`&fN3Ju;Q8jhd;?1zSv*5KR2@G&DGHq81`Aj7nCg3p9{pMO8>GzBMWo+yxL zxhJ0VU?$_K{b6~a>c~~=g_62G;D9a7TWLl+OD*`ZvGM7`)YH2lC8G?|8Dr@k-)~S`F`#4k_+Cv z5h}Vj-}u>iSC>;(g_ZdygM_)4JhUuE5& z&wtF?rJ|Q5PU>6w;79R;?CbAt&7I6yu&XTMoZ{vef((4@Tf@(*m3U-)Kh)K6hT&jy zlSE!~V?FPKziYU5od{Xfq^D#(-Rsa=@x%7-8_R1IiX)8}SF)%)no#pudt$}y`S*9( zOx*eR;rzz`y9=IcpV_{?S^fQ?{U`jtDc;-?bN$q<&$Eq>e@j2Cc>G|sJ>z@3tkV~7 zo_uwFd-G}6hs(L%`WfZ<%r;LAx|9@Lv@P6u!uGl62iuKz# zCB$ZgJv+awHBm}}k6C8s=leX%8y}vl>EC+H<8G~`O_6ZT^E`_OFW%bMRmxi2?a`4< zOnJ#65`Iv<@BEZcN8jHq+W+aKo>1HV`>xlLzHhnTZ}nbz=a&1IIC}FP?%rFx|M4wz zgT0GyyfvQ7w%|+8rMo^FN=BP2v}|0Ywr|Yq?(oS9eld4lM~~*|rhDIf1mm~se6D>f zePN4Dv7h;YgU1i_%eRHkJM>{^#GmJ9tNo5gC71kNsJ(e=m{h?e&8L3MmvbleE$K8n z>cPiw(tNvcadqN?^yfP#&1}80<4s+~{leX5O1rJwekVSjbte4u?EB_xTDFx=h@TZ% zxwlMz#ZB$cw%aR8W={LZo+RjH7jM1qr+VX}^P(5)s>{>ze;TiEGhOfGC^;o8|G%HC z^n1X3Er`46!cDSoU5PoY@&yEv0AA zx@(rPy);|f@lNH0L>3;Qzyoia*ZaV=ECs{i_H%&Hs4>ll5zfjxj9uYx4r-Jc}e9e2I2ZF^U}TX72i@)~Ko8Yz*`zS?`= zWw$>+?r|jXX8psZ`wxBYPoMWYdXAsZdgk;KhivcnZeP}LU=c%OEz=I~?R(|Rt!AqI z@tSe)Ior$XRkMHS@8etBYaJ(|YsBJre9QcM|EAqqogMl2sOggAOfNspWv>tF9ooNF z$GG^>f4w_J*BouQ`u}j1ujDR&*!SJRymt2ge?qaGb8h~+s;acf7*v`3ceB*JzI{U9 zvXy_zRNGcg(lfgGGPdtT$>%4rGi#S$*Ka>|ec?mX7w=ESq)W`OGv8PHN2Gq+jFfsI z?SIc+JlS5)?H8Wr_5G3aHk<3WA2zK1KXWGA{e5!Ztd)$j>~3x`N#pw2?SDYq-%*Fj zPyL(tIW`0;Xg!pajR3!C(e?#7ghF|^(8Rpyu% zsrN@-Po*M3;IKi)?w!3KUK?K9x2f!NZJ#}RpH=Gd>gL|x?WMPz30R8Ga}zA zN=~m2QQDmJXW9BI&+M1q|MTyf$**6v4?f>N-*fKYzvUl(ZhHDZiqCsqsN;RU%O*3w&)&JlB2{(bZvFFXp2Ww^wmkZ1`}Bvi zU&~(YdXskT+5ftz4<0Tl*DKOf?WTOY`uec%#FY-Lu_?1=R-cctah02+sQxl#*17wo zm;NT0-~G;?aP;xawWsVV-O?C$B;=(X+`Q+}NB(O!dA|SADXuFrnrK;m+u)#yfsZiH zy%^cL&(jkpMC#sSNWQ%4?Ng;={CR z!K0-|LR}9y{p1C8R_Ly zl$0(9e`mg1k-ZmO<9BuRG=W-Xk9EIJdf|ED%U-p%xUPhwLIH;CeLp#Ls`O>PTs$N4 zqw~Tpv3a!yo4x)_-p{PCVgB@+_h;|ETfEnO_4AE#W`9a7BLe=dE$Z^qlIlLP`$%w- zQ0?27Z|^6x^)J|eH1z5MLVeVb-}DUkm6`11;z^+K0-a~n&`_<5*yZa-dL7cD5r zsIW`X>%Z~ekeba*$$QFO1ScAT62w^@`%Ko(Zz*XlznIkz8OEO#`P}*EXinrz+w=K0 z{F4fKrcXZ5XqQ%-e{Du@-t&5$`G5MK_MhBX7M}2*;iA1++PRPCZyu|xowk(mi}}yz zKW0|HzBBiJfwj+iPb;3zc}FCc2?@^JH|eiuSbe7HJ16s>$8Y@p9pvKX4~k9CC0!4{ zY<~D6czdkW@!n{V}9^<^D{@cTFGX7v;6@;eUSd@9}qM>YlgD?0zeq zDN^fW@mWERO?&I-+g%+TC3mm8T1`s3_x@S##v98zeDXlUOlNcR9SqVR$?4B*5TDne zp4a|dj#;~R^##|9l}|d}hhzJ<$6iR+ZE$H?7~anD&iLI=(=1>O%4M6LtP(?;gGUskrk*$x=`@njyU9`L|uEAEw_w5dW^>pd8Qs z*%#QGrpyi9mU;BX%mY*TJD0z24%TP=Z|(J?QJ$@R^11uvs}{UpcxWI1%Fb@)Km5LqWA%S_KJ|N1;;Q23)!v`5***E@q7O%y zqUtYl#aD^{`60L>ZpY74YjP^S2lCkbWzn|V-84ym+JjT&4|yyL+vd!0ERNaMFuTv^ za>{-2ZyT-KI!;V^$YHf5ul!Q?{P?ZU*OF^rbL^<)Y~eDy|6tPYhyK?Ec7E5oHg|vCYvvixmgyfhG4L^vX;AKc zxaC7gg~rb!&V|io`{H+WbexE0s%C%jyIMZ1>a*BVC8M8`)0T?%xGZZvc+k;lp@5Cq z1j(IugIB8T`Q=~nRsO;rDXIAOYi>>NIfJTeb)UKTE}gH`7AK!{cKY?k)4c6QtH$0wIo9y{{exqPUZcDoStye$JG3j^9&D)+GJ-M^vM33p0 zQv%uh_Ow~i{(zjUw&|QlUk}HnCnPkyd1F}7uc&m}baVSYmz3K|i93EIf4Ft| zLD9n#Mg>o2KdD{YGf98Sjk$S2T<>I;{Ck#ltM01XkC*ldwm+?Z{0KMVJ{qduv`DMs zseHkkNP%1D%FJJy)I2sQu=;qeY?74cv;Ku7V3x{+dkKB!bYzCUGdsN2Pru2Q=4OCQ)dHf?9|bicG_cZw`? z|6Q(^r;wE;7>#+!Fl$S7u&y&m{e+0Y$UiPM5d8G+w!P*R+cAIbRB9 zO^e@V@S&fvU{}KZ!`thRAJ02D@$sFIbBud7@71ZQV7$v;dil4D{yL%SEH=!7f-_$w zy-r@z7L=lUsePAHaA(_57nQ|J8S5(L?v&X5+xurq?bb8zT!QEAKG0jfZTcDe6{_VRh(Hj4^QoXfpmkd0ZiWTK{<@(U&7SR1bE zHKv>A?>y|8@SmY{|EkT_SGPP~{aG;bD(A$+54q1{4m_JW!#JJ0QczIR{qTDJ$7{bn z;;?$tr=+yo0c1dA3Cq4xl|NtoitMMHj`P<`ICr+VQ-KPXJXv9 z`-bn&nNO$8kK{Y>NqD+&O}Rk%La_#6!HKrlzo*ErV-o*YS+{#}#|gbl0lg=DzC7T4 zP!jZYuh#C#91l1wJb1I`M}a-Anz&2;h1&ZWHazW#u+E>cZ-v0W8tcgF$^tf%&NL%~ zy=pH#ZoQLGQZhPv)cWxn+j`x9taV=d*GLvA1yAJKb;9TKsbGQrfU>r4mh*LZmN!n_ zR95FKC^+$L$JS#JpP!m0IGq(WosqZqtoY2XFZ$sr%PN0*^7PMsQ0KUN@`>4xWD8?j z^>!zBbes?o&F$Ls%X{@koo>tRXD_}NnW*W*8k@4L@*}6s(_hQ&BbO*?E_%J_M^dE=*)FI8755hQTK zJfU1fP;jPG&_j{4_StD)Ggp5MshClGTIMaAk`Zr4tH#8cPwMO07d&WTn%#UNx=QZt z!RY5#leGT&iO)<6x!{`C^-r(jo#CHulfSu} zI?UXSFW>%t@k^PY;7vpA+>4*O#jM`HS@L4D>y-M%GKa6U?^e3p3kvAM?@uT61eczS z0R^0of12ckCkdCHsVFHK-Q=}1_jo>c?v%N)ZYNi&mK_(ISh&dbk;^jU(@o#Le)v8A z5c7V84fFZm>&$&^6Iro(Z^bH`FE&?_!6EV_rgG-m%U`NvQmQU<>^f0ma)Oc z3-0FH)zR^WOMB_(^RCN`K`N#9hF%E%t2ujeN5_ej>3&N(*Y!TqD!M7_>T;|Tq_~%7 zJtNza#hJSocXXUkNsAQI4c|WDjsK+oA8U3$?l@r)2%7#47TR#2AbZ!Mj*gu8<8x&} zjhL%PLw{t|K;o@QPbq0}iH&hl-mb4jI!a2n(|7qA9E^Uu)w-*rNBM0tNcxM%vIWv| zy`c3v-$d(HP1vXYJL2!ut1Wz-4_AIj_~lzIW+qa$i7*d(z zr=+AbdFDf-8O5JvPVJBLt5P|8U^8>c-RnnBonN!$@j1TTk2_CDfcIPY;W8i z6fEZIl5(79y5q-_M@8nx@H9-_lCgK?)M>Ay7&Ppb-Z)pGWW)xVX2}tWlR6gt_-H{^ z*Y1vvH&TZ)1IofA+cGZ{#d7~W|0Vd(&LpSyRs){Dae_0uOpeC798o*DQ04FcH|pO% z#DD`#BvpcKX}s>zXRD-mE+@P-zkaErO!?xo6?ZSXq?oT*(A{xk$@@;bHA|NM&2e=} z=?AR@W-ppi{8}b!-Act>ks;LR0!-SlgA${HSBlK z`B^`sfAs;^!!vo;?5>bKd2k8HRq7y*t3{MJPuUiIOXHW1U?le@P-alNJZ1eg_rJPd z&+IA@Yd+7r=~<7dN_)s9S2a*Fn#h?FDJEUFg)zLb`;xI2Xi!V(@|;A8C-pY-e?`CQ z%QvDapk`m(sqCZ2Qy%_}o~vA^v9KlpFRocKoLb=z1S%Ph{n=fB*R^>n!hQD5?BTl0Z`j79xtKxww)Oo8is&7_0O+#GMD z6Yjdc=FsN^D+UF((YYk)sjkZx&PU zuRCI3`q?{03AD7PXY-3&8av%z-YFIooVkZ*y5ontj!p0R9?gHBez@Okf|RG>@86r> z_Nf^y1|_wg#UU21du;o*AIk=nsuKe>Ew(YV-#@tP{TgN4Ny}bYhnBeu%`^nX(y_oj z%6tvW?<5xs2?|cUc=~UE-m?2CZ&|Z5ZMI*0XQ5===GP%2DCz#PK#IZrKq6RGtgw}e z%U|EGD!YWs+y!CgWNEO1>^^Zt!uSu3(I?ylpbq{`X#2#l;C@-tgWOJ>~A$I?ZZyT z-N_wiBtY|%k2Or^Tmn^4GdDe&Tj+6fu2af0h&3Qtqp7OZlgiu$W(IU6^?DdEO?* z#=lGvh21yWB>q*_>6})2zrv>K-=*f|r<@bkH{A92ba6?U&b#00%&}~K*v$xf%gn9mCH&jH=sfeEQrg@X$ z9X96watVL=uRUJ*CE(Z9AfDxh2hTgXxTKu#StGIV;T*P2VyS^2&vJ>DOymR&NPjZB z*rqWtR4^^ptou*@)At{?t+NqlJua40T6uD%s>&|o%Z#zCxAne*DuK{7md9pozV=}4 zx1efY-H0-Ep_!JT7`mtS;T?m-guW%;Usz~8Q&KVt<=t!IlBMAKRzABh#nOX!`I|l! zqvQ0q)IrTZ4S^u$u+L|35Hx5O=WmUMj`tNyHwOODbyuHV?C{NX7zQ2o0np%GD zvIXu^N@nVUGbypHkSG&LIQ!;uCir_uH zFO632UdPvd-|?`yltkoWb9E&pqt7k(q!+#Kw7b-48$H?8rK}fZ-)y(Ao(qNL?ArhG zSv%*k?36!sH2B>{>uDVwCt9>^R!(pUZ~C|Y`)yg*6t|07@065MzS+lDe)3}YWH-zG zq`3EobDwU_@p5rFBDXI}{vdO6$-jk@FZ^~YJ1#iW(4t|pP4s#lkuq+znsN$w{M%+m$7PhM~BBzR#8y)HQd6#tK-CNk=k_~DfN@KMc;n0 zXSZ9KgTBw7Ezh+3xY~T&_cPJZ2qn7mo9so|ILXM>+ECs`~S`I-v{%g z&gC8WAdwPbrC!(gfUR$&#H!i*`OtRMh>&2p2?#=ZU)k%jtLF%R~4ZY*)a%_h2anGOEPrv+I ztnd6^8Z^__(b3@}2r3*OEBv2Pv+3KZML*NeMoa@$zo3N91j+)(8WW|a)a{&-;XLKU zst!=a?&6Zd1uj?B50zxe(;4Uk`qzy*De@Zr=4^WUpqS|C^=C@3g+(-K@D zisW}c*8F}$*4f3y#bp@-SS(3ZH%U6VVim|D7nhXhAo`eRNvufFgPBV~%afIqtU*g~ zjQn=Vzd1JZwaSL_11MHCKM9yL&%H|HM+oCGcm1s(M{Fvtx~`#Q#P@6d8+BR#;2$fU zz)7s*gb28V=VO~EtFWP*A-wT4)Ff9>4(@4oDQEIuD%OsOSV{G;Tbrz#Ktb)JsP#fg z>G1*k^ZuYoED4Z3My(Ki5B@nO`5G!^D}y?Gpe~;isQ#DPp?!w|6f*a~v22uT@s>|P z$!PA9w%{#y@3=kRJGUaO`h>04^>-d%!yt~BSfX=w*5+#hxjjK;VUn)%H4l|!E}8^# zK~Ep3@Q}#dzjyA5Qyj&0#_elZBf;g7;6zO~XKN*;WQ9$7PRC_sMd}wuJdFVbav7*= za6(Qh(%9+ob*aMXyET70bwXpX>yk*h;KaKLkz&sJJQshq`?38u2Cb>S`?Yk2TUslZexBPc!e$V6=egf}%jDOsBEb2RP(EfgYxeX{mfxD+J+Z1;xdL6zl z)v^6ZVTyHu=&k}$P`>K8v_9ht*!#!kfr89hg?-W*%VgeV=TrX8fA)Cwx0|w_Aorz# zQ(*avKhEka4~i7OpV7VhL@ub+C@45n5tI(^P3c?0sn37;@A14(c9WJv{4DGRDm+1h z2BoL8Ce?cGF^%&&f1&ajC_Icdg0wZfW8b||NUS(-w)3?|Iy}o0%T>T`P6SCZXlFe< zQ#|SGIvpNoNF1rn%PeOQoOn_pyHIQ+uVGkyp=oUW8zot9P~+3Z#U)Jw)ap?9?!5C# zTzvOSW6&7-Q+1u??^oLCoZe(T3zRm_2!O6h`n2pqwR6ioX>i*(+icUjrc#z~+yRAk ztpBR^-~9;kbIL5xp&BQwD^~Bl5*zRSRzJ)0i%LZ8tE@xbhsur%fr_+D@FGoXC-(Lk z_19}^ifc`3_BOuwwE`BY;1ZAVa(Ym8tZv_e=55ip!958jrOPuwq3vhU>{nB2Cp4E6 zn(0iIfmYB7>t5e(@Zk)@y{z?j1Hmqlx(uq^tOeqPmOb7sD>6UK=jF?#(Daxd zI;WE!n@WGY`dh<#G0)+|8<2QgX6RceE_kzVoqdU5ovqK$oliki%t}f|??8#?6JOY^ zMc+5ZnZ<3MxM*_s2|I(^&b_8jFRgEJpxH~R4|m-z9W z;qZF?5c1; zxj$u{%JQAN@8x4qX6SeW+NyBlRP^+lyUxTuS@!OhmC|daHNU@Eh0Wd66*>K^(uR13 z!#6fx{PLnrL-+a?gCF-D*DP_pb}w>D{oXlq_@6w`EA2meSpej`o5^jdk<;!fx}==v z<>M3LYQ6D$=H5aUnX=;TADk#l zP}R*^zv}3h+@1TDPTk<)8f39~`@b_Azpvk$^W!30%uhWoe=U{g&6Yd5Lr%H6xVRyY zS?8=htz42xBZba&Ec3k1oArl&+iJ9DYn;+*C7%6OXJ+ZIPrP^c^M|XyCF*i#?2>-v z!Mn6$P45IL55XJe22Yp$2Bm@%XF#>x<3pQtqSoat{QP|`gM||x({HvFzsf`#Ynh_& z-jghvRGxB=uRn8_FPB{)gM-zyXIq=&7k`}NCUlqclij?X>y=+9Z1{fdxHu>!%zOiO zvP+ozi$AsMN8>e?z1Zw(Q9LKv>g=5_Gp^hZns532&jJO@_GdjeH@bo{3fW_Pxn1StA;KL*7| zhfkH(3ninxJFaU6aLR+zq#H*I(=JQ707=s_dMTEa!t82 zrFJQgcIHIC<&rgd6L_cRC0rE`GyMK-r-gIXPmmu4E3JJC#U~b~TJXx`vF~hu8dP1X zyK$Ms!|R73C8XfYl8_6oDTiF7lpZv!DNhBrja^()E`erEIE_ENXJo2oFX7t-3Y8OP zD;9L0X!&@pf>WO}|CV$t*d=Dcj^YzJgUiw+_gTqjpNn$7t(&XzdvcjOr~nq6X#zHW zM&9IGud_~CYxRG#z7_fF;!>0Nn?8G#^U6)YuDrbxWN^{b-7EHNnB>~8zvxA=>ld3l zhkwbh*$(PUbaZsQ4Y}ZYL~LD*xa#t04UCO@nW53KaW2=cjvHwoS{*MbXBOE{0gnU- z3JQXZ?8t44mpc~w?3nd!6yaK#grz!bwxpJWod{K0#CKZp;=~27@99Cx`i>i*x+6#U zhPuN;&(ha^I`i*g z&Z6GHTXk2{Al0zoZBS|Z_Rr@(Q|1MF9iJ=9^Edwl%)9_c@rj-be@sbYde3#C#8dd= zx*d>~jf>hG&;n1cw!;bE{L`8lv(HC+TP^y05tPbP(m;{qc{ujPvTv`VlzIiP{ZFu+ zw)8JV5;Rya(etSNegCJeQ@{LO+h5VWY!@VVf?AG~{SxLgFnlxv)yIN@;C^Vzr9$!D zpatom)^a2$-Yyy1s-3G*-*{~Xq@Ht8>jAmO>t1ABk~F9V;Nk)vl$hvwvOs!C@~tdi zP?AXF1Fg85@@Q?L%~LthGy|w%4yyQPmP~5)Ogd{=Q)&kdV;_j{q4li?n-1(_L=}DX zwvcCe4C?2p{`A_6!fzYu2gR~+JIJqAfBnBE|MICR26farIy%nC zfb7eJj#NA@mlc^C)AI6~_Y_bLIU^I*=;@-?dc~uwZM~^LoYb-}r3&#zx&>h}D- zwWi%tXgfG<&B@Pvu`b74t)?w|`^?Ph-KzuP&y_c6H5p&`y!w6B2}_gX?B{v0!?t$)4v%^D+_x^`%4%t?-zmU>gx$>rOf2M-h$25>OAA86cu z&-=$!gMUBk(qhfHnQTj@2P0P_e_sqM9Gra%49g{$H-LM}i4e&s+t+Xwv*k5_)^`JLR^(Q)D&?>+;M z|G|G5RDMrl`Nlb+*oE(%()PUvUD70a7j&OVaQz?d@^$LfC5JR;?Yn$L+I`Q#Tc58B z<@fi$e(VeI)mwV_@4>ocZ1f_S-pFeaCPPC8J}lc?)Vhza^1DF{Mg1tVhf#}XUwzx z9dmw@j?i7sn4{m;$bbTBw(2e+&1}0pr-_RK?>Q#*lkZgKMasRZkL=%Fa(>zF$V~2_ z{C}3I7fbWSH*S+Sxld*4{WV8suAZ(YC^)gx;KwC}mj$y{y${RPdd_ezM*XY#)ysA6 z*5_>0A6`FXwoGKEt8BT?G5LkhgSB5Dt^O>S-+#HFjM?{o{;4<7 zdGGE$%40CEn^3u! zozdrWil^^dxobt&m4dEs(YJCv)Qvuas=Tl{H~pO2Tej^u6aG5+Tk2-e9*0?ad51z@ z95T|8iDO@yKIL6dqQ2G6j%Dx7HokjQDzVJ*!Cl6-c&TN-y0WGg3kpu;Oj6Zln=h@B zT{!J-pvx0qP$80au$&#V4zBq;|E2#v_WxSzcKy5N`XH8Z6aP86uZ2Z?rxPDGb9?fs zeVkGu5ovj7mie^{-@n@x^`DSE4jygEm#itAaHCCPN#fuBYmZlcm{9Gqt}Ie;BWN`E z&7?!ZT$&d97!I3wv<8E=kvG=!zX@_=FL=7U;OTCUy z@L@8wU#a+iM$N4HOJ`ocub=yLew5$u{9B%&!BjP)WYE#@W!~Ta-YvOzo72H+-o2M^ zFHba)UU$Rc{o=h(>Xqi7`mAkO`>Q9w#U*8vK@3~y^pL%SomA^7R%?_<^Kl%GbUwD3hUdN_yf3~uG z<2Lwy4zx&LNon$w)W`@;ZcsaMiRbalUuKewG5bu%`F33PRco9;cybkKnJnPMRe z1BZ7LcQUB3PcFH8z18@*=eO$3AE#6?WbEH6>%Ogd*8FQPYCy@^GvmWgN6@H;oJ58MF${Oq9ru!#KLTASJ_R1Zf?=q+<-mTn44d_W`MuNMd{3GDeWQ)fWfo?GgVwjZ z>(|XM3AudRRjmuurjD|j_>*;RhJTLMi)pD7rF;VaUe5aS`R^K=N>$$YT!o9X4+K9{ z{2!sq0UEcyx#V%?to1o+zin?`i3{&elmazPK~35>O?&vCK0H%?>Fe>cx7Y6Y6e}Uu z>=M3g!u9{F=3Pis1Pvg*YqRp%9+&3g;-V&edJ|~bW<~X!PoGbPo^w?b>|M}(VukDM zMJm;kQueD?Urueyd@%oc`irNEU3S4O_50-i*X-}r1dT^myM^^%DDvfY*5?Z>E0f%p zrTak3XeOv=S+Vv1Hreor-FNt(>-OW#A}CtekNBwOgjo_@~NpHH<=d}m?Xmr2S>N=AZfwz%Gp|COx>2=v2NpSANN_Rlhh};rE0$XSm)ieW#oM;aNk~>8-jd)sugS|L|15 z^u_L0_wqx|ImtZ-{xN2)TXj(K%IUt2juR1^g2X!Kv9u*N2rI2t-tuqL)QPFePihR> zH?5!kaP5~{vcWEHj_;?qrYxUx)6ZwQ=lQ?3D!V6NiHqHR^lRJk1@DeoffD7z&uWIeu%rnIb=9@6o6CwDj+3>7TXF zRQvuRCU>Wrl9Ex|um4y5KZ~9Pl^qun7oI80^ebqa^W*u?t+lgGfY$+9r&{pb%Fk7= zNSJV;+Ie?r{o#e?oJvYc)mox{7r%$dcb;R3t$(5PdqU2tebG~A-qTYGp4Yb7C1v@q zf4AJXD0;n|?p^-+-#aez=Kr!P_r&BMrzj~Y8J|8jKR@MhsI+9HVN?CW`8TJZ4YL%V z3EFI(vis6SlfCtCm;OvY`$T4UzsxK2odsYPU*n-L1FDKeK9d zcH}euls~=vbNO7I-$#so&3hw#cniou%?}Mdj$bZ2E-$1c z{m-=9mvvuG{<2_6K&7KtbkU^uxtUOQUtoQ34R1n4sXq?cMA8LBk(w zmbmUw?R#kE;ePqc|Hbn8Q>Xu${fhI={_5;Q9VecEM(iEZZr!=XecfnNP0OzMYY*o? zmY;t7V_2%!{;(2pK|x0C)QJ)v0+EsnpC6R__5Wu7OY@U<7PDQ#nY8mB&VRrB$rhn5 zf4yU0vY6JKC;^QiGJtmNe7NbjYW)he59>DmPr2t6rSePY%m2;t4FCUp{K?<|s&zK% zbZ0nEIVjHVS)wXYmpbE0Lf4aoNmmlM4ksrZ)v*bc11%kRzqoRSoM_?1nI5dME(``T zGi^g`MdumXm#xutI~>V7BTiU5b>jDlHZ`SI?6EE`%l4nx#o;^ML@-kH;0K8(GSiyZ zpKDisa$x4$Ba%grI4nP0{rw@NYRmGSCwM^qW|;jgkaxe}G5h=+_wCX78LG0L!QZYL z?YSDa=W23&-fqy6oXdY5%+H3KKGysk@Vh&z={K9HYphEd*f|B$cb)w2VyA1q<-zR7 z(w8&eecWbou$=v*tx@@zK20ShqnVMJ-M!)YN5Y>cpF3M@P^$t(vj*b&grb&5SEOcl8 z*IFkN$p>0qB(kvhf@{ibP!h83t8bLoP6Z9gZQLf|sxJ2MjO<euI!rs2dk{!zgzP0 zj@zY+7w3A17dSC4yPonjbG2vhl4F(|K`WgS9jvCQWxvuxwBP_mqPj3=S%`JERcEzL1CA{g2$E+&_TAz#ko2F$)XIN}*bnVwWRFJ6}Ehsp1 zSKB}HBeyu{xwb)hR=(Hbx6Lat>OH)4Vu_&O%vnNvIi=3!f#xwx?N=X^EDHKMS4-+#PQuyn z>km#8CaCJXst@hgKA&11BRI1OG*)uQ)!c>g#qVtShvtVKG`OTUo#NK|IHfwr57Y*+ zVm{B4psJI#?!=U0hV*Tdcb1<^{ZW57qOEoPG0K(-R(Fm5%(hQFY6`D_(o7{r(64{qg*F;jTEG0;p#o`(KQlGo9bGQ6`O|0Z%zu%_pyh>gKrLJE zzy9AY|7`dBWH-MDIQDp7@ ztgY649UUAD&icHGM|GXvbAyH^!ShEOr!GI^{8Dmh$=%zo6_GcYZ78srfzMtvR5X zDI-YxF2ut1Vy7!;RiLED>K)x3Z#UhW+FHMF{yF;+rUz$=lYaU5tnb`?qqlzD{bwyo zN=C9vlrs$ud`UaD!Y!;%|?v!0kLkZf>u#l2Y}u z-}~}vKG%r6iFVjy+PC|N@5z;_EquI*7QDM3cXlv<;#G1csDIado-e2}P_?h&@H-dK za^t1RnN7c0HSLz(08J;~294uS_9`;)yj(s@;?H>nOZR611vQPJ>9Z6mkK>mm@_MIq zpLhbQ(#7;SuZ!$^72ei6nq4UW-R@2nBDY~5$_tLP~m$19Li*K(5OT+eC))Na|Atja% zSKH|WUXkEYX+gn>p2s%nM6JtS`1$+X9iL*CxCL1_`+524D(*2kb1d8ZQeimz(s(V^ z|Bru4tULRBmisl=8x>F8iulf7WIv!}^b#~wy(HknNv2zQIg9_VtZVws3SRR!+2eX` zY{|cMlP|5GHmN*BuI>1NsqYUJNQl&IYIt;B{Bl{bv~=B`#=iSy0l%gOIlbqe_`>VL zkFRbqNA*_ii*8NKm}nt5^A4ya3EGe(#t{3xY+`XmpVzLA4u%Ob9+%33rGFlO8vJYN zrQCbRtWSG?eR@@-e&LL5@mnu`xvR#&v%E2VTKlfouM60|ZVPu&v)>!kd1A=}y~5y{ zEJNAyk_l2iH)TP~c_&QW)KPw<)ATr~_Pc!`_R+Da&lf%YCAMaX>&@`fWmPiud*|O; zoh=z@>9oeO?V$;Wtk@v~(;_{k;AYTpsMONs(~Um7VUXSbR>5>i(ubptYg$^3pQ!ww zQS+zxZ}gmS4JD=E$y2vT)D%v*Xa614V5;zz(VjWe^J)B(^puw#&(44T3tCC_$~tt% zr`W}I`|9V(|F`+SBSlwf*a=l=cg-5GYE zz2_eq6hfzmBwB=Cb9GrZYoe&KN!{j&F78bETc^Ki-uyAFvM_wd$B?Rmr#n5qsda8Y z?s@#OMe*De-4mOvw{@Io0S~pS{$7wH_CMEf$wA3edt4$pyC+Un2DJ~a#c#Rv*@J(o zcxV!62FYk@%k;L)A5qNnwD`B$uRm&je*4+h+cJ@SHdCVtV_nkb<>rfNDkUkWU)Z^F zj&mCKwlzm1Mdac+4!n^+cdX>~Q*W0PEzd7%5yj7>_L#=K%3pKb{{H&VtFA8h9N!nX zrkpZhR$Hee{_trcXwdqEp46Z7prNl>tFu4@9>)a*XHEg7hf@YT&3E{pUi#}`?yS!T zjz+hWn{<@2l^-N^O9m+^ZBhjdxCeRpX&(%Iko1@TI(W#}?Vwj=&Yz!dht{`#y!!jX zCq*Tt+n_dGaF_8DmG>`fHoO6?Otu!z?Ah>YOK8d6%dX!R-aNCncHK7>alxC6XAOlW zYN}roIvi^7>u-UpOUfhH*^AcL<(i&jQZKHvZ9j02akp|Obf)ZSkB+qB?*}=c(S9H6 zuv3d3_wmU%vRfP|kgzD8({fMzP{Es9C(2*@CduDfX+_MTLrA@)0_+EPCR??AK z$tiE=rk0BcPRvYyQSZFv-VH83qvb+Nji>(>|Fv@OHnH$~FVgf~XD|BlfARcP-K#^+ zxw@1!o^uqRsG0g=r=o$vmwgjJL;1_*9=ONo^#1&wedqQj>;2xdg&*Y98^0vxmY4SZ zvXCt=dvL0J;`fbvK6Ys-8R>%Z@|2_so(&4JexNW*xn*dpW@^9oVD#Iif3Lp<4dcZ! zGW}-lFmZD$?RjY4_Of=*bnryp*RWuhl<*g!!7j_DT=?x|;lvk}p9flbdtyt<4xXZW z^PMX^D=w$@<*hQ4!``=>o+$nV{r_5`w z?l9@eGjVruDVxX|mQ*Zx{&#`g#nQmAIa`|A@=Y!jlrh)(f6Fc1el33MqnU3Pz7sE% zvK1G+$y@bQWTNKs2Q5rCPvxT4WpA|Z>Nv3lG|+qNea8Kywf%3HH?Q2kQtrQ#eOsnL zZr7zRd)3x_nWp@za~(@#Ez=CUy+=g^Z^~AE6`81cyksV*R5|#cZ<34$Xsv(BtqqgJ z&W4*zt}QUzyw5zl`*qWA)|s_0b5`lESCjR9y!KntjM>}cq-*LXytt+D&+=bqpRSTo zZpLg=!I@vyOgZ{N`fy7;uW*gOK>D`H8Ob6IB`Um87h+vf&O~H#YbQ>W@_fjX`*`i6 z*|*n6dUm^nGlehY*3RAd&|R8CPU6a`w@OOYpq)lWDT==?N?^Ru7`}Rw_Uz+W!lHXi!G21jg()mZP z!OM(gM|OLEUAVI2#5~ZohCW%${`?PSKUe<#A;xFAXTg7kgSAas&y|!OpP2f7(W~2` zppJCg<%F}-uM5P=-+g2Tij%s@3&qB%)*A{_hXxKWAs>*=vxJ93?n$r9bH0hPfdYM-S|0 z&-fQ<{MY~cDORqoZe%@$r*u-k(YO%YV)I&ntte;vthj zi}8~?JAAZ3;~j?Ae|3kM#qFJV;uS~Vgyw(hzc&ia4E*xplfhc^?M8oY8R%Z$0@@XF zahb-_c-^D+poEcPbo#f4+~@Z*`|H=u-+DjB`+a=X+ddT~qqU$Macs)eZ7=>7>#HuG z7EqQZ`A{`6tTs{9+kT^n`vJ!-nq9lE_#V%}ZRrl&QeY#3Yi=WJWyY$&B zsabk?Nsq5epS0ByKYZa)p^{Rvqw)(Sqh)SkeG{a-1aH_gI9z+A^X#7C^gW9|pRm)I zeTrLa=J(x|5t-d7@skcdXDhGj+XdP-(3Uvi_rsV;ww^+zTR*G$b9~ z*!^JNLEq`=x~G(~1Fwl~H|1gepJabnpLg;b??%N~li7f#>(@p|^tGQo)}&%{1j_Gk~6 z*S-*^@AG%P+_QZ0JNDfte>(6TT`n?tYsHuS(k?D(R-obOJnyf|JJxgs{OkP`tM#1W z;nGB=_gp=}MuLJfGtT9xt1h3q;l)MQkk}yCC5DGq1&43^<-J<6CilX-3MHlBCbtW& zDcg@)KVqoxvfW)`e|l5Ly6#EUF7GOi2nh;G&y<_o^qA|!e-}IE^E?+m?&h1Nm!nit zz)?O^I(%XGpZ;gbJGPk4?l@r$s%7&$-7jysd#P<^>Z7%v-(9K|p37;VaB=b4N*9-9 z+J{X}{B+=3_`Utbk6d=p`lw(2T`BRC_U-=~SRJdo%zLt>tIIvmYK$`P%jL5rYU(Du znjiM~!`nyKtlZL`eh)D*wR;F!vtq#0JSo^)!*VN2Lt{F7hRyPc55wC*``VtBC@D?u zw%aB$F*Yqy?63d#;9pOJiulgneEQpc_9D_dF+1YX83242+ z?lT5FJj)wj-rqZY!W-sInwEQ8_U->VktgzXss!B$hpy8DjOWTZ{ zv`x~VE>NeOQ!XPo(bEw;r?bJI!To~c`Ng)?H9ChAK|@Gv^CS}<+-FXn;OFA9Oi4R0 z@zj&j_)83%4S za)D+DgEvl-INcY2>{k9-)eZ3tf092Pf3l-3aYA*9Uh{cgq1QbVWxV=M7P`8mWO;m1 zk*Lbd=oga}6`Tp$YM8Rz>`w+W!`JQCg6orQ+b&CNPJS*ku~~F`#J7v7YphB|!@Qm^ z?(R4vGWUB)l0~oK?+4*7DXTyWm}I-mTqUatJ2n}g;&>-5bGeA`f#%nMqA1Rr?J2_9 zT^B#kShl;n;|$A6kFIz2Wx)k8jb&d11S==U@w%q$hAizY6y1Ho(kA_m-10YTj2NWO zXD@kuPY<;4%;4C!W`>zkJUmY4Cfqf2NnzS@_paMI_36JRzxrrlTXuZrC$>q<5gB5$ zAO|$wHvMph0n{%qPUT&e{zv_eh)lG@Ha$jrA_T7M`K;KY07$T{&uW?$BLyuliIE7B7P?x@AAGoWqz>V zX;WQLpYO?MRhIk0R~8i--}rdC|9a(ArOO?nn zR~4pMsy+FbTJ+NY+v)|~KEfZ@S)8@cOe-juaA=p)-`iq>mF(adjS?H*&;GMc-qP;= zwE499nmPMbpEp~!*a;*(h-U`1Q0A6{mc_hmNfQv9xN#!a@{GM3r@mv~Ww=-E>h$o( ztH0iq^@c8y%k}!E=GlH(BCq+tKE`Mxi8jY`iIz`fr@DW4zWYP$SBFl2z>k+sb8c4s z6cU`Nb*uia-}mObQ))K0EbO6-^HOn_8CS}-%;IO3Cw~U;fi?x0e6?KC(Qy|vB=Y-Vj9JV+#``kz`>cMar+0Sv zxK%yZQo8*_uPFG>&m^n5+Xp8to_68)_PE{3xd$H>2UOOnR{u}VU$uTs+P%Ay=-^(js64<%6|KZwi zNx!}bsVf=H+`)bK%+6fCsp26*b;@U6T@Ks)$yi&ms`A9U3?-$>P51V8o$#BfH+fNT z7icVb=4e_Q^~b!>Xn@@AWE~=)rdQ<=ebx~ zFMe3NUH$3ol_e&di>eF$FE|U@fM?PccXCesycd_xs0#{$+_Ux2WG>Ek;!A#ZrJ4OJ zQI^)bpHRMJZH1QYgT`<7eR^5ny11n6x}$7tJTJ+2a(%C`;KYxhgt_?H+Al%>S67MI z?&3(_R~)o%m-UbPjvbB(`x`(V{S=WoJN-8CpIi2~uWZ)7+b*EBq$+~oHI^szidkfM zY^`0+C0drb-*j4J?RfsMErUf9-|WjB9Vap*+8ob@nug2?KX}30dCk8^S(BPQcPDpt z+;9S&2oqTmDWRP?vHHrBh>o*f(Ixg5&VG74T{u!W@f&~o@+vD6q(18h{p}#r&&o(^x$NHpJ zh5xWY&RJC@rQPRZU#XR3bbvQQD=8&$gG#4VOZgLu*@a?f?Q_$P{$IP{ZOy?FrL(uV zK?}fw>x*qS@3ZGl@4GxrM@h-ZY?D}uV5H>CDb}qW9X;k??Vu^J_cKl}QWu-pw?wk) z;Jl-c+TtXVQf_j%&ey%PElWx1vP;5zhL;($K1|vG3QIN664N)^T$b;xzQ*>A^TF)b zi+?xfMHhE;oVf8(|HEUgvWuTH`VlIpy=c?mO*efI|3dw{^EVx_^eP{o<&DYFP z`f+#1i60tP8#&5%&OVlJa_Msgf2Uk^dQNADkBDf=#LToMi79vFm1TWFhoe-=pWmGO z#p<5i@~6ARoZ4GC-pFoHZSLsk;lG?7R9-7^5?D2Kk z$Nwbe?tiahI%&}ZVb;h0B5qIWS_1AErUreTs}*h3(Q)F(r;v(>56fAv#DqFmS)4tw z>f?WgD3>GP6OPV2sAoT3`t+P9;Q?=hYna}e&zr*%i-ozQfyT^(mQ{B|>UoVcN7yLQU5_hyD)E(shg@Be%6 z!O8;A3bj3pKOOsXWAVk`75eXl%vtAeO0U}M%DrxQz&IzOLaBSR*yOh-(hN*bO!^@7?)9#I@%FeoufDOaW4b3? z!~dK8`|@+)?)!}A%cS#NESd6kRt3u$OMWgttMW^T|n>pLg0G~FjRnvx@>BTu`& z)?1`_Ys1yrbDH+;!Cn40A8lgV+`#{&28{2Q{h9VUdfoj;zb<$AKfdfb|K6(zy~{_H zo-2u^>OPvxI{(S)?0u(x-T1Y!c9PQNmhGobKiJ$Hp~-!C;q`jKnft(zblBj8t=05v zucJ5Wa38+$PkQEuPX^iNW4((MI;U<^V6}9AB5*_B;eYU7moWDeb@^tw+qYi)S|EP% zo60*Q^RMPtAL|wRKiGWhj927>-1DjYUsZqoxc}jQ!R$P*7}YDkvI-?;{@<8YV|vH% zJKwn+i^=AP@^f~bH~e`#C-B^E;k#=jA`jZ!x8b_m%22cK$7d7Q*%eEkPt3J@ckG7S ztVO<0c7K}re*XTKpOVTAr-#R%OAoIrvzfQ<#1!$G@(J5!-v+JSdr+5bZ|&ofvMIn( zd}d!zf<>?Hsh=mh1b_Xz*#6MuguR-4dE@L-@pXqopDg-!t?Eu|Ue*6w-k|m9`>lEs zr9$EZeZMi@oH8fM=`^n{&sUzn;?myS?!$}`p4^95UKGA*+|ByB2!w!?q_#hmu?qo z*nH~Tqw}`)YMyCx*|@ux|DONs+qc`1W}9*@8}gmEoHIY{zsThiI_$>h?fWbDRj%n- zBlG>azR}f`w^Lj5*Y)>?=P&uUtZI(q-d53xFFm`Dbow|eYrB6q`;~E~;PY*_Z$(s| z@~V=5zx4Gyy=k>clDyB&1oC@>D;-tuY3VOJzvRIUCNaAW6I}WAlP*5)2DNt>;^+3i zI=#AZ`p%mLH`y+AZpl5bdr$Cq=z^)YQ**W+i~i~M*gQfiZr96APUVW~BJ&syINoFr zd~j>eyMxWP{6=%m%`vu{Blm3KymqtL@CRBC4!mJD|65c2`)y6}Tl4K2&l&u`+8@n6 zygs+^X0&R&%QoMX!{xhd&lUPdNx2;Bhy0^t~-u*H&dhX-rAFNmWD>R*GDmZK3?Utz< z)Ly;JNm{C#bk@*j^Bd`d(_d=4c17RHyZLC-;bK1agu-i&boJs5Hzl>(zn{AG`ZD|P zD%IP5&v?JbkNaq6PW-h)I?w(l%I&kXGy9Xm?A;f22(*&RGUNO@B_*ZDj-Q)dmMwgA zUQ{?vYT5snbw2$k=iGiSa6_9RrK{{?dUyHj9shpTt*Q??yQ}-!#y>4jMQYb|fL1!y z+ErC#&UhH!=2@cdQKDWTX0b6zERuWk30oua%iEu(cXXa(2|IHr`sv-Z$AxdsoZcR% zmZ@4OH8Z}y_;0bH;mS{8xrMvmxqKJ1|E{u4=hpi@f45ce@c(A}cK1uMiR|4ZmUx$K z&on;=RF~?0{AK}K5&5&-?@)fr%HOH7@0_Zyxd{qNdV`Lso3Q@g@k8ulle(4}*goSE z@46idS|Rc7{j*DD#nNZ(Gnd`WIu`s=vBF`(9{%ToH`F&=PF7)`%wuDF;MZv*?Xc>! zN~6oy<_g5hF8%#44>Z`eY5i2t;;?0ZHui2j^H$rWN$;_8+R+#O-|}ajduKAIWsYJ~ zpRV}QuBFM*e`I{!xBswAc=zZ2!JVSdC%r#)|I6q3yZ#*s$jT^R+ zr||Knn_T#FIW4O`F1uVuaH8$9COxBG%RP@b-`QE;H~-fB>yzI28-3ZY*cK;~^x~)D zF8No>zO9OKYHus6_`mh}+SDIc&xG9D)BoJ?_obWBG4k1+7yr#Jn^k|w=f_ursp8>} zK3JN~pR(BWQHqS@`ycXWl3ri7yjM9p_HX^CH=8z_&%Mw0;nW4~Ka0MK?=BM%JQ)6V z@tfDFYyRJ>I^=x_e8l3UjuUbhEng^Yx;@9zuZaKr(pQVL#O~~GxS*&wYv1iHhh3kz zh4mWzd1WAae@(*u|8IAPTC#tbQa$7A+{iQkF6R9DfARdP^XrpRzH;!@KVxpc;?Z?t z7sucKuhLVFo~W?3o!PjjZTf`b&+I;)+9wl=3RV{%wq2IK`uE@Gss77< z<_6V=s?jla=k5ESx6ix(==t_)bI zsq8Cwf3r_TN8_wUA6cLn21 zcPGENxn;%eLe}FSm#?!ooFk|9fTJMi;KteSu1|jPu=Sw0+21#YHZhUKs_%LCmS0Zg zFSS3?Z~kY7iPTwPN$$2pgV*evK}&~HkLxLCuh+Tbnm5PN?~Kmmhv97-Cy7mc9xfCo zw(RvjyS@-qJ2vjBvD;Q&i#{!SHT;25%#vg4CHHLg!REx6M?=ku;(9?IftcXu4icq}&E{?2EEtM{_(!v9z@aK*67NLiJ1 z-@bFRP`&?)&8DNNjK`-%udDQZUnc+iW@GwKd94>pyH8JjzUas1qaSX{-aj|=jwV9%`eVpFW9w(B7;gE>;m zv@g0kFKMj*^1r#B|4;So=+%rdw~KVo^V%KnY*pW+ku9j`-qCo4!TYfH&h@YD;v}jP zXMY!-c=EUb@2T^;$E|OBAJ4arD1T@rX0w6e@RhiEN=fpdIrC|AEd7#RCm*qX6s;?! zV(cHir}uB%&3vD}uZJ#h?+!VlA6u_Eeck>NAGv6kW785ri#Zs=7j_@ZHxbJ3e7y3@ zn?K;g%WkjfJh3ID#>?=XkU4L<>4Z1e|6Nj2+Em+E&T3%8_I7{f@lD%oo84Selt6i8 z%ac>Zf#u1vC-lpqHq7QCl4T%YGd>%X3B=(ZaB7M-t{F#lQ5!a~CXTJs(MR7Kt z=Qa9s3v^JGONx;8uM)w{`|P_9K4;IgSw0c8Z&gKbCTJIbO4RFJ%e${hM;&B*XQV5p zuB2o=t=`A(>;5(Bwy_pUGxv)XZ=fm$GyA z_s_qPKfCO|{NFA2Ze*3q2+ni_JA+$JMCFo%;?3n#@3^|8d?~V<;QZ6_X~~~u&GX!= zK-=t%Tex<0_++!r*8wfF%ih0rT1M~{&}uHDR*|_eF8>ODuK9nlsx3|qbhyVE@S>%) zGxa9V(#|euo3qBQ*7Rbj)=MQNBdfN=fYL9IGcUt$|Rulv{R z*M-k4BL7ak3LfB5QBn$Sd1$oaU!>_d8};7jCX?P=*9=xNssp*%tzz|(-JfFCSl04R zWSd$dC@3kLe!=tZ*3u;)bAB?THTmOMQ5^`d{vs$yLAuGN(CzFhHbyQtvA ziyuR(R_s{N)L74J015e&S)k6ZIV}`Xer|(<#-bC^pg1jlRl zB1P)g%{XAkxO;IIWKFtpU!ug5dX@PP!`mcl>I6=2GT=GEg@-p-+@HlsD|@f0{T$s!?1}&|nT*=>4@y_XN}5nqN11KF#vSt6J~{k51i3I#2XG zJyB%vecjF}^_%CoxHr9MdtsJ;{rh#hIXnH*{w9buma`hfu(jP*xHvW8Z|dvFpF5}W z>|do@?&6|yxMU`19h6vf*z6L#>}sLsp1ckIh7 ziM-}N{m&-BDSZ(3y3W^4Bb1Ds4&zP3KDLZ?bCIer$K<@2%yh>?~$4oZh}6=vvry)_bA} z@8%YRZU_a9sQ)~bb}KJSditD~F0*bNljvM`WQR<=i_5WT$`2O2+htYMe{ShZYhRxI z>u!cAZ2~Xnd|bK8#zlH@%k&mc-lZPym!hW>p4Z_IJEL@Q=i8*58Eij~KiT|ZqASZc z-UHWc>-tr83FrLy$ac@-5AUpf_m50kJl){Op$9kYIyyRfxDTfqy#BrU!?nueZ<%8R zXWD_*%d&K|duO@SDHoP=1d}ejhQm6frv3KDQw~78PE^2cUr9|phO?Won zELnA};a^)trOTkxV9r!5yPk6I?q`XrObz3zd0RTxbzk}%!T(S+aS?CetNKv;RZKaN zVqry}1*%efTOM9-<9sK7Bzo`b=S%tb8~Lo!JT@o(yyAy-3=E~$uN!WvX?c<`sUmyM zy5GABrtZ-Am-A6iKHkMet!?)WUWZNkovRCO->&NF0Bz%DSaw{c#3Q5owAcP1uRXSX zFHH-d_P;wjrGDT1#(KVlNU^rW3m?9+@w9_Z1`LUd@Vs~Yvq8_?{y98*Esi|sZsxHu zZrFXt_u9S4+3P-E{rTZ)>b5tY-&BA8|Mt$>Zqu%N|9|}U$)7nX&irKB=3c&kA_0y9 zu1~dAi0dqf6Wpj^#_~q=gI1g?tH@H02nOk@tJ$m@8*T)g`sQo4H+|B{FEfpwe?NZW z(I(y9v)}lrt$+S_Bmbl`XJ(#nNh!Mb{P*9weZuAb8XwQMl>B4dlfZBw@#zZ9d1cG1 zf>=rzs*g&QFx=oioOj~xqj}{P)0aHh+;plhZR)*wVT!R6EYnxLiVW?VBN=#K{nwS^ z$bO-I)sPb+DNl7Guf5~Gmi})3#cSJhuYU1g_H<40s?V>^?QQ#Y<=YgMlXtg0=ljCY z@aaMHPMrYhp#W8gmVZfo{i*=*CQ(<{#GSb5Cc^c~OH ziN;D?^TopcOx&?4Ir5~AS>tA|X(?jgL*#!Qny@D}&NTj#&H9xe+7efM-4u3It}pY! ze)cV|v{yg-YQb>e;q$!W?6-5XuYTSqm%FcEv()_?E85IWG>m5iewiM)wRVN?#LG%u z_r$NB=vBV;VZL<8-%DAcve8Q~e0JKipZPQcqb!5ijLp|pZqvT~tzvefdC1qERkruS z%H!rn-Mgt&eWK1m_GYf!>|6KlFMB&Z@A{K+_0aOTyN*|R86s-du}u%Vzb8sLUi#vR zv&ysnz1$L$t9O&h?CPE^Zf47UOV_Un{;_3)+divBZ!*HH?Y24VPT#iTUCh1vjb82! z>~vwywvvDOk<~IptOf z`GQFokIFJ=wLCPq@@1Kt?9a{0TVMSO&8o_toRc@ZO8@=U2kGqIv2qLv`rky)sjmFD z_3I`dZ|8U!D<4rt4N<*=j1H}ZZgYy}Jqh`+WPw!N^#vdE`?EjPvxR>CB=s}w_mtV^ zG_B`N-F!`8edZXzr{3A^UCS z%C-L2j(IhSK}U$miXmjjuHx4wAMbMJRv$O}dF`i2wT9Y#K|57>-&6Hd;#+eZSDsz@ zsLY;E^H=wZkO?-ia;)=Zr))l_X`H5IK5w#a!eq;2t)euSgOi(mX0taOUh-{DR4SX1 z)UQJm?%cj}soy(Ru;HkK1A7Bkx&?1({nBV<^ZpZpB^nh)0gaEDy>dM>zcof$zMh*^ z7rnXZye8Yb8lCk!?ayX@>)+hANQ1B zs!RtqT`0=z-V+=5v~JSvx7(cdC{%g{h%~UeIY`VD#S8?4b4&kg)=)6q2klFogp`-}GTF+{vu z6(6+r!|6l2Yil1AGjr8-%=A4Fy(6`;_uVil3 zTeYus3&LOSE9ul?ZFrjd?fd3gJE|95NoBBbVJTra;AoiBw(9(vYro#FyWYjWHsFtZ zVXj4a^Dn!r%im;dyYiIrz^0(;vbAmN<-^K)zQ-qMDlcGW;Ol&767st%O1AL5U{+;# zcUrymYW28(Eo|##1Kup0@yYmS&~y$4(e)n>x!tTW%H1~OD8dG2*_ca9d+;SqJ8~e zG`}sM(WK7i9V^t(?BKx8prcWJVBNCr*;gt87aKK8s+y}zy%X`r{8w+Fs1WPbIkAhs z^>2IsKY^j4a&=wd)@ASJUOJG@zUAGz(oH*O=y2>oxTQh1GapGcWjK&{`Txo~%T=;b zKX*=Ds>jNpHEH|l)xWM^$$s)o@a*5pbyuD;SUB{6LaO_R{o`4G@2;_0_in=Oo3XEo z7#1X%?%nEna;@jrn2XB)Ki2)c{_CmzG5`Pk37iQmvJ3?gJvFH=^FrlZ<0LdoH5mdf zzKPo{6?a>q_*_Vx()y3Pk8OSX_V$*KdwP3TF{k!5@G(S`6xYwYd?)_dl|S3k-0~S7 z7|i&0bITpsytO-%d;9*Ky%<${I?GatFSqt~7;jCPLu<*xE2>O4n3=2?5-#@Er^nng zjcfJeow`eeVMWEyh&bc#=U04t6D8TEc-TP1!fe62*}Ja(+85^guOLYJ+}#Bq-}jvM znYC0;{J?(21=BOZ`z+*^(@uYh{x?bW5UL>f2!Q3Wv=|CdUbcr-3^kf>V5ZK ztE*o7$NjhIk5)(9f0K@zep#xRdVI6$DzO9mK?zDM^ox0*XV4SYHMZ;xhZUvIp1S#9 z%FG*|U+ma^dG)!~)}>GS`$NuJn$G%huVtRaZ_cxK%!@0ySvN?7{1E8+Uw_pDb>({-|-0*U(j~Pz4?`_Q8|9w0An^!+v+HGXzzQ)~L?bO9q zU#lny7hU{eRqli7(b+`0WVF5f-O6 znf!U0xN}wv*E|uOQcH#nZ*Kf8+j;wrSFY#T--aviO;Ou#u6bY3&U8;*UGQT@9Ub?T z+zbpM)1Dk#!nR&I!ktC{r<N?q*O*6|lD38YlJw-P|1P_;{w-d1$@LW_)dEF z)!z@}-u`&NCz8o; zL0jWvgwt2?EAk(b=a%}d-Iux5s9Eyt9rNHjQ57j*|agZMd{I^Xi;n z<=Ll~T_|=gGT-eTD>iN7vWGo&pDwAF{hXCKxyaACIFzsVy7ktrw^!e{(_eGn-dscS zSX}?tGwsP%@8@yKevNQCIAdkRg>}dKKE0mz`PG-_>2LQ5H`?dD3N7z{-Jw1y>gMFI z3^V=uLm{`4FMCY(?w1k2P=0=Gu)p}(Z2?jn?;lS&=G*GeFaO2x&e}ZFJ^LKf?u2|v zzu2nHcOXvi0wV*vs_}%tC#`~8V=e`~3Tl}9hV|sUjZaQK2{E5}Sx|bC)pPgYS1-T3 zV4nZ(%C>iRnLqDdCw=Ahdzt%Bv$qCU&i!^f5`^#m`&Cu@GIs6mJ8|X{FRPmOy(wGc zuxP=%+|1H^@7JRCGp@9+e|2GfT*TfD`a+^-jdYimFPSQP-mCKD_H*j#Yd<&i8-Jaw z`SaS(Cr_0GH!J~V681BjbY>a`o9XX$3$$C5*#57~$zffNWA9?i(p>+OaT@owZ8Be* z|L1zz-oM8}tG>)wJ}qg_8~4e(TRxwZYByW=IrHtZDX-LuCoM6*W4KOMR_^bQH@EK2 zGk&-^bHUlQomR`43WMG4=1noq_naiN?90N{>|bs_Z=G8Fad%Vg>GMxa3(vQxy_*?e zH*5Opn@ismgas9z+L=Gs|K8R(P_x3K?EUG^AnTx6f8VZ2lb><5tAC9}%v0tF1yIy8 zcK?eH+1WW~)xY@AmEMeHx9&Z?ICXyP&d;BpE$p%T@RD)vp8%gpPkhC{+|;i6+9kgx z{8IjZvwI~B3{K*nE{-A7mD68Nl5Q)%SHIxuTJC*2!#-;5W-4B`ukxVUR^Buf&*^sz z*393##H}*Da8`}UqYJy&y}oq#{Hj~3HQV`8N^VP=ueO>sT_yCW@7i0_E*<;&&$a$< z#I8$!Gjn$qbe~zWa@O>#8lV1j?8)A1l)P-x>`7jEI{#+xsCIg`W@SXJkJRnI7Qy!O zF8#Rs*elm_<-0vrSLgU%_Dfg^DzN!HzDy7NTD!^rYI^AES2I~kbmSH%XqwEv|N8C0 z<#(T*h~#oFwzl{GmGkSy@$eVk?{BRu{hw73YCiMw>-Q3uW7n^{y!oF<@Y^fF$AA3n zRw{bJ&E?*G_?^AI@f!2{K|YS41odzB%h+p+?dz8K|7+1yop-BEOK!uDO;Ism*&hDxoz+IneM5Qds9Q&PG6WZ9Su?KxyN#$U-@r+ z|0SO%2d>K|XKt#@-SlaijOlMXQ*$2YcWT=YrMH*w*0rBG-7-3d%iV%~nx2>oBg3=Q zZ{?e%eqEX%^>4MK?Ddip&z|^mFzB>=&`f-~{L`r~>3qK=qVMf-o%AFx*_<~)^YI%l zh7JDHQbA3~SAPT6J1uX!QsZf?{G4G!!yotGsh@9~eA;@qoNdPX51ENu>-WrU;L|At zCBisWbJeXcO=oZUJNLGzh2Da`)mAAR^u!p%rr0KgpSF$?`Rf|;bLZagu{WkqE8n`} z*;3O@83KJHKAn|0Iqpln`zz;g{uh<|XWy;dZ(h4M z+SjVyLEc*>Nl0%6Eot}ZAC60jhCOQA6m1iNpbJrw$NL< zs@_)zwx@sk^{+l}&hgdms>Lm`lT;)B-&)3h;FF63JHwlcAEvjbs`-MNDlxq4f~GTj zOiDY{H}~x2J^#55`k%7ywKWT?KKDMoysg;t){b+_Uq(&eR$5)o`C?wr*3*w|XI{}e zeskZc-RFIPjq7cY$@IQeXiUz72C2a>#8TOzdPm5^XL6?w)^*< zQO_>t{dn~2^tT)8hX`{rm|tK~0FVz!PFu>Pz?kasL_meSYauJ$8!> z-Db(!kFmE)jC#r)wdZ3lDyN?ddYloqdfU>nnYZSBxmEIWtM=3{ zw^c=#AGu%Px!La5$~w=W*8ySo>z@kW+Hi0ASLsQs=2m4r`TeWhMEiZstM3n|+&}y3 zta*QyTFUipp>ao<%UaVvMeSGA3_o}4sbzg(+E=ChMLMNviz*UN$ZeXwLx^Fi8z?fB zw(6>;&ker!Zm;=Prc;3_YU_>bj5i;@y=^_D?)etF`(Moe7jvRYzb*T^E5FZsQr7ZM zR!_fgjD1&p{PnA^k2hz3uekGJ&C2vYy8DjbepENxuEKZuF)2yMathfd2-I2 z-!F<87JLHLdb>Sxy-#kwwE4d^Q|gH=o|elORvcK@X|;UY+E1_cT|WHlZ?W^HZ<|~n zl)lfr>a5OMde2ta>eI&-r_IaKoXc$Mmc)Ob6TZCN|IXfnx2NmpUMv15aCu_CdWiYN z;0iVU!;_L6cUM{4{<_@hc(>YbZJN@Yti=CwdXEOolRbIr`djTnQwFcj{Zb4Ku_+Y+PKts4#A%zJd@o71ih^Q)Ow zl$dlfGrT!;D%xlcxXqjT?tSqj6@T{4(;J?G8ubheQ!cz=-u$Vg^2J}qh6X-{8&eaF zQ=YE*dtZ=YgTf}|$Vw~QH;sG{ng1F4)BYQ1uXgZYZ#bGJs+0Q5xajKTxALH|j}InS z{|Byp6A*S%eG<5<68GhLV5<9OuK9v`rJ4+jT7kB)! zzq^7LGJXt;3Q`!+4-*~{O71&>CM#8HMK%#Veb1I zYWJn)TdjMiQEJI>iiJ^@LBUh%|G6DP(n7EPWo>72H=e}I(5?E>#VK01i5X|v{ zfx&ZFb$W`#Wss?Yl<{-l@-Fz9AZXhmqlw@AE0QrUiZVUgaIj z6%b^0`BGv3kx=WIms8dT_sfU}96WdLibcuB_T*Q89oFB;%`1(+uUp+vz?V?YQo_*C zmM=5yYl*+u6*%dcJ<3NHA|&Gkq17N+^P+%{r2hJ z-F-%V$d6#D<$uG_i)oaR4|n6xuf&gKW-X1^Ws`%{#pSy~Fi z4eN797!qc7|F_lCPS>n)+i_(ngKDC&ZfxD#gpZGx-&b3y@UnKk^cCjiZ8P8X-Cgqg z(yYIS*F384*8cZ>#~I7uw%Zf_YwUj&AH4p6G1DjchttpczE)@W4H}_J)!S*QSv@uO zU0C@_Z$__2JKP`b_Q|fdn!V)M#yNe}D(m*!E`Ievv~AP0J2S4lSi5-E&V0AF+W`+= zG`u>$KK!cjswdWm)Ms})@I5#nc!4otrgyII$=$cK4=1DuoDP2bfm-3znz^L6X~e7UW1a)RCWePL2Zbb}9@iyf{!T^+UM**8-zdwm}Z z_6->vFBmqQY4zvVHlG&!sWSx>YR~>%R^IjKmY?sH_g1~Ndk(JDw!3{&Ec^78ALYkP z%U;ijx_5U`8@JSptBeU34Uft)OxtFfH{;fG&KdBqAfq&7A1F`S+oYZTMA#wPeq zW7FLP?X9VLS0`WkR-PZ8XS96U_bn^_ZT-4bkMn?$6DWl9o?SOKO85PF?Uz?97sHg6 z&<#^=O}lhw{xg#=M-?q!&xxx4URAb(q2LBM617serS{cDJTC9m{<3F6lRCS1tPq1t z*tE>dKhck+b{G5ne7T2b`@#d9j9X(bx>>LX2!Uc`*|z=ZyC2neul|{Pc2zxZumz)z z{o#1oYd3O}SJk?%RnqS`QNJbL%-nVg;}kwdS%zr~@3{CC*Ut+6ef(DF=S{PMrZY3N z$L_LUyYcq%Dm0B_=bmm@TNQm^ZnK(fu)OK=O1j97>)0<36?oODq)z5U# zJifOKr`W;9y@?2GyF6j@!JYrDnH^X+>Ub~S-jnsMF>-6%HLcn0mlGMDHfz3P*uXP$ z^RhRNyLp=b&Slh*Zw+y*4gae7>+=dJ{k)JTKPLuFXJOc_uz>l1(Ub}$#rInID^D{t z99}j-H{*2lHjTZuYy14mSNv+dx>S#oq0AW+xN7oev)}0#XH^;dPHb3u#z^<5e5bbg z%*mUttvpc3C|QU13+$*VL83Uq~h%ZyZ6RFb~;8bE1jXG zRqwCIxWaaMSlRr&SDrE)umdF&$qhQ*wc%e^PS9TQSNN?_&YED>X^Va+f4u8+YeSX=++isxYoHyc(vJ6@=yY$x{JkPu8*;7-l`Eq)tmJEE2o3HI$ z@I9JO#<6{tUe=`}w!&S1HN!wbJD=kPL%>6~eCesmZvtMYu3f6fdO(p&Mts8Ny891r z-we1@#OuG(et+D-$xXNZ-FrLh=Utzbrx_deDlK4kXzl)Mxa>r?@}}y{J{FzQwz~nZ zpZ?x)Bh6#&`|MQvFUt+zw1w5>EpdOV4@rCrADFg7>XwbAzAPmxIR2Uj25Nf9#!vcBv=B25GZ{tPNad zWw&RfOkXuGGW1mtgU*5zF9loudBu0{`kyVm@jxM?+qv(DH%Lc)Tqs)PA_MC2d@`;y zjlZRH_`z?s1vUZ~7#BFD9^WLjyVj>y-0aldGaOa{nLN7}u1YWX_|`$PZQ(TUs3$!Z zra$bPKdt$);+cJxSF9L=M^cwHL&%z$ztdDadBshpY!hJ6aQ?b}ZTO2V6F}1%PTK-r z6)`vnf#TrWo%zp2Ec6tr8=e&~Y*0Tt-9+1Z(%ni&VFs_>20jMS6Pt8Y<-AYSZ`prk zDTBk!Pi0k4Uw+Z}Ch&VPvj%7^YlTatru@=sYlb)eU%gj}{!I<}=>8bgBmqTNC(m-l z!t($)48a?h=uy|9= ze|z(3yI4XL4kvoXyVe^q|uVugaW|(?>(^5TlhG{&9^H#jn^_}(m@|;Kg7w*a) zcz9Tvjgj9_BUB|)ti5Mp7<}0ZQ zGmUcEX5GKF=I#5N>vpz37qKyn0C|Slr;xpYOWev-#q-pcbgvjr1|8jl&)J^ZA6x$~ z``1l**#n873Y#nav*`U-+@9ZD*c+G=CEBdky_#T|o^{;4?8K?)rFxtWt;!3S9hUwM z*V9koc)?Jx;Lh2+tueP2-H=b3_4jYi%F~Pi4?%JM&@E4D;zJXW8nM^vj1Ll2|8M;)D6=DXf^zLMz$M>beKU>dwnpHG)mkdKhQIM^s@81-!UUAb??>2)1R}|D> z7S;L~;p7}I0~&(O+Oc3EsFa#yQuBC2Ot0S6eT%kTS;`Q>2C{Ww+J6h}>J#gpZ8rrE z+)fheR|SBXh;+iX^ zRjSFbL8bSurP}?8cC7PH^GPu9$%Cf57VPu?=GhkV|JJXd=}ZjXL60uBD5blkNc7BO zwx|KQxKZf8$BK7*taiS-5yi{E7or#&0Gir6zS5}SaCf;Z!wQFQ8)Bc$iF{?mkl+cb zpW7}6e3v>*Q}>Xo;nfve#+U*$(HF^Z_XK}9^ZVb_vw{S z=fr+q`{@;{*T4m;1GzRoerzrB+u3LB`&?a+KfAANn-asTcXRcdrFyCBSH%ac{Sp6I z>ffggZToF>BqwdYx$;j$+$Qg<`s>2#%+{aHzqKax`ud=&A48YwNjk79E?{z~o8Yp0_^|4UizVAkLdJ9p`UIGbtV_ZFw~yenVtS{F2ZOL*Jm3tjzd0uI-kYFN(+ zEi=(J&OG&OgJwyT$2zO&Tr-=t?Jb^Nwf@c3UDel4N)}GrmBSzkYCegkd|Mc~Qo;3H z$CO=DCT;NX{&@Vc*FR%T_g?3R&s$T!Pk-+ryFo_e66@Ex4dEN@k3ETd8KxNj?{q%T z;R)%j?(;I z{FB^K`Oei7^iOz2N%8Pzz1@Dzt5S2LrDFc{@OyswD^Igb>wR);$+p;CzG;_2ejmSm zwchvt9z6xIB34y-f32;$OE0Wc-1+Ks{%Mc&wZXaJ+cJ-{muvj<*=RDj9t+>`H1qq3xYY1J@`b*4Oc&PZ=xZlu z{#jSJ_W!#o$!$M-1D3O2n)UbXnrHuvmjCgIJ6E-wtFvj(>b;-Vemp5yc4G4-0k9h}@$bj{kd=I@56dzY0w zrG9*AcvRoNdV=nXS1npk)rx2RIyq%ckLrKJI#qL((7%teuEq!G8|P)6ZjBcC9qhAk z^7q=0hQ^aFKG@nkt2QC5?RLP`kD;H+s-JRLPI>2_{cN9PZ+­0GavcC)Y5X5Zc8 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" abbreviations known +# to the "date" command +metFilePattern="/alcc/gpfs2/home/mbees/data/meteo/GFS_OPR/GF%Y%m%d%H" +# example: +# "/glade/p/rda/data/ds083.2/grib2/%Y/%Y.%m/fnl_%Y%m%d_%H_00.grib2" + +# --- Pre/Postprocessing settings --- + +# prepararation script +preScriptPath=NONEXISTENT.bash + +# postprocessing scripts (arbitrary) +postScriptPath=NONEXISTENT.bash +# postprocessing scripts (actions for each wrfout file) +postPerFileScriptPath=NONEXISTENT.bash + +# --- Working directories --- + +# where the WRF will be run (some fast, large disk like "scratch" or similar) +workDir=${SCRATCH}/WRF/work/ + +# where the unprocessed WRF output will be stored +stagingRootDir=${SCRATCH}/WRF/staging/ +# where the WRF output will be stored +archiveRootDir=${SCRATCH}/archive/WRF/ +# where the WRF restart files will be stored +restartRootDir=${SCRATCH}/WRF/restart/ + +# remove run directory after run is finished? +removeRunDir=false + +# --- Chemistry --- + +withChemistry=true + +# WRF-Chem installation directory +WRFChemDir=${WRF_CHEM_SRC_PATH} + +# path to utility executables +meganBioEmissBin=megan_bio_emiss +mozbcBin=mozbc +weselyBin=wesely +exo_coldensBin=exo_coldens +anthro_emisBin=anthro_emis +fire_emisBin=fire_emis + +# path to Wesely and Exo_Coldens input data +wesColdensDataPath=${WESELY_EXO_COLDENS_DATA} + +# path to MEGAN input data +MEGANdir=/alcc/gpfs2/home/mbees/data/emissions/biogenic/MEGAN + +# use anthro_emiss or predefined files? +emissUseAnthroEmiss=false +# raw emission input - the files you read in with anthro_emiss +emissDir=/alcc/gpfs2/home/mbees/data/emissions/anthropogenic/EDGARv5/MOZART_MOSAIC +# emission conversion script for anthro_emis - must match emissions in emissDir +emissInpFile=emis_edgarv5_mozmos.inp +# year the emissions are valid for (for offset calculation) +emissYear=2015 + +# FINN fires +fireFilePattern="/alcc/gpfs2/home/mbees/data/emissions/fires/FINN/GLOB_MOZ4_%Y%j.txt" +fireInpFile=finn_fires.inp + +# boundary condition input +chembcFilePattern="/alcc/gpfs2/home/mbees/data/chembc/WACCM/WACCM%Y%m%d" +chembcInpFile=waccm.inp + +# TUV photolysis option 4 data file +TUVDataPath="/alcc/gpfs2/home/mbees/data/tuv/TUV.phot.bz2" diff --git a/blueprints/highres_chemistry/emis_edgarv5_mozmos.inp b/blueprints/highres_chemistry/emis_edgarv5_mozmos.inp new file mode 100644 index 0000000..5bd229e --- /dev/null +++ b/blueprints/highres_chemistry/emis_edgarv5_mozmos.inp @@ -0,0 +1,29 @@ +&CONTROL + domains = __domains__ + anthro_dir = '__emissDir__' + src_file_prefix = 'edgar_v5_2015_' + src_file_suffix = '_0.1x0.1.nc' + src_names = 'CO(28)','NOx(30)','SO2(64)','NH3(17)','BC(12)','OC(12)','PM2.5(1)','PM10(1)','BENZENE(78)','BIGALK(72)','BIGENE(56)','C2H2(26)','C2H4(28)', + 'C2H5OH(46)','C2H6(30)','C3H6(42)','C3H8(44)','CH2O(30)', + 'CH3CHO(44)','CH3COCH3(58)','CH3OH(32)','CH3COOH(60)','HCOOH(46)', + 'MEK(72)','TOLUENE(92)','XYLENES(106)' + sub_categories = 'TOTAL', + serial_output = .true., + start_output_time = '__startDate__', + stop_output_time = '__startDate__', + output_interval = 3600, + data_yrs_offset = __emissYearOffset__, + emissions_zdim_stag = 1, + emis_map = 'CO->CO','NO->0.8*NOx','NO2->0.2*NOx','SO2->SO2','NH3->NH3','BIGALK->BIGALK','BIGENE->BIGENE', + 'C2H4->C2H4','C2H5OH->C2H5OH','C2H6->C2H6','CH2O->CH2O','CH3CHO->CH3CHO', + 'CH3COCH3->CH3COCH3','CH3OH->CH3OH','MEK->MEK','TOLUENE->TOLUENE', + 'C3H6->C3H6','C3H8->C3H8','ISOP->0.0*CO','C10H16->0.0*CO', + 'SULF->0.0*SO2','C2H2->0.00561790*CO','BENZENE->BENZENE','XYLENE->XYLENES', + 'GLY->0.0*CO','MACR->0.0*CO','MGLY->0.0*CO','MVK->0.0*CO', + 'HCOOH->0.0*CO','HONO->0.0*CO','VOCA->0.04*CO','VOCBB->0.0*CO', + 'ECI(a)->0.1*BC','ECJ(a)->0.9*BC','ORGI(a)->0.1*OC','ORGJ(a)->0.9*OC','PM25I(a)->0.1*PM2.5', + 'PM25J(a)->0.9*PM2.5','PM_10(a)->PM10 + -1.0*PM2.5','SO4I(a)->0.0*PM10','SO4J(a)->0.0*PM10','NO3I(a)->0.0*PM10', + 'NO3J(a)->0.0*PM10','NH4I(a)->0.0*PM10','NH4J(a)->0.0*PM10','NAI(a)->0.0*PM10','NAJ(a)->0.0*PM10', + 'CLI(a)->0.0*PM10','CLJ(a)->0.0*PM10','CO_A->CO','CO_BB->0.0*CO','ORGI_A(a)->0.0*PM10', + 'ORGI_BB(a)->0.0*PM10','ORGJ_A(a)->0.0*PM10','ORGJ_BB(a)->0.0*PM10' +/ diff --git a/blueprints/highres_chemistry/exo_coldens.inp b/blueprints/highres_chemistry/exo_coldens.inp new file mode 100644 index 0000000..19febe5 --- /dev/null +++ b/blueprints/highres_chemistry/exo_coldens.inp @@ -0,0 +1,6 @@ +&control + +wrf_dir = './' +domains = __domains__, + +/ diff --git a/blueprints/highres_chemistry/finn_fires.inp b/blueprints/highres_chemistry/finn_fires.inp new file mode 100644 index 0000000..96ff076 --- /dev/null +++ b/blueprints/highres_chemistry/finn_fires.inp @@ -0,0 +1,30 @@ +&control +fire_directory = './' +fire_filename(1) = 'FINN_FIRES.txt' +start_date = '__startYear__-__startMonth__-__startDay__', +end_date = '__endYear__-__endMonth__-__endDay__', +Model = 'WRF', +wrf_directory = './', +domains = __domain__, +defaultUnits = 'molecules/cm^2/s', +FinnVers = '1.5', + +wrf2fire_map = 'co -> CO', 'no -> NO', 'no2 -> NO2', 'so2 -> SO2', + 'nh3 -> NH3', 'open -> BIGALD', 'bigalk -> BIGALK', + 'bigene -> BIGENE', 'apin -> C10H16', 'c2h4 -> C2H4', + 'c2h5oh -> C2H5OH', 'c2h6 -> C2H6', 'c3h6 -> C3H6', + 'c3h8 -> C3H8', 'ch2o -> CH2O', 'ald -> CH3CHO', + 'ch3cn -> CH3CN', 'ACET -> CH3COCH3', 'mgly -> CH3COCHO', + 'ch3cooh -> CH3COOH', 'ch3oh -> CH3OH', 'cres -> CRESOL', + 'glyald -> GLYALD', 'hcn -> HCN', 'acetol -> HYAC', + 'isop -> ISOP', 'macr -> MACR', 'mek -> MEK', 'mvk -> MVK', + 'toluene -> TOLUENE', 'hcooh -> HCOOH', 'c2h2 -> C2H2', + 'oc_a01 -> 0.01*OC;aerosol', 'oc_a02 -> 0.09*OC;aerosol', + 'oc_a03 -> 0.70*OC;aerosol', 'oc_a04 -> 0.20*OC;aerosol', + 'bc_a01 -> 0.01*BC;aerosol', 'bc_a02 -> 0.09*BC;aerosol', + 'bc_a03 -> 0.70*BC;aerosol', 'bc_a04 -> 0.20*BC;aerosol', + 'oin_a04 -> 1.00*PM10+-1.00*PM25+-0.20*OC+-0.20*BC;aerosol', + 'oin_a01 -> 0.01*PM25+-0.01*OC+-0.01*BC;aerosol', + 'oin_a02 -> 0.09*PM25+-0.09*OC+-0.09*BC;aerosol', + 'oin_a03 -> 0.90*PM25+-0.90*OC+-0.90*BC;aerosol' +/ diff --git a/blueprints/highres_chemistry/iofields.chem b/blueprints/highres_chemistry/iofields.chem new file mode 100644 index 0000000..a459019 --- /dev/null +++ b/blueprints/highres_chemistry/iofields.chem @@ -0,0 +1,20 @@ ++:h:0:alt ++:h:0:gsw ++:h:0:extaer1 ++:h:0:extaer2 ++:h:0:extaer3 ++:h:0:extaer4 ++:h:0:tauaer1 ++:h:0:tauaer2 ++:h:0:tauaer3 ++:h:0:tauaer4 ++:h:0:gaer1 ++:h:0:gaer2 ++:h:0:gaer3 ++:h:0:gaer4 ++:h:0:waer1 ++:h:0:waer2 ++:h:0:waer3 ++:h:0:waer4 ++:h:0:brnch_rto ++:h:0:ccn1 diff --git a/blueprints/highres_chemistry/iofields.met b/blueprints/highres_chemistry/iofields.met new file mode 100644 index 0000000..10455b4 --- /dev/null +++ b/blueprints/highres_chemistry/iofields.met @@ -0,0 +1,4 @@ ++:h:0:alt ++:h:0:gsw ++:h:0:tke ++:h:0:SWDDIF \ No newline at end of file diff --git a/blueprints/highres_chemistry/megan_bio_emiss.inp b/blueprints/highres_chemistry/megan_bio_emiss.inp new file mode 100644 index 0000000..e54891e --- /dev/null +++ b/blueprints/highres_chemistry/megan_bio_emiss.inp @@ -0,0 +1,9 @@ +&control + +domains = __domains__, +start_lai_mnth = 1, +end_lai_mnth = 12, +wrf_dir = '.', +megan_dir = '__MEGANdir__' + +/ diff --git a/blueprints/highres_chemistry/mozart4.inp b/blueprints/highres_chemistry/mozart4.inp new file mode 100644 index 0000000..2d33d08 --- /dev/null +++ b/blueprints/highres_chemistry/mozart4.inp @@ -0,0 +1,86 @@ +&control + +do_ic = __do_ic__, +do_bc = __do_bc__, + +domain = __domain__, + +dir_wrf = './', +dir_moz = './', +fn_moz = 'moz0000.nc', +moz_var_suffix='', + +spc_map = +'o3 -> O3', +'no -> NO', +'no2 -> NO2', +'hno3 -> HNO3', +'ho -> OH', +'ho2 -> HO2', +'h2o2 -> H2O2', +'so2 -> SO2', +'co -> CO', +'hcho -> CH2O', +'c2h4 -> C2H4', +'c2h6 -> C2H6', +'c3h6 -> C3H6', +'c3h8 -> C3H8', +'ald -> CH3CHO', +'acet -> CH3COCH3', +'ch3cooh -> CH3COOH', +'ch3oh -> CH3OH', +'ch3ooh -> CH3OOH', +'pan -> PAN', +'macr -> MACR', +'mvk -> MVK', +'c2h5oh -> C2H5OH', +!'etooh -> C2H5OOH', +'bigene -> BIGENE', +'bigalk -> BIGALK', +'tol -> TOLUENE', +'benzene -> BENZENE', +'xylenes -> XYLENES', +! http://www.atmos-chem-phys.net/12/7215/2012/acp-12-7215-2012.pdf Fig 6 +'apin -> 0.75*MTERP', +'bpin -> 0.25*MTERP', +'isopr -> ISOP', +! +! aerosols +! +'oc_a01->0.1216*pom_a1+0.9886*soa1_a2+0.1216*soa1_a1+0.9886*soa2_a2+ 0.1216*soa2_a1+0.9886*soa3_a2+0.1216*soa3_a1+0.9886*soa4_a2+0.1216*soa4_a1+ 0.9886*soa5_a2+ 0.1216*soa5_a1;1.e9', +'oc_a02->0.7618*pom_a1+0.0114*soa1_a2+0.7618*soa1_a1+0.0114*soa2_a2+ 0.7618*soa2_a1+0.0114*soa3_a2+0.7618*soa3_a1+0.0114*soa4_a2+0.7618*soa4_a1+ 0.0114*soa5_a2+ 0.7618*soa5_a1;1.e9', +'oc_a03->0.1164*pom_a1+0.0000*soa1_a2+0.1164*soa1_a1+0.0000*soa2_a2+ 0.1164*soa2_a1+0.0000*soa3_a2+0.1164*soa3_a1+0.0000*soa4_a2+0.1164*soa4_a1+ 0.0000*soa5_a2+ 0.1164*soa5_a1;1.e9', +'oc_a04->0.0002*pom_a1+0.0000*soa1_a2+0.0002*soa1_a1+0.0000*soa2_a2+ 0.0002*soa2_a1+0.0000*soa3_a2+0.0002*soa3_a1+0.0000*soa4_a2+0.0002*soa4_a1+ 0.0000*soa5_a2+ 0.0002*soa5_a1;1.e9', +'bc_a01->0.1216*bc_a1+0.1216*bc_a4;1.e9', +'bc_a02->0.7618*bc_a1+0.7618*bc_a4;1.e9', +'bc_a03->0.1164*bc_a1+0.1164*bc_a4;1.e9', +'bc_a04->0.0002*bc_a1+0.0002*bc_a4;1.e9', +'so4_a01->0.9886*so4_a2+0.1216*so4_a1+0.0000*so4_a3;1.e9', +'so4_a02->0.0114*so4_a2+0.7618*so4_a1+0.0000*so4_a3;1.e9', +'so4_a03->0.0000*so4_a2+0.1164*so4_a1+0.0995*so4_a3;1.e9', +'so4_a04->0.0000*so4_a2+0.0002*so4_a1+0.9003*so4_a3;1.e9', +'nh4_a01->0.1856*so4_a2+0.0050*so4_a1+0.0000*so4_a3;1.e9', +'nh4_a02->0.0021*so4_a2+0.0930*so4_a1+0.0000*so4_a3;1.e9', +'nh4_a03->0.0000*so4_a2+0.0203*so4_a1+0.0186*so4_a3;1.e9', +'nh4_a04->0.0000*so4_a2+0.0000*so4_a1+0.1690*so4_a3;1.e9', +'no3_a01->0.0000*so4_a2+0.0000*so4_a1+0.0000*so4_a3;1.e9', +'no3_a02->0.0000*so4_a2+0.0000*so4_a1+0.0000*so4_a3;1.e9', +'no3_a03->0.0000*so4_a2+0.0000*so4_a1+0.0000*so4_a3;1.e9', +'no3_a04->0.0000*so4_a2+0.0000*so4_a1+0.0000*so4_a3;1.e9', +'na_a01->0.3889*ncl_a2+0.0479*ncl_a1+0.0000*ncl_a3;1.e9', +'na_a02->0.0045*ncl_a2+0.2997*ncl_a1+0.0000*ncl_a3;1.e9', +'na_a03->0.0000*ncl_a2+0.0458*ncl_a1+0.0391*ncl_a3;1.e9', +'na_a04->0.0000*ncl_a2+0.0000*ncl_a1+0.3542*ncl_a3;1.e9', +'cl_a01->0.5996*ncl_a2+0.0737*ncl_a1+0.0000*ncl_a3;1.e9', +'cl_a02->0.0068*ncl_a2+0.4621*ncl_a1+0.0000*ncl_a3;1.e9', +'cl_a03->0.0000*ncl_a2+0.0709*ncl_a1+0.0604*ncl_a3;1.e9', +'cl_a04->0.0000*ncl_a2+0.0001*ncl_a1+0.5462*ncl_a3;1.e9', +'oin_a01->0.9886*dst_a2+0.1216*dst_a1+0.0000*dst_a3;1.e9', +'oin_a02->0.0114*dst_a2+0.7618*dst_a1+0.0002*dst_a3;1.e9', +'oin_a03->0.0000*dst_a2+0.1164*dst_a1+0.0995*dst_a3;1.e9', +'oin_a04->0.0000*dst_a2+0.0002*dst_a1+0.9003*dst_a3;1.e9', +'num_a01->0.9996*num_a2+0.7135*num_a1+0.0000*num_a3;1.0', +'num_a02->0.0004*num_a2+0.2470*num_a1+0.2118*num_a3;1.0', +'num_a03->0.0000*num_a2+0.0016*num_a1+0.6258*num_a3;1.0', +'num_a04->0.0000*num_a2+0.0000*num_a1+0.3501*num_a3;1.0', +/ diff --git a/blueprints/highres_chemistry/mozbc.inp b/blueprints/highres_chemistry/mozbc.inp new file mode 100644 index 0000000..9709723 --- /dev/null +++ b/blueprints/highres_chemistry/mozbc.inp @@ -0,0 +1,60 @@ +&control + +do_ic = __do_ic__, +do_bc = __do_bc__, + +domain = __domain__, + +dir_wrf = './', +dir_moz = './', +fn_moz = 'moz0000.nc', +moz_var_suffix='', + +def_missing_var = .true. +spc_map = 'o3 -> O3', 'n2o -> N2O', 'no -> NO', +'no2 -> NO2', 'nh3 -> NH3', 'hno3 -> HNO3', 'hno4 -> HO2NO2', 'n2o5 -> N2O5', 'h2o2 -> H2O2', +'ch4 -> CH4', 'co -> CO', 'ch3ooh -> CH3OOH', +'hcho -> CH2O', 'ch3oh -> CH3OH', 'c2h4 -> C2H4', +'ald -> CH3CHO', 'acet -> CH3COCH3', 'mgly -> CH3COCHO', +'pan -> PAN', 'mpan -> MPAN', 'macr -> MACR', +'mvk -> MVK', 'c2h6 -> C2H6', 'c3h6 -> C3H6', 'c3h8 -> C3H8', 'c2h5oh -> C2H5OH', 'c10h16 -> MTERP', +'isopr -> ISOP','acetol -> HYAC', 'mek -> MEK', +'bigene -> BIGENE', 'bigalk -> BIGALK', +'tol -> TOLUENE+BENZENE+XYLENES', 'cres -> CRESOL', 'dms -> DMS', 'so2 -> SO2', +'oc_a01->0.12*pom_a1+0.99*soa1_a2+0.12*soa1_a1+0.99*soa2_a2+0.12*soa2_a1+0.99*soa3_a2+0.12*soa3_a1+0.99*soa4_a2+0.12*soa4_a1+0.99*soa5_a2+0.12*soa5_a1;1.e9', +'oc_a02->0.76*pom_a1+0.01*soa1_a2+0.76*soa1_a1+0.01*soa2_a2+0.76*soa2_a1+0.01*soa3_a2+0.76*soa3_a1+0.01*soa4_a2+0.76*soa4_a1+0.01*soa5_a2+0.76*soa5_a1;1.e9', +'oc_a03->0.12*pom_a1+0.00*soa1_a2+0.12*soa1_a1+0.00*soa2_a2+0.12*soa2_a1+0.00*soa3_a2+0.12*soa3_a1+0.00*soa4_a2+0.12*soa4_a1+0.00*soa5_a2+0.12*soa5_a1;1.e9', +'oc_a04->0.00*pom_a1+0.00*soa1_a2+0.00*soa1_a1+0.00*soa2_a2+0.00*soa2_a1+0.00*soa3_a2+0.00*soa3_a1+0.00*soa4_a2+0.00*soa4_a1+0.00*soa5_a2+0.00*soa5_a1;1.e9', +'bc_a01->0.1216*bc_a1+0.1216*bc_a4;1.e9', +'bc_a02->0.7618*bc_a1+0.7618*bc_a4;1.e9', +'bc_a03->0.1164*bc_a1+0.1164*bc_a4;1.e9', +'bc_a04->0.0002*bc_a1+0.0002*bc_a4;1.e9', +'so4_a01->0.9886*so4_a2+0.1216*so4_a1+0.0000*so4_a3;1.e9', +'so4_a02->0.0114*so4_a2+0.7618*so4_a1+0.0002*so4_a3;1.e9', +'so4_a03->0.0000*so4_a2+0.1216*so4_a1+0.0995*so4_a3;1.e9', +'so4_a04->0.0000*so4_a2+0.0002*so4_a1+0.9003*so4_a3;1.e9', +'nh4_a01->0.1856*so4_a2+0.0050*so4_a1+0.0000*so4_a3;1.e9', +'nh4_a02->0.0021*so4_a2+0.0930*so4_a1+0.0000*so4_a3;1.e9', +'nh4_a03->0.0000*so4_a2+0.0203*so4_a1+0.0186*so4_a3;1.e9', +'nh4_a04->0.0000*so4_a2+0.0000*so4_a1+0.1690*so4_a3;1.e9', +'no3_a01->0.0000*so4_a2+0.0000*so4_a1+0.0000*so4_a3;1.e9', +'no3_a02->0.0000*so4_a2+0.0000*so4_a1+0.0000*so4_a3;1.e9', +'no3_a03->0.0000*so4_a2+0.0000*so4_a1+0.0000*so4_a3;1.e9', +'no3_a04->0.0000*so4_a2+0.0000*so4_a1+0.0000*so4_a3;1.e9', +'na_a01->0.3889*ncl_a2+0.0479*ncl_a1+0.0000*ncl_a3;1.e9', +'na_a02->0.0045*ncl_a2+0.2997*ncl_a1+0.0000*ncl_a3;1.e9', +'na_a03->0.0000*ncl_a2+0.0458*ncl_a1+0.0391*ncl_a3;1.e9', +'na_a04->0.0000*ncl_a2+0.0000*ncl_a1+0.3542*ncl_a3;1.e9', +'cl_a01->0.5995*ncl_a2+0.0737*ncl_a1+0.0000*ncl_a3;1.e9', +'cl_a02->0.0068*ncl_a2+0.4621*ncl_a1+0.0000*ncl_a3;1.e9', +'cl_a03->0.0000*ncl_a2+0.0709*ncl_a1+0.0604*ncl_a3;1.e9', +'cl_a04->0.0000*ncl_a2+0.0001*ncl_a1+0.5462*ncl_a3;1.e9', +'oin_a01->0.9886*dst_a2+0.1216*dst_a1+0.0000*dst_a3;1.e9', +'oin_a02->0.0114*dst_a2+0.7618*dst_a1+0.0002*dst_a3;1.e9', +'oin_a03->0.0000*dst_a2+0.1216*dst_a1+0.0995*dst_a3;1.e9', +'oin_a04->0.0000*dst_a2+0.0002*dst_a1+0.9003*dst_a3;1.e9', +'num_a01->0.9996*num_a2+0.7135*num_a1+0.0000*num_a3;1.0', +'num_a02->0.0004*num_a2+0.2847*num_a1+0.0239*num_a3;1.0', +'num_a03->0.0000*num_a2+0.0016*num_a1+0.6258*num_a3;1.0', +'num_a04->0.0000*num_a2+0.0000*num_a1+0.3501*num_a3;1.0', +/ diff --git a/blueprints/highres_chemistry/namelist.chem b/blueprints/highres_chemistry/namelist.chem new file mode 100644 index 0000000..4ce3023 --- /dev/null +++ b/blueprints/highres_chemistry/namelist.chem @@ -0,0 +1,44 @@ + &chem + kemit = 1, + chem_opt = 202, 202, 202, + bioemdt = 12., 4., 4., + photdt = 12., 4., 4., + chemdt = 12., 4., 4., + io_style_emissions = 2, + emiss_inpt_opt = 102, 102, 102, + emiss_opt = 10, 10, 10, + chem_in_opt = 1, 2, 2, + phot_opt = 4, 4, 4, + gas_drydep_opt = 1, 1, 1, + aer_drydep_opt = 1, 1, 1, + bio_emiss_opt = 3, 3, 3, + gas_bc_opt = 1, 1, 1, + gas_ic_opt = 1, 1, 1, + aer_bc_opt = 1, 1, 1, + aer_ic_opt = 1, 1, 1, + gaschem_onoff = 1, 1, 1, + aerchem_onoff = 1, 1, 1, + wetscav_onoff = 1, 1, 1, + cldchem_onoff = 0, 0, 0, + vertmix_onoff = 1, 1, 1, + chem_conv_tr = 1, 1, 1, + conv_tr_wetscav = 1, 1, 1, + conv_tr_aqchem = 1, 1, 1, + seas_opt = 2, + dust_opt = 3, + dmsemis_opt = 1, + aer_ra_feedback = 1, 1, 1, + aer_op_opt = 1, 1, 1, + ne_area = 500, + opt_pars_out = 1, + have_bcs_chem = .true., + have_bcs_upper = .false., + biomass_burn_opt = 5, 5, 5, + plumerisefire_frq = 30, 30, 30, + scale_fire_emiss = .true., .true., .true., + n2o5_hetchem = 1, + lnox_opt = 1, 1, 1, + diagnostic_chem = 0, 0, 0, + diagnostic_dep = 0, 0, 0, + / + diff --git a/blueprints/highres_chemistry/namelist.wps b/blueprints/highres_chemistry/namelist.wps new file mode 100644 index 0000000..7499aec --- /dev/null +++ b/blueprints/highres_chemistry/namelist.wps @@ -0,0 +1,39 @@ +&share + wrf_core = 'ARW', + max_dom = 3, + start_date = '__startDate__','__startDate__','__startDate__' + end_date = '__endDate__','__startDate__','__startDate__', + interval_seconds = __metIncSec__, + io_form_geogrid = 2, +/ + +&geogrid + parent_id = 1, 1, 2, + parent_grid_ratio = 1, 9, 5, + i_parent_start = 1, 96, 69, + j_parent_start = 1, 75, 74, + e_we = 185, 172, 151, + e_sn = 186, 163, 156, +! geog_data_res = 'modis_fpar+modis_lai+modis_lakes+modis_30s+modis_15s+30s', 'modis_fpar+modis_lai+modis_lakes+modis_30s+modis_15s+30s', +! 'modis_fpar+modis_lai+modis_lakes+modis_30s+modis_15s+30s', + dx = 20000, + dy = 20000, + map_proj = 'lambert', + ref_lat = 50.0, + ref_lon = 7.5, + truelat1 = 30.0, + truelat2 = 60.0, + stand_lon = 7.5, + geog_data_path = '__geogDir__' +/ + +&ungrib + out_format = 'WPS', + prefix = 'FILE', +/ + +&metgrid + fg_name = 'FILE', + constants_name = 'TAVGSFC', + io_form_metgrid = 2, +/ diff --git a/blueprints/highres_chemistry/namelist.wrf b/blueprints/highres_chemistry/namelist.wrf new file mode 100644 index 0000000..e1072e9 --- /dev/null +++ b/blueprints/highres_chemistry/namelist.wrf @@ -0,0 +1,160 @@ + &time_control + start_year = __startYear__, __startYear__, __startYear__, + start_month = __startMonth__, __startMonth__, __startMonth__, + start_day = __startDay__, __startDay__, __startDay__, + start_hour = __startHour__, __startHour__, __startHour__, + start_minute = 00, 00, 00, + start_second = 00, 00, 00, + end_year = __endYear__, __endYear__, __endYear__, + end_month = __endMonth__, __endMonth__, __endMonth__, + end_day = __endDay__, __endDay__, __endDay__, + end_hour = __endHour__, __endHour__, __endHour__, + end_minute = 00, 00, 00, + end_second = 00, 00, 00, + interval_seconds = __metIncSec__, + input_from_file = .true., .true., .true., + history_interval = 60, 60, 60, + frames_per_outfile = 1, 1, 1, + restart = __isRestart__, + restart_interval = __restartInterval__, + override_restart_timers = .true., + io_form_history = 2 + io_form_restart = 2 + io_form_input = 2 + io_form_boundary = 2 + debug_level = 0 + iofields_filename = "iofields" ,"iofields", "iofields", + force_use_old_data = .true., + ! CHEM + / + + &domains + use_adaptive_time_step = .false., + step_to_output_time = .true., + target_cfl = 1.0, 1.0, 1.0, + max_step_increase_pct = 5, 51, 51, + starting_time_step = -1, -1, -1, + max_time_step = 200, 40, 3, + min_time_step = -1, -1, -1, + adaptation_domain = 3, + time_step = 120, + time_step_fract_num = 0, + time_step_fract_den = 1, + max_dom = 3, + e_we = 185, 172, 151, + e_sn = 186, 163, 156, + e_vert = 33, 33, 33, + num_metgrid_levels = 34, + num_metgrid_soil_levels = 4, + dx = 20000, 2222, 400, + dy = 20000, 2222, 400, + grid_id = 1, 2, 3, + parent_id = 0, 1, 2, + i_parent_start = 1, 96, 69, + j_parent_start = 1, 75, 74, + parent_grid_ratio = 1, 9, 5, + parent_time_step_ratio = 1, 9, 5, + feedback = 0, + / + + &physics + mp_physics = 10, 10, 10, + progn = 1, 1, 1, + prec_acc_dt = 60., 60., 60., + ra_lw_physics = 4, 4, 4, + ra_sw_physics = 4, 4, 4, + radt = 16, 4, 4, + aer_opt = 1, + sf_sfclay_physics = 5, 5, 5, ! Ravans suggestion + sf_surface_physics = 2, 2, 2, ! NOAH + sf_surface_mosaic = 0, + sf_lake_physics = 1, 1, 1, + sf_urban_physics = 1, 1, 1, + bl_pbl_physics = 5, 5, 5, ! MYNN 2.5 + bl_mynn_cloudpdf = 1, + bl_mynn_cloudmix = 1, + scalar_pblmix = 1, + tracer_pblmix = 1, +! grav_settling = 0, 2, 2, ! settling of fog / cloud droplets + bldt = 0, 0, 0, + cu_physics = 5, 5, 0, ! Grell 3D + cudt = 1, + cugd_avedx = 1, ! set to 3 for 4km run, 1 for 36km + ishallow = 0, + iz0tlnd = 1, ! thermal roughness length over land determined by vegetation type + isfflx = 1, + ifsnow = 1, + icloud = 1, + icloud_bl = 1, + num_soil_layers = 4, + cu_rad_feedback = .true., .true.,.false., + cu_diag = 1, 1, 0, + slope_rad = 0, 0, 1, + topo_shading = 0, 0, 0, + num_land_cat = 21, + / + + &fdda + grid_fdda = 1, 0, 0, + gfdda_inname = "wrffdda_d", + gfdda_end_h = 312, 0, 0, + gfdda_interval_m = 60, 0, 0, + if_no_pbl_nudging_uv = 1, 1, 1, + if_no_pbl_nudging_t = 1, 1, 1, + if_no_pbl_nudging_q = 1, 1, 1, + if_zfac_uv = 0, 0, 0, + k_zfac_uv = 2, + if_zfac_t = 0, 0, 0, + k_zfac_t = 2, + if_zfac_q = 0, 0, 0, + k_zfac_q = 2, + guv = 0.0006, 0.0006, 0.0006, + gt = 0.0006, 0.0006, 0.0006, + gq = 0.0006, 0.0006, 0.0006, + if_ramping = 0, + dtramp_min = 360, + io_form_gfdda = 2, + / + + &dynamics + rk_ord = 3, + time_step_sound = 4, 4, 4, + w_damping = 1, + diff_opt = 1, 1, 2, + km_opt = 4, 4, 4, + diff_6th_opt = 0, 0, 0, + diff_6th_factor = 0.12, 0.12, 0.75, + epssm = 0.1, 0.1, 0.5, + sfs_opt = 0, 0, 0, + base_temp = 290. + damp_opt = 3, + zdamp = 5000., 5000., 5000., + dampcoef = 0.15, 0.15, 0.15, + khdif = 0, 0, 0, + kvdif = 0, 0, 0, + mix_isotropic = 0, 0, 1, + non_hydrostatic = .true., + moist_adv_opt = 2, 2, 4, + scalar_adv_opt = 2, 2, 4, + tke_adv_opt = 2, 2, 4, + do_avgflx_em = 1, 1, 1, + hybrid_opt = 0, + use_theta_m = 1, + / + + &bdy_control + spec_bdy_width = 5, + spec_zone = 1, + relax_zone = 4, + specified = .true., .false., .false., + nested = .false., .true., .true., + / + + &grib2 + / + + &namelist_quilt + nio_tasks_per_group = 0, + nio_groups = 1 + / + diff --git a/blueprints/highres_chemistry/namelist_timecontrol_chem_patch.wrf b/blueprints/highres_chemistry/namelist_timecontrol_chem_patch.wrf new file mode 100644 index 0000000..70e3851 --- /dev/null +++ b/blueprints/highres_chemistry/namelist_timecontrol_chem_patch.wrf @@ -0,0 +1,12 @@ + io_form_auxinput5 = 2, + auxinput5_inname = 'wrfchemi_d_', + auxinput5_interval_h = 1, 1, + frames_per_auxinput5 = 1, 1, + io_form_auxinput6 = 2, + auxinput6_inname = 'wrfbiochemi_d' + auxinput6_interval_h = 2400, 2400, + io_form_auxinput7 = 2, + auxinput7_inname = 'wrffirechemi_d_', + auxinput7_interval_m = 60, 60, + frames_per_auxinput7 = 1, 1, + \ No newline at end of file diff --git a/blueprints/highres_chemistry/pp/plotting/crontab b/blueprints/highres_chemistry/pp/plotting/crontab new file mode 100644 index 0000000..e6d46be --- /dev/null +++ b/blueprints/highres_chemistry/pp/plotting/crontab @@ -0,0 +1,34 @@ +# Edit this file to introduce tasks to be run by cron. +# +# Each task to run has to be defined through a single line +# indicating with different fields when the task will be run +# and what command to run for the task +# +# To define the time you can provide concrete values for +# minute (m), hour (h), day of month (dom), month (mon), +# and day of week (dow) or use '*' in these fields (for 'any').# +# Notice that tasks will be started based on the cron's system +# daemon's notion of time and timezones. +# +# Output of the crontab jobs (including errors) is sent through +# email to the user the crontab file belongs to (unless redirected). +# +# For example, you can run a backup of all your user accounts +# at 5 a.m every week with: +# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ +# +# For more information see the manual pages of crontab(5) and cron(8) +# +# m h dom mon dow command +HOME=/home/m/met-wrf-chem +MAILTO=christoph.knote@physik.uni-muenchen.de + +# wrf meteogram +52 * * * * /usr/bin/sbatch /alcc/gpfs2/home/u/knotechr/wrfotron/blueprints/operational_chemistry/pp/plotting/meteograms/run.sh + +# wrf maps +00 07 * * * /usr/bin/sbatch /alcc/gpfs2/home/u/knotechr/wrfotron/blueprints/operational_chemistry/pp/plotting/maps/run.sh + +# wrf geotiffs +17 6,12,18 * * * /usr/bin/sbatch /alcc/gpfs2/home/u/knotechr/wrfotron/blueprints/operational_chemistry/pp/plotting/geotiffs/run.sh + diff --git a/blueprints/highres_chemistry/pp/plotting/geotiffs/run.sh b/blueprints/highres_chemistry/pp/plotting/geotiffs/run.sh new file mode 100755 index 0000000..dbffc99 --- /dev/null +++ b/blueprints/highres_chemistry/pp/plotting/geotiffs/run.sh @@ -0,0 +1,37 @@ +#!/bin/bash -l +#SBATCH --partition=alcc1 +#SBATCH -o /alcc/gpfs2/scratch/mbees/knotechr/WRF/postprocessing/geotiffs.%j.%N.out +#SBATCH -J geotiffs +#SBATCH --ntasks=1 +#SBATCH --mem=5G +#SBATCH --mail-type=FAIL +#SBATCH --mail-user=christoph.knote@med.uni-augsburg.de +#SBATCH --time=00:30:00 + +module load gnu gdal geos proj + +scriptPath=/alcc/gpfs2/home/u/knotechr/wrfotron/tools/nc_2_geotiff.py +wrfDataPathPattern="/alcc/gpfs2/scratch/mbees/knotechr/archive/WRF/operational_chemistry/wrfout___domain___%Y-%m-%d_%H:%M:%S" +firstDateToProcess=`date --date="2 days ago" "+%Y-%m-%d"` +intervalHours=1 +rangeHours=120 +plotDirPattern="/alcc/gpfs2/scratch/mbees/knotechr/plots/WRF/operational_chemistry/__domain__/geotiffs/%Y/%m/%d" + +for domain in d01 d02 +do + plotPathPattern="${plotDirPattern/__domain__/${domain}}/{species:s}_%Y-%m-%d_%H-%M.tif" + + for anHour in $(seq 0 ${intervalHours} ${rangeHours}) + do + aWRFDataPath=$(date -u --date="${firstDateToProcess} 0 UTC +${anHour} hours" "+${wrfDataPathPattern/__domain__/${domain}}") + + aPlotDir=$(date -u --date="${firstDateToProcess} 0 UTC +${anHour} hours" "+${plotDirPattern/__domain__/${domain}}") + aPlotPath=$(date -u --date="${firstDateToProcess} 0 UTC +${anHour} hours" "+${plotPathPattern}") + + if [ -f ${aWRFDataPath} ] + then + mkdir -p $aPlotDir + python3 $scriptPath -s "o3,O3" -s "no2,NO2" -s "co,CO" -s "PM2_5_DRY,PM2.5" -s "PM10,PM10" "${aWRFDataPath}" "${aPlotPath}" + fi + done +done diff --git a/blueprints/highres_chemistry/pp/plotting/maps/plots.py b/blueprints/highres_chemistry/pp/plotting/maps/plots.py new file mode 100644 index 0000000..b44e3a1 --- /dev/null +++ b/blueprints/highres_chemistry/pp/plotting/maps/plots.py @@ -0,0 +1,197 @@ + +from wrf import to_np, getvar, smooth2d, latlon_coords, interplevel, get_cartopy +import numpy as np +import matplotlib +from matplotlib import pyplot as plt +import cartopy.feature as cfeature +import cartopy.crs as ccrs +from matplotlib.colors import LinearSegmentedColormap, ListedColormap + + +from tools import total_prec, cartopy_lim_buffered, make_fig_and_ax, add_title_and_description + +def slp_map(t, nc, prec_prev, output_path, plevels=np.arange(950, 1050, 5)): +# + slp = getvar(nc, "slp") + mid_clouds = getvar(nc, "mid_cloudfrac") + prec = total_prec(nc, prec_prev) +# + # Smooth the sea level pressure since it tends to be noisy near the + # mountains + smooth_slp = smooth2d(slp, 5, cenweight=4) + # Get the latitude and longitude points + lats, lons = latlon_coords(slp) +# + # Get the WRF projection (CRS) object + crs = get_cartopy(slp) +# + # Create a figure + fig, ax, ax_cbarv, ax_cbarh = make_fig_and_ax(plt, crs, add_horiz_cbar=True) +# + # Draw the contours and filled contours + cmap = LinearSegmentedColormap.from_list("", ["white", "silver"]) + cmap2 = matplotlib.cm.viridis_r +# + con = ax.contourf(to_np(lons), to_np(lats), to_np(mid_clouds), + levels=[1/10, 1/4, 1/2, 3/4, 1], cmap=cmap, zorder=2, + transform=ccrs.PlateCarree()) + con2 = ax.contourf(to_np(lons), to_np(lats), to_np(prec), + levels=[0.5, 1, 2, 5, 10, 25, 50], cmap=cmap2, zorder=2, extend='max', + transform=ccrs.PlateCarree()) +# + linewidths = np.ones(plevels.shape) + linewidths[np.where(plevels == 1015)[0]] = 3 + cs = ax.contour(to_np(lons), to_np(lats), to_np(smooth_slp), levels=plevels, + linewidths=linewidths, colors="black", zorder=4, + transform=ccrs.PlateCarree()) + plt.clabel(cs, fmt='%1.0f', fontsize=8) +# + ax.coastlines(linewidth=0.3, zorder=2) + countries = cfeature.NaturalEarthFeature(category='cultural', name='admin_0_countries', scale='50m') + ax.add_feature(countries, facecolor='none', edgecolor='black', linewidth=0.3, zorder=3) +# + cbar = plt.colorbar(con, cax=ax_cbarv, ticks=[1/10, 1/4, 1/2, 3/4, 1]) + cbar2 = plt.colorbar(con2, cax=ax_cbarh, orientation="horizontal") +# + try: + cbar.ax.set_yticklabels(["1/10", "1/4", "1/2", "3/4", "1"], fontsize=10) + except: + print("Plotting tick labels failed") +# + ax.set_xlim(cartopy_lim_buffered(slp, "x")) + ax.set_ylim(cartopy_lim_buffered(slp, "y")) + + add_title_and_description(nc, "Sea Level Pressure [hPa], Mid-Level Cloud Cover, Total prec. in the last hour [mm] \n" + "WRF {init:s} +{fcsthour:d}", ax) +# + plt.savefig(output_path, bbox_inches='tight', pad_inches=0.1) + plt.close() + + return prec + + +def plevel_map(t, nc, output_path, plevel, phi_contour_intervals=np.arange(400, 800, 8)): +# + def interp_var(nc, variablename, p, plevel): + var = getvar(nc, variablename) + return interplevel(var, p, plevel) +# + p = getvar(nc, "p", units='hPa') +# + geop = interp_var(nc, "geopt", p, plevel) + geop = smooth2d(geop, 5, cenweight=4) +# + temp = interp_var(nc, "tc", p, plevel) +# + u, v = interp_var(nc, "uvmet", p, plevel) +# + # Get the latitude and longitude points + lats, lons = latlon_coords(temp) +# + # Get the WRF projection (CRS) object + crs = get_cartopy(temp) +# + # Create a figure + fig, ax, ax_cbarv, ax_cbarh = make_fig_and_ax(plt, crs) +# + # Temperature + lab = np.array([-46, -41, -36, -31, -26, -21, -16, -11, -6, -1, 4]) + con = ax.contourf(to_np(lons), to_np(lats), temp, levels=lab, + transform=ccrs.PlateCarree(), + cmap='viridis', zorder=0, extend='both') +# + # Geopotential height + linewidths = np.ones(phi_contour_intervals.shape) + linewidths[np.where(phi_contour_intervals == 552)[0]] = 3 + cs = ax.contour(to_np(lons), to_np(lats), geop/98.0, levels=phi_contour_intervals, + linewidths=linewidths, colors="black", + zorder=1, + transform=ccrs.PlateCarree()) + plt.clabel(cs, fmt='%1.0f', fontsize=10) +# +# + ax.coastlines(linewidth=0.3, zorder=2) + countries = cfeature.NaturalEarthFeature(category='cultural', name='admin_0_countries', scale='50m') + ax.add_feature(countries, facecolor='none', edgecolor='black', linewidth=0.3, zorder=3) +# + nb = 20 + brsb = ax.barbs(to_np(lons[::nb,::nb]), to_np(lats[::nb,::nb]), + to_np(u[::nb,::nb]), to_np(v[::nb,::nb]), + transform=ccrs.PlateCarree(), + length=4.5, zorder=4, linewidth=0.3) +# + ax.set_xlim(cartopy_lim_buffered(temp, "x")) + ax.set_ylim(cartopy_lim_buffered(temp, "y")) +# + cbar = plt.colorbar(con, cax=ax_cbarv) + add_title_and_description(nc, "{:d}".format(plevel) + " hPa level Geopotential [gpdm], Temperature [°C] and Wind \n" + "WRF {init:s} +{fcsthour:d}", ax) +# + plt.savefig(output_path, bbox_inches='tight', pad_inches=0.1) + plt.close() + +# https://stackoverflow.com/questions/37327308/add-alpha-to-an-existing-matplotlib-colormap +def alphafy_colormap(name, mina=0.0, maxa=0.8): + # Choose colormap + cmap = matplotlib.cm.get_cmap(name) + + # Get the colormap colors + my_cmap = cmap(np.arange(cmap.N)) + + # Set alpha + my_cmap[:,-1] = np.linspace(mina, maxa, cmap.N) + + # Create new colormap + return ListedColormap(my_cmap) + + +def sfc_map(t, nc, get_var_fun, levels, ticks, label, bg_function, output_path, cmap="YlOrRd", extend='both'): +# + var = get_var_fun(nc) + u, v = getvar(nc, 'uvmet10') +# + # Get the latitude and longitude points + lats, lons = latlon_coords(u) +# + # Get the WRF projection (CRS) object + crs = get_cartopy(u) +# + # Create a figure + fig, ax, ax_cbarv, ax_cbarh = make_fig_and_ax(plt, crs) +# + # Draw the contours and filled contours + lab = np.array(levels) + con = ax.contourf(to_np(lons), to_np(lats), var, levels=lab, + transform=ccrs.PlateCarree(), + cmap=alphafy_colormap(cmap), zorder=1, extend=extend) +# + linewidths = np.ones(lab.shape)/2 + linewidths[np.where(lab == 0)[0]] = 1 + cs = ax.contour(to_np(lons), to_np(lats), var, levels=lab[::2], + linewidths=linewidths, colors="black", alpha=0.5, + zorder=2, + transform=ccrs.PlateCarree()) + plt.clabel(cs, fmt='%1.0f', fontsize=8) +# + # Add background (needs to happen after map is already created...) + bg_function(ax, crs) +# + nb = 10 + brsb = ax.barbs(to_np(lons[::nb,::nb]), to_np(lats[::nb,::nb]), + to_np(u[::nb,::nb]), to_np(v[::nb,::nb]), + transform=ccrs.PlateCarree(), + length=4.5, zorder=4, linewidth=0.5) + + xlim = cartopy_lim_buffered(u, "x") + ylim = cartopy_lim_buffered(u, "y") +# + ax.set_xlim(xlim) + ax.set_ylim(ylim) +# + cbar = plt.colorbar(con, cax=ax_cbarv) + cbar.set_ticks(ticks) +# + add_title_and_description(nc, label + " and Wind (10m) \n" + "WRF {init:s} +{fcsthour:d}", ax) +# + plt.savefig(output_path, bbox_inches='tight', pad_inches=0.1) + plt.close() diff --git a/blueprints/highres_chemistry/pp/plotting/maps/pois.py b/blueprints/highres_chemistry/pp/plotting/maps/pois.py new file mode 100644 index 0000000..6824452 --- /dev/null +++ b/blueprints/highres_chemistry/pp/plotting/maps/pois.py @@ -0,0 +1,268 @@ +southern_germany = [ { 'name':'Munich', 'lon':11.582, 'lat':48.135}, + { 'name':'Salzburg', 'lon':13.0550, 'lat':47.8095}, + { 'name':'Augsburg', 'lon':10.8978, 'lat':48.3705}, + { 'name':'Passau', 'lon':13.4319, 'lat':48.5667}, + { 'name':'Rosenheim', 'lon':12.1181, 'lat':47.8571}, + { 'name':'Ingolstadt', 'lon':11.4258, 'lat':48.7665}, + { 'name':'Garmisch-Partenkirchen', 'lon':11.0948, 'lat':47.4919}, + { 'name':'Ulm', 'lon':9.9876, 'lat':48.4011}, + { 'name':'Stuttgart', 'lon':9.1829, 'lat':48.7758}, + { 'name':'Konstanz', 'lon':9.1737, 'lat':47.6780}, + { 'name':'Zürich', 'lon':8.5417, 'lat':47.3769}, + { 'name':'Nürnberg', 'lon':11.0767, 'lat':49.4521}, + { 'name':'Regensburg', 'lon':12.101624, 'lat':49.013432}, + { 'name':'Innsbruck', 'lon':11.388397, 'lat':47.258320} ] + + +capitals = [ { 'name':'Sukhumi', 'lat':43.001525, 'lon':41.023415}, + { 'name':'Kabul', 'lat':34.575503, 'lon':69.240073}, + { 'name':'Mariehamn', 'lat':60.1, 'lon':19.933333}, + { 'name':'Tirana', 'lat':41.327546, 'lon':19.818698}, + { 'name':'Algiers', 'lat':36.752887, 'lon':3.042048}, + { 'name':'Pago Pago', 'lat':-14.275632, 'lon':-170.702036}, + { 'name':'Andorra la Vella', 'lat':42.506317, 'lon':1.521835}, + { 'name':'Luanda', 'lat':-8.839988, 'lon':13.289437}, + { 'name':'The Valley', 'lat':18.214813, 'lon':-63.057441}, + { 'name':'South Pole', 'lat':-90, 'lon':0}, + { 'name':'St. John\'s', 'lat':17.12741, 'lon':-61.846772}, + { 'name':'Buenos Aires', 'lat':-34.603684, 'lon':-58.381559}, + { 'name':'Yerevan', 'lat':40.179186, 'lon':44.499103}, + { 'name':'Oranjestad', 'lat':12.509204, 'lon':-70.008631}, + { 'name':'Canberra', 'lat':-35.282, 'lon':149.128684}, + { 'name':'Vienna', 'lat':48.208174, 'lon':16.373819}, + { 'name':'Baku', 'lat':40.409262, 'lon':49.867092}, + { 'name':'Nassau', 'lat':25.047984, 'lon':-77.355413}, + { 'name':'Manama', 'lat':26.228516, 'lon':50.58605}, + { 'name':'Dhaka', 'lat':23.810332, 'lon':90.412518}, + { 'name':'Bridgetown', 'lat':13.113222, 'lon':-59.598809}, + { 'name':'Minsk', 'lat':53.90454, 'lon':27.561524}, + { 'name':'Brussels', 'lat':50.85034, 'lon':4.35171}, + { 'name':'Belmopan', 'lat':17.251011, 'lon':-88.75902}, + { 'name':'Porto-Novo', 'lat':6.496857, 'lon':2.628852}, + { 'name':'Hamilton', 'lat':32.294816, 'lon':-64.781375}, + { 'name':'Thimphu', 'lat':27.472792, 'lon':89.639286}, + { 'name':'La Paz', 'lat':-16.489689, 'lon':-68.119294}, + { 'name':'Sarajevo', 'lat':43.856259, 'lon':18.413076}, + { 'name':'Gaborone', 'lat':-24.628208, 'lon':25.923147}, + { 'name':'Bouvet Island', 'lat':-54.43, 'lon':3.38}, + { 'name':'Brasília', 'lat':-15.794229, 'lon':-47.882166}, + { 'name':'Camp Justice', 'lat':21.3419, 'lon':55.4778}, + { 'name':'Road Town', 'lat':18.428612, 'lon':-64.618466}, + { 'name':'Bandar Seri Begawan', 'lat':4.903052, 'lon':114.939821}, + { 'name':'Sofia', 'lat':42.697708, 'lon':23.321868}, + { 'name':'Ouagadougou', 'lat':12.371428, 'lon':-1.51966}, + { 'name':'Bujumbura', 'lat':-3.361378, 'lon':29.359878}, + { 'name':'Phnom Penh', 'lat':11.544873, 'lon':104.892167}, + { 'name':'Yaoundé', 'lat':3.848033, 'lon':11.502075}, + { 'name':'Ottawa', 'lat':45.42153, 'lon':-75.697193}, + { 'name':'Praia', 'lat':14.93305, 'lon':-23.513327}, + { 'name':'George Town', 'lat':19.286932, 'lon':-81.367439}, + { 'name':'Bangui', 'lat':4.394674, 'lon':18.55819}, + { 'name':'N\'Djamena', 'lat':12.134846, 'lon':15.055742}, + { 'name':'Santiago', 'lat':-33.44889, 'lon':-70.669265}, + { 'name':'Beijing', 'lat':39.904211, 'lon':116.407395}, + { 'name':'Flying Fish Cove', 'lat':-10.420686, 'lon':105.679379}, + { 'name':'West Island', 'lat':-12.188834, 'lon':96.829316}, + { 'name':'Bogotá', 'lat':4.710989, 'lon':-74.072092}, + { 'name':'Moroni', 'lat':-11.717216, 'lon':43.247315}, + { 'name':'Kinshasa', 'lat':-4.441931, 'lon':15.266293}, + { 'name':'Brazzaville', 'lat':-4.26336, 'lon':15.242885}, + { 'name':'Avarua', 'lat':-21.212901, 'lon':-159.782306}, + { 'name':'San José', 'lat':9.928069, 'lon':-84.090725}, + { 'name':'Yamoussoukro', 'lat':6.827623, 'lon':-5.289343}, + { 'name':'Zagreb', 'lat':45.815011, 'lon':15.981919}, + { 'name':'Havana', 'lat':23.05407, 'lon':-82.345189}, + { 'name':'Willemstad', 'lat':12.122422, 'lon':-68.882423}, + { 'name':'Nicosia', 'lat':35.185566, 'lon':33.382276}, + { 'name':'Prague', 'lat':50.075538, 'lon':14.4378}, + { 'name':'Copenhagen', 'lat':55.676097, 'lon':12.568337}, + { 'name':'Djibouti', 'lat':11.572077, 'lon':43.145647}, + { 'name':'Roseau', 'lat':15.309168, 'lon':-61.379355}, + { 'name':'Santo Domingo', 'lat':18.486058, 'lon':-69.931212}, + { 'name':'Quito', 'lat':-0.180653, 'lon':-78.467838}, + { 'name':'Cairo', 'lat':30.04442, 'lon':31.235712}, + { 'name':'San Salvador', 'lat':13.69294, 'lon':-89.218191}, + { 'name':'Malabo', 'lat':3.750412, 'lon':8.737104}, + { 'name':'Asmara', 'lat':15.322877, 'lon':38.925052}, + { 'name':'Tallinn', 'lat':59.436961, 'lon':24.753575}, + { 'name':'Addis Ababa', 'lat':8.980603, 'lon':38.757761}, + { 'name':'Stanley', 'lat':-51.697713, 'lon':-57.851663}, + { 'name':'Tórshavn', 'lat':62.007864, 'lon':-6.790982}, + { 'name':'Suva', 'lat':-18.124809, 'lon':178.450079}, + { 'name':'Helsinki', 'lat':60.173324, 'lon':24.941025}, + { 'name':'Paris', 'lat':48.856614, 'lon':2.352222}, + { 'name':'Cayenne', 'lat':4.92242, 'lon':-52.313453}, + { 'name':'Papeete', 'lat':-17.551625, 'lon':-149.558476}, + { 'name':'Saint-Pierre ', 'lat':-21.3419, 'lon':55.4778}, + { 'name':'Libreville', 'lat':0.416198, 'lon':9.467268}, + { 'name':'Banjul', 'lat':13.454876, 'lon':-16.579032}, + { 'name':'Tbilisi', 'lat':41.715138, 'lon':44.827096}, + { 'name':'Berlin', 'lat':52.520007, 'lon':13.404954}, + { 'name':'Accra', 'lat':5.603717, 'lon':-0.186964}, + { 'name':'Gibraltar', 'lat':36.140773, 'lon':-5.353599}, + { 'name':'Athens', 'lat':37.983917, 'lon':23.72936}, + { 'name':'Nuuk', 'lat':64.18141, 'lon':-51.694138}, + { 'name':'St. George\'s', 'lat':12.056098, 'lon':-61.7488}, + { 'name':'Basse-Terre', 'lat':16.014453, 'lon':-61.706411}, + { 'name':'Hagåtña', 'lat':13.470891, 'lon':144.751278}, + { 'name':'Guatemala City', 'lat':14.634915, 'lon':-90.506882}, + { 'name':'St. Peter Port', 'lat':49.455443, 'lon':-2.536871}, + { 'name':'Conakry', 'lat':9.641185, 'lon':-13.578401}, + { 'name':'Bissau', 'lat':11.881655, 'lon':-15.617794}, + { 'name':'Georgetown', 'lat':6.801279, 'lon':-58.155125}, + { 'name':'Port-au-Prince', 'lat':18.594395, 'lon':-72.307433}, + { 'name':'Tegucigalpa', 'lat':14.072275, 'lon':-87.192136}, + { 'name':'Hong Kong', 'lat':22.396428, 'lon':114.109497}, + { 'name':'Budapest', 'lat':47.497912, 'lon':19.040235}, + { 'name':'Reykjavík', 'lat':64.126521, 'lon':-21.817439}, + { 'name':'New Delhi', 'lat':28.613939, 'lon':77.209021}, + { 'name':'Jakarta', 'lat':-6.208763, 'lon':106.845599}, + { 'name':'Tehran', 'lat':35.689198, 'lon':51.388974}, + { 'name':'Baghdad', 'lat':33.312806, 'lon':44.361488}, + { 'name':'Dublin', 'lat':53.349805, 'lon':-6.26031}, + { 'name':'Douglas', 'lat':54.152337, 'lon':-4.486123}, + { 'name':'Tel Aviv', 'lat':32.0853, 'lon':34.781768}, + { 'name':'Rome', 'lat':41.902784, 'lon':12.496366}, + { 'name':'Kingston', 'lat':18.042327, 'lon':-76.802893}, + { 'name':'Tokyo', 'lat':35.709026, 'lon':139.731992}, + { 'name':'St. Helier', 'lat':49.186823, 'lon':-2.106568}, + { 'name':'Amman', 'lat':31.956578, 'lon':35.945695}, + { 'name':'Astana', 'lat':51.160523, 'lon':71.470356}, + { 'name':'Nairobi', 'lat':-1.292066, 'lon':36.821946}, + { 'name':'Tarawa Atoll', 'lat':1.451817, 'lon':172.971662}, + { 'name':'Pristina', 'lat':42.662914, 'lon':21.165503}, + { 'name':'Kuwait City', 'lat':29.375859, 'lon':47.977405}, + { 'name':'Bishkek', 'lat':42.874621, 'lon':74.569762}, + { 'name':'Vientiane', 'lat':17.975706, 'lon':102.633104}, + { 'name':'Riga', 'lat':56.949649, 'lon':24.105186}, + { 'name':'Beirut', 'lat':33.888629, 'lon':35.495479}, + { 'name':'Maseru', 'lat':-29.363219, 'lon':27.51436}, + { 'name':'Monrovia', 'lat':6.290743, 'lon':-10.760524}, + { 'name':'Tripoli', 'lat':32.887209, 'lon':13.191338}, + { 'name':'Vaduz', 'lat':47.14103, 'lon':9.520928}, + { 'name':'Vilnius', 'lat':54.687156, 'lon':25.279651}, + { 'name':'Luxembourg', 'lat':49.611621, 'lon':6.131935}, + { 'name':'Macau', 'lat':22.166667, 'lon':113.55}, + { 'name':'Skopje', 'lat':41.997346, 'lon':21.427996}, + { 'name':'Antananarivo', 'lat':-18.87919, 'lon':47.507905}, + { 'name':'Lilongwe', 'lat':-13.962612, 'lon':33.774119}, + { 'name':'Kuala Lumpur', 'lat':3.139003, 'lon':101.686855}, + { 'name':'Malé', 'lat':4.175496, 'lon':73.509347}, + { 'name':'Bamako', 'lat':12.639232, 'lon':-8.002889}, + { 'name':'Valletta', 'lat':35.898909, 'lon':14.514553}, + { 'name':'Majuro', 'lat':7.116421, 'lon':171.185774}, + { 'name':'Fort-de-France', 'lat':14.616065, 'lon':-61.05878}, + { 'name':'Nouakchott', 'lat':18.07353, 'lon':-15.958237}, + { 'name':'Port Louis', 'lat':-20.166896, 'lon':57.502332}, + { 'name':'Mamoudzou', 'lat':-12.780949, 'lon':45.227872}, + { 'name':'Mexico City', 'lat':19.432608, 'lon':-99.133208}, + { 'name':'Palikir', 'lat':6.914712, 'lon':158.161027}, + { 'name':'Chisinau', 'lat':47.010453, 'lon':28.86381}, + { 'name':'Monaco', 'lat':43.737411, 'lon':7.420816}, + { 'name':'Ulaanbaatar', 'lat':47.886399, 'lon':106.905744}, + { 'name':'Podgorica', 'lat':42.43042, 'lon':19.259364}, + { 'name':'Plymouth', 'lat':16.706523, 'lon':-62.215738}, + { 'name':'Rabat', 'lat':33.97159, 'lon':-6.849813}, + { 'name':'Maputo', 'lat':-25.891968, 'lon':32.605135}, + { 'name':'Naypyidaw', 'lat':19.763306, 'lon':96.07851}, + { 'name':'Stepanakert', 'lat':39.826385, 'lon':46.763595}, + { 'name':'Windhoek', 'lat':-22.560881, 'lon':17.065755}, + { 'name':'Yaren', 'lat':-0.546686, 'lon':166.921091}, + { 'name':'Kathmandu', 'lat':27.717245, 'lon':85.323961}, + { 'name':'Amsterdam', 'lat':52.370216, 'lon':4.895168}, + { 'name':'Willemstad ', 'lat':12.1091242, 'lon':-68.9316546}, + { 'name':'Nouméa', 'lat':-22.255823, 'lon':166.450524}, + { 'name':'Wellington', 'lat':-41.28646, 'lon':174.776236}, + { 'name':'Managua', 'lat':12.114993, 'lon':-86.236174}, + { 'name':'Niamey', 'lat':13.511596, 'lon':2.125385}, + { 'name':'Abuja', 'lat':9.076479, 'lon':7.398574}, + { 'name':'Alofi', 'lat':-19.055371, 'lon':-169.917871}, + { 'name':'Kingston', 'lat':-29.056394, 'lon':167.959588}, + { 'name':'Pyongyang', 'lat':39.039219, 'lon':125.762524}, + { 'name':'Nicosia', 'lat':35.185566, 'lon':33.382276}, + { 'name':'Saipan', 'lat':15.177801, 'lon':145.750967}, + { 'name':'Oslo', 'lat':59.913869, 'lon':10.752245}, + { 'name':'Muscat', 'lat':23.58589, 'lon':58.405923}, + { 'name':'Islamabad', 'lat':33.729388, 'lon':73.093146}, + { 'name':'Ngerulmud', 'lat':7.500384, 'lon':134.624289}, + { 'name':'Ramallah', 'lat':31.9073509, 'lon':35.5354719}, + { 'name':'Panama City', 'lat':9.101179, 'lon':-79.402864}, + { 'name':'Port Moresby', 'lat':-9.4438, 'lon':147.180267}, + { 'name':'Asuncion', 'lat':-25.26374, 'lon':-57.575926}, + { 'name':'Lima', 'lat':-12.046374, 'lon':-77.042793}, + { 'name':'Manila', 'lat':14.599512, 'lon':120.98422}, + { 'name':'Adamstown', 'lat':-25.06629, 'lon':-130.100464}, + { 'name':'Warsaw', 'lat':52.229676, 'lon':21.012229}, + { 'name':'Lisbon', 'lat':38.722252, 'lon':-9.139337}, + { 'name':'San Juan', 'lat':18.466334, 'lon':-66.105722}, + { 'name':'Doha', 'lat':25.285447, 'lon':51.53104}, + { 'name':'Saint-Denis', 'lat':-20.882057, 'lon':55.450675}, + { 'name':'Bucharest', 'lat':44.426767, 'lon':26.102538}, + { 'name':'Moscow', 'lat':55.755826, 'lon':37.6173}, + { 'name':'Kigali', 'lat':-1.957875, 'lon':30.112735}, + { 'name':'St. Pierre', 'lat':46.775846, 'lon':-56.180636}, + { 'name':'Kingstown', 'lat':13.160025, 'lon':-61.224816}, + { 'name':'Apia', 'lat':-13.850696, 'lon':-171.751355}, + { 'name':'San Marino', 'lat':43.935591, 'lon':12.447281}, + { 'name':'São Tomé', 'lat':0.330192, 'lon':6.733343}, + { 'name':'Riyadh', 'lat':24.749403, 'lon':46.902838}, + { 'name':'Dakar', 'lat':14.764504, 'lon':-17.366029}, + { 'name':'Belgrade', 'lat':44.786568, 'lon':20.448922}, + { 'name':'Victoria', 'lat':-4.619143, 'lon':55.451315}, + { 'name':'Freetown', 'lat':8.465677, 'lon':-13.231722}, + { 'name':'Singapore', 'lat':1.280095, 'lon':103.850949}, + { 'name':'Bratislava', 'lat':48.145892, 'lon':17.107137}, + { 'name':'Ljubljana', 'lat':46.056947, 'lon':14.505751}, + { 'name':'Honiara', 'lat':-9.445638, 'lon':159.9729}, + { 'name':'Mogadishu', 'lat':2.046934, 'lon':45.318162}, + { 'name':'Pretoria', 'lat':-25.747868, 'lon':28.229271}, + { 'name':'King Edward Point', 'lat':-54.28325, 'lon':-36.493735}, + { 'name':'Seoul', 'lat':37.566535, 'lon':126.977969}, + { 'name':'Tskhinvali', 'lat':42.22146, 'lon':43.964405}, + { 'name':'Juba', 'lat':4.859363, 'lon':31.57125}, + { 'name':'Madrid', 'lat':40.416775, 'lon':-3.70379}, + { 'name':'Sri Jayawardenepura Kotte', 'lat':6.89407, 'lon':79.902478}, + { 'name':'Gustavia', 'lat':17.896435, 'lon':-62.852201}, + { 'name':'Basseterre', 'lat':17.302606, 'lon':-62.717692}, + { 'name':'Castries', 'lat':14.010109, 'lon':-60.987469}, + { 'name':'Marigot', 'lat':18.067519, 'lon':-63.082466}, + { 'name':'Khartoum', 'lat':15.500654, 'lon':32.559899}, + { 'name':'Paramaribo', 'lat':5.852036, 'lon':-55.203828}, + { 'name':'Longyearbyen ', 'lat':78.062, 'lon':22.055}, + { 'name':'Mbabane', 'lat':-26.305448, 'lon':31.136672}, + { 'name':'Stockholm', 'lat':59.329323, 'lon':18.068581}, + { 'name':'Bern', 'lat':46.947974, 'lon':7.447447}, + { 'name':'Damascus', 'lat':33.513807, 'lon':36.276528}, + { 'name':'Taipei', 'lat':25.032969, 'lon':121.565418}, + { 'name':'Dushanbe', 'lat':38.559772, 'lon':68.787038}, + { 'name':'Dodoma', 'lat':-6.162959, 'lon':35.751607}, + { 'name':'Bangkok', 'lat':13.756331, 'lon':100.501765}, + { 'name':'Dili', 'lat':-8.556856, 'lon':125.560314}, + { 'name':'Lomé', 'lat':6.172497, 'lon':1.231362}, + { 'name':'Nukunonu', 'lat':-9.2005, 'lon':-171.848}, + { 'name':'Nuku\'alofa', 'lat':-21.139342, 'lon':-175.204947}, + { 'name':'Tiraspol', 'lat':46.848185, 'lon':29.596805}, + { 'name':'Port of Spain', 'lat':10.654901, 'lon':-61.501926}, + { 'name':'Edinburgh of the Seven Seas', 'lat':-37.068042, 'lon':-12.311315}, + { 'name':'Tunis', 'lat':36.806495, 'lon':10.181532}, + { 'name':'Ankara', 'lat':39.933364, 'lon':32.859742}, + { 'name':'Ashgabat', 'lat':37.960077, 'lon':58.326063}, + { 'name':'Cockburn Town', 'lat':21.467458, 'lon':-71.13891}, + { 'name':'Funafuti', 'lat':-8.520066, 'lon':179.198128}, + { 'name':'Charlotte Amalie', 'lat':18.3419, 'lon':-64.930701}, + { 'name':'Kampala', 'lat':0.347596, 'lon':32.58252}, + { 'name':'Kiev', 'lat':50.4501, 'lon':30.5234}, + { 'name':'Abu Dhabi', 'lat':24.299174, 'lon':54.697277}, + { 'name':'London', 'lat':51.507351, 'lon':-0.127758}, + { 'name':'Washington', 'lat':38.907192, 'lon':-77.036871}, + { 'name':'Montevideo', 'lat':-34.901113, 'lon':-56.164531}, + { 'name':'Tashkent', 'lat':41.299496, 'lon':69.240073}, + { 'name':'Port Vila', 'lat':-17.733251, 'lon':168.327325}, + { 'name':'Vatican City', 'lat':41.902179, 'lon':12.453601}, + { 'name':'Caracas', 'lat':10.480594, 'lon':-66.903606}, + { 'name':'Hanoi', 'lat':21.027764, 'lon':105.83416}, + { 'name':'Mata-Utu', 'lat':-13.282509, 'lon':-176.176447}, + { 'name':'El Aaiún', 'lat':27.125287, 'lon':-13.1625}, + { 'name':'Sana\'a', 'lat':15.369445, 'lon':44.191007}, + { 'name':'Lusaka', 'lat':-15.387526, 'lon':28.322817}, + { 'name':'Harare', 'lat':-17.825166, 'lon':31.03351} ] \ No newline at end of file diff --git a/blueprints/highres_chemistry/pp/plotting/maps/run.py b/blueprints/highres_chemistry/pp/plotting/maps/run.py new file mode 100644 index 0000000..c9820b9 --- /dev/null +++ b/blueprints/highres_chemistry/pp/plotting/maps/run.py @@ -0,0 +1,110 @@ +import datetime + +from argparse import ArgumentParser, ArgumentTypeError + +def valid_date(s): + try: + return datetime.datetime.strptime(s, "%Y-%m-%d") + except ValueError: + raise ArgumentTypeError("Not a valid date: '{0}'.".format(s)) + +parser = ArgumentParser() +parser.add_argument('wrf_data_fpath_pattern', type=str, help='WRF input data path pattern (including strptime pattern for date and {domain:02d} for domain (01, 02, ...))') +parser.add_argument('date', type=valid_date, help='Date to process (YYYY-mm-dd)') +parser.add_argument('interval_hours', type=int, help='Time interval in hours for plotting') +parser.add_argument('fcst_time_hours', type=int, help='Forecast time in hours') +parser.add_argument('plot_fpath_pattern', type=str, help='Plot output path pattern (including strptime pattern for date, {plot:s} for plot identifier (e.g., 500hPa...) and {domain:02d} for domain (01, 02)') + +args = parser.parse_args() + +from plots import plevel_map, sfc_map, slp_map +import pois +import netCDF4 +from wrf import getvar +import numpy as np +import cartopy.feature as cfeature +import contextily +import rasterio + +times = [ args.date + datetime.timedelta(hours=t) for t in range(0, args.fcst_time_hours, args.interval_hours) ] + +# for calculating delta precip +prec_prev = None + +def bg_function(ax, wrfcrs): + wrfcrs_proj4 = wrfcrs.proj4_init + wrfcrs_proj4 = wrfcrs_proj4.replace('+nadgrids=@null', '') + rasteriocrs = rasterio.crs.CRS.from_proj4(wrfcrs_proj4) + contextily.add_basemap(ax, source=contextily.providers.Stamen.TonerLite, crs=rasteriocrs, zorder=0) + +for t in times: + input_path_d01 = t.strftime(args.wrf_data_fpath_pattern).format(domain=1) + input_path_d02 = t.strftime(args.wrf_data_fpath_pattern).format(domain=2) + + try: + nc_d01 = netCDF4.Dataset(input_path_d01) + nc_d02 = netCDF4.Dataset(input_path_d02) + except Exception as e: + print("Not all data available for step {:s}: {:s}".format(t.strftime("%Y-%m-%d %H"), str(e))) + continue + + print(t) + + # 500 hPa Europe domain +# output_path = t.strftime(args.plot_fpath_pattern).format(plot='500hPa', domain=1) +# plevel_map(t, nc_d01, output_path, 500) + + # Surface Europe domain + # temperature +# sfc_map(t, nc_d01, lambda nc: getvar(nc, 'T2') - 273.15, +# levels=[-25, -20, -15, -12.5, -10, -7.5, -5, -2.5, 0, 2.5, 5, 7.5, 10, 12.5, 15, 17.5, 20, 22.5, 25, 27.5, 30, 32.5, 35], +# ticks=[-25, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35], +# label="Temperature (2m) [°C]", pois=pois.capitals, +# output_path=t.strftime(args.plot_fpath_pattern).format(plot='T', domain=1)) + + # Ozone + for domain, nc_d, poilist in zip([1,2],[nc_d01, nc_d02], [pois.capitals, pois.southern_germany]): + sfc_map(t, nc_d, lambda nc: getvar(nc, 'o3')[0,:,:] * 1e3, + levels=range(0, 160, 10), + ticks=range(0, 150, 20), + label="Ozone (ground level) [ppbv]", bg_function=bg_function, + output_path=t.strftime(args.plot_fpath_pattern).format(plot='O3', domain=domain), + extend='max') + # NO2 + sfc_map(t, nc_d, lambda nc: getvar(nc, 'no2')[0,:,:] * 1e3, + levels=range(0, 110, 10), + ticks=range(0, 110, 20), + label="NO$_2$ (ground level) [ppbv]", bg_function=bg_function, + output_path=t.strftime(args.plot_fpath_pattern).format(plot='NO2', domain=domain), + extend='max') + # PM + def get_pm(nc, bins=[ 1, 2, 3 ]) : + pmspecs = [ "so4", "no3", "smpa", "smpbb", "glysoa_sfc", "biog1_c", "biog1_o", "cl", "co3", "nh4", "na", "cl", "oin", "oc", "bc", "water" ] # ug kg-1 + alt = getvar(nc, "ALT")[0,:,:] # inverse density m3 kg-1 + all = [ getvar(nc, spec + "_a{:02d}".format(bin))[0,:,:] / alt for spec in pmspecs for bin in bins ] + return np.sum(all, axis=0) + +# sfc_map(t, nc_d, lambda nc: get_pm(nc, bins=[1]), +# levels=range(0, 130, 10), +# ticks=range(0, 130, 20), +# label="UFP (ground level) [$\mu$g m$^{{-3}}$]", bg_function=bg_function, +# output_path=t.strftime(args.plot_fpath_pattern).format(plot='UFP', domain=domain), +# extend='max') + sfc_map(t, nc_d, lambda nc: get_pm(nc, bins=[1,2,3]), + levels=range(0, 130, 10), + ticks=range(0, 130, 20), + label="PM$_{{2.5}}$ (ground level) [$\mu$g m$^{{-3}}$]", bg_function=bg_function, + output_path=t.strftime(args.plot_fpath_pattern).format(plot='PM2_5', domain=domain), + extend='max') + sfc_map(t, nc_d, lambda nc: get_pm(nc, bins=[1,2,3,4]), + levels=range(0, 130, 10), + ticks=range(0, 130, 20), + label="PM$_{{10}}$ (ground level) [$\mu$g m$^{{-3}}$]", bg_function=bg_function, + output_path=t.strftime(args.plot_fpath_pattern).format(plot='PM10', domain=domain), + extend='max') + + # SLP Europe +# output_path = t.strftime(args.plot_fpath_pattern).format(plot='SLP', domain=1) +# prec_prev = slp_map(t, nc_d01, prec_prev, output_path) + + nc_d01.close() diff --git a/blueprints/highres_chemistry/pp/plotting/maps/run.sh b/blueprints/highres_chemistry/pp/plotting/maps/run.sh new file mode 100644 index 0000000..248dc5b --- /dev/null +++ b/blueprints/highres_chemistry/pp/plotting/maps/run.sh @@ -0,0 +1,50 @@ +#!/bin/bash -l +#SBATCH --partition=alcc1,alcc3,epyc +#SBATCH -o /alcc/gpfs2/scratch/mbees/knotechr/WRF/postprocessing/maps/%j.%N.out +#SBATCH -J maps +#SBATCH --ntasks=1 +#SBATCH --mem=10G +#SBATCH --mail-type=FAIL +#SBATCH --mail-user=christoph.knote@med.uni-augsburg.de +#SBATCH --time=01:00:00 + +module load gnu geos ffmpeg + +export MPLBACKEND="agg" + +scriptPath=/alcc/gpfs2/home/u/knotechr/wrfotron/blueprints/operational_chemistry/pp/plotting/maps/run.py +wrfDataPathPattern="/alcc/gpfs2/scratch/mbees/knotechr/archive/WRF/operational_chemistry/wrfout_d{domain:02d}_%Y-%m-%d_%H:%M:%S" +tmpWorkDir="/alcc/gpfs2/scratch/mbees/knotechr/WRF/postprocessing/maps/movie" +plotPathPattern="${tmpWorkDir}/{plot:s}_d{domain:02d}_%Y%m%d%H.png" +webDir="/alcc/gpfs2/scratch/mbees/knotechr/plots/WRF/operational_chemistry/__domain__/maps/%Y/%m" +dateToProcess="today" +fcstIntervalHours=1 +fcstRangeHours=72 +nSecondsWait=2 + +mkdir -p ${tmpWorkDir} +rm -f ${tmpWorkDir}/* + +python3 $scriptPath ${wrfDataPathPattern} $(date -u --date="${dateToProcess}" "+%Y-%m-%d") ${fcstIntervalHours} ${fcstRangeHours} ${plotPathPattern} + +frameRate=3 + +for domain in d01 d02 +do + # get all plot type names ("500hpa_d01, o3_d02", ...) + typs=$(ls -1 ${tmpWorkDir}/*${domain}*.png | sed -e "s|${tmpWorkDir}/||" | sed -E -e "s/_[0-9]+.png//g" | uniq) + + for typ in ${typs} + do + echo "" + echo $typ $domain + outFilePath=$(date --date="${dateToProcess} 0 UTC" "+${webDir/__domain__/${domain}}/${typ/_${domain}/}_%Y%m%d.mp4") + mkdir -p $(dirname $outFilePath) + rm -f ${outFilePath} + # see here for why we need vf argument https://stackoverflow.com/questions/20847674/ffmpeg-libx264-height-not-divisible-by-2 + cat ${tmpWorkDir}/${typ}_*.png | ffmpeg -y -r ${frameRate} -f image2pipe -i - -vcodec libx264 -crf 18 -preset slow -pix_fmt yuv420p -vf "pad=ceil(iw/2)*2:ceil(ih/2)*2, tpad=stop_mode=clone:stop_duration=2, fps=fps=${frameRate}" ${outFilePath} + done +done + +rm -f ${tmpWorkDir}/* + diff --git a/blueprints/highres_chemistry/pp/plotting/maps/tools.py b/blueprints/highres_chemistry/pp/plotting/maps/tools.py new file mode 100644 index 0000000..b2a7fdf --- /dev/null +++ b/blueprints/highres_chemistry/pp/plotting/maps/tools.py @@ -0,0 +1,68 @@ +from wrf import cartopy_xlim, cartopy_ylim +import matplotlib.gridspec as gridspec + +from matplotlib.offsetbox import AnchoredText + +import datetime +import numpy as np + +t2datetime = lambda x: datetime.datetime.strptime(x, '%Y-%m-%d_%H:%M:%S') + +def wrf_time(nc): + first = ''.join([x.decode('utf-8') for x in nc['Times'][0]]) + return t2datetime(first) + +def total_prec(nc, prec_p): + prec_vars = ['RAINC', 'RAINSH', 'RAINNC', 'SNOWNC', 'GRAUPELNC', 'HAILNC'] + start = t2datetime(nc.START_DATE) + prec = np.sum([nc[var][0, :, :] for var in prec_vars], axis=0) +# + if type(prec_p) == type(None): + prec_p = prec +# + if start == wrf_time(nc): + return prec + else: + return prec-prec_p + +# buffer 0.1 -> 10% border around the edges +def cartopy_lim_buffered(field, direction, buffer=0.1): + if direction == "x": + lims = cartopy_xlim(field) + elif direction == "y": + lims = cartopy_ylim(field) + else: + raise Exception("Direction not understood!") + dlim = lims[1] - lims[0] + lims[0] += 0.5 * buffer * dlim + lims[1] -= 0.5 * buffer * dlim + return lims + +def make_fig_and_ax(plt, crs, add_horiz_cbar=False): + fig = plt.figure(figsize=(7,7)) +# + gs = gridspec.GridSpec(2, 2, width_ratios=[20,1], height_ratios=[20,1], wspace=0.05, hspace=0.05) +# + ax = fig.add_subplot(gs[0,0], projection=crs) + ax_cbarv = fig.add_subplot(gs[0,1]) + ax_cbarh = None + if add_horiz_cbar: + ax_cbarh = fig.add_subplot(gs[1,0]) + return fig, ax, ax_cbarv, ax_cbarh + +def add_title_and_description(nc, title, ax): + ''' + title: including {init:s} for timestamp of run initialization, and {fcsthour:d} for forecast hour + ''' + fcstHour = int((wrf_time(nc) - t2datetime(nc.START_DATE)).total_seconds()/3600.) +# + ax.set_title(title.format(init=t2datetime(nc.START_DATE).strftime("%d.%m.%Y %H:%M UTC"), + fcsthour=fcstHour), fontdict={ 'fontsize':8, 'horizontalalignment': 'left'}, loc='left') +# + texttime = AnchoredText(wrf_time(nc).strftime("%H UTC %a"), + loc=2, pad=0.2, prop={'size': 10}, frameon=True) + ax.add_artist(texttime) +# + textcopyright = AnchoredText("$\copyright$ MBEES, Faculty of Medicine, University of Augsburg", + loc=4, pad=0.1, prop={'size': 6, 'color':'white'}, frameon=False) + ax.add_artist(textcopyright) diff --git a/blueprints/highres_chemistry/pp/plotting/meteograms/plot.py b/blueprints/highres_chemistry/pp/plotting/meteograms/plot.py new file mode 100755 index 0000000..278d373 --- /dev/null +++ b/blueprints/highres_chemistry/pp/plotting/meteograms/plot.py @@ -0,0 +1,757 @@ +#!/usr/bin/env python + +from wrf import getvar, ll_to_xy, to_np, extract_times +import numpy as np + + +def fT2m(D, xmin, xmax, ymin, ymax): + return D["T2"][0, xmin:xmax, ymin:ymax] - 273.15 + + +def fTd2m(D, xmin, xmax, ymin, ymax): + return getvar(D, "td2")[xmin:xmax, ymin:ymax] + + +def wind10m(D, lat, lon): + """Returns the wind speed and the wind direction at 10 m""" + try: + x, y = ll_to_xy(D, lat, lon) + w_speed, w_dir = getvar(D, "uvmet10_wspd_wdir") + return w_speed.values[int(x), int(y)], w_dir.values[int(x), int(y)] + except: + return np.NaN, np.NaN + + +def wind_uv(D, lat, lon): + """Returns the u and v wind components at 10 m""" + try: + x, y = ll_to_xy(D, lat, lon) + w_u, w_v = getvar(D, "uvmet10") + return w_u.values[int(x), int(y)], w_v.values[int(x), int(y)] + except: + return np.NaN, np.NaN + + +def Mslp(D, lat, lon): + try: + """Returns the mean sea level pressure""" + x, y = ll_to_xy(D, lat, lon) + slp = getvar(D, "slp") + return slp.values[int(x), int(y)] + except: + return np.NaN + + +def cin_cape(D, lat, lon): + try: + """Returns the 2D max cin and cape""" + x, y = ll_to_xy(D, lat, lon) + var = getvar(D, "cape_2d") + return (var[1].values[int(x), int(y)], var[0].values[int(x), int(y)]) + except: + return np.NaN, np.NaN + + +def vert_wind(D, lat, lon): + try: + from wrf import vertcross, CoordPair + + x, y = ll_to_xy(D, lat, lon) + xy = CoordPair(x=x, y=y) + u, v = getvar(D, "uvmet") + p = getvar(D, "p", units="hPa") + levels = np.arange(400, 1060, 60) + u_vert = vertcross( + u, + p, + levels=levels, + start_point=xy, + end_point=CoordPair(x=x + 1, y=y + 1), + meta=False, + missing=np.NaN, + ) + v_vert = vertcross( + v, + p, + levels=levels, + start_point=xy, + end_point=CoordPair(x=x + 1, y=y + 1), + meta=False, + missing=np.NaN, + ) + return list(u_vert[:, 0]), list(v_vert[:, 0]) + except: + levels = np.arange(400, 1060, 60) + return [np.NaN for x in range(len(levels))], [ + np.NaN for x in range(len(levels)) + ] + + +def vert_T(D, lat, lon): + try: + from wrf import vertcross, CoordPair + + x, y = ll_to_xy(D, lat, lon) + xy = CoordPair(x=x, y=y) + T = getvar(D, "tc") + p = getvar(D, "p", units="hPa") + levels = np.arange(400, 1060, 60) + T_vert = to_np( + vertcross( + T, + p, + levels=levels, + start_point=xy, + end_point=CoordPair(x=x + 1, y=y + 1), + meta=False, + missing=np.NaN, + ) + ) + return T_vert[:, 0][:] + except: + levels = np.arange(400, 1060, 60) + return [np.NaN for x in range(len(levels))], [ + np.NaN for x in range(len(levels)) + ] + + +def fcfrac(D, lat, lon): + from wrf import interplevel, CoordPair + + levels = np.arange(400, 1030, 30) + try: + x, y = ll_to_xy(D, lat, lon) + p = getvar(D, "p", units="hPa") + cf = interplevel(D["CLDFRA"], p, levels) + return cf.values[:, int(x), int(y)] + + except: + return [np.NaN for x in range(len(levels))] + + +def ftot_accum_rain_2d(D, xmin, xmax, ymin, ymax): + try: + return np.sum( + [ + D[var][0, xmin:xmax, ymin:ymax] + for var in [ + "RAINC", + "RAINSH", + "RAINNC", + "SNOWNC", + "GRAUPELNC", + "HAILNC", + ] + ], + axis=0, + ) + except: + return np.mgrid[xmin:xmax, ymin:ymax][0] * np.NaN + + +def fdrain(DS, xmin, xmax, ymin, ymax): + tot_accum_rain = np.array( + [ftot_accum_rain_2d(D, xmin, xmax, ymin, ymax) for D in DS] + ) + + # weird construct to remove negative rain rates + # because timeseries have restarts in them + # i.e. we search for spots where rainrate accumulation starts + + starts = np.array([t2datetime(D.START_DATE) for D in DS]) + dt = np.array([x.total_seconds() for x in (starts[1:] - starts[:-1])]) + drain = np.zeros_like(tot_accum_rain) + drain[1:] = tot_accum_rain[1:] - tot_accum_rain[:-1] + drain[1:] = np.where( + dt > 0, tot_accum_rain[1:].T, (tot_accum_rain[1:] - tot_accum_rain[:-1]).T + ).T + return drain + + +def ftot_accum_snow_2d(D, xmin, xmax, ymin, ymax): + try: + return np.sum( + [D[var][0, xmin:xmax, ymin:ymax] for var in ["SNOWNC", "GRAUPELNC"]], axis=0 + ) + except: + return np.mgrid[xmin:xmax, ymin:ymax][0] * np.NaN + + +def fdsnow(DS, xmin, xmax, ymin, ymax): + tot_accum_snow = np.array( + [ftot_accum_snow_2d(D, xmin, xmax, ymin, ymax) for D in DS] + ) + + starts = np.array([t2datetime(D.START_DATE) for D in DS]) + dt = np.array([x.total_seconds() for x in (starts[1:] - starts[:-1])]) + drain = np.zeros_like(tot_accum_snow) + drain[1:] = tot_accum_snow[1:] - tot_accum_snow[:-1] + drain[1:] = np.where( + dt > 0, tot_accum_snow[1:].T, (tot_accum_snow[1:] - tot_accum_snow[:-1]).T + ).T + return drain + + +def t2datetime(x): + import datetime + + return datetime.datetime.strptime(x, "%Y-%m-%d_%H:%M:%S") + + +def ftimes(D): + """Convert first WRF timestamp description into datetimes string""" + return t2datetime("".join([x.decode("utf-8") for x in D["Times"][0]])) + + +def corresponding_pixels(D, location_lon, location_lat, deg_round_loc): + import numpy as np + + xlon = D["XLONG"][0] + xlat = D["XLAT"][0] + + around_loc = (np.abs(xlat - location_lat) < deg_round_loc) & ( + np.abs(xlon - location_lon) < deg_round_loc + ) + + xmin, xmax = np.nonzero(around_loc)[0][[0, -1]] + ymin, ymax = np.nonzero(around_loc)[1][[0, -1]] + + xlon = xlon[xmin:xmax, ymin:ymax] + xlat = xlat[xmin:xmax, ymin:ymax] + + # print("Using {} pixels for plot".format(np.size(xlon))) + return (xmin, xmax), (ymin, ymax), xlon, xlat + + +def haversine(lat1, lon1, lat2, lon2): + """ + Compute distance between lat lon points + """ + import numpy as np + + R = 6378137 # Earth radius + dLat = np.deg2rad(lat2) - np.deg2rad(lat1) + dLon = np.deg2rad(lon2) - np.deg2rad(lon1) + a = np.sin(dLat / 2) * np.sin(dLat / 2) + np.cos(np.deg2rad(lat1)) * np.cos( + np.deg2rad(lat2) + ) * np.sin(dLon / 2.0) * np.sin(dLon / 2.0) + c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1.0 - a)) + return R * c + + +def compute_average_resolution(D, xmin, xmax, ymin, ymax): + import numpy as np + + lon = D["XLONG"][0] + lat = D["XLAT"][0] + + dy_avg = np.average( + haversine( + lat[xmin:xmax, ymin : ymax - 1], + lon[xmin:xmax, ymin : ymax - 1], + lat[xmin:xmax, ymin + 1 : ymax], + lon[xmin:xmax, ymin + 1 : ymax], + ) + ) + dx_avg = np.average( + haversine( + lat[xmin : xmax - 1, ymin:ymax], + lon[xmin : xmax - 1, ymin:ymax], + lat[xmin + 1 : xmax, ymin:ymax], + lon[xmin + 1 : xmax, ymin:ymax], + ) + ) + + return (dy_avg + dx_avg) / 2 + + +def datetime_to_float(d): + import datetime + + return d.timestamp() + + +# -------------------------------------------------------------------------------- + + +def plot_var( + filenames, outfile, deg_round_loc=0.2, location_lon=10.8978, location_lat=48.3705 +): + """ + Plot meteogram for given location (location_lon,location_lat) + Script uses all pixels around location in a radius of ''deg_round_loc'' + to attain model spread. + """ + import matplotlib as mpl + + mpl.use("Agg") + import matplotlib.pyplot as plt + import numpy as np + import netCDF4 + import datetime + + from matplotlib.colors import LinearSegmentedColormap + from matplotlib.font_manager import FontProperties + + def draw_vlines(ax, labels=False): + for t in time[1:]: + if t.hour == 0.0 and t.minute == 0.0: + ax.vlines( + datetime_to_float(t), + *ax.get_ylim(), + color="black", + linestyle=":", + lw=1 + ) + for t in time: + if t.hour == 1.0 and t.minute == 0.0: + if labels: + ycoo = ax.get_ylim() + ax.text( + datetime_to_float(t + datetime.timedelta(hours=11)), + -ycoo[1] / 3, + t.strftime("%A %-d %b"), + ha="center", + ) + + # -----------------reading input files:------------------------- + + def get_only_valid_file(f): + try: + nc = netCDF4.Dataset(f) + ts = extract_times(nc, None) + if len(ts) == 0: + nc = None + except: + nc = None + return nc + + DS = [get_only_valid_file(f) for f in sorted(filenames)] + DS = [x for x in DS if not x is None] + + (xmin, xmax), (ymin, ymax), xlon, xlat = corresponding_pixels( + DS[0], location_lon, location_lat, deg_round_loc + ) + + time = np.array([ftimes(D) for D in DS]) + + extent = (xmin, xmax, ymin, ymax) + + # -----------------reading data from input files----------------------- + T2m = [fT2m(D, *extent) for D in DS] + Tavg, Tmin, Tmax = [x(T2m, axis=(1, 2)) for x in [np.average, np.min, np.max]] + + Td2m = [fTd2m(D, *extent) for D in DS] + Tdavg, Tdmin, Tdmax = [x(Td2m, axis=(1, 2)) for x in [np.average, np.min, np.max]] + + wind_speed = [wind10m(D, location_lat, location_lon)[0] for D in DS] + wind_u = [wind_uv(D, location_lat, location_lon)[0] for D in DS] + wind_v = [wind_uv(D, location_lat, location_lon)[1] for D in DS] + mslp = [Mslp(D, location_lat, location_lon) for D in DS] + + drain = fdrain(DS, *extent) + ravg = np.average(drain, axis=(1, 2)) + + dsnow = fdsnow(DS, *extent) + snow = np.average(dsnow, axis=(1, 2)) + + conv = [cin_cape(D, location_lat, location_lon) for D in DS] + cape = [x[1] for x in conv] + cin = [x[0] for x in conv] + + w_vert = [vert_wind(D, location_lat, location_lon) for D in DS] + u_vert = [x[0] for x in w_vert] + v_vert = [x[1] for x in w_vert] + + T_vert = [vert_T(D, location_lat, location_lon) for D in DS] + + cf_vert = [list(fcfrac(D, location_lat, location_lon)) for D in DS] + + # figure settings: + fig = plt.figure(figsize=(8.27 * 1.25, 11.69 * 1.25), num=1) + plt.clf() + + mplotkw = {"ls": "-", "marker": "."} + + ax = plt.subplot2grid((8, 20), (0, 19), rowspan=3) + ax0 = plt.subplot2grid((8, 20), (0, 0), colspan=19, rowspan=3) + ax1 = plt.subplot2grid((8, 20), (3, 0), colspan=19, rowspan=2) + ax2 = plt.subplot2grid((8, 20), (5, 0), colspan=19) + ax3 = plt.subplot2grid((8, 20), (6, 0), colspan=19) + ax4 = plt.subplot2grid((8, 20), (7, 0), colspan=19) + + # for the xticks: + hours = np.array(list(map(lambda x: x.hour, time))) + ind = list(np.where(hours % 6 == 0)[0]) + + # 0.--------------vertical plot------------------------ + + ax0.grid(axis="y") + + # (vertical) cloud fraction + levels = np.arange(400, 1030, 30) + cf_vert = np.matrix(cf_vert).transpose() + cmap = LinearSegmentedColormap.from_list("", ["steelblue", "white"]) + time_mod = list(map(lambda x: datetime_to_float(x), time)) + cs = ax0.contourf( + time_mod, levels, cf_vert, levels=[x / 8 for x in range(10)], cmap=cmap + ) + ax0.contourf(time_mod, levels, cf_vert, levels=[x / 8 for x in range(9)], cmap=cmap) + cbar = fig.colorbar(cs, cax=ax, orientation="vertical") + cbar.set_ticks([x / 8 for x in range(0, 9)]) + try: + cbar.ax.set_yticklabels(["{}/8".format(x) for x in range(0, 9)]) + except: + print("Plotting tick labels failed") + ax.set_ylabel("cloud cover") + + # (vertical) temperature contours + levels = np.arange(400, 1060, 60) + T_vert = np.matrix(T_vert).transpose() + cs = ax0.contour(time_mod, levels, T_vert, cmap="plasma") + ax0.clabel(cs, fmt="%1.0f", fontsize=10) + + # (vertical) wind barbs: + for i, j in enumerate(time_mod[:]): + if i % (len(time) // 24) == 0: + for k, l in enumerate(levels): + ax0.barbs( + j, + l, + u_vert[i][k], + v_vert[i][k], + length=5, + pivot="middle", + linewidth=0.5, + ) + + ax0.set_yticks(np.arange(400, 1050, 50)) + ax0.set_ylim(980, 400) + ax0.set_xlim( + datetime_to_float(time[0] - datetime.timedelta(hours=3 * len(time) / (24 * 3))), + datetime_to_float( + time[-1] + datetime.timedelta(hours=3 * len(time) / (24 * 3)) + ), + ) + ax0.set_ylabel("pressure [hPa]") + try: + ax0.set_xticklabels([], minor=False) + ax0.set_xticklabels([], minor=True) + except: + print("Plotting tick labels failed") + ax0.set_xticks([time_mod[i] for i in ind]) + draw_vlines(ax0) + + # 1.--------------temperature plot------------------------ + + ax1.fill_between(time_mod, Tdmin, Tdmax, alpha=0.3, color="lightblue") + ax1.fill_between(time_mod, Tmin, Tmax, alpha=0.3, color="grey") + ax1.grid(axis="y") + ax1.plot(time_mod, Tdavg, color="blue", label="Td(2m)", **mplotkw) + ax1.plot(time_mod, Tavg, color="black", label="T(2m)", **mplotkw) + + actual_day = time[0].day + actual_month = time[0].month + day = 0 + + # min and max temperature for the current day + for i, j in enumerate(time): + + if time[i - 1].month != actual_month and (i != 0): + day += 1 + actual_month = time[i - 1].month + + elif ( + (day != time[i - 1].day - actual_day) + and (i != 0) + and (time[i - 1].day - actual_day >= 0) + ): + day += 1 + + try: + if Tavg[i] == min(Tavg[day * 24 : (day + 1) * 24]): + ax1.text( + datetime_to_float(time[i]), + Tavg[i] + 2, + str(np.round(Tavg[i], 1)), + color="blue", + ha="center", + ) + elif Tavg[i] == max(Tavg[day * 24 : (day + 1) * 24]): + ax1.text( + datetime_to_float(time[i]), + Tavg[i] + 1.5, + str(np.round(Tavg[i], 1)), + color="red", + ha="center", + ) + except: + pass + + ax1.set_ylabel(r"temp. [$^\circ$C]") + ax1.legend(loc="best", fontsize="small", ncol=3) + ax1.set_ylim(min(min(Tmin), min(Tdmin)) - 3, max(max(Tmax), max(Tdmax)) + 7.5) + ax1.set_xlim( + datetime_to_float(time[0] - datetime.timedelta(hours=3 * len(time) / (24 * 3))), + datetime_to_float( + time[-1] + datetime.timedelta(hours=3 * len(time) / (24 * 3)) + ), + ) + try: + ax1.xaxis.set_ticklabels([], minor=True) + ax1.xaxis.set_ticklabels([], minor=False) + except: + print("Plotting tick labels failed") + ax1.set_xticks([time_mod[i] for i in ind]) + draw_vlines(ax1) + + # 2.--------------10m wind plot------------------------ + + ax2.grid(axis="y") + ax2.plot(time_mod, wind_speed, color="black", **mplotkw) + ax2.set_xlim( + datetime_to_float(time[0] - datetime.timedelta(hours=3 * len(time) / (24 * 3))), + datetime_to_float( + time[-1] + datetime.timedelta(hours=3 * len(time) / (24 * 3)) + ), + ) + for i, j in enumerate(time_mod): + if i % (len(time) // 24) == 0: + ax2.text( + j, + wind_speed[i] - 4.9, + str(int(round(wind_speed[i]))), + color="black", + ha="center", + ) + ax2.barbs( + j, + max(15, max(wind_speed) + 5), + wind_u[i], + wind_v[i], + length=5, + pivot="middle", + linewidth=0.5, + ) + ax2.set_ylabel(r"10 m ws [ms$^{-1}$]") + ax2.set_ylim(-4.9, max(20, max(wind_speed) + 8)) + try: + ax2.xaxis.set_ticklabels([], minor=True) + ax2.xaxis.set_ticklabels([], minor=False) + except: + print("Plotting tick labels failed") + ax2.set_xticks([time_mod[i] for i in ind]) + draw_vlines(ax2) + + # 3.--------------mslp plot------------------------ + + ax3.grid(axis="y") + ax3.plot(time_mod, mslp, color="red", **mplotkw) + ax3.set_ylabel(r"MSLP [hPa]") + try: + ax3.xaxis.set_ticklabels([], minor=True) + ax3.xaxis.set_ticklabels([], minor=False) + except: + print("Plotting tick labels failed") + ax3.set_xlim( + datetime_to_float(time[0] - datetime.timedelta(hours=3 * len(time) / (24 * 3))), + datetime_to_float( + time[-1] + datetime.timedelta(hours=3 * len(time) / (24 * 3)) + ), + ) + ax3.set_ylim(min(mslp) - 2, max(mslp) + 2) + ax3.ticklabel_format(useOffset=False, axis="y") + ax3.set_xticks([time_mod[i] for i in ind]) + draw_vlines(ax3) + + # 4.--------------prec. plot------------------------ + # rain: + + ax4.grid(axis="y") + ax4.bar(time_mod, ravg, color="c", label="tot. prec.", width=3600) + ax4.set_ylabel(r"total prec. [mm/h]") + ax4.set_ylim(0, max(max(ravg), 3) + 1) + ax4.set_xlim( + datetime_to_float(time[0] - datetime.timedelta(hours=3 * len(time) / (24 * 3))), + datetime_to_float( + time[-1] + datetime.timedelta(hours=3 * len(time) / (24 * 3)) + ), + ) + ax4.set_xticks([time_mod[i] for i in ind], minor=True) + ax4.set_yticks( + [x for x in range(0, max(int(max(ravg)), 3) + 2, max(int(max(ravg)), 3) // 3)] + ) + try: + ax4.xaxis.set_ticklabels( + ["00", "06", "12", "18"] * (len(time) // 24), minor=True + ) + except: + print("Plotting tick labels failed") + draw_vlines(ax4, labels=True) + + # print a red (magenta) thunderstorm symbol if cape > 500 (> 1500) Jkg-1 and cin < 100 Jkg-1 + prop = FontProperties() + prop.set_file("/usr/share/fonts/truetype/freefont/FreeMono.ttf") + for i, j in enumerate(time_mod): + if (cin[i] < 100 or np.isnan(cin[i])) and (cape[i] >= 1500): + ax4.text( + datetime_to_float(time[i]), + ax4.get_ylim()[1] * 0.62, + "\u2608", + fontproperties=prop, + color="magenta", + ha="center", + fontsize="large", + ) + elif (cin[i] < 100 or np.isnan(cin[i])) and (cape[i] >= 500): + ax4.text( + datetime_to_float(time[i]), + ax4.get_ylim()[1] * 0.62, + "\u2608", + fontproperties=prop, + color="red", + ha="center", + fontsize="large", + ) + + # snow: + ax5 = ax4.twinx() + ax5.bar(time_mod, snow, color="magenta", label="snow", width=3600) + ax5.set_ylabel(r"snow [cm/h]") + ax5.set_ylim(0, max(max(ravg), 3) + 1) + ax5.set_xlim( + datetime_to_float(time[0] - datetime.timedelta(hours=3 * len(time) / (24 * 3))), + datetime_to_float( + time[-1] + datetime.timedelta(hours=3 * len(time) / (24 * 3)) + ), + ) + ax5.set_yticks( + [ + x + for x in range(max(int(max(ravg)), 3) + 2) + if x % (max(int(max(ravg)), 3) / 3) == 0 + ] + ) + ax5.set_xticks([time_mod[i] for i in ind]) + try: + ax5.yaxis.set_ticklabels([]) + ax5.xaxis.set_ticklabels([]) + except: + print("Plotting tick labels failed") + lines, labels = ax4.get_legend_handles_labels() + lines2, labels2 = ax5.get_legend_handles_labels() + ax4.legend(lines + lines2, labels + labels2, loc="best", fontsize="small", ncol=2) + + # ---------------additional----------------- + + date = datetime.datetime.utcnow().strftime("%H:%M, %B %d, %Y, UTC") + ax0.text( + 1, + 1.01, + "{0:} \n experimental WRF setup \n $\Delta x = {1:.3f}$ km".format( + date, compute_average_resolution(DS[0], *extent) / 1e3 + ), + fontsize="x-small", + transform=ax0.transAxes, + horizontalalignment="right", + ) + + plt.figtext( + 0.483, + 0.948, + r"Christoph Knote (MBEES, Uni Augsburg), Fabian Jakub, Matjaz Puh (Meteorological Institute, LMU Munich)", + fontsize="x-small", + alpha=0.4, + ) + ax0.text( + 0.05, + 1.15, + "MIM Forecast", + transform=ax0.transAxes, + fontsize="xx-large", + horizontalalignment="left", + ) + ax0.text( + 0.05, + 1.05, + " Meteogram @{0:.5f},{1:.5f} \n using {2:} pts for output statistics".format( + location_lon, location_lat, np.size(xlon) + ), + transform=ax0.transAxes, + fontsize="small", + horizontalalignment="left", + ) + + # plt.ticklabel_format(useoffset=False, axis='y') + plt.savefig(outfile, bbox_inches="tight") + + +if __name__ == "__main__": + import datetime + from argparse import ArgumentParser, ArgumentTypeError + + def valid_date(s): + try: + return datetime.datetime.strptime(s, "%Y-%m-%d") + except ValueError: + raise ArgumentTypeError("Not a valid date: '{0}'.".format(s)) + + parser = ArgumentParser() + parser.add_argument( + "wrf_data_fpath_pattern", + type=str, + help="WRF input data path pattern (including strptime pattern for date and {domain:s} for domain (01, 02, ...))", + ) + parser.add_argument( + "start_date", type=valid_date, help="First date to process (YYYY-mm-dd)" + ) + parser.add_argument( + "end_date", type=valid_date, help="Last date to process (YYYY-mm-dd)" + ) + parser.add_argument( + "interval_hours", type=int, help="Time interval in hours for plotting" + ) + parser.add_argument("domain", type=int, help="Which domain to process") + parser.add_argument( + "plot_fpath_pattern", + type=str, + help="Plot output path pattern (including strptime pattern for date and {plot:s} for plot identifier (e.g., 500hPa_europe...)", + ) + parser.add_argument( + "--spatial_patch_deg", + type=float, + default=0.1, + help="Size of the patch (in degrees) to use for uncertainty calculations", + ) + + args = parser.parse_args() + # args = parser.parse_args( [ "/alcc/gpfs2/scratch/mbees/knotechr/archive/WRF/operational_chemistry/wrfout_d{domain:02d}_%Y-%m-%d_%H:%M:%S", "2021-03-11", "2021-03-14", "3", "1", "{plot:s}_%Y%m%d%H.png" ]) + + import numpy as np + + filenames = [ + d.strftime(args.wrf_data_fpath_pattern).format(domain=args.domain) + for d in np.arange( + args.start_date, + args.end_date, + datetime.timedelta(hours=args.interval_hours), + dtype=datetime.datetime, + ) + ] + + try: + plot_var( + filenames, + args.start_date.strftime(args.plot_fpath_pattern.format(plot="met")), + deg_round_loc=args.spatial_patch_deg, + ) + except: + import matplotlib.font_manager as fm + + print("Rebuilding font cache") + fm._rebuild() + plot_var( + filenames, + args.start_date.strftime(args.plot_fpath_pattern.format(plot="met")), + deg_round_loc=args.spatial_patch_deg, + ) diff --git a/blueprints/highres_chemistry/pp/plotting/meteograms/run.sh b/blueprints/highres_chemistry/pp/plotting/meteograms/run.sh new file mode 100755 index 0000000..bac9178 --- /dev/null +++ b/blueprints/highres_chemistry/pp/plotting/meteograms/run.sh @@ -0,0 +1,26 @@ +#!/bin/bash -l +#SBATCH --partition=alcc1 +#SBATCH -o /alcc/gpfs2/scratch/mbees/knotechr/WRF/postprocessing/meteograms.%j.%N.out +#SBATCH -J meteograms +#SBATCH --ntasks=1 +#SBATCH --mem=10G +#SBATCH --mail-type=FAIL +#SBATCH --mail-user=christoph.knote@med.uni-augsburg.de +#SBATCH --time=00:30:00 + +module load gnu geos + +export MPLBACKEND="agg" + +scriptPath=/alcc/gpfs2/home/u/knotechr/wrfotron/blueprints/operational_chemistry/pp/plotting/meteograms/plot.py +wrfDataPathPattern="/alcc/gpfs2/scratch/mbees/knotechr/archive/WRF/operational_chemistry/wrfout_d{domain:02d}_%Y-%m-%d_%H:%M:%S" +firstDateToProcess=`date --date="2 days ago" "+%Y-%m-%d"` +lastDateToProcess=`date --date="3 days" "+%Y-%m-%d"` +intervalHours=1 +domain=2 +plotDir="/alcc/gpfs2/scratch/mbees/knotechr/plots/WRF/operational_chemistry/meteograms" +plotPathPattern="${plotDir}/{plot:s}_%Y%m%d%H.png" + +mkdir -p $plotDir + +python3 $scriptPath "$wrfDataPathPattern" "$firstDateToProcess" "$lastDateToProcess" "$intervalHours" "$domain" "$plotPathPattern" diff --git a/blueprints/highres_chemistry/waccm.inp b/blueprints/highres_chemistry/waccm.inp new file mode 100644 index 0000000..4491518 --- /dev/null +++ b/blueprints/highres_chemistry/waccm.inp @@ -0,0 +1,67 @@ +&control + +do_ic = __do_ic__, +do_bc = __do_bc__, + +domain = __domain__, + +dir_wrf = './', +dir_moz = './', +fn_moz = 'moz0000.nc', +moz_var_suffix='', + +def_missing_var = .true. + +spc_map = 'o3 -> O3', 'n2o -> N2O', 'no -> NO', +'no2 -> NO2', 'nh3 -> NH3', 'hno3 -> HNO3', 'hno4 -> HO2NO2', +'n2o5 -> N2O5', 'h2o2 -> H2O2', +'ch4 -> CH4', 'co -> CO', 'ch3ooh -> CH3OOH', +'hcho -> CH2O', 'ch3oh -> CH3OH', 'c2h4 -> C2H4', +'ald -> CH3CHO', 'acet ->CH3COCH3', 'mgly -> CH3COCHO', +'pan -> PAN', 'mpan ->MPAN', 'macr -> MACR', +'mvk -> MVK', 'c2h6 -> C2H6', 'c3h6 -> C3H6', 'c3h8 -> C3H8', +'c2h5oh -> C2H5OH', 'apin -> 0.75*MTERP', 'bpin -> 0.25*MTERP', +'isopr -> ISOP','acetol -> HYAC', 'mek -> MEK', +'bigene -> BIGENE', 'bigalk -> BIGALK', +'tol -> TOLUENE', 'benzene -> BENZENE','xylenes ->XYLENES', +'cres -> CRESOL', 'dms -> DMS', 'so2 -> SO2' +! +! aerosols +! +'oc_a01->0.1216*pom_a1+0.9886*soa1_a2+0.1216*soa1_a1+0.9886*soa2_a2+ 0.1216*soa2_a1+0.9886*soa3_a2+0.1216*soa3_a1+0.9886*soa4_a2+0.1216*soa4_a1+ 0.9886*soa5_a2+ 0.1216*soa5_a1;1.e9', +'oc_a02->0.7618*pom_a1+0.0114*soa1_a2+0.7618*soa1_a1+0.0114*soa2_a2+ 0.7618*soa2_a1+0.0114*soa3_a2+0.7618*soa3_a1+0.0114*soa4_a2+0.7618*soa4_a1+ 0.0114*soa5_a2+ 0.7618*soa5_a1;1.e9', +'oc_a03->0.1164*pom_a1+0.0000*soa1_a2+0.1164*soa1_a1+0.0000*soa2_a2+ 0.1164*soa2_a1+0.0000*soa3_a2+0.1164*soa3_a1+0.0000*soa4_a2+0.1164*soa4_a1+ 0.0000*soa5_a2+ 0.1164*soa5_a1;1.e9', +'oc_a04->0.0002*pom_a1+0.0000*soa1_a2+0.0002*soa1_a1+0.0000*soa2_a2+ 0.0002*soa2_a1+0.0000*soa3_a2+0.0002*soa3_a1+0.0000*soa4_a2+0.0002*soa4_a1+ 0.0000*soa5_a2+ 0.0002*soa5_a1;1.e9', +'bc_a01->0.1216*bc_a1+0.1216*bc_a4;1.e9', +'bc_a02->0.7618*bc_a1+0.7618*bc_a4;1.e9', +'bc_a03->0.1164*bc_a1+0.1164*bc_a4;1.e9', +'bc_a04->0.0002*bc_a1+0.0002*bc_a4;1.e9', +'so4_a01->0.9886*so4_a2+0.1216*so4_a1+0.0000*so4_a3;1.e9', +'so4_a02->0.0114*so4_a2+0.7618*so4_a1+0.0000*so4_a3;1.e9', +'so4_a03->0.0000*so4_a2+0.1164*so4_a1+0.0995*so4_a3;1.e9', +'so4_a04->0.0000*so4_a2+0.0002*so4_a1+0.9003*so4_a3;1.e9', +'nh4_a01->0.1856*so4_a2+0.0050*so4_a1+0.0000*so4_a3;1.e9', +'nh4_a02->0.0021*so4_a2+0.0930*so4_a1+0.0000*so4_a3;1.e9', +'nh4_a03->0.0000*so4_a2+0.0203*so4_a1+0.0186*so4_a3;1.e9', +'nh4_a04->0.0000*so4_a2+0.0000*so4_a1+0.1690*so4_a3;1.e9', +'no3_a01->0.0000*so4_a2+0.0000*so4_a1+0.0000*so4_a3;1.e9', +'no3_a02->0.0000*so4_a2+0.0000*so4_a1+0.0000*so4_a3;1.e9', +'no3_a03->0.0000*so4_a2+0.0000*so4_a1+0.0000*so4_a3;1.e9', +'no3_a04->0.0000*so4_a2+0.0000*so4_a1+0.0000*so4_a3;1.e9', +'na_a01->0.3889*ncl_a2+0.0479*ncl_a1+0.0000*ncl_a3;1.e9', +'na_a02->0.0045*ncl_a2+0.2997*ncl_a1+0.0000*ncl_a3;1.e9', +'na_a03->0.0000*ncl_a2+0.0458*ncl_a1+0.0391*ncl_a3;1.e9', +'na_a04->0.0000*ncl_a2+0.0000*ncl_a1+0.3542*ncl_a3;1.e9', +'cl_a01->0.5996*ncl_a2+0.0737*ncl_a1+0.0000*ncl_a3;1.e9', +'cl_a02->0.0068*ncl_a2+0.4621*ncl_a1+0.0000*ncl_a3;1.e9', +'cl_a03->0.0000*ncl_a2+0.0709*ncl_a1+0.0604*ncl_a3;1.e9', +'cl_a04->0.0000*ncl_a2+0.0001*ncl_a1+0.5462*ncl_a3;1.e9', +'oin_a01->0.9886*dst_a2+0.1216*dst_a1+0.0000*dst_a3;1.e9', +'oin_a02->0.0114*dst_a2+0.7618*dst_a1+0.0002*dst_a3;1.e9', +'oin_a03->0.0000*dst_a2+0.1164*dst_a1+0.0995*dst_a3;1.e9', +'oin_a04->0.0000*dst_a2+0.0002*dst_a1+0.9003*dst_a3;1.e9', +'num_a01->0.9996*num_a2+0.7135*num_a1+0.0000*num_a3;1.0', +'num_a02->0.0004*num_a2+0.2470*num_a1+0.2118*num_a3;1.0', +'num_a03->0.0000*num_a2+0.0016*num_a1+0.6258*num_a3;1.0', +'num_a04->0.0000*num_a2+0.0000*num_a1+0.3501*num_a3;1.0', +/ diff --git a/blueprints/highres_chemistry/wesely.inp b/blueprints/highres_chemistry/wesely.inp new file mode 100644 index 0000000..19febe5 --- /dev/null +++ b/blueprints/highres_chemistry/wesely.inp @@ -0,0 +1,6 @@ +&control + +wrf_dir = './' +domains = __domains__, + +/ diff --git a/tools/plot_domains.py b/tools/plot_domains.py index 0b88471..da2df98 100644 --- a/tools/plot_domains.py +++ b/tools/plot_domains.py @@ -844,11 +844,12 @@ if __name__ == '__main__': print( "Try e_sn = {:d}".format( ceil(wps_info.e_sn_original[i] / wps_info.parent_grid_ratio[i]) * wps_info.parent_grid_ratio[i] + 1) ) print( "" ) - #ll_x, ll_y = wpsproj.transform_point(5.5, 47., latlonproj) - #ur_x, ur_y = wpsproj.transform_point(15., 55., latlonproj) + ll_x, ll_y = wpsproj.transform_point(5.5, 47., latlonproj) + ur_x, ur_y = wpsproj.transform_point(15., 55., latlonproj) # - #ax1.set_xlim([ll_x, ur_x]) - #ax1.set_ylim([ll_y, ur_y]) + ax1.set_xlim([ll_x, ur_x]) + ax1.set_ylim([ll_y, ur_y]) + # Augsburg lon, lat = wpsproj.transform_point(10.898333, 48.371667, latlonproj) ax1.scatter(lon, lat, marker='o', color='r', label='point') -- GitLab