From bd682ade65fd102d445373150bb9d549770b3656 Mon Sep 17 00:00:00 2001 From: herjy Date: Mon, 20 Mar 2017 13:22:49 +0100 Subject: [PATCH] SLIT V1.0 --- Examples/Test_SLIT.py | 1 - Examples/Test_SLIT_MCA.py | 25 ++++---- Examples/Test_SLIT_forUsers.py | 102 +++++++++++++++++++++++++++++++++ README.md | 49 +++++++++++++++- SLIT/Lens.pyc | Bin 7542 -> 0 bytes SLIT/SLIT.py | 7 +-- SLIT/SLIT.pyc | Bin 18132 -> 0 bytes SLIT/__init__.pyc | Bin 194 -> 0 bytes SLIT/wave_transform.pyc | Bin 4327 -> 0 bytes build/lib/SLIT/SLIT.py | 7 +-- dist/SLIT-0.1-py2.7.egg | Bin 17472 -> 17449 bytes 11 files changed, 166 insertions(+), 25 deletions(-) create mode 100644 Examples/Test_SLIT_forUsers.py delete mode 100644 SLIT/Lens.pyc delete mode 100644 SLIT/SLIT.pyc delete mode 100644 SLIT/__init__.pyc delete mode 100644 SLIT/wave_transform.pyc diff --git a/Examples/Test_SLIT.py b/Examples/Test_SLIT.py index 4c40004..225ae75 100644 --- a/Examples/Test_SLIT.py +++ b/Examples/Test_SLIT.py @@ -97,7 +97,6 @@ def SIE(x0,y0,n1,n2,b,beta,q,xc,theta): -sourcesl[np.where(real_source!=0)])**2 /real_source[np.where(real_source!=0)]**2)/(np.size( np.where(real_source!=0))/2.) - image_chi2 = np.std(Image-Imsl)**2/sigma**2 print('Residuals in source space', source_error) print('Residuals in image space',image_chi2) diff --git a/Examples/Test_SLIT_MCA.py b/Examples/Test_SLIT_MCA.py index 879fa38..3e97032 100644 --- a/Examples/Test_SLIT_MCA.py +++ b/Examples/Test_SLIT_MCA.py @@ -63,15 +63,12 @@ def SIE(x0,y0,n1,n2,b,beta,q,xc,theta): #Generation of lensed source I2 = slit.Lens.source_to_image(newsource, nt1 ,nt2 , Fkappa) - +HI2 = scp.fftconvolve(I2, PSF.astype(float), mode = 'same') #Noise levels SNR = 500 sigma = np.sqrt(np.sum(I2**2)/SNR/(nt1*nt2*size**2)) -#Convolution by the PSF and generation of the final image -I2 = scp.fftconvolve(I2, PSF, mode = 'same') - #Convolution of the observed image simu = scp.fftconvolve(gal0.astype(float)+I2, PSF.astype(float), mode = 'same') #Sotring the convolved lens light profile: @@ -94,7 +91,7 @@ def SIE(x0,y0,n1,n2,b,beta,q,xc,theta): start = time.clock() #Running SLIT_MCA -sourcesl, Imsl, G = slit.SLIT_MCA(Image, Fkappa, kmax, niter,riter, size,PSF, PSFconj, levels = levels) +S, FS, G = slit.SLIT_MCA(Image, Fkappa, kmax, niter,riter, size,PSF, PSFconj, levels = levels) #Stop clock elapsed = (time.clock()-start) @@ -104,11 +101,11 @@ def SIE(x0,y0,n1,n2,b,beta,q,xc,theta): real_source = newsource source_error = np.sum(np.abs(real_source[np.where(real_source!=0)] - -sourcesl[np.where(real_source!=0)])**2 + -S[np.where(real_source!=0)])**2 /real_source[np.where(real_source!=0)]**2)/(np.size( np.where(real_source!=0))/2.) -image_chi2 = np.std(Image-Imsl-G)**2/sigma**2 +image_chi2 = np.std(Image-FS-G)**2/sigma**2 print('Residuals in source space', source_error) print('Residuals in image space',image_chi2) @@ -117,7 +114,7 @@ def SIE(x0,y0,n1,n2,b,beta,q,xc,theta): plt.figure(0) plt.title('Source from SLIT') - plt.imshow((sourcesl), vmin = np.min(real_source), vmax = np.max(real_source), cmap = cm.gist_stern, interpolation = 'nearest') + plt.imshow((S), vmin = np.min(real_source), vmax = np.max(real_source), cmap = cm.gist_stern, interpolation = 'nearest') plt.axis('off') plt.colorbar() @@ -129,26 +126,26 @@ def SIE(x0,y0,n1,n2,b,beta,q,xc,theta): plt.figure(2) plt.title('relative difference') - diff = (real_source-sourcesl) + diff = (real_source-S) plt.imshow((np.abs(diff)), cmap = cm.gist_stern, interpolation = 'nearest') plt.axis('off') plt.colorbar() ####Lensed source plt.figure(3) plt.title('Original lensed galaxy') - plt.imshow(I2, cmap = cm.gist_stern, interpolation = 'nearest') + plt.imshow(HI2, cmap = cm.gist_stern, interpolation = 'nearest') plt.axis('off') plt.colorbar() plt.figure(4) plt.title('reconstructed lensed source') - plt.imshow((Imsl), vmin = np.min(I2), vmax = np.max(I2), cmap = cm.gist_stern, interpolation = 'nearest') + plt.imshow((FS), vmin = np.min(I2), vmax = np.max(I2), cmap = cm.gist_stern, interpolation = 'nearest') plt.axis('off') plt.colorbar() plt.figure(5) plt.title('error on the source in image plane') - plt.imshow((I2-Imsl), cmap = cm.gist_stern, interpolation = 'nearest') + plt.imshow((HI2-FS), cmap = cm.gist_stern, interpolation = 'nearest') plt.axis('off') plt.colorbar() ###Galaxy @@ -178,13 +175,13 @@ def SIE(x0,y0,n1,n2,b,beta,q,xc,theta): plt.figure(9) plt.title('Reconstructed image') - plt.imshow(Imsl+G, cmap = cm.gist_stern, interpolation = 'nearest') + plt.imshow(FS+G, cmap = cm.gist_stern, interpolation = 'nearest') plt.axis('off') plt.colorbar() plt.figure(10) plt.title('difference with reconstructed image') - plt.imshow(Image-Imsl-G,cmap = cm.gist_stern, interpolation = 'nearest', vmin = -5*sigma, vmax = 5*sigma)#slit.fft_convolve(Im,PSF) + plt.imshow(Image-FS-G,cmap = cm.gist_stern, interpolation = 'nearest', vmin = -5*sigma, vmax = 5*sigma)#slit.fft_convolve(Im,PSF) plt.axis('off') plt.colorbar() diff --git a/Examples/Test_SLIT_forUsers.py b/Examples/Test_SLIT_forUsers.py new file mode 100644 index 0000000..2127dfc --- /dev/null +++ b/Examples/Test_SLIT_forUsers.py @@ -0,0 +1,102 @@ +import pyfits as pf +import matplotlib.pyplot as plt +import numpy as np +import matplotlib.cm as cm +from scipy import signal as scp +import SLIT +import time +from scipy import signal as scp +import warnings +warnings.simplefilter("ignore") + +#Example of a run of the SLIT algorithm on simulated images. +#Here the first part of the file shows how simulations are generated. +#For users intereseted only in seeing the code run, have a look at the running SLIT section. +#The command line that builds the Fkappa operator is also of outmost importance. + +Image = '''Input 2D image of the lens to invert ''' +nt1,nt2 = np.shape(Image) +###############################Mass profile############################### +x0,y0 = '''Input the center of mass of the lens with regard to coodinates in Image ''' +kappa = '''Input dimensionless pixelated mass density profile here ''' +size = '''Input the desired size of the output with regard to Image. Chosing 1 will result in a source with the same number of pixels as in Image. ''' +#Mapping between lens and source IMPORTANT +Fkappa = SLIT.Lens.F(kappa, nt1,nt2, size,x0,y0) + +PSF = '''Input the PSF for Image here''' +PSFconj = '''Input the conjugate of the PSF here given by + np.real(np.fft.ifft2(np.conjugate(np.fft.fft2(PSF0[:-1,:-1])))), but be carefull that the result is still centered ''' + +################################Running SLIT############################ +#Parameters +kmax = 5 +niter =50 + +#Start clock +start = time.clock() + +#Running SLIT +S, FS = SLIT.SLIT(Image, Fkappa, kmax, niter, size, PSF, PSFconj) + +#Stop clock +elapsed = (time.clock()-start) +print('execution time:', elapsed, 'seconds') + +#Reconstruction goodness +real_source = newsource +source_error = np.sum(np.abs(real_source[np.where(real_source!=0)] + -S[np.where(real_source!=0)])**2 + /real_source[np.where(real_source!=0)]**2)/(np.size( + np.where(real_source!=0))/2.) +image_chi2 = np.std(Image-FS)**2/sigma**2 +print('Residuals in source space', source_error) +print('Residuals in image space',image_chi2) + +#Display of results +for i in [1]: + plt.figure(2) + # plt.suptitle('FISTA: error per pixel on the source: '+str(source_error)+' image chi2:'+str(image_chi2)) + # plt.subplot(2,3,1) + plt.title('Source from SLIT') + plt.imshow((S), vmin = np.min(real_source), vmax = np.max(real_source),cmap = cm.gist_stern, interpolation = 'nearest') + plt.axis('off') + plt.colorbar() +# plt.subplot(2,3,2) + plt.figure(3) + plt.title('Original source') + plt.imshow(real_source, cmap = cm.gist_stern, interpolation = 'nearest') + plt.axis('off') + plt.colorbar() + # plt.subplot(2,3,3) + plt.figure(4) + plt.title('Lensed source') + plt.imshow(Image, cmap = cm.gist_stern, interpolation = 'nearest') + plt.axis('off') + plt.colorbar() + plt.figure(41) + plt.title('Reconstructed lensed source') + plt.imshow(FS, vmin = np.min(Image), vmax = np.max(Image), cmap = cm.gist_stern, interpolation = 'nearest') + plt.axis('off') + plt.colorbar() + # plt.subplot(2,3,4) + plt.figure(5) + plt.title('relative difference') + diff = (real_source-S)/real_source + diff[np.where(real_source==0)] = 0 + diff[np.where(diff>1)]= np.log(0.) + plt.imshow(np.abs(diff), vmax = 1., vmin = 0., cmap = cm.gist_stern, interpolation = 'nearest' ) + plt.axis('off') + plt.colorbar() + # plt.subplot(2,3,5) + plt.figure(6) + plt.title('difference with reconstructed lensed image') + plt.imshow(Image-FS, vmin = -5*sigma, vmax = 5*sigma, cmap = cm.gist_stern, interpolation = 'nearest') + plt.axis('off') + plt.colorbar() + # plt.subplot(2,3,6) + plt.figure(7) + plt.title('difference with true source') + plt.imshow((np.abs(real_source-S)), cmap = cm.gist_stern, interpolation = 'nearest') + plt.axis('off') + plt.colorbar() +plt.show() diff --git a/README.md b/README.md index 2c6225d..f4c94fb 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,47 @@ -# SLIT -SLIT is a python code that provides a method for invertion of lensed images in the frame of strong gravitational lensing +When using this algorithm for publications, please acknowledge the work presented in: +http://arxiv.org/abs/17soon + +======================================================== +INSTALLATION: +- Download and unzip the SLIT.zip file +- In command line, open the SLIT folder with "cd SLIT" +- Install the python package: +"python setup.py install" + +======================================================== +TESTS: +In SLIT, open the "Examples" folder and execute either of the examples: +"python Test_SLIT.py" to test the reconstruction of a deblended lensed source. +"python Test_SLIT_HR.py" to test the reconstruction of a deblended lensed source at higher resolution. +"python Test_SLIT_MCA.py" to test the joint separation of lens and source light profiles and reconstruction of the source. +"python Test_sparsity.py" to reproduce the non-linear approximation error plot from the paper to show the sparsity of lensed and unlensed galaxies. + +Inputs provided in the "Files" folder: +"source.fits": the source used to generate simulations in Test_SLIT.py and Test_SLIT_MCA.py. +"Source_HR.fits": the source used to generate simulations in Test_SLIT_HR.py. +"Galaxy.fits": the lens galaxy light profile used in Test_SLIT_MCA.py. +"kappa.fits": the lens mass density profile used in all simulations. +"PSF.fits": the TinyTim PSF used in all simulations. +"Noise_levels_SLIT_HR.fits": noise levels used in "Test_SLIT_HR" saved as a fits cube. They are usually computed in the algorithm, but we provide them as inputs to save time. +"Noise_levels_SLIT_MCA.fits": noise levels used in "Test_SLIT_MCA" saved as a fits cube. They are usually computed in the algorithm, but we provide them as inputs to save time. +"Noise_levels_SLIT.fits": noise levels used in "Test_SLIT_HR" saved as a fits cube. They are usually computed in the algorithm, but we provide them as inputs to save time. + +Results are displayed in pyplot windows. + +Users may change the input parameters via the same files and are encouraged to use them for further applications. + +======================================================== +HOW TO USE: +We provide a Test_for_user.py file, that users may fill in with their own inputs and where the commands are a bit more detailed than in the other Test files. + +SLIT needs very little amount of inputs. It requires the input image along with lens mass profile and a PSF. The user then has to chose a maximum number of iterations after which the algorithm will stop if not converged and a image size ratio to the input image to set the resolution of the reconstructed source. + +Please do not hesitate emailing me for support via github, or at: remy.joseph@epfl.ch. + + + + +Contact GitHub API Training Shop Blog About + +© 2017 GitHub, Inc. Terms Privacy Security Status Help + diff --git a/SLIT/Lens.pyc b/SLIT/Lens.pyc deleted file mode 100644 index eeea1d30265d16790774b73868c47af582dcf2bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7542 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 Md*80E-3-(JAEIxRt^fc4 diff --git a/SLIT/__init__.pyc b/SLIT/__init__.pyc deleted file mode 100644 index 47d322ebba5be93b7a9e6dfaf172fa2068e91acb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 194 zcmZSn%*%EE=%I*Y1}IAi-b_ zW}wo{|3IL@2xOIj2rWObXbB6D9qi*70%rK6<`tLl0Y%Ca%TnV@iW2jR)AEaQHGm=v r2%=a3sz*OQJ~J<~BtBlRpt6JmC}@+LpHiBWY6r5Q7-TXRBM&10wL>K; diff --git a/SLIT/wave_transform.pyc b/SLIT/wave_transform.pyc deleted file mode 100644 index 04d16b635e93be0d195bf151bd8a5bd8d29fada1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4327 zcmcIn?`|7K5T9M2W5;p+IWb9SftHlw(h`%jAfORcrK%_`0bPpHMy(>(cX7@=pWVAl z+En(ZgjYb~5%|DEz;o~jd;sws_|5G3?1Z*Lf+qIt?A*-k?9S|O&Y3^P3*W8HZPY3G zvoK!4H;OQA%O9HGrzf10P}C^ZYTIYy4ALl_px$&h2wp`y)k zavbf?6~WujPdOR!g8nV74_azyCPMpOM?bJGM%(>Y1z0R(avVK@$X`BJ^T8)?uBk!qej4ztuk{OoGuu_2z35jlj zt9}!?VN?y>)_(Px8$FEMo$Bo!H*%}%w{F~qyc4#a-MaU{ceg|`AdhQ%?p7Suf@r%P zww5~kae>$0Z?)Vw^ddLMvk4H=WmQyP;s2((sXdm|Ib<$2-k((0&tOb-H6=r+4wTkF zqPXOGk~XC5p{DSvJVgyy$)f^E&^$PE2&BIM0$)%*E_QZ>1*OffvHohih+uO0^Hw3dH zn)P>!Px5%hG(}FS7uO z@Q=-GVIO;Kf6tx4Jema|T~Z~hs7ty4uB=b1(>mq?xf*qRFL33=>U?-?!gVA?ae#_O zLXb{i46-xdQ%OnS&Tu`L{GebYtH>J{#+NFA4H5QoVuC^t7jsaBr-lBIqlT%UJU#g( zsSzM1%7NFzaFC&E_kW_^D9hN&q6J>%cS5ERMt5`oYq-<+FxX_Uf>{r!3nW3Ubo0+p zOfBGM+oIJ+hl$(tLCUbke{j2j_1BYK_X@HT97Au6qeENZEq$*XY&(xjfMFCvft<0y z%sgvk`7DAH)K`MIm?||g{FKihNg0(K6=jOEGgF)++ETHf(HWlMq-W=nq#?91YT(3h zeB)Gpn5FPN&Ckqbg*l?))W9xB^JUi4G{@DTh#`QeH-0ST#%D&tL7sEs58bd|6!XZH z*_JO0H zq$WH=5sh?;kqj$vCgwBoI5j7zJ5Jpxa?q)<4wz|Z>fSU3_b7%fOrRhkq-DZg$0>1C zFk|o&gG77!dD^IfA#K2D5=hk=1odM-D0um2P^F=up1aI&P^JDBO8+J(C}FE51!Lj|RtQifgft*J05tqEQQZY^}9*dV<0T|D9| zOLX1yV>h&41>0aD(Qlu6Qy4r8BoXDWc#Oo-91;;-5oB+*9aosBh6c(?58AtdQw#Tv z6n)hmgS0XYB27fvgUz5R4WQ)((oUYbVLK8BK-Q>JtGh9G;iK(ZG;3j4Gu~mkCCm8j z#)^3J-9SdC9ZLtfEnTJFktW~A_Z3H^QT>Q?*^vXYdE3U2pbLz4xTSc_OrOXnVW5Q+5 zT8o*2UexjmJ`TTWKl~GC!TnGR;-oL)z+8NW-oJ5q(F@BwSQzBJKb@IpfN=&f(?Ido zbgWm(s}$pFdKprNn-H4 z0Csd4#>k@JmqA@9NC<;HGpGV}(Cguv+c_H~7!3q}wl+HBkT!Rd^jOgko^!NwIM_!& z&;~aVv>1dU@34G68c;NedRVhhfF|(q0+8XGBS<4}pK{6U*CDgtU~-CyAPR%j5Td-r zQ-Ku=T)o}dw-;ITCX=&F_)6Ja_x3wX&NI2dF1B!ZmDPVzSJHFS}i3 z!YF6+OR4=nlMg`T($>GQKV-p2Og?6E8RR8iWWfw?_i-Fzoruqf)QFx}E4Z*1GH3KM zU)79UP`#w9y23{$7#i%ha6W7h^V@G!_d5Gak=F=nzH|k{$`Qqk+^t&N@!PTQJ-{y} z=0q!DxuJCYI4-B20>^9B8t&4zG?&OAsF4Yu$j!ksPS^`f&M>(GGB`8g{{P>6oWfP~ Zu3g{#gzHUy@f8{AR4FrBEWT2@@i*sW_)`D? diff --git a/build/lib/SLIT/SLIT.py b/build/lib/SLIT/SLIT.py index 315bd06..74c7b55 100644 --- a/build/lib/SLIT/SLIT.py +++ b/build/lib/SLIT/SLIT.py @@ -67,6 +67,7 @@ def SLIT(img, Fkappa, kmax, niter, size, PSF, PSFconj, levels = [0], mask = [0] #Noise simulations to estimate noise levels in source plane if np.sum(levels)==0: + print('Calculating noise levels') levels = simulate_noise(nt1,nt2, size, Fkappa, lensed, PSFconj) #Saves levels hdus = pf.PrimaryHDU(levels) @@ -203,6 +204,7 @@ def SLIT_MCA(img, Fkappa, kmax, niter, riter, size,PSF, PSFconj, levels = [0], m levelg = level(nt1,nt1) #Noise simulations to estimate noise levels in source plane if np.sum(levels)==0: + print('Calculating noise levels') levels = simulate_noise(nt1,nt2, size, Fkappa, lensed, PSFconj) #Saves levels hdus = pf.PrimaryHDU(levels) @@ -236,8 +238,6 @@ def star_inv(x): #Initialisations - RS = Lens.image_to_source(img, size, Fkappa, lensed = lensed) - RG = np.copy(img) if np.sum(Ginit)==0: G = np.random.randn(nt1,nt2)*sigma0 else: @@ -315,8 +315,7 @@ def star_inv(x): G = mw.iuwt(alphag) S[np.where(S<0)] = 0 FS = Lens.source_to_image(S, nt1, nt2,Fkappa) - if np.sum(PSF)!=0: - FS = scp.fftconvolve(FS,PSF,mode = 'same') + FS = scp.fftconvolve(FS,PSF,mode = 'same') return S, FS,G diff --git a/dist/SLIT-0.1-py2.7.egg b/dist/SLIT-0.1-py2.7.egg index 586f40bd8d59b8e46fc54672f55808707d1d48ed..1621ea24ca74981de128a90e6d6b4bb9f2954a38 100644 GIT binary patch delta 8656 zcmZ9Sbxfa27p-x3cPs8*pt!p`#oeLB?Zw^Qp}4yicX!v~?);FV_ned5n|yb&GtbUU zX8zq-E2}pgygVEnSy>Je3JVMj3=VAA#w7vS8S-BQJpYR%AMlF*NC%PdFB`ic*kS)` z?%)aF%nGz!WFNjI>ZqfGfl*3;fg%0#i<-QQI?KNsvy4*zBGP4Nk>-)SJk?eln)9a^=inSxk4V%Lk z(6tBGW{*|TFB27^T?%7Lz)b8#7h#n|i;p%iAsSz)-^HAgM0n@Ud+dldAah3EjYXq^ zHeW9H21@g4aFE4D>MrQw`2_^OaY7QP@_NcosF~_WpbJ7H(@}NOvCAp&pd=URO#B4i zI`S3=p?D65A-6IWcFiJuQ{HLG2y!dZ-uPxwer`NSKA}}?3 z`8L2C^Pea?Ax}k;HJSDKkOEWqozPY?OY^0>t=spdlBBU!5r$yRT*`^z@_J5^im+wD zcayHMshCeIup@96x@3A$8h&TR&QcdzA7=VAoKo%oxOwcU{R4PCwd@-0=CP1PxHj%G zB#Gj1f{P`&<4_|!<>PQ-)`z73{h3sX!wvDelJp115};vG-euW7=?4$7QuAS}@?K8K zItpefFFX#fWbZ$h>JGKI^m$Lcsu&`Aky8f5@8OoWOG55puG0C{iSY%Z7De%bs zW~yU2;A=H=A0(xhfrWt*?ZX=1wB`<8V`agf`d#-NxbBg%wUJej4UbBdafUbZ{3{hB zz26;ks9nqf0*YRAvh0CBsE4t!II-J(js@A?-iO03+;$wXKCG!AyvZ8lq>K?OXG`mV z(1y%Tp*D=@f`wH-i2JJXnPe|IPK9oao9Njq!1yyn>~uW-g-BOCTJ}uRn_=5R)}8lD|oeB z^^+m|uxc?(|;|H+gyhh4zLG8l1sh>fNPIcHccJEnM8LXQscS8-s5jbn$rXTyfcI<|N zT=ui3^CfHTwi4|89E2nrl5KJ8nQ#Z8Fpy#*!#|b&72d!k^rfBlcK@lb462X-MM*K} zckR5Zz_r{ALmbTjCIuT27ZS0ah0%t}R^Q$k#`v3hsszw{wft8-q~xu>*n?9U)7-z< zf`onR!=sDl`%2-urb~Bz+vN9!`id|1d(DRo~384 zjepTh#MJ90zeK2#`&ESrLzAz@m1-{K=k?z>Q3+6bGC9O9eG@Ov+C{}PrdEGFUnYeU zcB0*xSR@59k7EugkD3E>PV@(mG^1E(G&Q_pPjI0Q-`9znTrG9R_6Rh=v+^O-9|k-; z)WY&vv`%p=F=0>5AUJ1mA*&>FJ$G?}x`6x4s-Mt;QF;IZ;$6FO5KN6;|A{48N5AM* z__XE=__04X%Ya8O1$I*&CU7&Vc?UN$W3sc^{!a9 zIqw9Sc3rzf@v{#-MTnhQf{xDsWY2EEpPODGLJ~L*A(+3|^httOuA46k zJtxr*@jXZ^ojSsoX%VEAUvw>Azz`0DMaAqDFs7kdj7(WlKT~q}8%Auct$h69H(}>O zZZUu=@B1YaPS9%Ztn2ct(?ct?mb2JBvN7;(N>MfU30qJ9sgg;xLPxjm#`U%|t2{?l zu(i+218Nmj%PL3CC@$!x6xMCwl&O5t~L@+Ng#|m zqVH-WtD0u#hC}S0+)@#*3RM;)9DUCog9}Tr&(>=3H#oy?_Lk_*qFhlO;)Z&do5Qi$+N_x^?79#US5 z{8fWSySZ1zspq5A4qr0`j;$ zVD3yG@g3!Sb$0r*wwc{OLG({i>I!Lz{JA?To2fkRN=YDY?;s&2Om5~<*q=}tNh@4W zW7;eDOlMrb?o#<9qGQ&{46x@CCLBw)981O=OWKq3?lTG6#l`4`DQ*okdG6P9!JRK+ zr%p(U`KF6CMOtpcT7(?2+z?COtU%-_#55u3euF5Nl*13i2hIfyRb7tkTO<8eIEr)C zd6eaBW0T+h3U}oSXsfcgJ>2ehK)*)ko(aP{wz8}&MS4G9&)&|^04EB1M#1#U1czI2 z@L8uctM#Eu9z!|PM)3qMpOSX1WMZHj8;RDdpR4X8ce7h|L_+3{@d%k@SoCl+mV>o- z+FTi;WblP|szM>ClSx z!4aC$k`i3FfZnGa;E=~-DOslWcfvV%|2=rwH;n<8&mp9b>bj)kZ-GEkm73%7U2W%`)%9c`pOE+X93;3Y|U& z>k@)1EA0rvP1AVpbNuwAjOg{Lwy%TmNdaHa_So0$Pqb_7IHKJYen(jf516*7OUM~EdSY)e4lyP zK&MQlzPAMMQqv9+ycy=H+;Ps&{!D1tekWBm<`O{j^IM)Q%)8OI`x6- zpE6&5MO!-LfVS8@ufiu3(y*Yu(KY_039RX?>_BURBlhPjd>DitxsUbMRr^E=TVRIS zEMLRi&SaphiOy_f;5)4`$8TD&`%|y$Yc>l+;g_qI8-1w;d4YWx%}r^$xE0Goqpp!@ zPIh~5Grq|F%H8K5m$?2b*~@NNdt-vowwPfpXhadG=Gwo-97Mvi2kHKx)Bba}v^ZmW zDbnTa`wtl`$FtTV@VXXc^7oyXnClPPo-J^kTMXJx=*W%YkHhmX?JSqn@9KKcAb(AO zIG%i*pJd?|ABneElSwM(z1J5%tr=YWpc zMnk)-gm5s*bQlGULa9W}xoWE**tPC$D0eH1%~p9pm}4|s?YvgF0W##qFAd_Zr!xfr zzAH_KMm%7)Waec~L~XI5eVzB*@;n-FY&D7DNqR)m;BR$ze0;diA^uTzQ(S%MmWGst6Ngrf|;Lm;E^So5@$`gKWe!<}@Fj;M+;v#Hk0NAu9w5YOd$ zp9>e}(`$_a+R=-Pgdq_YuxLLHOR~^f)u~Y|i#qB!9US z61j4*+b;yYwVz`=>=YZct>{6}^LaC8o)iuU2Ci^luC<9+GRo*Hu}!{0DY&OBq1`m| z?ErZaPnelp=iR%!^wF1(FUEsnURRvoG1e)>Y$M@zegBF_#>j<0H5Bq4F{SW07?1W-Pxhu z=ab|0=SS5bfOH7FYyf|k=uh(~KmY7~<{P26zgemTSuL@k_A+!&hw(6)xRwhf`GJOqo#WG9_pgyg;?f zcv;-$V=bjqYLuMvs&UBxU6Sf{Lp`Sa^|6%;N_Ev-=we5 z1X`^gpxOuKJrXwq)sKWn#{1zohCfL^bPSBHl+$4f-*hYI!}ACQg_euP1ukQcgQ}N^ za7+IR4Sd4OZ&)aXiMvKo^k;NiEKCq}O)mJwKEjr@<)xu^WEDC929oQl)U@NK{GVNu zvT}(9j3gO@G~BN1^XZAMcTL8Hm086&#$QNuE)a@sR<6K8@Yh=(thR4;5)CZOA{Z|% zg-Jt^MWg4)bf0SnQ9GBAySz&rpIRAHkLKT5acjeuJasd3i_0hEj>`q}X<53z ziG(i6&%5*@TpiEJ{d&FGz3bRnL<1&xw|bI%+hl_qRXS_@#8fr}M6APJU>S8e+PA=0 zPLb=wMr#oGGOxkE$|X97Cs8=BLE)ZUKp{azFS)PoGGYaEF6MwSbR#dn$xS z7%4Zv!p8~gy?0kJ5_b3os}#B&hfm)Y^H* zr1tox$Fio4+_M`Qv8Gkkxos>>zt+hR+eSWO-X;tplps|qj$!csg<4XQ-j^AGJ>kL} zZi=$o@k%#j9HEgp)0T{7~^ z+s^nE#c@{04essT8^w958yT52evSR1Nis!THOYY3c;S~i#PIhhYI|= zrhWI)Bcx;Z?xjZz8Qzc)XH|LV5V8=Gs7Jj`VORH+YlSxC=Z(j{wqxWAKVh_CCl4c) zaWx~bs;%rPTZ`>c!x`M>wtZ~bf=ykiQ|@VN?9F85=w6X~S4~U8NEw~g^;Fc*uH&3& z@nZ)#VA_%Iqrg4i@Ehprym}F7Tdh*x=-V!?)WQ*RA9D;b*l*CP)Hm?_>=UEI`I^^& zxCi~dJWWu$=J7jPLl|49YoK^?ml}m=dj1$N{iub@nD{{iJ8(#Q2E`LaBufk}rs=~Q zl_UXaQ+-qM(dl;ZQ<(8-kzCN{T`b%qd9DUdWukx1V&ehJmO(*DMuxfO%z~#kkC4!~ zd28MJtJ@3IK_&gLZ`+US(c{tbzh{)w&Wd|G<8JwbvaF`GtQ@JqwGq>03V)R!OzALy z+FNCnj~i`vFaah<_tu8}h#Y$Ke5LWm zN2G;4uO^rGJwFa%dtN|t*GtlV9}gugP#`<$&1#MqUYo&DCjDP}g52frPpzMqwSwB8 zHznye#E+;3rNe?B$tqjR7I27gBwE}8bIK*!>P2%k`f4BM9dyW-skqVuu&vhsf~~WD zm2)NIO~Q&btO<0$pTVKS>ak|3EIWrXO!w7ex7_WXR}K@ox4(k-a%UaHLZJQ@J5XKY zWk`^=^+II>FIVbX=0U9S!jBDwHPoe4q}rCRdBYCk{9Q@h>sOPRK{fp9FilJFIi8?i z%khc}g3i>+X@ZKGaWArt3&BT#Z@b^xw9But6%q_u4n$9DZ(%{jxDkNcvPZJ(y?Ll3e!mAbW}$Rb>xqB9If*~@-rPj=x0^$ z$4wIssL6nD=$m~M?vJAH2_@bP4SvP-f7>Vy)FBOjr(6)Tw4DiKnkPd7B2gcs&s>iI z^CSf&NM?1GI3~?&BrGM-<#1ZbzjMXGg${-FgPo;Z!^#Hm0tMpP3}urqeiWFcRQs6B zGOw9xCgiCuN9)%OSHWK~twH~tS~Gq7X1eQ6k0sc7}(?v(X2#(_lbSUKOj6+5*@?pl3(ycaP~?NA%O*{67u^~ zwi|vKI}i!x&EE)^!5W@;Fz$>)?w2>#k74}@V|-*Fl0Fc~Dia6eU=*Ao96b(D39}+P z!LwBsE1PQ$mworDu%ezNNIKTN0O=c24Bt(J)uy;%nOJ%~&fGc>UT>QIk3{ht1R}T zz~~+;oP=Q2C#LldM+w}U@Q5BHZK5uCJ8fn+78UIxzQ)Hy!2gemzX;0Wtf0t)j5RK@ z+3b)k+;^V{ijv>*4|JfrcKqnumcS@ny6h4w6(?sLBnW0^)+`)ys(7w1AGQC5N`BFcVbzF5~T~(~oq1imLaRZgWL~IApPayu5LFS5n z#~{5?Cnc~@1pFhEv8d??G&8ZgBqo~)6IdVk?%mEE_7b-5LFiA59j>)-4c!zC3~sfm zF3V0Jdd`x#!j<5E>q}}*nV#{fR`Yq!p{dr4td)Gzog*F4px1K?(P8KAk&b8f z>#xnzZZY)FoG+RKgkI(DW>+0n7^zIN%ffNymLQkrhCUhRG=?1MdoDCfH0way}>T=OX&JC3Iueb*TEbnLLGiED_| zvGUX=X+3~1JD~oZp)a{2C02~O>^baHik-&0`ObMX7{TvT+YDlUkn9`E;cI?+aAlyn z8v)S#B`I>}1vV`H<;7ojcF+>4glh8B@`aPf;}f;}HS6=EE6yMwsK0b&AQ&-!i8pGG zDDs|Gxayud5|Ngy zl-6(4Nx5p{FGM6uU{J%Nx0(DKb);Ts#WX-3KhYkuM>82umFJxC6V~4Sm6OV;+f1^m zwH5#I!C!Yur+??wOj#cFhye?8pbl0WoS8OM-*4fsjEipur@Ea3%jpa@xTYLRL;AE* z0(g$Us>t_hI!40hfbvDNk2L%_ncVUcF#I$3r9{`IU$5WpcB|m#H7gNSQexW6tHU%X!~b=5nX4Xf8ViO1bC_|7-sx{~H8^!?j)yPrX@^8T_Med|U2c zwjeF&nz5H6btn(i8B*i(S#meH2H8DeW(?TS+c&K# zM`Rm$`!>#@ES)b~+_ZHum{hkAUQT-ze;M!EbnryPH%(r;bX5Yi7h|YuEsb!^xtA*P zMZ6q%=!|F2uA;2eZ9y8a_TD9%hBQPjqeZ!712c1V`pwO7YLd~wCW|DFKg{Z*NVo%g zn10_>xX+=6x6Fhaq_D2REKtbsD}gys6#8L7)xrh-?*`{IBAc1oA;%oVLn^vCN~KjG zl*iKjEF{SowkC=u*cS~?Ofn0WrwY~|`7{c*E4K=0->hz@+VI4Kr!FN=zPtl{;RnCq z*tmUE;8(8ID-!q7QNQpyTPH~zu&p{oHVSTQ{B7hvJSH18MmLkW=m6{to0wNMtVoGm z`onKnyeO(RGOeX8K=QOq7gPBd<|p@CP19v3u}!N+nu)aVIr?iG7)@o{6d&!K59aY% ziC&Hp=n;YUwGP~5S;%EmMZ@19>zt|w&+lR3#zoOB++>z1{25 zXJ1=~x+zg<*SZx;?|{X25kAAxNjoK9e&m#rn`ZhWq837mJ!Bn|0msV|P74pcVy3TY z3SM)l=AkPpUuPX?e`rDOA?>OZN3Rw@(uoyX1^e=MGH0EWd4Gs}FolDcuB~W^80&sU zE!K{NGT@XWe~oAyFiTnwR)5yP3?Jkkrr>b4YOrJ(BT1u@jRc&N#JOON!z1OpWnTRF zNnp_;-(h(CW32Mca+-WZ{8|KUW|Rajp44jinjSTAI#a6Ov3?d*5n*R0QnS!9!!prT z9}ER`_WrW@qw`W47y0LJZPpJv>|GBBo+80_SzG%7M>1|qMUj<7^Mos8LW4xp0uz32BEjqlxW#r{(pccT%l z>bo{{kK}-@-^-<&EzjJ2pK}1D$@r+bla>4DR=*&a;YMBg=w4s&YRwc9u3f;&&+0sWgvCJsPm^RhbpV* z{<7i_>d;~GW4efLpZj?fI}-ubK+Tl-^|E4a*>9`4`Kx7p>P{~vY|STlRbjV6$T@(< zYnQX4MA`r}XC>U?XA)hb^vJ@gt5C@!Ha)#cU)Vw`oxy{{-t3o@{YU0)G$@%~jg zY08ptBLYQ3Y%GQq=}XXi%8WPI58mC83MsF(}J{LtsJv mzfgv(IOtwx5e5t_2n`Gj_y4~6heZJ+NoeBqFtft{9{wLshSAyp delta 8676 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 O^eD}Yv@h|$C;tbfCec#>