From b6cd0fac66b3f35ae6671db26eea982fd7d7f8ef Mon Sep 17 00:00:00 2001 From: Duc Nguyen Date: Sun, 29 Oct 2017 00:29:20 +0900 Subject: [PATCH 1/3] bugs fix --- SCFpyr.py | 20 ++++++++++---------- __init__.py | 2 +- convolve.h | 3 +++ pointOp.py | 8 ++++---- pyPyrUtils.py | 2 +- showIm.py | 2 +- wrap.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++- wrapConv.so | Bin 0 -> 115791 bytes 8 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 wrapConv.so diff --git a/SCFpyr.py b/SCFpyr.py index d368cb2..d702b81 100644 --- a/SCFpyr.py +++ b/SCFpyr.py @@ -67,16 +67,16 @@ def __init__(self, *args): # (image, height, order, twidth) #------------------------------------------------------ dims = numpy.array(self.image.shape) - ctr = numpy.ceil((numpy.array(dims)+0.5)/2) + ctr = numpy.ceil((numpy.array(dims)+0.5)/2).astype('int') - (xramp, yramp) = numpy.meshgrid((numpy.array(range(1,dims[1]+1))-ctr[1])/ - (dims[1]/2), + (xramp, yramp) = numpy.meshgrid((numpy.array(range(1, dims[1]+1))-ctr[1])/ + (dims[1]/2.), (numpy.array(range(1,dims[0]+1))-ctr[0])/ - (dims[0]/2)) + (dims[0]/2.)) angle = numpy.arctan2(yramp, xramp) log_rad = numpy.sqrt(xramp**2 + yramp**2) log_rad[ctr[0]-1, ctr[1]-1] = log_rad[ctr[0]-1, ctr[1]-2] - log_rad = numpy.log2(log_rad); + log_rad = numpy.log2(log_rad) ## Radial transition function (a raised cosine in log-frequency): (Xrcos, Yrcos) = rcosFn(twidth, (-twidth/2.0), numpy.array([0,1])) @@ -134,11 +134,11 @@ def __init__(self, *args): # (image, height, order, twidth) self.pyrSize.append(band.shape) dims = numpy.array(lodft.shape) - ctr = numpy.ceil((dims+0.5)/2) - lodims = numpy.ceil((dims-0.5)/2) - loctr = numpy.ceil((lodims+0.5)/2) - lostart = ctr - loctr - loend = lostart + lodims + ctr = numpy.ceil((dims+0.5)/2).astype('int') + lodims = numpy.ceil((dims-0.5)/2).astype('int') + loctr = numpy.ceil((lodims+0.5)/2).astype('int') + lostart = (ctr - loctr) + loend = (lostart + lodims).astype('int') log_rad = log_rad[lostart[0]:loend[0], lostart[1]:loend[1]] angle = angle[lostart[0]:loend[0], lostart[1]:loend[1]] diff --git a/__init__.py b/__init__.py index 204161c..5d8459c 100644 --- a/__init__.py +++ b/__init__.py @@ -49,7 +49,7 @@ from sp3Filters import sp3Filters from sp5Filters import sp5Filters from Spyr import Spyr -from SpyrMulti import SpyrMulti +# from SpyrMulti import SpyrMulti from steer2HarmMtx import steer2HarmMtx from steer import steer from strictly_decreasing import strictly_decreasing diff --git a/convolve.h b/convolve.h index 48d55f7..8f7b9d1 100755 --- a/convolve.h +++ b/convolve.h @@ -53,3 +53,6 @@ int internal_wrap_expand(image_type *image, image_type *filt, int x_fdim, int y_ int x_start, int x_step, int x_stop, int y_start, int y_step, int y_stop, image_type *result, int x_rdim, int y_rdim); +void internal_pointop(double *im, double *res, int size, double *lut, + int lutsize, double origin, double increment, + int warnings); diff --git a/pointOp.py b/pointOp.py index 8d9d4b9..c0025b7 100644 --- a/pointOp.py +++ b/pointOp.py @@ -9,12 +9,12 @@ def pointOp(image, lut, origin, increment, warnings): result = numpy.zeros((image.shape[0], image.shape[1])) - lib.internal_pointop(image.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), + lib.internal_pointop(image.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), result.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), - image.shape[0] * image.shape[1], + image.shape[0] * image.shape[1], lut.ctypes.data_as(ctypes.POINTER(ctypes.c_double)), - lut.shape[0], - ctypes.c_double(origin), + lut.shape[0], + ctypes.c_double(origin), ctypes.c_double(increment), warnings) return numpy.array(result) diff --git a/pyPyrUtils.py b/pyPyrUtils.py index 536d154..6b6b7c1 100644 --- a/pyPyrUtils.py +++ b/pyPyrUtils.py @@ -13,7 +13,7 @@ from PyQt4 import QtCore import JBhelpers import PIL -import ImageTk +from PIL import ImageTk import Tkinter import ctypes lib = ctypes.cdll.LoadLibrary('./wrapConv.so') diff --git a/showIm.py b/showIm.py index f178cfd..6d97795 100644 --- a/showIm.py +++ b/showIm.py @@ -1,5 +1,5 @@ import numpy -import ImageTk +from PIL import ImageTk import PIL import scipy.stats import Tkinter diff --git a/wrap.c b/wrap.c index 3651b6b..de23af6 100755 --- a/wrap.c +++ b/wrap.c @@ -15,7 +15,8 @@ */ #include - +#include +#include #include "convolve.h" /* @@ -274,7 +275,55 @@ int internal_wrap_expand(image, filt, x_fdim, y_fdim, return(0); } /* end of internal_wrap_expand */ +void internal_pointop (im, res, size, lut, lutsize, origin, increment, warnings) + register double *im, *res, *lut; + register double origin, increment; + register int size, lutsize, warnings; + { + register int i, index; + register double pos; + register int l_unwarned = warnings; + register int r_unwarned = warnings; + + lutsize = lutsize - 2; /* Maximum index value */ + /* printf("size=%d origin=%f lutsize=%d increment=%f\n",size, origin, lutsize, + increment); */ + + if (increment > 0) + for (i=0; i lutsize) + { + index = lutsize; + if (r_unwarned) + { + printf("Warning: Extrapolating to right of lookup table...\n"); + r_unwarned = 0; + } + } + res[i] = lut[index] + (lut[index+1] - lut[index]) * (pos - index); + if(isnan(res[i])) + printf("**NAN: lut[%d]=%f lut[%d]=%f pos=%f index=%d\n", index, + lut[index], index+1, lut[index+1], pos, index); + } + else + for (i=0; itq7Ky2OU4 z(-0f1xU|>;F4d|PSI}Awi!5quYOS@^R;+z}q3A2MRjIbk|9j58zu!!TNc;MK@2~Iu zJD<;Q?m6e4d+)j1x!d{OU&%#1!X|{U;~5wbVh>#U^g*@acu%g`4&{PwcnUoYiQAJ(q6{6<) z5#r_B{&b`bfypu~fgFkDSd<P@_sqZ_iAZ^mmILT&QM!6&O;xB0@G3ka7Z1rc7f;kLSCsb73`)l4ICzxe zapIXD#RL$1xigz3ALns3h}00ifG6sgE3$KEwn@IfP#&7`P`XQ_m;f^0nwA!#X1nm$ zPSB~pcCos5W1$nqH?+H0zmOm+ll(+ zirn6rp?a2&>#!G|#7E^5^~)vsf`R%bv^3`HgD3HoMKJ+{d`oAkviDFYI*NzNk0pVt zez_uL>8zZEjQ#m0I4AJ*;9+5z%zw-`Cx_wobU5uO>`b`*OtSu%Z|*$C_ou?y4nE=+ zR5_6!^UXV(3GGxLz3@k066vvgxl3oAoy~mTqkQ(kpYq{} z>3qW%)`9FJB&>(rIlaC^)Y^rwa5q zm0iXyO+s|`x^Ef>?v8%V*EM!2;>#Hb8&|^TS&pM?#?CE59FKddAJGr|)E7Q^!smWu zj<2(~^<7`rlJN-871wc6cW?SFl6-0${`%iM3p!Itkah88{!8;N$-8ua?M(N$P4Grq zA8YL0`c}Z#WuHW?6=@&LBd6J!GvMo*F@qA#aF1&ze&51_?oDxsa0nsZ$@vgsd;?)g z49&f1Ecm+OkgZK0AgCf{fY|w=d($fvTbD5!?7l7(V{a&_B;5bB4svn$?SZ}yY z6ZAuIR3OJ*gfHjUYCRrb*E~14I$!aHUk?AIIQ)D#y|t>#IIn>kQs|5QkB&k%!u>h$ z|8sxZR3Y-h2Rh#f86BV4S|`FI{0s7UH;cI#0Ym>Ke;pV=d$M_Rep3)WddPu{3~=M+ zrnA4N|6)Yjoj+hkfO_7rqkl4o3cX-b`?n(6&R#^=dPc`5TI(a0AbA{37t`i|{D8TS;23nnfIS4^Di3l~q!>VFTzN5At7YG8Qcm(<>5dOg;!GVg-Cm84XpPFd&cesE$tg1e`-_W8mk z+2P6s1z~S)ak#|SwdVTG+gpvSLK4UDoZ=|Y2nJ3x+-(0?ql%qA@2c%6^FdN z-+J^uy;?F_nE2Q)m`2_Q@w2rHxt}>BL(s{FZRB4 zwF7S0`%)Lv7JCn0?UG>Fd)Qa)&Gqd)YD50}KbTDA;N9ixxO$gpO-J6pzX&D%BartX z&jZIU!MON+5+*PF*72D|)rWlDsm~LR?CkPseZK0S__`B+Dk+uOKJ5ixI3=&+kY>Ad zLBZmybFX?S?^*IJ=(@V?*x%5;3c3QTk9`xATKDfiEC_#MyEOMXV(4luJznh%|675r zVZrgz@auPcbaigH&v$!ldR@+fa6dd3uqS0hJN&*o#p#1+gxS14pyGY^g?rz3uQ~xq z@;aW^7JhWqgB|-dTWjg!)(5Y-y{P)2WbW)i((k*6Wp{bk6=+A%So1m#Y6Xh}2i%)4 zru=_xXh|=Cq{n@ykus&I`gu-5>-&eKdpsiD-G5)Ym)x7zl61EXEuEjF`)@A8ZGT_N zX7^@4r0nW!hnNN0$-M9(G>KmK=95rY$7piKjRC`(*%+*raEaLxihR}k|I3=dW06As z_TLvDO&~yp+&P4NrBuRsL&^4^t@!UpWP0H5%Y=&m63GOubxN77BANcX%ImJbFB_`6 z?$qi&?B1LXMSbi8v$}5|LiEp9$G?n9c=Hfqe)hfoauV&9Aw>K9bon)>w1FScxa8ja zH}rZQH8AdUd(>8rI}77v$ANX28q>@;@3K7qrThQhpz2ejYC-rgkEppcqHd*B&Z^8+ zgX&h&?4LHS=JL3jJM_3(%H!&~!DH-dHK?wpLDkzvBPxd2HXcrS5HUy8yD;q^Jfhak z!H9Yl$Z|woRWDd$>bhgkV}1%XT6*j^ z@S#o`8J{s4)8La$qwJj&P^s74V>^MchJA>lWerDT8OMH_L6<8sFWgsD-7Ckoy{8Wa zU8opi2Eheth(3rR8pHH3%^IfNn_JL+SSRLUsCM5}NzKW-Dt2%lP95Qe|3sE4qog1= zo?c`W;ZJ>3{N0Hur|0}sMgQrUyQ(89V@*S34C;M4W$c&#iHy-)3K{!cSK=i@Kv@T=bN!Q$}C z1zioz?-#gJyloh?f6$IFawh?+In0IfI^NT-;);>mB!wJJgFhbD>`NzNSzGN>%IZUFz z@1C|F@UK979qxX$b+8ZflIZxcM;i8mImO%CzY_ap*h#7;4cyU-WM~`WBxSNYUmKiK zt?zx?kuXvEL7xm2dI(R2T=?fi&g%aocJ64e&O`h42RRUJ+=Y!%6w4DJaNHmaBf>4j9)2B5f$WR-V}tN+ zR5aomNRbq5HgBT(hHUR<^)Evwz)qg~mR|Rhy&qAato>oOiE zLU*at*Olw^h12dK6#K02$gq+9P^QEq zeuzr?8p(mgFTU(p4M5r-%z5Lu9^T(wuK7C7c?~(}YyHFVeLa!*yNpE_aNBYGaX;}N zGA0Apkh9~PC=1s9axRVmW|5S8X77A!#vRz2^c_N#a2YJzAIk83^b=or>{#OHIFKt( z7WUWn__|T#18MiS(Uxfqf$IT=4=MNHK-#Uqi7Pw&{6N|c;+sk)woM>Y*_ia=M5)k;U7b9`MPYh?X9C9 zbnM3o%pY6diw@I&EFO*TDYZYJ(`)u5*`a*l!-zFfe}qdP`Ooq#@S*FkA}xZQ`&G1s zzq%OP_v@r4csqsUNh+I!meuWBowsK+3Y?D``mZ6cE@;61XPC*i+86#sQTRmvB%u9m z`0L?b7fCs({z#SCWpsm%Q;LpWba-U>#b9bNI=&ZA zv9=eu`zyP^NFzi?Z|1_^wL)qAy#EA>o}1eN_ojC!p6>bv;oJLfwxaNR#kLs>5ob}@ zo050P3s1YenIcK6F&5*p36M z%)`WEQ{Bkxd&g*QJCJsJ2r+agT{;n+eqaA(7&IWtwG=s`b;2hBJ~&Lta`xwuXLr&s z&P0gtFZyQ#?dhqEoMv!0UEMWyAwom{rTN0|S_8?YP+sj27M&@bBm>lcJ{2GK>+QLC zo<9R5U&qlC{V$-DpijS!bkW7Pku&wcA>*A3C^!%_9S^$68^B4)Ooci>8F$Ui_)oZI zazWQM+>u9v;#DXrH7sEj(9o}}GXYV}X?o1`H z+=(6n7_)m~L(_M6%ttBV&~h#nLw7@85s#=;bO_jGb3a**7IL&$d%NS~l;SSo-js)k z+}G>)@A%l`-t=V#a^0Pm0VtZ#w9anM^WxZ7O@pKBN=oCs581;98h@6nD42go9GD_&7dNo~L3QN4U(z^9~`1yZc6}BPcqX@qOT3 zDbO0f^mX~1s>Ovr&Kr0YP1e0>IK)9sZv|IL_zzHw{l2b}zJe}$X5PS0kKb?U7cK*; zYKV|cHQ#-8ALl%8kDZ187|Eju-nMC!k8T|6AxQAeV`rm?IzD!`*14Y?h8!1#Un#oo z1(;+FYF$&c0G?Z3kroxVFeuuet^W>yQ9J&P%Vz$qXVIWgc)cQ1?r`I zcPD)~9ugk%_Q6~9Z}|k3q~a-Yy&n?=NpD8+GjJZenxe3c?ST44OsN!8S3c@A-`Q2_ z>@NTd$d`iLzW}hQ(?~yeX-jY>(Yv8~3AWjLTfV#m)rulcLJ_-fcmwGyfxPYRO@ATK zAivI^0L*#iDf9r*e;xG$oXfg5Qt(^^r*i5452$!4 z(v3iAG}y=P%9(B+r&qdHB8wl0%J|)*GJwN8*r`@beg_ z%SlVNPV#lW7xJJ|PmUwKbT6nVcG15PRYX}%HFM)pvn85;`MSs6Q33z%w41^I6zTEe z?nxh_`@)za{MH|R4?N`o%@_Vz(bRW=0XRPMV4SNUyw>hRXYDFYq<$VQ|C0@qOX%mR z{l1Pv&T#%;!sRD@9e?wLX8Xc_=x@a_Dr9JV-bbbvw8a^IpGP(vtwZ8;h%k^g29_qr zE}(*=B#-}w>D_$#sk%!JHfBobLc_YmJgZjq{>QsH@GOC2W30%JAPfyhfD3y*i(?p zV|38f!|mCz5g~$GZuyB6LKw34tx$|?R++>b#lj(DN?J|A{-tdb^ znyj%@YidWz6x|W{4Wzw%1&}Ud8%2sHFsdtM;ZIrhX9yxBvc6pr0a&V}F2gT_mQ|%Fpz5XhcB)Xt; z!x-3EJwA$;dbQUrf;gjS{-l~H)_+l04|Y!avyeNK$S-`=OOdyI?%hiv+a)?=Tj~IP zAKB}5+uMEJSMAR_?t(hb@-6%%^rSf*qX~2Wn>HRJevMUQRPcC%aDrO?x1tK%_QpfKg zNb1cfq`oYr52>t*7w#<%?+ZFMAlj)NQTaHfc>Pp9?%f3`4rY+`tMcbXc%=3z`8$L*Wadxi%%^g8MCR-jRsGmE zIGpui?i3Hy5~iXPe3WC9QW_C_fT{(lROX`y$>I+*?R@>%ex^gFe)VH^PoJte5 z6f57@pJs4*=YZddUF zS`<<$=sFke>2PuQ2-?%RXitZ!J?%r^d!_ZAs2VWaQ?d4X>xkpOMPrcp%cIWH(VN=k z!!oHg4$~LZ;~}h`uKl-yE?;7a_H(oONqzFhJA;<{J?EGDmXQ5F?I2|aNBXWi##o0- z_+~J~z8n7CH+8QM#8np#4&K9BEs7S4*SfFSM_Z=7AN|6$&$qYVGYOslS{&EA_U(aT z`n6O0_MRLU6@FmSYqc0Qdj=*QRPK|?y;r%nD))Nju2*iYa#t$1P`UG!J6XBu%5^CB z!+=chx5|A@xd)Z|B)evL4@|mM(XUtTdgazCccpR*l{;U#la-sUT!(T$tWoJJ_ci4n zRPK|?y;r%nD))Nju2*iYa#t$1P`UG!JDFX!cRY6QYv%ZZ+TdUN67`-7DIxq!y2SqL z{&)SIbZF%m{WCX9P1+CDZlsC-%l)5K0`+xk)>dCWBWM21n)-U-KX<*qEU>n&B@_te z*H^W)1X^OUQ?$IoTedu}*ndG;Ug;uFVO3pypvDtw@>JF1eVM9Iz!M5IG<&Lo!K#hp z5%z+rU}Ih5+C?63TPRr7+*Dr`0!jhu1GOPfQ>~}Isp*Q=W>2VUO?_bIOnU8!exDvL zShsfFrw5!iZF%1EMV|WB(8ZH#E?qJS@khYsrWT^qHP!^$mQ1R_>KDU;>}Q^K)!)t< z-0w;t?S>f}=Fg><*g|y;0Z%Qm+!_ol;?N?mrY0C@Y4J>I_N=RF@iaDh>Kdxn24=Jb zszY^6jl$zuSr-hoR@I;18VGLWz$mZUrl4n1jc3iqP@u(A74lSBv5-jgv%-}In?i`o z47s5$w9ZqFm*_m%ZIjxFud?xq#-1}KHQqRkf){Y%0M)~lnSq<-Fyn15vN%IAR{bTWz^9TFmg`#RRZgOwg zIT%lkNzWM`>@Q;Q6E_a_KN*9IU4#9dF?dQ0?uo&7srF;ayevO|kteGxuzucj&(hYq zdc6O*(Nj`>Vfk#Tj>}P#Q$6!$&Y4LYA@utf|G&!TU+v-lpZ+3y{paW(YmE{-^iFRn z+^*qx#TIZ6+#@4|7z3Ezy&jh;#B{(OxRdeB1)L3cGoEvZAMUMqe1NyZ{Q!rMrGUvT znIuF#U~xEbyfcg zl>_S9OVw=Eg~@BmLT)slndg7hjgE(4Reu2a$9Hc4D(sPY z$5yVOCkyyoJh^yCcattB-ChQ~8c!P@3ZaV)SlZ<`HLjo8(j@8{v3P8(s`ocH0c>iH z5QxhkXlt%&tcf8812wJH*nj!g@BeiPoU=WWV)nflZ+7772R!C)GidcYO>D56c$dT{ zD)$`amMXVaxmPK7vvRj9_fh4(q}(@^ds4Y6cgy&vDK}TS70PW??pKt%UAgxu_Zj8B zpxoao_oQ;o+&J%%P`Yv_DtESWzo6Vg<(4Yub0`E^kcs1Jk!`N6tSU3FD`x!S||v+$BmizSO6Y0Cnk{MKMF z&=|rtO*Qs`#LK7BifY79qNo+?f`O_U5XCSZ;ft$ULf&AoDJaAw!b_TJTI&No=*ap& z9`?bAMv<$HCd|-@Qoa#ebPW~QkIHK)#1jQyi@vOZf5NxPx#15lb)Z%%2MSTmhyt1mkH6UKGe`+M+gk2?yu(X?ochXG? zXP2%D^82v^+SC|ms|$&8V0BGv{I$p{=FGxh)zGpQLl?ZnxthNY#R}mX#BR-xUC%2- zweD9T=h*zMjZAactJX9HLn6bDrUVMERkGIx0|A(|*=skTi2>SZZ%}^M*&6~4)y*iQ zuiBe~7&vhna+AHeHG~b=Z`)hy)?!4(tl!=e3f2d3Z^&+f8mk+c#n0^PYt0boC)@vf zpYyQ$>n)x$o41RRR4UT@uX-9<)>j8ZX3U8EU%$_;1X2d?i&}!H{qeqOpW<&Z{tNhD zQ3AcPo>wdPLABqV9kUPqzap>yKV~8u`(nuV?GNEESHe7olwxm+%43IfN6L=eouxZh z?`+=LzO!fN_MN+S_U`Q4d35KAo#L*PyF7Pg-<5lp*oD0&uxD=1-o9WvfL@7vwr80X z5dZc2yp;g9IgAetO?| zsNWb6b@8J!P5xLO8J``yzB0ZOD!w;p(`JaD%SOyv2 zU%qJix2y3G+ag2$B>!UtCjWNDf8?~~TTyB9H)qT8$~!H8<>e-S?_9}$xvbPvWRm%t zhgqen?-&m0|K6wi%l!Nq^I%nh zU`9Vl-OFdYB&BQWk2o0obj_P$)L181a1b;}_&wK_Iq&wrVU|S0d z68yC`(jp1A6<9mL$B6haL62)$ht*gNo84efyX2N|Tue-HlxApSb3o{JnciRq&1vB* zqusd*y2$W*SLJ(4D~eVu_m_F|SCkcq+ikbGlF=<4)*3e-b{xWXyK9<(+(gKQ^;K(I zgzXNd+avU{Ky_2FM%cdLDnkm+h=;j1VEd-)tB5MavAnfmO(0lWg=?6xpAkf4+c>h! zNSLBVUf{ElitSFyNl+Ka(R~S!ml+KlS2jiKJ(s>f!#JI;%I$z?QjAuF2?t#ku^$seOY)463 zehcdT21e&P$^&cjk((PGXTWy>p#?z0j4mS73-qguoa$R zqe~rLmGDiRQh}o&m@RByW7&K_a)hmiky0SDg>4HXtANZAwwoDQ4P?HseVvhYK+YDn zTNr6}lvT9}+g3)}9A(u&Ze^t1QC0)wHb!oAl&t}BJ0m@gvX*8v0!D6!50Gy#vK>Bk z!uCx@?n4AXwlT8HQMN$X?qqn6qimtDeT(5p+m3 zos1j>GFRB{Vx%9)JYl<=krR%xItX(QBPU(8XgN4;S&40xrl4s&CT!0-ZYK|$@}Sxc zHq{H;a~y2DJ-#5Yrgg1F?q%|Q_ITP4TN=d1)4GZ#PG>Ls?27g&3^p~e-#+%+BmJyy zr2_6}&)yhME9?RGK5Q4Z3yPL6U9qBA7}x%lBwl)9g;y9|dFW%d3#j87oBy5Y1rq6= z4iDXKudQ#Y3JF_r>B<#F;JJgkHuRLzLaYjO-H=*`G>fgWc*XK%{?dvv;m9HNB_o_a zS2*@DDkHLeOc5mzudrp(@s>#N5 zqU8wuef5wE+7fEzIGeaVwbcle@>QljQcfJN*!(Wm!dqJK^u`M$$ z2GvpAv_aT>#sT;VhYzNC!d7HF2FxiEB&+RQV-`4*iG3p;w+9KwNjz-gZjn43f$lJI zKhpa)kQ5SEciL;3T4}dYPqDLJSE${&A3VdH{#7L<{_?z)UVmPhH*XG(<#pTTjx#Ys zVXcC8cL6KTE4Z%9x^-R+p6;*2`p}|3t*d1komOyZQpay-Vkx7Pw_i0x& zllh&nHE}?PBG%Tn1W?D#tUaKbX-BslyUElkgzZbrn`p&}E*E4{vZDa^xvx;6TR3zI z(;|UG%$aHhMi*^mQo5-f*K@c`iTX>bTCNbb4NM#3D5Pd;c1!5HHb))G%;Q+q&=5u4 z=%A|E9&ctEJ^xAv)y{TJB*d1k?aPh>@EX2dv)%7liC*sTVMiOAwYKjvidGR=TUEVL z*dB-^2L1D(gWAA$N*aaw5M#RtLvehMv0lQEzlRy?BMg%4V(chkP(qI|b|M}awC$se zLH_`SzI}|*6h@&6A7|9VD74`djAk=R3h_zCb0rRub~9coaR{}C@zoNCSWhwDEO7|- zG~?|OhiKntyhoFbn-n8Ac1?^xgS?j&VrpT1s2m&b!uB0*pukZ-l5!tY(iYRqn!5`P z${fQ;k$gEC1vC|;3~fe4)FcN8n4eXLS!S)lz{{#ob5-PpM+8qe>r&?WVJgJ@SjjxRFb#M>#ry-_vhyo7cb4r zKTp`wM-?+i8U8cZ;!i48%CuChBSTed^H&rtFRECYSMC+|6w-lP?*!+l2-#m!SzJ+6 z;e!q<@D`xFMz4fETV7cr`JF zE)WK}`4Fk1|lz+5qcSr&*?NmwA#n1E>0B?V9h zK|H8t5`^L?N4bcRgwW_Yih%OGLT_GKS>AqA?T_ zh?Hc&P54SAg9;NVgvgQ*9%j6-%v*?kJ%Uk;-m;a{uG$GLDlYaeL!}K2L}4X)<>!Gz z##(Vqh0R~OvT&tvW&8j-07wxbnKWFFU5SRu?b&r_CpAw$4#4PuOrAT|FvY^L zEJS0);aU`fF3zAhT;I+^@Ns@W9gnVU`O*d&vh^c6&y5bj%cF)#&}a%aK8OKV`HKnu z3hz>J=5q5mwjuz9@Ey-P2xhZ8DfBph5vc$=nhVtAH#Ia@1q0ANP-klcrh3rJ?KHu% zosSzoJOzOkysE&K^a37C^S0%403r~lhaw7KwhBol1#02~gq}#ggOWTYt;=LucTrju zRl&8Co6BS}@<0<9#Uds_sr#$B$b|Lwe%do*rZ#g`SBSQbcUh|5#LFxzEZ`ym;}L3+xE(E z*j8>J@VvXhPz30#Mn*~7c~CKDJ<4b<&Om8LWp_05Oy+`#Y!rRCPX;9md4IHNO=K~zD}e@w7&o- ztEk40fHMDwD74?H2vsE`fIx+u-7|z2+W)KvK%avBodvPs7UHu_^y8ZNn~L-(2--!n z5Fyt@F#>W;Gy{+|F`r5%d$_C(ONQ19DF~I$*NKx$XRb$;P9yxx@|b(2B6drneigjV z*JfvFtMscO>4hrhJQUYGU|FPb?FLNOLX11_%f`|HV=LTImjqEeXitOAN5@thYGasiMjzfs8LK(>yMJ+PIE0sWB5 z0S$1ZdAT`?Wz!%QGs-F7RxBjhcZOzpP_a-3Ul@{Q>fWe?th~v# zMV41N4t(j1)No4jxANz+4aci9H&CI0Qtf=g-`?(c*`mW0^7IL++wHDTh^hW zebMi4h9!`{Dun6rI?@d@NjJD`qFqLt>-W=uwLai)k?o#b*qOL?9EVI3X?Q-Bg^g8Q zJCo9B5Ey~~ya*3=WE;?tXh?3s%WST@=fHm=Op7ODW2>I)9bWCNBUku`7i( zg|K8ARW7&KAiL1A{EDsG54NcatJ&D-$G5q7nDdjx%o;2KV3L0inDetSQAWg4o3FtO zij6|cCVg%ZS;gltiT9rURn5(Q-nG@{P$3mGSJRwBXp2d3mo0ObEHbY$z)?;@uU7a2 zu+!uEULpSZ=i23E(;faxcup(417vz!*BAZ}4n5kLg=65*qfJ_-8k;cP_)Ud(!-pR2 z>}7sG6{}E=HnH$4pwkl{Dx4389_?GA6P0cko1yzZrFc7I);*;*MOoxFbj|?wDpR?g&$hJ7(d< z9YNOOju2~cM~Jn!BZL-r%t4Dg31D$20W9vA1&cdLz~YVxw78QLTHFyN7k30%i#tMi zaYsPZ;*L;raYyi=#T^mU;!c8caYwMZxFgtH&P^gDvbZBGvbZBmF76027k3g?i@S(N zWF=Q%azsd8A`M#H5rGzW?8?O*fu}C+;wfa*;*M}@aYu-`xMN1OxFa}faYtxmaTkSI zi#wtXvA8obwxb~?NcE}A8MX0OfM)jj@1Qf#Puq4A2EIhLj+7iPV-QRlq@K?t7JbWV zMP>awQPS2WV-mF<_KeyjioF2)P41AgBk)4yrGyny3M3iP4AaWA1;V{GipPC#6q51- zh4>MmSO&msY8d8JTUHOloNCKD;eJ8!Tn--h8&OEgy9#NA&(&6P!!>1EfYj9ziF)V= z45(xWYOl~pH>4=0kz6oTG;bjWRWu7IKsU0NI#RKPKtOynHxME%W<<-R;&Iu`SC%br zF1wM^(|mt9ol0&R1kNBpWMWC(&}_yhv@u_Vm)$uU|090}e|n5vqolQ}{MXV(egrB# z+USvV!a@gXUw&-RpfZFMz`oEV2<4M}te_fL#Nw&qZX}~F^Vq^dO;07 z1j@mOAR2tw#o$9O4L=0YVaY{9DE2KH24rf z4L%Z-gAc*x;6t!A_z)5qdEroiNgki0}1H24sK1|N3i z;6vc4gO7_sMh!lMTZ0cF=HSDOYVaXAYVaX6GWbMc*5E_5L4yyCB7XEjp(WgcwipjP z{3id}`ldB_g{%grXDvcYH9Pw}bWr+f+rEqTnt*kEIssS#<;v+ibRMdD56fl8O0TV)5Nq_=o0x4igAq7m3RKNsT3YZX9 zzyw4oU_wm=Oz*NQ8l-@UKnj>$selPQRRKFFWRwCX+)}`Vm#O>N&yoZQNU4{rGSYRt$^cf z)KsYz+V5NlqDSJ@1qzA~?W?s+}PidXX%)3#x zfW{yc{T=aueZRUtL{~_pQubEL)=FPBF)fP1q5# z3o@x4A}P zC&{o30@yZEzuh$jH5)~iR(kp!Ot(8mBRc&XuFK&#BVkQ@Nd23xuOWDfaf&^pzKtWu zjD(4{ht%(MRge(@>>+K=2@osV9#X&7;YOr}vWL{$9qlZlvWL{KW87&ddr18&jHejN z9#ZdMJkwD2koqRZJ%+M})H@l^G6va0>eoA{AhHc<52@e4=v)IvjIf8)Z*+`??*c+$ z52=S4T|_ACA@#2^dJdtmht#_m{Q{w|htxMSnoB6`A@y!Xmm10*Qoo5)Dlo_%QvVvu z<^z%=^d3e^fnapn!pJHhbA)~~BddYT7y8#3SqJ27q2IztvqAQd`c_8T46=vRZ)K$2 zAbUvtHb!nV$R1L^osk}c>>>3#7`YujK)%7qcKFl@{hN&3hX{adV`P^Bdr19GhW8k- zht$8taIZo3kovb7ISd53+0IBG5aebDBd-HNZgw(q6v$km-^EBjka<#Y;>vwwt2K|{v||DkOq*p?g`ZCPGjkqV2!f&S&ve{h~=X_CqjVb zqkS)<95JE$7?p;Q`p2XY64|U#&(uCfM2twnJK9S`h*&=AztJdgl2iYq_9yC}uuOyj zG!E7Oq_GZhoJC@PplySvo%lY|#z3V;_)bRi{aNuP`-}6+VDE!jgm;-2)-wA0S|x(H zUqUn~twR5pQ%gC&wW>xY_ZRJcctO@d;qudKyTve4Nz84&x4F2 z^)E4Rq7^6lU64u1MwC&c-ol|%m}VJ8;yXR0@lvh8=%=krN;g&HdJdNKh$Y-qA*p`jrkUa_o~P#+I)BWe1i1i0ztwzhf=Bx}l6B z_3tu@h9-?7^#>w}K?yzRpo-m2Nuy97Vr&;-D30$j)=L=j_b_99gh3JQV(chk&_s_g zri>!>M;U_>f+v*jV~mV<}>Q6J?F8v|e_ZjceWQ!&3$SqhCsc4Y*vQ|tnjUx5$a03Ny8b#{&F~wbsb}M6e z%8X$oUN=#1Dd^8TXqZkcjUtQz!R{}sTu#PY{=&-T`DFVj67?gFxftAyrF4vF%@khX zmLUvpV~s_7k!f~A-c-PrjrvPWL+30#C1(AHj^&8h=KKXD9JU(GlWrL0%qEM(D8p*` zI*9%)7fpr|qfM@r&vw^s91(?&o-CEZf)LlQmWveq3D;Zjl=Gh_T~`B^-5SQA>NOF4 zx9bQ5fvAzBtqAlzt~(JXEwTi1+J3bNr>yBU8=yFmS9zs`?Jd@wpptHikdG1>Lxr`1 zvc3H=;)4lgc?CWpQjRTU(z6*(ZCoc}&8!XiTX3k0S9rAXq^6k=3bx`Z25kbRi>NBF z?{X2qk$yjJPi@7FeWN-J##It^u&$VGPKjRwKmD|AV-jIsR;~Q!mLf^AoMp? z3~e5zZrif!+R-r6s;#D7rumiVZ~B(pF^i|lJ);D~F_w#as8&P}z@zNZXh!Z| z+oEoM724W9#q|k`L4s^gg8qOCt;XdWQrflD0&YU`qfPnhc7aLXQVIgU3{jddv@5;@ zF0FiYUBgB$Exs|oQ&PS!Gw8Bem)wrg)a(1hAQ5G?1^?&k>(`CdR%zK{Ouq6imfl)6=)|LM z@I+z(mZh(6gOjbVZ-%pgf__y6^_xM(nA;TTN=d>R@O-sfH|7E5bu)XN?-&-ovAz8& zF@Be#Z@|(_45NCbvQvs<0u}b?W#xWrv7nl~#&`N6e)W<%@u+FE$uXJKM16ScBSHVSbHmRvfbE=Y0<~`VVjJ*`4#^N&F_BL*+l_j!$DTu(v#B?N zKBkZk_3n;wlg4Od!fO0RLKS>{Bm{v7<;>PXY{T zgH_eA%*6`;b=3%P2762tj-fMPj2lJy9m-c2vpH|dSXmoIwv>rDPlz%t5?UE;7HIdQ z43d@*RQ4+Vljbr=A|=tMb+xk1_)l(@N8A;}o!kt?Q2BEd4$9pJ0`~vSnCYBCXg5*J zW|x^ojQDBW(y@1y!b#mkNqL}+Q#iSsD7gy>f>;t9!?uSAU!z+=NP_K>G zQIz;;+vqz?Bbwp$B0`M#GJuuPiX*NE@HT+dEdWx#g}=0H6?U==Drg^$L)JsdamafJ zppZuZq{s4SP*ggMJ2NP{MF1e;S`{gah|}j#eK4?A76Xb&;LcU4;t_&>+O|I+*^#n5 zTd4SO0uDp)wi+@C^Af>j^C_b&Nr!P*p`@28`eoyeADr9^Z{Fh|mJEjrn#wYHG)-MnX6`Fm6% zW2PeyW7&YZ1XGz3Dg{JuHWAuEjk0TN_=E$S*PoA}WTY_FLTi+Xns=;7I#S#v=?hF@ zq^SnQTpwzw!PQoNywh8aiNa%)xXX5*ISvkHM0Zepk4wJ0hvaK%Z8G_ukbK(}-x=kI zo*r!+uE3%}Ya9m1&v?*c`@TS10K--xhR}avnEHoDrT_c!$W&3zd@4R?5&jLweEeU8 zCyorlP@bk;W&F9oaagFTUDDAu6C~ZdlAh>nV3{cC=GFF+4*n!bx30K<3_a2=+CKZL zlg)EopdOR-7Svztr5X=>{_E3e%^XfQSNL>ej+jG47iwJJx)=Y(X$}z`)*&MC!;0fP z)Tn{;9d(FEpgcq*hz=3i#UUcObco0<4iU+vLqu}rAtFKY5RqxtAtGVw5RqB<5RoA3 z5Rnk;5Rnk;5Rni%L}U&+M3evy5hZ{_L}tMuq9ouDkqLB&C@FM^NRT{4B*;2MB!mwU z35YsGB-A`aBzVvvA`#Rfq6Fn3BEjY%BEi-nA|clH=48UGC2%fb@(__A^AJ(O>JTyF z5jim|FgYS5FOdcvA`*cP5!sc8hyTc$c*X`k>IF9L_#Bn zh*6kzh)A^PLqw-P&`7UE$V-3mrlmIWJTytI1r5^0#vP1{cxs_NYHk3Kf7-TN0Va^K z93};cQX53lgyaWhJ_ ze|?o7D|sw`GWQ`fHmKw^^l=cF)|)=R0Nt*xInhm`KJGz~b#?2B?M!?;9;3yl-Fjj_ z<<=9FyfSXHts05?un%e6W|!BXz~Ptc>9PWQ%!&(%TGyb!@6;Pt?6KFN7*3tf5$s)C zk+9C^2=>j336={kdv`lYWStb2O7j}?5o58UZ6O*k?)3IM*y!4sfEg1;%0U+{ z;9~2@g$sJ**ulu5lGDqJF2b9;!uWa?!s;?Q$Hx?%-CBj&2d~1M{t|BqmQH@Ww_B7C zJy5u!tc2g9#^ofQVWVl@N*g!krlDi}uw{r`xbo!pkZ_YJ@9Q`wFx?qNH}4{KoH?u) zBBZ!z>$$0s7D~b~ao9pclj*`T4KHvwCNYc0Wrdl{go&;Sx|qf>g|RFV|Ea<{vW7Jv z!UQVUVhEiW0uU#X?2i15uK-UjUAM7?F1@ufQjkGXC98{5rBq&~VP+!NX60B`(gim@ zdSSUtWI6IOs3*IY({7bxX~sE-Shz~+TB?PkFoTkHx>S5tGRrv1L>DCxS!z0bOippB zJsDi-p;oAlBKAp*@(I9bfZx+>5sq`&H#6c}T-O+A-3m1ajeLA97W=AQX#uzM)?}5gRLjvpK_W}ewa1N z6F=SpzY@DJDNw*_lqXP*@&wT+&n`xJa%q%j7o$A6G|H1JM|pzeD9gwQC@95l*H0HeGFFv>FvMtMoVD9;2MXGS&36C5?l6B-%iqcCffCtCC< zKfoqKTWK&g?8@qGS=cUEEZDn4Ys;!q*Wp# zW)w`zWyI=xXhK_Yx~SJ9KqfzA=oSs|QN$xD6?#zsn-|(N zBA{w&Xx}diM^%~iIbSlZpY2~q(w)s|jRdqndkCqH8rdYYb=qSLHU>8ED;*6QmkFsn zstJdaYT4nWW`lhUx*QH?DFMFlTq`%HOjVRS{IqRNSdEUsW!pFtA#fvho5r4j<^_>& z{xvxCEvv>IQuD_tmz z4fq?HFxjmO)R;AdjmWpO3KT1q{o7RbR4u>eYC$)qUM#eCxVg^qHwWtGEST>%l?>}F zy!MF3-lsJyA^waGNk47d^{Aul4OQ}WRiV9tc7~abtygW3N~1^fZf*FBT#a)$J5^o{7ogVvlaoWL7-{p0pQxa7{GeG*L_wqfGw#2t_AQW zfGlcFm&}w^vz;Q|t6hu@U~V|W@!BsprTGL<DzQ8lMjC9_19niz-tp7mA8{ab{anvKGowiOs< za4zMdPVujXkJhYl4sy~}4k`(t9JB$L(J^EW=2AjjAX}Ax4@LE?Mmyac-8aqXo-?ES zHAS~~$mnuZWW%y$arIGT2ehZm$czjn+f)KbHhLF-#zMtDxIiGA$E|#*x4e#6xXqum zxz5@!`+$A?JR<)hE7e)8^ ze2?4iq!S-w9sV3T{;+6ogcCQkHE||7tJ5+NFs+Fv;nXFHY*`Z%-R_!%Ft8@36r7Q; zd6+cOr(Ix8d^^}uoI_a?Qv{ijFfrD|z3A{B5s%wdJxC%U>ULFF6DJ|4Gh$5~1`1r> zt_o{n!kx~DH8J5S&WJTJ;hD~eH8J5HXT+MA@GNJnH8IJX?X;|k37zYN39z tm^- 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 literal 0 HcmV?d00001 From af0049082d684f970cf608a2aba6f6692a0d1844 Mon Sep 17 00:00:00 2001 From: anhduc1210 Date: Sat, 4 Nov 2017 02:01:12 +0900 Subject: [PATCH 2/3] GPU support for SCFpyr --- Gpyr.py | 20 +-- JBhelpers.py | 30 ++-- Lpyr.py | 52 +++--- SCFpyr.py | 385 ++++++++++++++++++++++++--------------- SFpyr.py | 100 +++++------ Spyr.py | 78 ++++---- TESTS/unitTests.py | 440 ++++++++++++++++++++++----------------------- Wpyr.py | 62 +++---- __init__.py | 120 ++++++------- binomialFilter.py | 2 +- blur.py | 14 +- blurDn.py | 10 +- cconv2.py | 8 +- clip.py | 8 +- comparePyr.py | 8 +- compareRecon.py | 12 +- corrDn.py | 6 +- factorial.py | 2 +- histo.py | 12 +- imGradient.py | 6 +- imStats.py | 28 +-- kurt2.py | 2 +- makeChangelog.py | 14 +- mkAngle.py | 10 +- mkAngularSine.py | 8 +- mkDisc.py | 12 +- mkFract.py | 10 +- mkGaussian.py | 14 +- mkImpulse.py | 6 +- mkR.py | 8 +- mkRamp.py | 10 +- mkSine.py | 14 +- mkSquare.py | 18 +- mkZonePlate.py | 8 +- modulateFlip.py | 6 +- namedFilter.py | 4 +- pyPyrTools.py | 226 +++++++++++------------ pyPyrUtils.py | 374 +++++++++++++++++++------------------- pyramid.py | 2 +- range2.py | 2 +- rconv2.py | 4 +- rcosFn.py | 2 +- round.py | 4 +- showIm.py | 62 +++---- skew2.py | 6 +- steer.py | 34 ++-- steer2HarmMtx.py | 12 +- upBlur.py | 10 +- upConv.py | 4 +- zconv2.py | 6 +- 50 files changed, 1186 insertions(+), 1109 deletions(-) diff --git a/Gpyr.py b/Gpyr.py index 0db48f3..9408e74 100644 --- a/Gpyr.py +++ b/Gpyr.py @@ -1,8 +1,8 @@ -from Lpyr import Lpyr -from namedFilter import namedFilter -from maxPyrHt import maxPyrHt +from .Lpyr import Lpyr +from .namedFilter import namedFilter +from .maxPyrHt import maxPyrHt import numpy -from corrDn import corrDn +from .corrDn import corrDn class Gpyr(Lpyr): filt = '' @@ -13,8 +13,8 @@ class Gpyr(Lpyr): def __init__(self, *args): # (image, height, filter, edges) self.pyrType = 'Gaussian' if len(args) < 1: - print "pyr = Gpyr(image, height, filter, edges)" - print "First argument (image) is required" + print("pyr = Gpyr(image, height, filter, edges)") + print("First argument (image) is required") return else: self.image = args[0] @@ -22,10 +22,10 @@ def __init__(self, *args): # (image, height, filter, edges) if len(args) > 2: filt = args[2] if not (filt.shape == 1).any(): - print "Error: filt should be a 1D filter (i.e., a vector)" + print("Error: filt should be a 1D filter (i.e., a vector)") return else: - print "no filter set, so filter is binom5" + print("no filter set, so filter is binom5") filt = namedFilter('binom5') if self.image.shape[0] == 1: filt = filt.reshape(1,5) @@ -40,8 +40,8 @@ def __init__(self, *args): # (image, height, filter, edges) else: self.height = args[1] if self.height > maxHeight: - print ( "Error: cannot build pyramid higher than %d levels" - % (maxHeight) ) + print(( "Error: cannot build pyramid higher than %d levels" + % (maxHeight) )) return else: self.height = maxHeight diff --git a/JBhelpers.py b/JBhelpers.py index 9261b77..e097382 100644 --- a/JBhelpers.py +++ b/JBhelpers.py @@ -1,6 +1,6 @@ class struct( object ): def __init__( self, **kwargs ): - for k, v in kwargs.iteritems(): + for k, v in kwargs.items(): setattr( self, k, v ) @@ -65,7 +65,7 @@ def nbimage( data, vmin = None, vmax = None, vsym = False, saveas = None ): ''' from IPython.display import display, Image from PIL.Image import fromarray - from StringIO import StringIO + from io import StringIO data = rerange( data, vmin, vmax, vsym ) data = data.squeeze() # try to be smart @@ -93,14 +93,14 @@ def nbimageLCVbak( data, vmin = None, vmax = None, vsym = False, saveas = None, ''' from IPython.display import display, Image, HTML from PIL.Image import fromarray - from StringIO import StringIO + from io import StringIO css_styling() data = rerange( data, vmin, vmax, vsym ) data = data.squeeze() # try to be smart if 3 <= data.shape[ 0 ] <= 4: - print 'transposing' + print('transposing') data = data.transpose( ( 1, 2, 0 ) ) s = StringIO() @@ -135,7 +135,7 @@ def nbimageLCVbak2( data, vmin = None, vmax = None, vsym = False, saveas = None, ''' from IPython.display import display, Image, HTML from PIL.Image import fromarray - from StringIO import StringIO + from io import StringIO import base64 from PyQt4 import QtGui from PyQt4 import QtCore @@ -145,7 +145,7 @@ def nbimageLCVbak2( data, vmin = None, vmax = None, vsym = False, saveas = None, data = data.squeeze() # try to be smart if 3 <= data.shape[ 0 ] <= 4: - print 'transposing' + print('transposing') data = data.transpose( ( 1, 2, 0 ) ) s = StringIO() fromarray( data ).save( s, 'png' ) @@ -157,13 +157,13 @@ def nbimageLCVbak2( data, vmin = None, vmax = None, vsym = False, saveas = None, matrix = numpy.require(data, numpy.uint8, 'C') (w, h) = matrix.shape - print matrix + print(matrix) qim = QtGui.QImage(matrix.data, w, h, QtGui.QImage.Format_Indexed8) qim.ndarray = matrix # do we need this? # make colormap incr = (256/nshades)+1 - colors = range(0,255,(256/nshades)+1) + colors = list(range(0,255,(256/nshades)+1)) colors[-1] = 255 colctr = -1 for i in range(256): @@ -216,7 +216,7 @@ def nbimageLCV( dlist, vmin = None, vmax = None, vsym = False, saveas = None, ''' from IPython.display import display, Image, HTML from PIL.Image import fromarray - from StringIO import StringIO + from io import StringIO import base64 from PyQt4 import QtGui from PyQt4 import QtCore @@ -255,7 +255,7 @@ def nbimageLCV( dlist, vmin = None, vmax = None, vsym = False, saveas = None, # make colormap incr = (256/nshades)+1 - colors = range(0,255,(256/nshades)+1) + colors = list(range(0,255,(256/nshades)+1)) colors[-1] = 255 colctr = -1 for i in range(256): @@ -325,7 +325,7 @@ def showIm( dlist, v = None, zoom = 1, title = "", nshades = 256, ncols = 1): ''' from IPython.display import display, Image, HTML from PIL.Image import fromarray - from StringIO import StringIO + from io import StringIO import base64 from PyQt4 import QtGui from PyQt4 import QtCore @@ -353,9 +353,9 @@ def showIm( dlist, v = None, zoom = 1, title = "", nshades = 256, ncols = 1): vmin = p1-(p2-p1)/8.0 vmax = p2+(p2-p1)/8.0 else: - print "Error: range of %s is not recognized." % v - print " please use a two element tuple or " - print " 'auto', 'auto2' or 'auto3'" + print("Error: range of %s is not recognized." % v) + print(" please use a two element tuple or ") + print(" 'auto', 'auto2' or 'auto3'") return data = rerange( data, vmin, vmax, vsym ) @@ -377,7 +377,7 @@ def showIm( dlist, v = None, zoom = 1, title = "", nshades = 256, ncols = 1): # make colormap incr = (256/nshades)+1 - colors = range(0,255,(256/nshades)+1) + colors = list(range(0,255,(256/nshades)+1)) colors[-1] = 255 colctr = -1 for i in range(256): diff --git a/Lpyr.py b/Lpyr.py index d8992b7..1773d7a 100644 --- a/Lpyr.py +++ b/Lpyr.py @@ -1,10 +1,10 @@ -from pyramid import pyramid -from corrDn import corrDn -from namedFilter import namedFilter -from maxPyrHt import maxPyrHt -from upConv import upConv -from showIm import showIm -import JBhelpers +from .pyramid import pyramid +from .corrDn import corrDn +from .namedFilter import namedFilter +from .maxPyrHt import maxPyrHt +from .upConv import upConv +from .showIm import showIm +from . import JBhelpers import numpy import math import matplotlib @@ -20,17 +20,17 @@ def __init__(self, *args): # (image, height, filter1, filter2, edges) if len(args) > 0: self.image = args[0] else: - print "pyr = Lpyr(image, height, filter1, filter2, edges)" - print "First argument (image) is required" + print("pyr = Lpyr(image, height, filter1, filter2, edges)") + print("First argument (image) is required") return if len(args) > 2: filt1 = args[2] - if isinstance(filt1, basestring): + if isinstance(filt1, str): filt1 = namedFilter(filt1) elif len(filt1.shape) != 1 and ( filt1.shape[0] != 1 and filt1.shape[1] != 1 ): - print "Error: filter1 should be a 1D filter (i.e., a vector)" + print("Error: filter1 should be a 1D filter (i.e., a vector)") return else: filt1 = namedFilter('binom5') @@ -41,11 +41,11 @@ def __init__(self, *args): # (image, height, filter1, filter2, edges) if len(args) > 3: filt2 = args[3] - if isinstance(filt2, basestring): + if isinstance(filt2, str): filt2 = namedFilter(filt2) elif len(filt2.shape) != 1 and ( filt2.shape[0] != 1 and filt2.shape[1] != 1 ): - print "Error: filter2 should be a 1D filter (i.e., a vector)" + print("Error: filter2 should be a 1D filter (i.e., a vector)") return else: filt2 = filt1 @@ -58,8 +58,8 @@ def __init__(self, *args): # (image, height, filter1, filter2, edges) else: self.height = args[1] if self.height > maxHeight: - print ( "Error: cannot build pyramid higher than %d levels" - % (maxHeight) ) + print(( "Error: cannot build pyramid higher than %d levels" + % (maxHeight) )) return else: self.height = maxHeight @@ -144,8 +144,8 @@ def catBands(self, *args): # set a pyramid value def set(self, *args): if len(args) != 3: - print 'Error: three input parameters required:' - print ' set(band, element(tuple), value)' + print('Error: three input parameters required:') + print(' set(band, element(tuple), value)') self.pyr[args[0]][args[1][0]][args[1][1]] = args[2] def reconPyr(self, *args): @@ -169,15 +169,15 @@ def reconPyr(self, *args): maxLev = self.height - if isinstance(levs, (str,basestring)) and levs == 'all': - levs = range(0,maxLev) + if isinstance(levs, str) and levs == 'all': + levs = list(range(0,maxLev)) else: if (levs > maxLev-1).any(): - print ( "Error: level numbers must be in the range [0, %d]." % - (maxLev-1) ) + print(( "Error: level numbers must be in the range [0, %d]." % + (maxLev-1) )) return - if isinstance(filt2, basestring): + if isinstance(filt2, str): filt2 = namedFilter(filt2) else: if len(filt2.shape) == 1: @@ -297,11 +297,11 @@ def showPyr(self, pRange = None, gap = 1, scale = None, disp = 'qt'): av = numpy.mean(band) stdev = numpy.std(band) pRange[nind,:] = numpy.array([av-2*stdev, av+2*stdev]) - elif isinstance(pRange, basestring): - print "Error: band range argument: %s" % (pRange) + elif isinstance(pRange, str): + print("Error: band range argument: %s" % (pRange)) return elif pRange.shape[0] == 1 and pRange.shape[1] == 2: - scales = numpy.power( numpy.array( range(0,nind) ), scale) + scales = numpy.power( numpy.array( list(range(0,nind)) ), scale) pRange = numpy.outer( scales, pRange ) band = self.pyrLow() pRange[nind,:] = ( pRange[nind,:] + numpy.mean(band) - @@ -349,7 +349,7 @@ def showPyr(self, pRange = None, gap = 1, scale = None, disp = 'qt'): llpos[bnum,:] = ctr - numpy.floor(numpy.array(sz))/2.0 # make position list positive, and allocate appropriate image llpos = llpos - numpy.ones((nind,1))*numpy.min(llpos) - pind = range(self.height) + pind = list(range(self.height)) for i in pind: pind[i] = self.band(i).shape urpos = llpos + pind diff --git a/SCFpyr.py b/SCFpyr.py index d702b81..8bede10 100644 --- a/SCFpyr.py +++ b/SCFpyr.py @@ -1,211 +1,300 @@ -from SFpyr import SFpyr -import numpy -from steer2HarmMtx import steer2HarmMtx -from rcosFn import rcosFn -from pointOp import pointOp +from .SFpyr import SFpyr +import numpy as np +import cupy as cp +from .rcosFn import rcosFn +from .pointOp import pointOp import scipy -from mkAngle import mkAngle -import cmath +from .mkAngle import mkAngle + class SCFpyr(SFpyr): filt = '' edges = '' #constructor - def __init__(self, *args): # (image, height, order, twidth) + def __init__(self, image, height, order, twidth, scale, n_scales): # (image, height, order, twidth, scale, n_scales) self.pyrType = 'steerableFrequency' + self.image = image + self.ht = height + self.order = order + self.twidth = twidth + self.scale = scale + self.n_scales = n_scales + self.nbands = self.order+1 - if len(args) > 0: - self.image = args[0] - else: - print "First argument (image) is required." - return - - #------------------------------------------------ - # defaults: - - max_ht = numpy.floor( numpy.log2( min(self.image.shape) ) ) - 2 - if len(args) > 1: - if(args[1] > max_ht): - print "Error: cannot build pyramid higher than %d levels." % (max_ht) - ht = args[1] - else: - ht = max_ht - ht = int(ht) - - if len(args) > 2: - if args[2] > 15 or args[2] < 0: - print "Warning: order must be an integer in the range [0,15]. Truncating." - order = min( max(args[2],0), 15 ) - else: - order = args[2] - else: - order = 3 - - nbands = order+1 - - if len(args) > 3: - if args[3] <= 0: - print "Warning: twidth must be positive. Setting to 1." - twidth = 1 - else: - twidth = args[3] - else: - twidth = 1 - - #------------------------------------------------------ - # steering stuff: - - if nbands % 2 == 0: - harmonics = numpy.array(range(nbands/2)) * 2 + 1 - else: - harmonics = numpy.array(range((nbands-1)/2)) * 2 - - steermtx = steer2HarmMtx(harmonics, - numpy.pi*numpy.array(range(nbands))/nbands, - 'even') #------------------------------------------------------ - - dims = numpy.array(self.image.shape) - ctr = numpy.ceil((numpy.array(dims)+0.5)/2).astype('int') - - (xramp, yramp) = numpy.meshgrid((numpy.array(range(1, dims[1]+1))-ctr[1])/ - (dims[1]/2.), - (numpy.array(range(1,dims[0]+1))-ctr[0])/ - (dims[0]/2.)) - angle = numpy.arctan2(yramp, xramp) - log_rad = numpy.sqrt(xramp**2 + yramp**2) + self.xp = cp.get_array_module(self.image) + dims = np.array(self.image.shape) + ctr = np.ceil((dims+0.5)/2).astype('int') + + (xramp, yramp) = self.xp.meshgrid((self.xp.arange(1, dims[1]+1)-ctr[1]) / (dims[1]/2.), + (self.xp.arange(1, dims[0]+1)-ctr[0]) / (dims[0]/2.)) + angle = self.xp.arctan2(yramp, xramp) + log_rad = self.xp.sqrt(xramp**2 + yramp**2) log_rad[ctr[0]-1, ctr[1]-1] = log_rad[ctr[0]-1, ctr[1]-2] - log_rad = numpy.log2(log_rad) + log_rad = self.xp.log2(log_rad) ## Radial transition function (a raised cosine in log-frequency): - (Xrcos, Yrcos) = rcosFn(twidth, (-twidth/2.0), numpy.array([0,1])) - Yrcos = numpy.sqrt(Yrcos) + (Xrcos, Yrcos) = rcosFn(self.twidth, (-self.twidth/2.0), np.array([0,1])) + Yrcos = self.xp.sqrt(self.xp.array(Yrcos)) - YIrcos = numpy.sqrt(1.0 - Yrcos**2) - lo0mask = pointOp(log_rad, YIrcos, Xrcos[0], Xrcos[1]-Xrcos[0], 0) - - imdft = numpy.fft.fftshift(numpy.fft.fft2(self.image)) + YIrcos = self.xp.sqrt(1.0 - Yrcos**2) + imdft = self.xp.fft.fftshift(self.xp.fft.fft2(self.image)) + if self.xp.__name__ == 'numpy': + lo0mask = pointOp(log_rad, YIrcos, Xrcos[0], Xrcos[1]-Xrcos[0], 0) + hi0mask = pointOp(log_rad, Yrcos, Xrcos[0], Xrcos[1] - Xrcos[0], 0) + else: + lo0mask = cp.array(pointOp(cp.asnumpy(log_rad), cp.asnumpy(YIrcos), cp.asnumpy(Xrcos)[0], + cp.asnumpy(Xrcos)[1] - cp.asnumpy(Xrcos)[0], 0)) + hi0mask = cp.array(pointOp(cp.asnumpy(log_rad), cp.asnumpy(Yrcos), cp.asnumpy(Xrcos)[0], + cp.asnumpy(Xrcos)[1] - cp.asnumpy(Xrcos)[0], 0)) self.pyr = [] self.pyrSize = [] - hi0mask = pointOp(log_rad, Yrcos, Xrcos[0], Xrcos[1]-Xrcos[0], 0) - hi0dft = imdft * hi0mask.reshape(imdft.shape[0], imdft.shape[1]) - hi0 = numpy.fft.ifft2(numpy.fft.ifftshift(hi0dft)) + hi0 = self.xp.fft.ifft2(self.xp.fft.ifftshift(hi0dft)) - self.pyr.append(numpy.real(hi0.copy())) + self.pyr.append(self.xp.real(hi0.copy())) self.pyrSize.append(hi0.shape) lo0mask = lo0mask.reshape(imdft.shape[0], imdft.shape[1]) lodft = imdft * lo0mask - for i in range(ht): - bands = numpy.zeros((lodft.shape[0]*lodft.shape[1], nbands)) - bind = numpy.zeros((nbands, 2)) - - Xrcos -= numpy.log2(2) + # self.pind = numpy.zeros((nbands, 2)) + self.bands = [] + for i in range(self.ht - 1, -1, -1): + # Xrcos -= numpy.log2(2) + Xrcos -= np.log2(1. / self.scale) lutsize = 1024 - Xcosn = numpy.pi * numpy.array(range(-(2*lutsize+1), (lutsize+2))) / lutsize - - order = nbands -1 - const = (2**(2*order))*(scipy.misc.factorial(order, exact=True)**2)/float(nbands*scipy.misc.factorial(2*order, exact=True)) - - alfa = ( (numpy.pi+Xcosn) % (2.0*numpy.pi) ) - numpy.pi - Ycosn = ( 2.0*numpy.sqrt(const) * (numpy.cos(Xcosn)**order) * - (numpy.abs(alfa) 0: - levs = args[0] - else: - levs = 'all' + def band(self, bandNum): + return self.xp.array(self.pyr[bandNum]) - if len(args) > 1: - bands = args[1] - else: - bands = 'all' + def spyrHt(self): + return self.ht - if len(args) > 2: - if args[2] <= 0: - print "Warning: twidth must be positive. Setting to 1." - twidth = 1 - else: - twidth = args[2] - else: - twidth = 1 + def numBands(self): + return self.order + 1 - #----------------------------------------------------------------- + def pyrLow(self): + return self.xp.array(self.band(len(self.pyrSize)-1)) + def pyrHigh(self): + return self.xp.array(self.band(0)) + + # methods + def reconPyr(self, levs='all', bands='all'): pind = self.pyrSize - Nsc = int(numpy.log2(pind[0][0] / pind[-1][0])) - Nor = (len(pind)-2) / Nsc + Nsc = int(np.round(np.log2(pind[0, 0] / pind[-1, 0].astype('float')) / np.log2(1 / self.scale))) + Nor = (len(pind)-2) // Nsc pyrIdx = 1 for nsc in range(Nsc): - firstBnum = nsc * Nor+2 + firstBnum = nsc * Nor + 1 dims = pind[firstBnum][:] - ctr = (numpy.ceil((dims[0]+0.5)/2.0), numpy.ceil((dims[1]+0.5)/2.0)) #-1? - ang = mkAngle(dims, 0, ctr) - ang[ctr[0]-1, ctr[1]-1] = -numpy.pi/2.0 + ctr = np.ceil((dims + 0.5) / 2).astype('int') #-1? + ang = self.xp.array(mkAngle(dims, 0, ctr)) + ang[ctr[0]-1, ctr[1]-1] = -np.pi / 2.0 for nor in range(Nor): nband = nsc * Nor + nor + 1 ch = self.pyr[nband] - ang0 = numpy.pi * nor / Nor - xang = ((ang-ang0+numpy.pi) % (2.0*numpy.pi)) - numpy.pi - amask = 2 * (numpy.abs(xang) < (numpy.pi/2.0)).astype(int) + (numpy.abs(xang) == (numpy.pi/2.0)).astype(int) + ang0 = np.pi * nor / Nor + xang = ((ang - ang0 + np.pi) % (2.0 * np.pi)) - np.pi + amask = 2 * (self.xp.abs(xang) < (np.pi/2.0)).astype(int) + (self.xp.abs(xang) == (np.pi/2.0)).astype(int) amask[ctr[0]-1, ctr[1]-1] = 1 amask[:,0] = 1 amask[0,:] = 1 - amask = numpy.fft.fftshift(amask) - ch = numpy.fft.ifft2(amask * numpy.fft.fft2(ch)) # 'Analytic' version + amask = self.xp.fft.fftshift(amask) + ch = self.xp.fft.ifft2(amask * self.xp.fft.fft2(ch)) # 'Analytic' version # f = 1.000008 # With this factor the reconstruction SNR # goes up around 6 dB! f = 1 - ch = f*0.5*numpy.real(ch) # real part + ch = f*0.5*self.xp.real(ch) # real part self.pyr[pyrIdx] = ch pyrIdx += 1 - res = self.reconSFpyr(levs, bands, twidth); + res = self._reconSFpyr(levs, bands) return res + + def _reconSFpyr(self, levs='all', bands='all'): + nbands = self.numBands() + + maxLev = 1 + self.spyrHt() + if isinstance(levs, str) and levs == 'all': + levs = np.array(list(range(maxLev + 1))) + elif isinstance(levs, str): + raise ValueError("Error: %s not valid for levs parameter. " + "levs must be either a 1D numpy array or the string 'all'." % (levs)) + else: + levs = np.array(levs) + + if isinstance(bands, str) and bands == 'all': + bands = np.array(list(range(nbands))) + elif isinstance(bands, str): + raise ValueError("Error: %s not valid for bands parameter. " + "bands must be either a 1D numpy array or the string 'all'." % (bands)) + else: + bands = np.array(bands) + + # ------------------------------------------------------------------- + # matlab code starts here + pind = self.pyrSize + dims = np.array(self.pyrSize[0]) + ctr = np.ceil((dims + 0.5) / 2.0).astype('int') + + (xramp, yramp) = self.xp.meshgrid((self.xp.arange(1, dims[1] + 1) - ctr[1]) / (dims[1] / 2.), + (self.xp.arange(1, dims[0] + 1) - ctr[0]) / (dims[0] / 2.)) + angle = self.xp.arctan2(yramp, xramp) + log_rad = self.xp.sqrt(xramp ** 2 + yramp ** 2) + log_rad[ctr[0] - 1, ctr[1] - 1] = log_rad[ctr[0] - 1, ctr[1] - 2] + log_rad = self.xp.log2(log_rad) + + ## Radial transition function (a raised cosine in log-frequency): + (Xrcos, Yrcos) = rcosFn(self.twidth, (-self.twidth / 2.0), np.array([0, 1])) + Xrcos = self.xp.array(Xrcos) + Yrcos = self.xp.sqrt(self.xp.array(Yrcos)) + YIrcos = self.xp.sqrt(self.xp.abs(1.0 - Yrcos ** 2)) + + resdft = self._reconvSFpyr(self.pyr[1:], pind[1:], log_rad, Xrcos, Yrcos, angle, nbands, levs, bands, self.scale) + + # apply lo0mask + if self.xp.__name__ == 'numpy': + lo0mask = pointOp(log_rad, YIrcos, Xrcos[0], Xrcos[1] - Xrcos[0], 0) + else: + lo0mask = self.xp.array(pointOp(cp.asnumpy(log_rad), cp.asnumpy(YIrcos), cp.asnumpy(Xrcos)[0], + cp.asnumpy(Xrcos)[1] - cp.asnumpy(Xrcos)[0], 0)) + resdft = resdft * lo0mask + + # residual highpass subband + if self.xp.__name__ == 'numpy': + hi0mask = pointOp(log_rad, Yrcos, Xrcos[0], Xrcos[1] - Xrcos[0], 0) + else: + hi0mask = self.xp.array(pointOp(cp.asnumpy(log_rad), cp.asnumpy(Yrcos), cp.asnumpy(Xrcos)[0], + cp.asnumpy(Xrcos)[1] - cp.asnumpy(Xrcos)[0], 0)) + + hi0mask = hi0mask.reshape(resdft.shape[0], resdft.shape[1]) + if 0 in levs: + resdft += self.xp.fft.fftshift(self.xp.fft.fft2(self.pyr[0])) * hi0mask + + outresdft = self.xp.real(self.xp.fft.ifft2(self.xp.fft.ifftshift(resdft))) + return outresdft + + def _reconvSFpyr(self, pyr, pind, log_rad, Xrcos, Yrcos, angle, nbands, levs, bands, scale): + lo_ind = nbands + 1 + dims = pind[0] + ctr = np.ceil((dims + 0.5) / 2).astype('int') + XXrcos = self.xp.copy(Xrcos - self.xp.log2(1. / scale)) + + if (levs > 1).any(): + lodims = pind[bands[-1] + 1] + loctr = np.ceil((lodims + 0.5) / 2).astype('int') + lostart = ctr - loctr + 1 + loend = lostart + lodims - 1 + nlog_rad = self.xp.copy(log_rad[lostart[0] - 1:loend[0], lostart[1] - 1:loend[1]]) + nangle = self.xp.copy(angle[lostart[0] - 1: loend[0], lostart[1] - 1: loend[1]]) + + if pind.shape[0] > lo_ind: + nresdft = self._reconvSFpyr(pyr[lo_ind - 1:len(pyr)], pind[lo_ind - 1:], nlog_rad, XXrcos, Yrcos, + nangle, nbands, levs - 1, bands, scale) + else: + nresdft = self.xp.fft.fftshift(self.xp.fft.fft2(pyr[lo_ind - 1])) + + YIrcos = self.xp.sqrt(self.xp.abs(1. - Yrcos ** 2)) + + if self.xp.__name__ == 'numpy': + lomask = pointOp(nlog_rad, YIrcos, XXrcos[0], XXrcos[1] - XXrcos[0], 0) + else: + lomask = cp.array(pointOp(cp.asnumpy(nlog_rad), cp.asnumpy(YIrcos), cp.asnumpy(XXrcos)[0], + cp.asnumpy(XXrcos)[1] - cp.asnumpy(XXrcos)[0], 0)) + + resdft = self.xp.zeros(dims).astype('complex128') + resdft[lostart[0] - 1:loend[0], lostart[1] - 1:loend[1]] = nresdft * lomask + else: + resdft = self.xp.zeros(dims) + + if (levs == 1).any(): + lutsize = 1024 + Xcosn = np.pi * self.xp.arange(-(2*lutsize + 1), lutsize + 1) / lutsize + order = nbands - 1 + const = 2 ** (2*order) * (scipy.special.factorial(order) ** 2) / (nbands * scipy.special.factorial(2.*order)) + Ycosn = self.xp.sqrt(const) * (self.xp.cos(Xcosn)) ** order + + if self.xp.__name__ == 'numpy': + himask = pointOp(log_rad, Yrcos, XXrcos[0], XXrcos[1] - XXrcos[0], 0) + else: + himask = self.xp.array(pointOp(cp.asnumpy(log_rad), cp.asnumpy(Yrcos), cp.asnumpy(XXrcos)[0], + cp.asnumpy(XXrcos)[1] - cp.asnumpy(XXrcos)[0], 0)) + + ind = 0 + for b in range(nbands): + if (bands == b).any(): + if self.xp.__name__ == 'numpy': + anglemask = pointOp(angle, Ycosn, Xcosn[0] + np.pi*b/nbands, Xcosn[1] - Xcosn[0], 0) + else: + anglemask = cp.asarray(pointOp(cp.asnumpy(angle), cp.asnumpy(Ycosn), cp.asnumpy(Xcosn)[0] + + np.pi * b / nbands, cp.asnumpy(Xcosn)[1] - cp.asnumpy(Xcosn)[0], 0)) + band = pyr[ind] + banddft = self.xp.fft.fftshift(self.xp.fft.fft2(band)) + resdft += (self.xp.power(-1 + 0j, 0.5)) ** (nbands - 1) * banddft * anglemask * himask + ind += 1 + return resdft diff --git a/SFpyr.py b/SFpyr.py index d649a47..ed42697 100644 --- a/SFpyr.py +++ b/SFpyr.py @@ -1,8 +1,8 @@ -from Spyr import Spyr +from .Spyr import Spyr import numpy -from steer2HarmMtx import steer2HarmMtx -from rcosFn import rcosFn -from pointOp import pointOp +from .steer2HarmMtx import steer2HarmMtx +from .rcosFn import rcosFn +from .pointOp import pointOp import scipy class SFpyr(Spyr): @@ -16,7 +16,7 @@ def __init__(self, *args): # (image, height, order, twidth) if len(args) > 0: self.image = args[0] else: - print "First argument (image) is required." + print("First argument (image) is required.") return #------------------------------------------------ @@ -25,7 +25,7 @@ def __init__(self, *args): # (image, height, order, twidth) max_ht = numpy.floor( numpy.log2( min(self.image.shape) ) ) - 2 if len(args) > 1: if(args[1] > max_ht): - print "Error: cannot build pyramid higher than %d levels." % (max_ht) + print("Error: cannot build pyramid higher than %d levels." % (max_ht)) ht = args[1] else: ht = max_ht @@ -33,7 +33,7 @@ def __init__(self, *args): # (image, height, order, twidth) if len(args) > 2: if args[2] > 15 or args[2] < 0: - print "Warning: order must be an integer in the range [0,15]. Truncating." + print("Warning: order must be an integer in the range [0,15]. Truncating.") order = min( max(args[2],0), 15 ) else: order = args[2] @@ -44,7 +44,7 @@ def __init__(self, *args): # (image, height, order, twidth) if len(args) > 3: if args[3] <= 0: - print "Warning: twidth must be positive. Setting to 1." + print("Warning: twidth must be positive. Setting to 1.") twidth = 1 else: twidth = args[3] @@ -55,21 +55,21 @@ def __init__(self, *args): # (image, height, order, twidth) # steering stuff: if nbands % 2 == 0: - harmonics = numpy.array(range(nbands/2)) * 2 + 1 + harmonics = numpy.array(list(range(nbands/2))) * 2 + 1 else: - harmonics = numpy.array(range((nbands-1)/2)) * 2 + harmonics = numpy.array(list(range((nbands-1)/2))) * 2 steermtx = steer2HarmMtx(harmonics, numpy.pi * - numpy.array(range(nbands))/nbands, 'even') + numpy.array(list(range(nbands)))/nbands, 'even') #------------------------------------------------------ dims = numpy.array(self.image.shape) ctr = numpy.ceil((numpy.array(dims)+0.5)/2) - (xramp, yramp) = numpy.meshgrid((numpy.array(range(1,dims[1]+1))-ctr[1])/ + (xramp, yramp) = numpy.meshgrid((numpy.array(list(range(1,dims[1]+1)))-ctr[1])/ (dims[1]/2), - (numpy.array(range(1,dims[0]+1))-ctr[0])/ + (numpy.array(list(range(1,dims[0]+1)))-ctr[0])/ (dims[0]/2)) angle = numpy.arctan2(yramp, xramp) log_rad = numpy.sqrt(xramp**2 + yramp**2) @@ -106,7 +106,7 @@ def __init__(self, *args): # (image, height, order, twidth) Xrcos -= numpy.log2(2) lutsize = 1024 - Xcosn = numpy.pi * numpy.array(range(-(2*lutsize+1), (lutsize+2))) / lutsize + Xcosn = numpy.pi * numpy.array(list(range(-(2*lutsize+1), (lutsize+2)))) / lutsize order = nbands -1 const = (2**(2*order))*(scipy.misc.factorial(order, exact=True)**2)/float(nbands*scipy.misc.factorial(2*order, exact=True)) @@ -160,8 +160,8 @@ def numBands(self): # FIX: why isn't this inherited return 0 else: b = 2 - while ( b <= len(self.pyrSize) and - self.pyrSize[b] == self.pyrSize[1] ): + while ( b < len(self.pyrSize) and + (self.pyrSize[b] == self.pyrSize[1]).all() ): b += 1 return b-1 @@ -172,47 +172,26 @@ def spyrHt(self): spHt = 0 return spHt - def reconSFpyr(self, *args): - - if len(args) > 0: - levs = args[0] - else: - levs = 'all' - - if len(args) > 1: - bands = args[1] - else: - bands = 'all' - - if len(args) > 2: - if args[2] <= 0: - print "Warning: twidth must be positive. Setting to 1." - twidth = 1 - else: - twidth = args[2] - else: - twidth = 1 - + def reconSFpyr(self, levs='all', bands='all', twidth=1): + assert twidth > 0, 'twidth must be a positive number.' #----------------------------------------------------------------- nbands = self.numBands() maxLev = 1 + self.spyrHt() - if isinstance(levs, basestring) and levs == 'all': - levs = numpy.array(range(maxLev+1)) - elif isinstance(levs, basestring): - print "Error: %s not valid for levs parameter." % (levs) - print "levs must be either a 1D numpy array or the string 'all'." - return + if isinstance(levs, str) and levs == 'all': + levs = numpy.array(list(range(maxLev+1))) + elif isinstance(levs, str): + raise ValueError("Error: %s not valid for levs parameter. " + "levs must be either a 1D numpy array or the string 'all'." % levs) else: levs = numpy.array(levs) - if isinstance(bands, basestring) and bands == 'all': - bands = numpy.array(range(nbands)) - elif isinstance(bands, basestring): - print "Error: %s not valid for bands parameter." % (bands) - print "bands must be either a 1D numpy array or the string 'all'." - return + if isinstance(bands, str) and bands == 'all': + bands = numpy.array(list(range(nbands))) + elif isinstance(bands, str): + raise ValueError("Error: %s not valid for bands parameter. " \ + "bands must be either a 1D numpy array or the string 'all'." % bands) else: bands = numpy.array(bands) @@ -224,30 +203,30 @@ def reconSFpyr(self, *args): dims = numpy.array(self.pyrSize[dimIdx]) if (dims[0], dims[1]) not in dimList: dimList.append( (dims[0], dims[1]) ) - ctr = numpy.ceil((dims+0.5)/2) - lodims = numpy.ceil((dims-0.5)/2) - loctr = numpy.ceil((lodims+0.5)/2) + ctr = numpy.ceil((dims+0.5)/2).astype('int') + lodims = numpy.ceil((dims-0.5)/2).astype('int') + loctr = numpy.ceil((lodims+0.5)/2).astype('int') lostart = ctr - loctr loend = lostart + lodims bounds = (lostart[0], lostart[1], loend[0], loend[1]) if bounds not in boundList: boundList.append( bounds ) - boundList.append((0.0, 0.0, dimList[len(dimList)-1][0], + boundList.append((0, 0, dimList[len(dimList)-1][0], dimList[len(dimList)-1][1])) dimList.append((dimList[len(dimList)-1][0], dimList[len(dimList)-1][1])) # matlab code starts here dims = numpy.array(self.pyrSize[0]) - ctr = numpy.ceil((dims+0.5)/2.0) + ctr = numpy.ceil((dims+0.5)/2.0).astype('int') - (xramp, yramp) = numpy.meshgrid((numpy.array(range(1,dims[1]+1))-ctr[1])/ - (dims[1]/2), - (numpy.array(range(1,dims[0]+1))-ctr[0])/ - (dims[0]/2)) + (xramp, yramp) = numpy.meshgrid((numpy.array(list(range(1,dims[1]+1)))-ctr[1])/ + (dims[1]/2.), + (numpy.array(list(range(1,dims[0]+1)))-ctr[0])/ + (dims[0]/2.)) angle = numpy.arctan2(yramp, xramp) log_rad = numpy.sqrt(xramp**2 + yramp**2) log_rad[ctr[0]-1, ctr[1]-1] = log_rad[ctr[0]-1, ctr[1]-2] - log_rad = numpy.log2(log_rad); + log_rad = numpy.log2(log_rad) ## Radial transition function (a raised cosine in log-frequency): (Xrcos, Yrcos) = rcosFn(twidth, (-twidth/2.0), numpy.array([0,1])) @@ -256,7 +235,7 @@ def reconSFpyr(self, *args): # from reconSFpyrLevs lutsize = 1024 - Xcosn = numpy.pi * numpy.array(range(-(2*lutsize+1), (lutsize+2))) / lutsize + Xcosn = numpy.pi * numpy.array(list(range(-(2*lutsize+1), (lutsize+2)))) / lutsize order = nbands -1 const = (2**(2*order))*(scipy.misc.factorial(order, exact=True)**2)/float(nbands*scipy.misc.factorial(2*order, exact=True)) @@ -278,6 +257,7 @@ def reconSFpyr(self, *args): bounds[0]+boundList[idx][0] + diff[0], bounds[1]+boundList[idx][1] + diff[1]) Xrcos -= numpy.log2(2.0) + bounds = numpy.array(bounds, dtype='int') nlog_rad = log_rad[bounds[0]:bounds[2], bounds[1]:bounds[3]] nlog_rad_tmp = numpy.reshape(nlog_rad, diff --git a/Spyr.py b/Spyr.py index 554e39a..b3beee3 100644 --- a/Spyr.py +++ b/Spyr.py @@ -1,18 +1,18 @@ -from pyramid import pyramid +from .pyramid import pyramid import numpy -from sp0Filters import sp0Filters -from sp1Filters import sp1Filters -from sp3Filters import sp3Filters -from sp5Filters import sp5Filters +from .sp0Filters import sp0Filters +from .sp1Filters import sp1Filters +from .sp3Filters import sp3Filters +from .sp5Filters import sp5Filters import os -from maxPyrHt import maxPyrHt -from corrDn import corrDn +from .maxPyrHt import maxPyrHt +from .corrDn import corrDn import math -from LB2idx import LB2idx +from .LB2idx import LB2idx import matplotlib -from showIm import showIm -import JBhelpers -from upConv import upConv +from .showIm import showIm +from . import JBhelpers +from .upConv import upConv class Spyr(pyramid): filt = '' @@ -24,7 +24,7 @@ def __init__(self, *args): # (image height, filter file, edges) if len(args) > 0: self.image = numpy.array(args[0]) else: - print "First argument (image) is required." + print("First argument (image) is required.") return #------------------------------------------------ @@ -40,10 +40,10 @@ def __init__(self, *args): # (image height, filter file, edges) elif args[2] == 'sp5Filters': filters = sp5Filters() elif os.path.isfile(args[2]): - print "Filter files not supported yet" + print("Filter files not supported yet") return else: - print "filter parameters value %s not supported" % (args[2]) + print("filter parameters value %s not supported" % (args[2])) return else: filters = sp1Filters() @@ -60,8 +60,8 @@ def __init__(self, *args): # (image height, filter file, edges) if args[1] == 'auto': ht = max_ht elif args[1] > max_ht: - print "Error: cannot build pyramid higher than %d levels." % ( - max_ht) + print("Error: cannot build pyramid higher than %d levels." % ( + max_ht)) return else: ht = args[1] @@ -115,20 +115,20 @@ def __init__(self, *args): # (image height, filter file, edges) # methods def set(self, *args): if len(args) != 3: - print 'Error: three input parameters required:' - print ' set(band, location, value)' - print ' where band and value are integer and location is a tuple' - if isinstance(args[1], (int, long)): + print('Error: three input parameters required:') + print(' set(band, location, value)') + print(' where band and value are integer and location is a tuple') + if isinstance(args[1], int): self.pyr[args[0]][0][args[1]] = args[2] elif isinstance(args[1], tuple): self.pyr[args[0]][args[1][0]][args[1][1]] = args[2] else: - print 'Error: location parameter must be int or tuple!' + print('Error: location parameter must be int or tuple!') return def spyrLev(self, lev): if lev < 0 or lev > self.spyrHt()-1: - print 'Error: level parameter must be between 0 and %d!' % (self.spyrHt()-1) + print('Error: level parameter must be between 0 and %d!' % (self.spyrHt()-1)) return levArray = [] @@ -140,13 +140,21 @@ def spyrLev(self, lev): def spyrBand(self, lev, band): if lev < 0 or lev > self.spyrHt()-1: - print 'Error: level parameter must be between 0 and %d!' % (self.spyrHt()-1) + print('Error: level parameter must be between 0 and %d!' % (self.spyrHt()-1)) return if band < 0 or band > self.numBands()-1: - print 'Error: band parameter must be between 0 and %d!' % (self.numBands()-1) + print('Error: band parameter must be between 0 and %d!' % (self.numBands()-1)) return self.band( ((lev*self.numBands())+band)+1 ) + def bandIndex(self, lev, band): + if lev < 0 or lev > self.spyrHt()-1: + raise ValueError('Error: level parameter must be between 0 and %d!' % (self.spyrHt()-1)) + if band < 0 or band > self.numBands()-1: + raise ValueError('Error: band parameter must be between 0 and %d!' % (self.numBands()-1)) + + return ((lev*self.numBands())+band)+1 + def spyrHt(self): if len(self.pyrSize) > 2: spHt = (len(self.pyrSize)-2)/self.numBands() @@ -183,10 +191,10 @@ def reconPyr(self, *args): elif args[0] == 'sp5Filters': filters = sp5Filters() elif os.path.isfile(args[0]): - print "Filter files not supported yet" + print("Filter files not supported yet") return else: - print "filter %s not supported" % (args[0]) + print("filter %s not supported" % (args[0])) return else: filters = sp1Filters() @@ -218,22 +226,22 @@ def reconPyr(self, *args): maxLev = 2 + self.spyrHt() if levs == 'all': - levs = numpy.array(range(maxLev)) + levs = numpy.array(list(range(maxLev))) else: levs = numpy.array(levs) if (levs < 0).any() or (levs >= maxLev).any(): - print "Error: level numbers must be in the range [0, %d]." % (maxLev-1) + print("Error: level numbers must be in the range [0, %d]." % (maxLev-1)) return else: levs = numpy.array(levs) if len(levs) > 1 and levs[0] < levs[1]: levs = levs[::-1] # we want smallest first if bands == 'all': - bands = numpy.array(range(self.numBands())) + bands = numpy.array(list(range(self.numBands()))) else: bands = numpy.array(bands) if (bands < 0).any() or (bands > bfilts.shape[1]).any(): - print "Error: band numbers must be in the range [0, %d]." % (self.numBands()-1) + print("Error: band numbers must be in the range [0, %d]." % (self.numBands()-1)) return else: bands = numpy.array(bands) @@ -359,10 +367,10 @@ def showPyr(self, prange = 'auto2', gap = 1, scale = 2, disp = 'qt'): av = numpy.mean(band) stdev = numpy.sqrt( numpy.var(band) ) prange[nind-1,:] = numpy.array([av-2*stdev, av+2*stdev]) - elif isinstance(prange, basestring): - print "Error:Bad RANGE argument: %s'" % (prange) + elif isinstance(prange, str): + print("Error:Bad RANGE argument: %s'" % (prange)) elif prange.shape[0] == 1 and prange.shape[1] == 2: - scales = numpy.power(scale, range(ht)) + scales = numpy.power(scale, list(range(ht))) scales = numpy.outer( numpy.ones((nbands,1)), scales ) scales = numpy.array([1, scales, numpy.power(scale, ht)]) prange = numpy.outer(scales, prange) @@ -381,11 +389,11 @@ def showPyr(self, prange = 'auto2', gap = 1, scale = 2, disp = 'qt'): ncols = int(numpy.ceil((nbands+1)/2)) nrows = int(numpy.ceil(nbands/2)) - a = numpy.array(range(1-nrows, 1)) + a = numpy.array(list(range(1-nrows, 1))) b = numpy.zeros((1,ncols))[0] ab = numpy.concatenate((a,b)) c = numpy.zeros((1,nrows))[0] - d = range(-1, -ncols-1, -1) + d = list(range(-1, -ncols-1, -1)) cd = numpy.concatenate((c,d)) relpos = numpy.vstack((ab,cd)).T diff --git a/TESTS/unitTests.py b/TESTS/unitTests.py index aaea27b..f297a0d 100755 --- a/TESTS/unitTests.py +++ b/TESTS/unitTests.py @@ -11,41 +11,41 @@ class maxPyrHtTests(unittest.TestCase): def test1(self): - self.failUnless(ppt.maxPyrHt((1,10),(3,4)) == 0) + self.assertTrue(ppt.maxPyrHt((1,10),(3,4)) == 0) def test2(self): - self.failUnless(ppt.maxPyrHt((10,1),(3,4)) == 0) + self.assertTrue(ppt.maxPyrHt((10,1),(3,4)) == 0) def test3(self): - self.failUnless(ppt.maxPyrHt((10,10),(1,4)) == 4) + self.assertTrue(ppt.maxPyrHt((10,10),(1,4)) == 4) def test4(self): - self.failUnless(ppt.maxPyrHt((10,10),(3,1)) == 2) + self.assertTrue(ppt.maxPyrHt((10,10),(3,1)) == 2) def test5(self): - self.failUnless(ppt.maxPyrHt((10,10),(3,4)) == 2) + self.assertTrue(ppt.maxPyrHt((10,10),(3,4)) == 2) def test6(self): - self.failUnless(ppt.maxPyrHt((20,10),(5,1)) == 2) + self.assertTrue(ppt.maxPyrHt((20,10),(5,1)) == 2) def test7(self): - self.failUnless(ppt.maxPyrHt((10,20),(5,1)) == 2) + self.assertTrue(ppt.maxPyrHt((10,20),(5,1)) == 2) def test8(self): - self.failUnless(ppt.maxPyrHt((20,10),(1,5)) == 5) + self.assertTrue(ppt.maxPyrHt((20,10),(1,5)) == 5) def test9(self): - self.failUnless(ppt.maxPyrHt((10,20),(1,5)) == 5) + self.assertTrue(ppt.maxPyrHt((10,20),(1,5)) == 5) def test10(self): - self.failUnless(ppt.maxPyrHt((256,1),(1,5)) == 6) + self.assertTrue(ppt.maxPyrHt((256,1),(1,5)) == 6) def test11(self): - self.failUnless(ppt.maxPyrHt((256,1),(5,1)) == 6) + self.assertTrue(ppt.maxPyrHt((256,1),(5,1)) == 6) def test12(self): - self.failUnless(ppt.maxPyrHt((1,256),(1,5)) == 6) + self.assertTrue(ppt.maxPyrHt((1,256),(1,5)) == 6) def test13(self): - self.failUnless(ppt.maxPyrHt((1,256),(5,1)) == 6) + self.assertTrue(ppt.maxPyrHt((1,256),(5,1)) == 6) class binomialFilterTests(unittest.TestCase): def test1(self): - self.failUnless((ppt.binomialFilter(2) == np.array([[0.5], + self.assertTrue((ppt.binomialFilter(2) == np.array([[0.5], [0.5]])).all() ) def test2(self): - self.failUnless((ppt.binomialFilter(3) == np.array([[0.25], [0.5], + self.assertTrue((ppt.binomialFilter(3) == np.array([[0.25], [0.5], [0.25]])).all()) def test3(self): - self.failUnless((ppt.binomialFilter(5) == np.array([[0.0625], [0.25], + self.assertTrue((ppt.binomialFilter(5) == np.array([[0.0625], [0.25], [0.3750], [0.25], [0.0625]])).all()) @@ -55,34 +55,34 @@ def test1(self): img = Image.open('../lenna-256x256.tif') img = np.array(img.getdata()).reshape(256,256) pyPyr = ppt.Gpyr(img) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/buildGpyr2row.mat') - img = np.array(range(256)).astype(float) + img = np.array(list(range(256))).astype(float) img = img.reshape(1, 256) pyPyr = ppt.Gpyr(img) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/buildGpyr2col.mat') - img = np.array(range(256)).astype(float) + img = np.array(list(range(256))).astype(float) img = img.reshape(256, 1) pyPyr = ppt.Gpyr(img) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/buildGpyr3.mat') img = ppt.mkRamp(10) pyPyr = ppt.Gpyr(img) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/buildGpyr4.mat') img = ppt.mkRamp((10,20)) pyPyr = ppt.Gpyr(img) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test6(self): matPyr = scipy.io.loadmat('../matFiles/buildGpyr5.mat') img = ppt.mkRamp((20, 10)) pyPyr = ppt.Gpyr(img) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) class LpyrTests(unittest.TestCase): def test1(self): @@ -90,289 +90,289 @@ def test1(self): img = Image.open('../lenna-256x256.tif') img = np.array(img.getdata()).reshape(256,256) pyPyr = ppt.Lpyr(img) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test2(self): matPyr2 = scipy.io.loadmat('../matFiles/buildLpyr2.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Lpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr2['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr2['pyr'], pyPyr)) def test3(self): matPyr2 = scipy.io.loadmat('../matFiles/buildLpyr3.mat') pyRamp = ppt.mkRamp((100,200)) pyPyr = ppt.Lpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr2['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr2['pyr'], pyPyr)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/buildLpyr4.mat') pyRamp = ppt.mkRamp(200,100) pyPyr = ppt.Lpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/buildLpyr5.mat') - pyRamp = np.array(range(200)).reshape(1, 200) + pyRamp = np.array(list(range(200))).reshape(1, 200) pyPyr = ppt.Lpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test6(self): matPyr = scipy.io.loadmat('../matFiles/buildLpyr6.mat') - pyRamp = np.array(range(200)) + pyRamp = np.array(list(range(200))) pyPyr = ppt.Lpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test7(self): matPyr = scipy.io.loadmat('../matFiles/buildLpyr7.mat') img = Image.open('../lenna-256x256.tif') img = np.array(img.getdata()).reshape(256,256) pyPyr = ppt.Lpyr(img) recon = pyPyr.reconPyr() - self.failUnless((matPyr['recon'] == recon).all()) + self.assertTrue((matPyr['recon'] == recon).all()) def test8(self): matPyr = scipy.io.loadmat('../matFiles/buildLpyr8.mat') pyRamp = ppt.mkRamp(200) pyPyr = ppt.Lpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless((matPyr['recon'] == recon).all()) + self.assertTrue((matPyr['recon'] == recon).all()) def test9(self): matPyr = scipy.io.loadmat('../matFiles/buildLpyr9.mat') pyRamp = ppt.mkRamp((200,100)) pyPyr = ppt.Lpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless((matPyr['recon'] == recon).all()) + self.assertTrue((matPyr['recon'] == recon).all()) def test10(self): matPyr = scipy.io.loadmat('../matFiles/buildLpyr10.mat') pyRamp = ppt.mkRamp((100,200)) pyPyr = ppt.Lpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless((matPyr['recon'] == recon).all()) + self.assertTrue((matPyr['recon'] == recon).all()) def test11(self): matPyr = scipy.io.loadmat('../matFiles/buildLpyr11.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Lpyr(pyRamp) recon = pyPyr.reconPyr([1]) - self.failUnless((matPyr['recon'] == recon).all()) + self.assertTrue((matPyr['recon'] == recon).all()) def test12(self): matPyr = scipy.io.loadmat('../matFiles/buildLpyr12.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Lpyr(pyRamp) recon = pyPyr.reconPyr([0,2,4]) - self.failUnless((matPyr['recon'] == recon).all()) + self.assertTrue((matPyr['recon'] == recon).all()) class spFilterTests(unittest.TestCase): def test1(self): matFilt0 = scipy.io.loadmat('../matFiles/sp0Filters.mat') pySP0filt = ppt.sp0Filters() tmpKeys = [] - for key in matFilt0.keys(): + for key in list(matFilt0.keys()): if "_" not in key: tmpKeys.append(key) - self.failUnless(tmpKeys == pySP0filt.keys()) + self.assertTrue(tmpKeys == list(pySP0filt.keys())) for key in tmpKeys: - self.failUnless((matFilt0[key] == pySP0filt[key]).all()) + self.assertTrue((matFilt0[key] == pySP0filt[key]).all()) def test2(self): matFilt1 = scipy.io.loadmat('../matFiles/sp1Filters.mat') pySP1filt = ppt.sp1Filters() tmpKeys = [] - for key in matFilt1.keys(): + for key in list(matFilt1.keys()): if "_" not in key: tmpKeys.append(key) - self.failUnless(tmpKeys == pySP1filt.keys()) + self.assertTrue(tmpKeys == list(pySP1filt.keys())) for key in tmpKeys: - self.failUnless((matFilt1[key] == pySP1filt[key]).all()) + self.assertTrue((matFilt1[key] == pySP1filt[key]).all()) def test3(self): matFilt3 = scipy.io.loadmat('../matFiles/sp3Filters.mat') pySP3filt = ppt.sp3Filters() tmpKeys = [] - for key in matFilt3.keys(): + for key in list(matFilt3.keys()): if "_" not in key: tmpKeys.append(key) - self.failUnless(tmpKeys == pySP3filt.keys()) + self.assertTrue(tmpKeys == list(pySP3filt.keys())) for key in tmpKeys: - self.failUnless((matFilt3[key] == pySP3filt[key]).all()) + self.assertTrue((matFilt3[key] == pySP3filt[key]).all()) def test4(self): matFilt5 = scipy.io.loadmat('../matFiles/sp5Filters.mat') pySP5filt = ppt.sp5Filters() tmpKeys = [] - for key in matFilt5.keys(): + for key in list(matFilt5.keys()): if "_" not in key: tmpKeys.append(key) - self.failUnless(tmpKeys == pySP5filt.keys()) + self.assertTrue(tmpKeys == list(pySP5filt.keys())) for key in tmpKeys: - self.failUnless((matFilt5[key] == pySP5filt[key]).all()) + self.assertTrue((matFilt5[key] == pySP5filt[key]).all()) class SpyrTests(unittest.TestCase): def test00(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr00.mat') pyRamp = ppt.mkRamp((20,20)) pyPyr = ppt.Spyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr1.mat') img = np.array(Image.open('../lenna-256x256.tif')).astype(float) pyPyr = ppt.Spyr(img) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr2.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Spyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr3.mat') pyRamp = ppt.mkRamp((100,200)) pyPyr = ppt.Spyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr4.mat') pyRamp = ppt.mkRamp((200,100)) pyPyr = ppt.Spyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test0(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr0.mat') pyRamp = ppt.mkRamp(20) pyPyr = ppt.Spyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr5.mat') img = np.array(Image.open('../lenna-256x256.tif')).astype(float) pyPyr = ppt.Spyr(img) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test6(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr6.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Spyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test7(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr7.mat') pyRamp = ppt.mkRamp((256,128)) pyPyr = ppt.Spyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test8(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr8.mat') pyRamp = ppt.mkRamp((128,256)) pyPyr = ppt.Spyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test9(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr9.mat') pyRamp = ppt.mkRamp((200,100)) pyPyr = ppt.Spyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test10(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr10.mat') pyRamp = ppt.mkRamp((100,200)) pyPyr = ppt.Spyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test11(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr11.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Spyr(pyRamp) recon = pyPyr.reconPyr('sp1Filters', 'reflect1', [1]) - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test12(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr12.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Spyr(pyRamp) recon = pyPyr.reconPyr('sp1Filters', 'reflect1', [0,2,4]) - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test13(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr13.mat') pyRamp = ppt.mkRamp((20,20)) pyPyr = ppt.Spyr(pyRamp, 1, 'sp0Filters') - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test14(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr14.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Spyr(pyRamp, 3, 'sp0Filters') - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test15(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr15.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Spyr(pyRamp, 1, 'sp1Filters') - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test16(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr16.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Spyr(pyRamp, 3, 'sp1Filters') - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test17(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr17.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Spyr(pyRamp, 1, 'sp3Filters') - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test18(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr18.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Spyr(pyRamp, 3, 'sp3Filters') - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test19(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr19.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Spyr(pyRamp, 1, 'sp5Filters') - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test20(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr20.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Spyr(pyRamp, 3, 'sp5Filters') - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test21(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr21.mat') texture = scipy.io.loadmat('../matFiles/im04-1.mat')['res'][0:256,0:256] pyPyr = ppt.Spyr(texture, 3, 'sp0Filters') recon = pyPyr.reconPyr('sp0Filters'); - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test22(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr22.mat') texture = scipy.io.loadmat('../matFiles/im04-1.mat')['res'][0:256,0:256] pyPyr = ppt.Spyr(texture, 3, 'sp1Filters') recon = pyPyr.reconPyr('sp1Filters'); - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test23(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr23.mat') texture = scipy.io.loadmat('../matFiles/im04-1.mat')['res'][0:256,0:256] pyPyr = ppt.Spyr(texture, 3, 'sp3Filters') recon = pyPyr.reconPyr('sp3Filters'); - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test24(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr24.mat') texture = scipy.io.loadmat('../matFiles/im04-1.mat')['res'][0:256,0:256] pyPyr = ppt.Spyr(texture, 3, 'sp5Filters') recon = pyPyr.reconPyr('sp5Filters'); - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test25(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr25.mat') texture = scipy.io.loadmat('../matFiles/im04-1.mat')['res'][0:256,0:256] pyPyr = ppt.Spyr(texture, 3, 'sp5Filters') recon = pyPyr.reconPyr('sp5Filters','reflect1',[0,1,2], [0]); - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test26(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr26.mat') texture = scipy.io.loadmat('../matFiles/im04-1.mat')['res'][0:128,0:256] pyPyr = ppt.Spyr(texture, 3, 'sp0Filters') recon = pyPyr.reconPyr('sp0Filters','reflect1',[0,1,2], [0]); - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test27(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr27.mat') texture = scipy.io.loadmat('../matFiles/im04-1.mat')['res'][0:128,0:256] pyPyr = ppt.Spyr(texture, 3, 'sp1Filters') recon = pyPyr.reconPyr('sp1Filters','reflect1',[0,1,2], [0]); - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test28(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr28.mat') texture = scipy.io.loadmat('../matFiles/im04-1.mat')['res'][0:128,0:256] pyPyr = ppt.Spyr(texture, 3, 'sp3Filters') recon = pyPyr.reconPyr('sp3Filters','reflect1',[0,1,2], [0]); - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test29(self): matPyr = scipy.io.loadmat('../matFiles/buildSpyr29.mat') texture = scipy.io.loadmat('../matFiles/im04-1.mat')['res'][0:128,0:256] pyPyr = ppt.Spyr(texture, 3, 'sp5Filters') recon = pyPyr.reconPyr('sp5Filters','reflect1',[0,1,2], [0]); - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) @@ -385,137 +385,137 @@ def test1(self): #foo = pointOp(200, 200, img, 5, filt, 0, 1, 0); foo = ppt.pointOp(img, filt, 0, 1, 0); foo = np.reshape(foo,(200,200)) - self.failUnless((matImg['foo'] == foo).all()) + self.assertTrue((matImg['foo'] == foo).all()) class SFpyrTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr0.mat') pyRamp = ppt.mkRamp((20,20)) pyPyr = ppt.SFpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr1.mat') img = Image.open('../lenna-256x256.tif') img = np.array(img.getdata()).reshape(256,256) pyPyr = ppt.SFpyr(img) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr2.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.SFpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr3.mat') pyRamp = ppt.mkRamp((100,200)) pyPyr = ppt.SFpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr4.mat') pyRamp = ppt.mkRamp((200,100)) pyPyr = ppt.SFpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr5.mat') pyRamp = ppt.mkRamp((20,20)) pyPyr = ppt.SFpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test6(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr6.mat') img = Image.open('../lenna-256x256.tif') img = np.array(img.getdata()).reshape(256,256) pyPyr = ppt.SFpyr(img) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test7(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr7.mat') pyRamp = ppt.mkRamp((256,128)) pyPyr = ppt.SFpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test8(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr8.mat') pyRamp = ppt.mkRamp((128,256)) pyPyr = ppt.SFpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test9(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr9.mat') pyRamp = ppt.mkRamp((200,100)) pyPyr = ppt.SFpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test10(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr10.mat') pyRamp = ppt.mkRamp((100,200)) pyPyr = ppt.SFpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test11(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr11.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.SFpyr(pyRamp) recon = pyPyr.reconPyr([0]) - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test12(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr12.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.SFpyr(pyRamp) recon = pyPyr.reconPyr([0,2,4]) - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test13(self): matPyr = scipy.io.loadmat('../matFiles/buildSFpyr13.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.SFpyr(pyRamp) recon = pyPyr.reconPyr([0,2,4], [1]) - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) class SCFpyrTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/buildSCFpyr0.mat') pyRamp = ppt.mkRamp((20,20)) pyPyr = ppt.SCFpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/buildSCFpyr1.mat') img = Image.open('../lenna-256x256.tif') img = np.array(img.getdata()).reshape(256,256) pyPyr = ppt.SCFpyr(img) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/buildSCFpyr2.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.SCFpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/buildSCFpyr3.mat') pyRamp = ppt.mkRamp((100,200)) pyPyr = ppt.SCFpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/buildSCFpyr4.mat') pyRamp = ppt.mkRamp((200,100)) pyPyr = ppt.SCFpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/buildSCFpyr5.mat') img = Image.open('../lenna-256x256.tif') img = np.array(img.getdata()).reshape(256,256) pyPyr = ppt.SCFpyr(img) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test6(self): matPyr = scipy.io.loadmat('../matFiles/buildSCFpyr6.mat') pyRamp = ppt.mkRamp((256,128)) pyPyr = ppt.SCFpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test7(self): matPyr = scipy.io.loadmat('../matFiles/buildSCFpyr7.mat') pyRamp = ppt.mkRamp((128,256)) pyPyr = ppt.SCFpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) #def test8(self): # fails in matlab version # matPyr = scipy.io.loadmat('../matFiles/buildSCFpyr8.mat') # pyRamp = ppt.mkRamp((200,100)) @@ -533,170 +533,170 @@ def test10(self): pyRamp = ppt.mkRamp((256,256)) pyPyr = ppt.SCFpyr(pyRamp) recon = pyPyr.reconPyr([0]) - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test11(self): matPyr = scipy.io.loadmat('../matFiles/buildSCFpyr11.mat') pyRamp = ppt.mkRamp((256,256)) pyPyr = ppt.SCFpyr(pyRamp) recon = pyPyr.reconPyr([0,2,4]) - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test12(self): matPyr = scipy.io.loadmat('../matFiles/buildSCFpyr12.mat') pyRamp = ppt.mkRamp((256,256)) pyPyr = ppt.SCFpyr(pyRamp) recon = pyPyr.reconPyr([0,2,4], [1]) - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) class WpyrTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr0.mat') pyRamp = ppt.mkRamp((20,20)) pyPyr = ppt.Wpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr1.mat') img = np.array(Image.open('../lenna-256x256.tif')).astype(float) pyPyr = ppt.Wpyr(img) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr2.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Wpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr3.mat') pyRamp = ppt.mkRamp((100,200)) pyPyr = ppt.Wpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr4.mat') pyRamp = ppt.mkRamp((200,100)) pyPyr = ppt.Wpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr5.mat') img = np.array(Image.open('../lenna-256x256.tif')).astype(float) pyPyr = ppt.Wpyr(img) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test6(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr6.mat') pyRamp = ppt.mkRamp((256,128)) pyPyr = ppt.Wpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test7(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr7.mat') pyRamp = ppt.mkRamp((128,256)) pyPyr = ppt.Wpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test8(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr8.mat') pyRamp = ppt.mkRamp((200,200)) pyPyr = ppt.Wpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test9(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr9.mat') pyRamp = ppt.mkRamp((200,100)) pyPyr = ppt.Wpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test10(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr10.mat') pyRamp = ppt.mkRamp((100,200)) pyPyr = ppt.Wpyr(pyRamp) recon = pyPyr.reconPyr() - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test11(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr11.mat') pyRamp = ppt.mkRamp((256,256)) pyPyr = ppt.Wpyr(pyRamp) recon = pyPyr.reconPyr('qmf9', 'reflect1', [0]) - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test12(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr12.mat') pyRamp = ppt.mkRamp((256,256)) pyPyr = ppt.Wpyr(pyRamp) recon = pyPyr.reconPyr('qmf9', 'reflect1', [0,2,4]) - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test13(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr13.mat') pyRamp = ppt.mkRamp((256,256)) pyPyr = ppt.Wpyr(pyRamp) recon = pyPyr.reconPyr('qmf9', 'reflect1', [0,2,4], [1]) - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test14(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr14.mat') pyRamp = ppt.mkRamp((256,256)) pyPyr = ppt.Wpyr(pyRamp) recon = pyPyr.reconPyr('qmf8') - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test15(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr15.mat') pyRamp = ppt.mkRamp((256,128)) pyPyr = ppt.Wpyr(pyRamp) recon = pyPyr.reconPyr('qmf8') - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test16(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr16.mat') pyRamp = ppt.mkRamp((128,256)) pyPyr = ppt.Wpyr(pyRamp) recon = pyPyr.reconPyr('qmf8') - self.failUnless(ppt.compareRecon(matPyr['recon'], recon)) + self.assertTrue(ppt.compareRecon(matPyr['recon'], recon)) def test17(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr17.mat') pyRamp = ppt.mkRamp((1,200)) pyPyr = ppt.Wpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) def test18(self): matPyr = scipy.io.loadmat('../matFiles/buildWpyr18.mat') pyRamp = ppt.mkRamp((1,200)).T pyPyr = ppt.Wpyr(pyRamp) - self.failUnless(ppt.comparePyr(matPyr['pyr'], pyPyr)) + self.assertTrue(ppt.comparePyr(matPyr['pyr'], pyPyr)) class blurDnTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/blurDn0.mat') pyRamp = ppt.mkRamp((20,20)) res = ppt.blurDn(pyRamp) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/blurDn1.mat') pyRamp = ppt.mkRamp((256,256)) res = ppt.blurDn(pyRamp) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/blurDn2.mat') pyRamp = ppt.mkRamp((256,128)) res = ppt.blurDn(pyRamp) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/blurDn3.mat') pyRamp = ppt.mkRamp((128,256)) res = ppt.blurDn(pyRamp) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/blurDn4.mat') pyRamp = ppt.mkRamp((200, 100)) res = ppt.blurDn(pyRamp) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/blurDn5.mat') pyRamp = ppt.mkRamp((100, 200)) res = ppt.blurDn(pyRamp) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test6(self): matPyr = scipy.io.loadmat('../matFiles/blurDn6.mat') pyRamp = ppt.mkRamp((1, 256)).T res = ppt.blurDn(pyRamp) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test7(self): matPyr = scipy.io.loadmat('../matFiles/blurDn7.mat') pyRamp = ppt.mkRamp((1, 256)) res = ppt.blurDn(pyRamp) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) #def test8(self): need a 2D filter # matPyr = scipy.io.loadmat('../matFiles/blurDn8.mat') # pyRamp = ppt.mkRamp((256, 256)) @@ -707,243 +707,243 @@ class mkAngularSineTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/mkAngularSine0.mat') res = ppt.mkAngularSine(20) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/mkAngularSine1.mat') res = ppt.mkAngularSine(20, 5) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/mkAngularSine2.mat') res = ppt.mkAngularSine(20, 5, 3) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/mkAngularSine3.mat') res = ppt.mkAngularSine(20, 5, 3, 2) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/mkAngularSine4.mat') res = ppt.mkAngularSine(20, 5, 3, 2, (2,2)) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) class mkGaussianTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/mkGaussian0.mat') res = ppt.mkGaussian(20) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/mkGaussian1.mat') res = ppt.mkGaussian(20, (2,3)) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/mkGaussian2.mat') res = ppt.mkGaussian(20, [[-1, 0], [0, 1]]) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/mkGaussian3.mat') res = ppt.mkGaussian(10, [[-1, 0], [0, 1]]) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/mkGaussian4.mat') res = ppt.mkGaussian(20, [[2, 0], [0, 1]]) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) class mkDiscTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/mkDisc0.mat') res = ppt.mkDisc(20) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/mkDisc1.mat') res = ppt.mkDisc(20, 8) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/mkDisc2.mat') res = ppt.mkDisc(20, 8, (0,0)) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/mkDisc3.mat') res = ppt.mkDisc(20, 8, (0,0), 5) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/mkDisc4.mat') res = ppt.mkDisc(20, 8, (0,0), 5, (0.75, 0.25)) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) class mkSineTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/mkSine0.mat') res = ppt.mkSine(20, 5.5) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/mkSine1.mat') res = ppt.mkSine(20, 5.5, 2) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/mkSine2.mat') res = ppt.mkSine(20, 5.5, 2, 3) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/mkSine3.mat') res = ppt.mkSine(20, 5.5, 2, 3, 5) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/mkSine4.mat') res = ppt.mkSine(20, 5.5, 2, 3, 5, [4,5]) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/mkSine5.mat') res = ppt.mkSine(20, [1,2]) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test6(self): matPyr = scipy.io.loadmat('../matFiles/mkSine6.mat') res = ppt.mkSine(20, [1,2], 3) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test7(self): matPyr = scipy.io.loadmat('../matFiles/mkSine7.mat') res = ppt.mkSine(20, [1,2], 3, 2) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test8(self): matPyr = scipy.io.loadmat('../matFiles/mkSine8.mat') res = ppt.mkSine(20, [1,2], 3, 2, [5,4]) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) class mkZonePlateTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/mkZonePlate0.mat') res = ppt.mkZonePlate(20) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/mkZonePlate1.mat') res = ppt.mkZonePlate(20, 4) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/mkZonePlate2.mat') res = ppt.mkZonePlate(20, 4, 3) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) class mkSquareTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/mkSquare0.mat') res = ppt.mkSquare(20, 5.5) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/mkSquare1.mat') res = ppt.mkSquare(20, 5.5, 3) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/mkSquare2.mat') res = ppt.mkSquare(20, 5.5, 3, 5.1) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/mkSquare3.mat') res = ppt.mkSquare(20, 5.5, 3, 5.1, -1) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/mkSquare4.mat') res = ppt.mkSquare(20, 5.5, 3, 5.1, -1, (2,3)) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/mkSquare5.mat') res = ppt.mkSquare(20, 5.5, 3, 5.1, -1, (2,3), 0.25) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test6(self): matPyr = scipy.io.loadmat('../matFiles/mkSquare6.mat') res = ppt.mkSquare(20, (1,2)) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test7(self): matPyr = scipy.io.loadmat('../matFiles/mkSquare7.mat') res = ppt.mkSquare(20, (1,2), 3.2) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test8(self): matPyr = scipy.io.loadmat('../matFiles/mkSquare8.mat') res = ppt.mkSquare(20, (1,2), 3.2, -2) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test9(self): matPyr = scipy.io.loadmat('../matFiles/mkSquare9.mat') res = ppt.mkSquare(20, (1,2), 3.2, -2, (2,3)) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test10(self): matPyr = scipy.io.loadmat('../matFiles/mkSquare10.mat') res = ppt.mkSquare(20, (1,2), 3.2, -2, (2,3), 0.55) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) class blurTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/blur0.mat') res = ppt.blur(ppt.mkRamp(20)) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/blur1.mat') res = ppt.blur(ppt.mkRamp(20), 3) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/blur2.mat') res = ppt.blur(ppt.mkRamp(20), 3, ppt.namedFilter('qmf5')) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/blur3.mat') res = ppt.blur(ppt.mkRamp((20,30))) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/blur4.mat') res = ppt.blur(ppt.mkRamp((20,30)), 3) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/blur5.mat') res = ppt.blur(ppt.mkRamp((20,30)), 3, ppt.namedFilter('qmf5')) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) class cconv2Tests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/cconv2_0.mat') res = ppt.cconv2(ppt.mkRamp(20), ppt.mkRamp(10)) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/cconv2_1.mat') res = ppt.cconv2(ppt.mkRamp(10), ppt.mkRamp(20)) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/cconv2_2.mat') res = ppt.cconv2(ppt.mkRamp(20), ppt.mkRamp(10), 3) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/cconv2_3.mat') res = ppt.cconv2(ppt.mkRamp(10), ppt.mkRamp(20), 3) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/cconv2_4.mat') res = ppt.cconv2(ppt.mkRamp((20,30)), ppt.mkRamp((10,20))) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/cconv2_5.mat') res = ppt.cconv2(ppt.mkRamp((10,20)), ppt.mkRamp((20,30))) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test6(self): matPyr = scipy.io.loadmat('../matFiles/cconv2_6.mat') res = ppt.cconv2(ppt.mkRamp((20,30)), ppt.mkRamp((10,20)), 5) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test7(self): matPyr = scipy.io.loadmat('../matFiles/cconv2_7.mat') res = ppt.cconv2(ppt.mkRamp((10,20)), ppt.mkRamp((20,30)), 5) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) class clipTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/clip0.mat') res = ppt.clip(ppt.mkRamp(20) / ppt.mkRamp(20).max()) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/clip1.mat') res = ppt.clip(ppt.mkRamp(20) / ppt.mkRamp(20).max(), 0.3) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/clip2.mat') res = ppt.clip(ppt.mkRamp(20) / ppt.mkRamp(20).max(), (0.3,0.7)) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/clip3.mat') res = ppt.clip(ppt.mkRamp(20) / ppt.mkRamp(20).max(), 0.3, 0.7) - self.failUnless(ppt.compareRecon(matPyr['res'], res)) + self.assertTrue(ppt.compareRecon(matPyr['res'], res)) # python version of histo # adding 0.7 to ramp to nullify rounding differences between Python and Matlab @@ -955,7 +955,7 @@ def test0(self): # python return edges #self.failUnless(ppt.compareRecon(matPyr['X'], X)) #self.failUnless(ppt.compareRecon(matPyr['N'], N)) - self.failUnless((matPyr['N'] == N).all()) + self.assertTrue((matPyr['N'] == N).all()) # FIX: why does matlab version return N+1 bins?? # def test1(self): # matPyr = scipy.io.loadmat('../matFiles/histo1.mat') @@ -994,11 +994,11 @@ class factorialTests(unittest.TestCase): def test0(self): matPyr = scipy.io.loadmat('../matFiles/factorial0.mat') res = ppt.factorial([[1,2],[3,4]]) - self.failUnless((matPyr['res'] == res).all()) + self.assertTrue((matPyr['res'] == res).all()) def test1(self): matPyr = scipy.io.loadmat('../matFiles/factorial1.mat') res = ppt.factorial(4) - self.failUnless(matPyr['res'] == res) + self.assertTrue(matPyr['res'] == res) #class histoMatchTests(unittest.TestCase): # def test0(self): @@ -1020,16 +1020,16 @@ def test0(self): [dx,dy] = ppt.imGradient(ramp) dx = np.array(dx) dy = np.array(dy) - self.failUnless(ppt.compareRecon(matPyr['res'][:,:,0], dx)) - self.failUnless(ppt.compareRecon(matPyr['res'][:,:,1], dy)) + self.assertTrue(ppt.compareRecon(matPyr['res'][:,:,0], dx)) + self.assertTrue(ppt.compareRecon(matPyr['res'][:,:,1], dy)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/imGradient1.mat') ramp = ppt.mkRamp(10) [dx,dy] = ppt.imGradient(ramp, 'reflect1') dx = np.array(dx) dy = np.array(dy) - self.failUnless(ppt.compareRecon(matPyr['res'][:,:,0], dx)) - self.failUnless(ppt.compareRecon(matPyr['res'][:,:,1], dy)) + self.assertTrue(ppt.compareRecon(matPyr['res'][:,:,0], dx)) + self.assertTrue(ppt.compareRecon(matPyr['res'][:,:,1], dy)) class skew2Tests(unittest.TestCase): def test0(self): @@ -1038,7 +1038,7 @@ def test0(self): mres = matPyr['res'][0][0] disc = ppt.mkDisc(10) res = ppt.skew2(disc) - self.failUnless(np.absolute(res - mres) <= math.pow(10,-11)) + self.assertTrue(np.absolute(res - mres) <= math.pow(10,-11)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/skew2_1.mat') # not sure why matPyr is [[ans]]??? @@ -1047,7 +1047,7 @@ def test1(self): # using incorrect mean for better test mn = disc.mean() + 0.1 res = ppt.skew2(disc, mn) - self.failUnless(np.absolute(res - mres) <= math.pow(10,-11)) + self.assertTrue(np.absolute(res - mres) <= math.pow(10,-11)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/skew2_2.mat') # not sure why matPyr is [[ans]]??? @@ -1057,7 +1057,7 @@ def test2(self): mn = disc.mean() + 0.1 v = ppt.var2(disc) + 0.1 res = ppt.skew2(disc, mn, v) - self.failUnless(np.absolute(res - mres) <= math.pow(10,-11)) + self.assertTrue(np.absolute(res - mres) <= math.pow(10,-11)) class upBlurTests(unittest.TestCase): def test0(self): @@ -1065,44 +1065,44 @@ def test0(self): mres = matPyr['res'] im = ppt.mkRamp((1,20)) res = ppt.upBlur(im) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/upBlur1.mat') mres = matPyr['res'] im = ppt.mkRamp((1,20)) res = ppt.upBlur(im.T) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/upBlur2.mat') mres = matPyr['res'] im = ppt.mkRamp(20) res = ppt.upBlur(im) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/upBlur3.mat') mres = matPyr['res'] im = ppt.mkRamp((1,20)) res = ppt.upBlur(im, 3) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/upBlur4.mat') mres = matPyr['res'] im = ppt.mkRamp((1,20)) res = ppt.upBlur(im.T, 3) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/upBlur5.mat') mres = matPyr['res'] im = ppt.mkRamp(20) res = ppt.upBlur(im, 3) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test6(self): matPyr = scipy.io.loadmat('../matFiles/upBlur6.mat') mres = matPyr['res'] im = ppt.mkRamp((1,20)) filt = ppt.namedFilter('qmf9') res = ppt.upBlur(im, 3, filt) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) #def test7(self): # fails in matlab and python because of dim mismatch # matPyr = scipy.io.loadmat('../matFiles/upBlur7.mat') # mres = matPyr['res'] @@ -1116,7 +1116,7 @@ def test8(self): im = ppt.mkRamp((1,20)) filt = ppt.namedFilter('qmf9') res = ppt.upBlur(im.T, 3, filt) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) #def test9(self): # fails in matlab and python because of dim mismatch # matPyr = scipy.io.loadmat('../matFiles/upBlur6.mat') # mres = matPyr['res'] @@ -1130,21 +1130,21 @@ def test10(self): im = ppt.mkRamp(20) filt = ppt.mkDisc(3) res = ppt.upBlur(im, 3, filt) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test11(self): matPyr = scipy.io.loadmat('../matFiles/upBlur11.mat') mres = matPyr['res'] im = ppt.mkRamp((20,10)) filt = ppt.mkDisc((5,3)) res = ppt.upBlur(im, 3, filt) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test12(self): matPyr = scipy.io.loadmat('../matFiles/upBlur12.mat') mres = matPyr['res'] im = ppt.mkRamp((10,20)) filt = ppt.mkDisc((3,5)) res = ppt.upBlur(im, 3, filt) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) class zconv2Tests(unittest.TestCase): def test0(self): @@ -1153,42 +1153,42 @@ def test0(self): ramp = ppt.mkRamp(10) disc = ppt.mkDisc(5) res = ppt.zconv2(ramp, disc) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test1(self): matPyr = scipy.io.loadmat('../matFiles/zconv2_1.mat') mres = matPyr['res'] ramp = ppt.mkRamp((10,20)) disc = ppt.mkDisc((5,10)) res = ppt.zconv2(ramp, disc) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/zconv2_2.mat') mres = matPyr['res'] ramp = ppt.mkRamp((20,10)) disc = ppt.mkDisc((10,5)) res = ppt.zconv2(ramp, disc) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/zconv2_3.mat') mres = matPyr['res'] ramp = ppt.mkRamp(10) disc = ppt.mkDisc(5) res = ppt.zconv2(ramp, disc, 3) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test4(self): matPyr = scipy.io.loadmat('../matFiles/zconv2_4.mat') mres = matPyr['res'] ramp = ppt.mkRamp((10,20)) disc = ppt.mkDisc((5,10)) res = ppt.zconv2(ramp, disc, 3) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test5(self): matPyr = scipy.io.loadmat('../matFiles/zconv2_5.mat') mres = matPyr['res'] ramp = ppt.mkRamp((20,10)) disc = ppt.mkDisc((10,5)) res = ppt.zconv2(ramp, disc, 3) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) class corrDnTests(unittest.TestCase): def test1(self): @@ -1196,19 +1196,19 @@ def test1(self): mres = matPyr['res'] ramp = ppt.mkRamp(20) res = ppt.corrDn(ramp, ppt.namedFilter('binom5')) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test2(self): matPyr = scipy.io.loadmat('../matFiles/corrDn2.mat') mres = matPyr['res'] ramp = ppt.mkRamp(20) res = ppt.corrDn(ramp, ppt.namedFilter('qmf13')) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def test3(self): matPyr = scipy.io.loadmat('../matFiles/corrDn3.mat') mres = matPyr['res'] ramp = ppt.mkRamp(20) res = ppt.corrDn(ramp, ppt.namedFilter('qmf16')) - self.failUnless(ppt.compareRecon(mres, res)) + self.assertTrue(ppt.compareRecon(mres, res)) def main(): unittest.main() diff --git a/Wpyr.py b/Wpyr.py index 1b1f6ac..63acd1a 100644 --- a/Wpyr.py +++ b/Wpyr.py @@ -1,11 +1,11 @@ -from Lpyr import Lpyr -from LB2idx import LB2idx -from namedFilter import namedFilter -from modulateFlip import modulateFlip -from maxPyrHt import maxPyrHt -from corrDn import corrDn -from upConv import upConv -import JBhelpers +from .Lpyr import Lpyr +from .LB2idx import LB2idx +from .namedFilter import namedFilter +from .modulateFlip import modulateFlip +from .maxPyrHt import maxPyrHt +from .corrDn import corrDn +from .upConv import upConv +from . import JBhelpers import numpy import matplotlib import pylab @@ -24,7 +24,7 @@ def __init__(self, *args): # (image, height, order, twidth) if len(args) > 0: im = args[0] else: - print "First argument (image) is required." + print("First argument (image) is required.") return #------------------------------------------------ @@ -34,11 +34,11 @@ def __init__(self, *args): # (image, height, order, twidth) filt = args[2] else: filt = "qmf9" - if isinstance(filt, basestring): + if isinstance(filt, str): filt = namedFilter(filt) if len(filt.shape) != 1 and filt.shape[0] != 1 and filt.shape[1] != 1: - print "Error: filter should be 1D (i.e., a vector)"; + print("Error: filter should be 1D (i.e., a vector)"); return hfilt = modulateFlip(filt) @@ -67,7 +67,7 @@ def __init__(self, *args): # (image, height, order, twidth) if ht == 'auto': ht = max_ht elif(ht > max_ht): - print "Error: cannot build pyramid higher than %d levels." % (max_ht) + print("Error: cannot build pyramid higher than %d levels." % (max_ht)) else: ht = max_ht ht = int(ht) @@ -166,28 +166,28 @@ def reconPyr(self, *args): maxLev = int(self.wpyrHt() + 1) if isinstance(levs, str) and levs == 'all': - levs = numpy.array(range(maxLev)) + levs = numpy.array(list(range(maxLev))) else: tmpLevs = [] for l in levs: tmpLevs.append((maxLev-1)-l) levs = numpy.array(tmpLevs) if (levs > maxLev).any(): - print "Error: level numbers must be in the range [0, %d]" % (maxLev) - allLevs = numpy.array(range(maxLev)) + print("Error: level numbers must be in the range [0, %d]" % (maxLev)) + allLevs = numpy.array(list(range(maxLev))) if isinstance(bands, str) and bands == "all": if ( len(self.band(0)) == 1 or self.band(0).shape[0] == 1 or self.band(0).shape[1] == 1 ): bands = numpy.array([0]); else: - bands = numpy.array(range(3)) + bands = numpy.array(list(range(3))) else: bands = numpy.array(bands) if (bands < 0).any() or (bands > 2).any(): - print "Error: band numbers must be in the range [0,2]." + print("Error: band numbers must be in the range [0,2].") - if isinstance(filt, basestring): + if isinstance(filt, str): filt = namedFilter(filt) hfilt = modulateFlip(filt).T @@ -302,25 +302,25 @@ def reconPyr(self, *args): def set(self, *args): if len(args) != 3: - print 'Error: three input parameters required:' - print ' set(band, location, value)' - print ' where band and value are integer and location is a tuple' - if isinstance(args[1], (int, long)): + print('Error: three input parameters required:') + print(' set(band, location, value)') + print(' where band and value are integer and location is a tuple') + if isinstance(args[1], int): self.pyr[args[0]][0][args[1]] = args[2] elif isinstance(args[1], tuple): self.pyr[args[0]][args[1][0]][args[1][1]] = args[2] else: - print 'Error: location parameter must be int or tuple!' + print('Error: location parameter must be int or tuple!') return def set1D(self, *args): if len(args) != 3: - print 'Error: three input parameters required:' - print ' set(band, location, value)' - print ' where band and value are integer and location is a tuple' - print '%d %d %d' % (args[0], args[1], args[2]) - print self.pyr[args[0]][0][1] + print('Error: three input parameters required:') + print(' set(band, location, value)') + print(' where band and value are integer and location is a tuple') + print('%d %d %d' % (args[0], args[1], args[2])) + print(self.pyr[args[0]][0][1]) def pyrLow(self): return numpy.array(self.band(len(self.pyrSize)-1)) @@ -410,10 +410,10 @@ def showPyr(self, prange = None, gap = 1, scale = None, disp = 'qt'): av = numpy.mean(band) stdev = numpy.sqrt( numpy.var(band) ) prange[nind-1,:] = numpy.array([av-2*stdev, av+2*stdev]) - elif isinstance(prange, basestring): - print "Error:Bad RANGE argument: %s'" % (prange) + elif isinstance(prange, str): + print("Error:Bad RANGE argument: %s'" % (prange)) elif prange.shape[0] == 1 and prange.shape[1] == 2: - scales = numpy.power(scale, range(ht)) + scales = numpy.power(scale, list(range(ht))) scales = numpy.outer( numpy.ones((nbands,1)), scales ) scales = numpy.array([1, scales, numpy.power(scale, ht)]) prange = numpy.outer(scales, prange) diff --git a/__init__.py b/__init__.py index 5d8459c..322cabf 100644 --- a/__init__.py +++ b/__init__.py @@ -1,66 +1,66 @@ -from binomialFilter import binomialFilter -from blurDn import blurDn -from blur import blur -from cconv2 import cconv2 -from clip import clip -from comparePyr import comparePyr -from compareRecon import compareRecon -from corrDn import corrDn -from entropy2 import entropy2 -from factorial import factorial -from Gpyr import Gpyr -from histoMatch import histoMatch -from histo import histo -from idx2LB import idx2LB -from imGradient import imGradient -from imStats import imStats -from kurt2 import kurt2 -from LB2idx import LB2idx -from Lpyr import Lpyr -from maxPyrHt import maxPyrHt -from mkAngle import mkAngle -from mkAngularSine import mkAngularSine -from mkDisc import mkDisc -from mkFract import mkFract -from mkGaussian import mkGaussian -from mkImpulse import mkImpulse -from mkRamp import mkRamp -from mkR import mkR -from mkSine import mkSine -from mkSquare import mkSquare -from mkZonePlate import mkZonePlate -from modulateFlip import modulateFlip -from namedFilter import namedFilter -from nextSz import nextSz -from pointOp import pointOp -from pyramid import pyramid -from range2 import range2 -from rconv2 import rconv2 -from rcosFn import rcosFn -from round import round -from roundVal import roundVal -from SCFpyr import SCFpyr -from SFpyr import SFpyr -from shift import shift -from showIm import showIm -from skew2 import skew2 -from sp0Filters import sp0Filters -from sp1Filters import sp1Filters -from sp3Filters import sp3Filters -from sp5Filters import sp5Filters -from Spyr import Spyr +from .binomialFilter import binomialFilter +from .blurDn import blurDn +from .blur import blur +from .cconv2 import cconv2 +from .clip import clip +from .comparePyr import comparePyr +from .compareRecon import compareRecon +from .corrDn import corrDn +from .entropy2 import entropy2 +from .factorial import factorial +from .Gpyr import Gpyr +from .histoMatch import histoMatch +from .histo import histo +from .idx2LB import idx2LB +from .imGradient import imGradient +from .imStats import imStats +from .kurt2 import kurt2 +from .LB2idx import LB2idx +from .Lpyr import Lpyr +from .maxPyrHt import maxPyrHt +from .mkAngle import mkAngle +from .mkAngularSine import mkAngularSine +from .mkDisc import mkDisc +from .mkFract import mkFract +from .mkGaussian import mkGaussian +from .mkImpulse import mkImpulse +from .mkRamp import mkRamp +from .mkR import mkR +from .mkSine import mkSine +from .mkSquare import mkSquare +from .mkZonePlate import mkZonePlate +from .modulateFlip import modulateFlip +from .namedFilter import namedFilter +from .nextSz import nextSz +from .pointOp import pointOp +from .pyramid import pyramid +from .range2 import range2 +from .rconv2 import rconv2 +from .rcosFn import rcosFn +from .round import round +from .roundVal import roundVal +from .SCFpyr import SCFpyr +from .SFpyr import SFpyr +from .shift import shift +from .showIm import showIm +from .skew2 import skew2 +from .sp0Filters import sp0Filters +from .sp1Filters import sp1Filters +from .sp3Filters import sp3Filters +from .sp5Filters import sp5Filters +from .Spyr import Spyr # from SpyrMulti import SpyrMulti -from steer2HarmMtx import steer2HarmMtx -from steer import steer -from strictly_decreasing import strictly_decreasing -from upBlur import upBlur -from upConv import upConv -from var2 import var2 -from Wpyr import Wpyr -from zconv2 import zconv2 +from .steer2HarmMtx import steer2HarmMtx +from .steer import steer +from .strictly_decreasing import strictly_decreasing +from .upBlur import upBlur +from .upConv import upConv +from .var2 import var2 +from .Wpyr import Wpyr +from .zconv2 import zconv2 import ctypes import os -import JBhelpers +from . import JBhelpers # load the C library lib = ctypes.cdll.LoadLibrary(os.path.dirname(os.path.realpath(__file__)) + diff --git a/binomialFilter.py b/binomialFilter.py index dfe41d0..bc4e879 100644 --- a/binomialFilter.py +++ b/binomialFilter.py @@ -4,7 +4,7 @@ def binomialFilter(size): ''' returns a vector of binomial coefficients of order (size-1) ''' if size < 2: - print "Error: size argument must be larger than 1" + print("Error: size argument must be larger than 1") exit(1) kernel = numpy.array([[0.5], [0.5]]) diff --git a/blur.py b/blur.py index fd45fb1..df8f77f 100644 --- a/blur.py +++ b/blur.py @@ -1,7 +1,7 @@ import numpy -from namedFilter import namedFilter -from corrDn import corrDn -from upConv import upConv +from .namedFilter import namedFilter +from .corrDn import corrDn +from .upConv import upConv def blur(*args): ''' RES = blur(IM, LEVELS, FILT) @@ -18,8 +18,8 @@ def blur(*args): # REQUIRED ARG: if len(args) == 0: - print "blur(IM, LEVELS, FILT)" - print "first argument is required" + print("blur(IM, LEVELS, FILT)") + print("first argument is required") exit(1) else: im = numpy.array(args[0]) @@ -31,7 +31,7 @@ def blur(*args): nlevs = 1 if len(args) > 2: - if isinstance(args[2], basestring): + if isinstance(args[2], str): filt = namedFilter(args[2]) else: filt = numpy.array(args[2]) @@ -49,7 +49,7 @@ def blur(*args): if len(im.shape) == 1 or im.shape[0] == 1 or im.shape[1] == 1: # 1D image if len(filt) == 2 and (numpy.asarray(filt.shape) != 1).any(): - print 'Error: can not apply 2D filter to 1D signal' + print('Error: can not apply 2D filter to 1D signal') return imIn = corrDn(im, filt, 'reflect1', len(im)) diff --git a/blurDn.py b/blurDn.py index cfd1751..aca322b 100644 --- a/blurDn.py +++ b/blurDn.py @@ -1,6 +1,6 @@ import numpy -from namedFilter import namedFilter -from corrDn import corrDn +from .namedFilter import namedFilter +from .corrDn import corrDn def blurDn(*args): ''' RES = blurDn(IM, LEVELS, FILT) @@ -15,7 +15,7 @@ def blurDn(*args): function res = blurDn(im, nlevs, filt) ''' if len(args) == 0: - print "Error: image input parameter required." + print("Error: image input parameter required.") return im = numpy.array(args[0]) @@ -28,7 +28,7 @@ def blurDn(*args): if len(args) > 2: filt = args[2] - if isinstance(filt, basestring): + if isinstance(filt, str): filt = namedFilter(filt) else: filt = namedFilter('binom5') @@ -48,7 +48,7 @@ def blurDn(*args): # 1D image if len(filt.shape) > 1 and (filt.shape[1]!=1 and filt.shape[2]!=1): # >1D filter - print 'Error: Cannot apply 2D filter to 1D signal' + print('Error: Cannot apply 2D filter to 1D signal') return # orient filter and image correctly if im.shape[0] == 1: diff --git a/cconv2.py b/cconv2.py index 3150f47..2d32819 100644 --- a/cconv2.py +++ b/cconv2.py @@ -18,9 +18,9 @@ def cconv2(*args): Python port by Rob Young, 8/15 ''' if len(args) < 2: - print 'Error: cconv2 requires two input matrices!' - print 'Usage: cconv2(matrix1, matrix2, center)' - print 'where center parameter is optional' + print('Error: cconv2 requires two input matrices!') + print('Usage: cconv2(matrix1, matrix2, center)') + print('where center parameter is optional') return else: a = numpy.array(args[0]) @@ -38,7 +38,7 @@ def cconv2(*args): large = b small = a else: - print 'Error: one matrix must be larger than the other in both dimensions!' + print('Error: one matrix must be larger than the other in both dimensions!') return ly = large.shape[0] diff --git a/clip.py b/clip.py index aa4905a..3e003ab 100644 --- a/clip.py +++ b/clip.py @@ -10,8 +10,8 @@ def clip(*args): ported to Python by Rob Young, 8/15 ''' if len(args) == 0 or len(args) > 3: - print 'Usage: clip(im, minVal or Range, maxVal)' - print 'first input parameter is required' + print('Usage: clip(im, minVal or Range, maxVal)') + print('first input parameter is required') return im = numpy.array(args[0]) @@ -20,7 +20,7 @@ def clip(*args): minVal = 0; maxVal = 1; elif len(args) == 2: - if isinstance(args[1], (int, long, float)): + if isinstance(args[1], (int, float)): minVal = args[1] maxVal = args[1]+1 else: @@ -31,7 +31,7 @@ def clip(*args): maxVal = args[2] if maxVal < minVal: - print 'Error: maxVal cannot be less than minVal!' + print('Error: maxVal cannot be less than minVal!') return im[numpy.where(im < minVal)] = minVal diff --git a/comparePyr.py b/comparePyr.py index 0434078..4d619e8 100644 --- a/comparePyr.py +++ b/comparePyr.py @@ -19,7 +19,7 @@ def comparePyr(matPyr, pyPyr): pySz += sz[0] * sz[1] if(matSz != pySz): - print "size difference: %d != %d, returning 0" % (matSz, pySz) + print("size difference: %d != %d, returning 0" % (matSz, pySz)) return 0 # values are the same? @@ -34,14 +34,14 @@ def comparePyr(matPyr, pyPyr): matTmp = numpy.reshape(matTmp, bandSz, order='F') matStart = matStart+matLen if (matTmp != pyPyr.pyr[idx]).any(): - print "some pyramid elements not identical: checking..." + print("some pyramid elements not identical: checking...") for i in range(bandSz[0]): for j in range(bandSz[1]): if matTmp[i,j] != pyPyr.pyr[idx][i,j]: if ( math.fabs(matTmp[i,j] - pyPyr.pyr[idx][i,j]) > prec ): - print "failed level:%d element:%d %d value:%.15f %.15f" % (idx, i, j, matTmp[i,j], pyPyr.pyr[idx][i,j]) + print("failed level:%d element:%d %d value:%.15f %.15f" % (idx, i, j, matTmp[i,j], pyPyr.pyr[idx][i,j])) return 0 - print "same to at least %f" % prec + print("same to at least %f" % prec) return 1 diff --git a/compareRecon.py b/compareRecon.py index 8961af4..69b62ad 100644 --- a/compareRecon.py +++ b/compareRecon.py @@ -8,15 +8,15 @@ def compareRecon(recon1, recon2): ## FIX: make precision a input parameter prec = -11 # desired precision if recon1.shape != recon2.shape: - print 'shape is different!' - print recon1.shape - print recon2.shape + print('shape is different!') + print(recon1.shape) + print(recon2.shape) return 0 for i in range(recon1.shape[0]): for j in range(recon2.shape[1]): if numpy.absolute(recon1[i,j].real - recon2[i,j].real) > math.pow(10,-11): - print "real: i=%d j=%d %.15f %.15f diff=%.15f" % (i, j, recon1[i,j].real, recon2[i,j].real, numpy.absolute(recon1[i,j].real-recon2[i,j].real)) + print("real: i=%d j=%d %.15f %.15f diff=%.15f" % (i, j, recon1[i,j].real, recon2[i,j].real, numpy.absolute(recon1[i,j].real-recon2[i,j].real))) return 0 ## FIX: need a better way to test # if we have many significant digits to the left of decimal we @@ -27,9 +27,9 @@ def compareRecon(recon1, recon2): prec = prec + int(math.log(numpy.abs(recon1[i,j].imag), 10)) if prec > 0: prec = -1 - print prec + print(prec) if numpy.absolute(recon1[i,j].imag - recon2[i,j].imag) > math.pow(10, prec): - print "imag: i=%d j=%d %.15f %.15f diff=%.15f" % (i, j, recon1[i,j].imag, recon2[i,j].imag, numpy.absolute(recon1[i,j].imag-recon2[i,j].imag)) + print("imag: i=%d j=%d %.15f %.15f diff=%.15f" % (i, j, recon1[i,j].imag, recon2[i,j].imag, numpy.absolute(recon1[i,j].imag-recon2[i,j].imag))) return 0 return 1 diff --git a/corrDn.py b/corrDn.py index 0b4ec80..456f763 100644 --- a/corrDn.py +++ b/corrDn.py @@ -10,7 +10,7 @@ def corrDn(image = None, filt = None, edges = 'reflect1', step = (1,1), start = (0,0), stop = None, result = None): if image is None or filt is None: - print 'Error: image and filter are required input parameters!' + print('Error: image and filter are required input parameters!') return else: image = image.copy() @@ -23,8 +23,8 @@ def corrDn(image = None, filt = None, edges = 'reflect1', step = (1,1), stop = (image.shape[0], image.shape[1]) if result is None: - rxsz = len(range(start[0], stop[0], step[0])) - rysz = len(range(start[1], stop[1], step[1])) + rxsz = len(list(range(start[0], stop[0], step[0]))) + rysz = len(list(range(start[1], stop[1], step[1]))) result = numpy.zeros((rxsz, rysz)) else: result = numpy.array(result.copy()) diff --git a/factorial.py b/factorial.py index a04a0c3..d3ea8a2 100644 --- a/factorial.py +++ b/factorial.py @@ -8,7 +8,7 @@ def factorial(*args): EPS, 11/02, Python port by Rob Young, 10/15 ''' # if scalar input make it a single element array - if isinstance(args[0], (int, long, float)): + if isinstance(args[0], (int, float)): num = numpy.array([args[0]]) else: num = numpy.array(args[0]) diff --git a/histo.py b/histo.py index 56ab20b..18b1485 100644 --- a/histo.py +++ b/histo.py @@ -1,6 +1,6 @@ import numpy -from range2 import range2 -from round import round +from .range2 import range2 +from .round import round def histo(*args): ''' [N,X] = histo(MTX, nbinsOrBinsize, binCenter); @@ -25,8 +25,8 @@ def histo(*args): Eero Simoncelli, 3/97. ported to Python by Rob Young, 8/15. ''' if len(args) == 0 or len(args) > 3: - print 'Usage: histo(mtx, nbins, binCtr)' - print 'first argument is required' + print('Usage: histo(mtx, nbins, binCtr)') + print('first argument is required') return else: mtx = args[0] @@ -47,7 +47,7 @@ def histo(*args): tmpNbins = ( round(float(mx-binCtr) / float(binSize)) - round(float(mn-binCtr) / float(binSize)) ) if tmpNbins != args[1]: - print 'Warning: Using %d bins instead of requested number (%d)' % (tmpNbins, args[1]) + print('Warning: Using %d bins instead of requested number (%d)' % (tmpNbins, args[1])) else: binSize = float(mx-mn) / 101.0 @@ -60,7 +60,7 @@ def histo(*args): # numpy.histogram uses bin edges, not centers like Matlab's hist #bins = firstBin + binSize * numpy.array(range(tmpNbins+1)) # compute bin edges - binsE = firstEdge + binSize * numpy.array(range(tmpNbins+1)) + binsE = firstEdge + binSize * numpy.array(list(range(tmpNbins+1))) [N, X] = numpy.histogram(mtx, binsE) diff --git a/imGradient.py b/imGradient.py index 7143ff3..83166f8 100644 --- a/imGradient.py +++ b/imGradient.py @@ -1,5 +1,5 @@ import numpy -from corrDn import corrDn +from .corrDn import corrDn def imGradient(*args): ''' [dx, dy] = imGradient(im, edges) @@ -18,8 +18,8 @@ def imGradient(*args): Python port by Rob Young, 10/15 ''' if len(args) == 0 or len(args) > 2: - print 'Usage: imGradient(image, edges)' - print "'edges' argument is optional" + print('Usage: imGradient(image, edges)') + print("'edges' argument is optional") elif len(args) == 1: edges = "dont-compute" elif len(args) == 2: diff --git a/imStats.py b/imStats.py index 5e7d437..b8024bc 100644 --- a/imStats.py +++ b/imStats.py @@ -1,7 +1,7 @@ import numpy -from range2 import range2 -from var2 import var2 -from kurt2 import kurt2 +from .range2 import range2 +from .var2 import var2 +from .kurt2 import kurt2 def imStats(*args): ''' Report image (matrix) statistics. @@ -11,16 +11,16 @@ def imStats(*args): stdev of the difference, and also SNR (relative to IM1). ''' if len(args) == 0: - print 'Error: at least one input image is required' + print('Error: at least one input image is required') return elif len(args) == 1 and not numpy.isreal(args[0]).all(): - print 'Error: input images must be real-valued matrices' + print('Error: input images must be real-valued matrices') return elif len(args) == 2 and ( not numpy.isreal(args[0]).all() or not numpy.isreal(args[1]).all()): - print 'Error: input images must be real-valued matrices' + print('Error: input images must be real-valued matrices') return elif len(args) > 2: - print 'Error: maximum of two input images allowed' + print('Error: maximum of two input images allowed') return if len(args) == 2: @@ -32,17 +32,17 @@ def imStats(*args): snr = numpy.inf else: snr = 10 * numpy.log10(var2(args[0])/v) - print 'Difference statistics:' - print ' Range: [%d, %d]' % (mn, mx) - print ' Mean: %f, Stdev (rmse): %f, SNR (dB): %f' % (mean, + print('Difference statistics:') + print(' Range: [%d, %d]' % (mn, mx)) + print(' Mean: %f, Stdev (rmse): %f, SNR (dB): %f' % (mean, numpy.sqrt(v), - snr) + snr)) else: (mn, mx) = range2(args[0]) mean = args[0].mean() var = var2(args[0]) stdev = numpy.sqrt(var.real) + numpy.sqrt(var.imag) kurt = kurt2(args[0], mean, stdev**2) - print 'Image statistics:' - print ' Range: [%f, %f]' % (mn, mx) - print ' Mean: %f, Stdev: %f, Kurtosis: %f' % (mean, stdev, kurt) + print('Image statistics:') + print(' Range: [%f, %f]' % (mn, mx)) + print(' Mean: %f, Stdev: %f, Kurtosis: %f' % (mean, stdev, kurt)) diff --git a/kurt2.py b/kurt2.py index 4a40f84..8c77966 100644 --- a/kurt2.py +++ b/kurt2.py @@ -6,7 +6,7 @@ def kurt2(*args): MEAN (optional) and VAR (optional) make the computation faster. ''' if len(args) == 0: - print 'Error: input matrix is required' + print('Error: input matrix is required') if len(args) < 2: mn = args[0].mean() diff --git a/makeChangelog.py b/makeChangelog.py index 6ae0411..5316189 100755 --- a/makeChangelog.py +++ b/makeChangelog.py @@ -2,25 +2,25 @@ # script makes a change log txt file from git logs # usage: makeChangelog.py > CHANGELOG.txt -import commands +import subprocess -atags = commands.getoutput('git tag -n') +atags = subprocess.getoutput('git tag -n') atags = atags.split('\n'); -tags = commands.getoutput('git tag -l') +tags = subprocess.getoutput('git tag -l') tags = tags.split('\n'); #for t in range(0, len(tags)-1): for t in range(len(tags)-1, -1, -1): if t == 0: #print "*** " + atags[t+1] - print "*** " + atags[t] + print("*** " + atags[t]) else: #print '\n\n*** ' + atags[t+1] - print '\n\n*** ' + atags[t] + print('\n\n*** ' + atags[t]) #commandStr = 'git log %s..%s --pretty=%s' % (tags[t], tags[t+1], '%s') commandStr = 'git log %s..%s --pretty=%s' % (tags[t-1], tags[t], '%s') - changes = commands.getoutput(commandStr) + changes = subprocess.getoutput(commandStr) changes = changes.split('\n') #changes = changes[::-1] for line in changes: - print ' + ' + line + print(' + ' + line) diff --git a/mkAngle.py b/mkAngle.py index bdbe675..29f9164 100644 --- a/mkAngle.py +++ b/mkAngle.py @@ -9,10 +9,10 @@ def mkAngle(*args): if len(args) > 0: sz = args[0] if not isinstance(sz, tuple): - sz = (sz, sz) + sz = tuple(sz) else: - print "Error: first input parameter 'size' is required!" - print "makeAngle(size, phase, origin)" + print("Error: first input parameter 'size' is required!") + print("makeAngle(size, phase, origin)") return # ------------------------------------------------------------ @@ -30,8 +30,8 @@ def mkAngle(*args): #------------------------------------------------------------------ - (xramp, yramp) = numpy.meshgrid(numpy.array(range(1,sz[1]+1))-origin[1], - (numpy.array(range(1,sz[0]+1)))-origin[0]) + (xramp, yramp) = numpy.meshgrid(numpy.array(list(range(1,sz[1]+1)))-origin[1], + (numpy.array(list(range(1,sz[0]+1))))-origin[0]) xramp = numpy.array(xramp) yramp = numpy.array(yramp) diff --git a/mkAngularSine.py b/mkAngularSine.py index b5b35cc..2e78bd8 100644 --- a/mkAngularSine.py +++ b/mkAngularSine.py @@ -1,5 +1,5 @@ import numpy -from mkAngle import mkAngle +from .mkAngle import mkAngle def mkAngularSine(*args): ''' IM = mkAngularSine(SIZE, HARMONIC, AMPL, PHASE, ORIGIN) @@ -13,15 +13,15 @@ def mkAngularSine(*args): Eero Simoncelli, 2/97. Python port by Rob Young, 7/15. ''' if len(args) == 0: - print "mkAngularSine(SIZE, HARMONIC, AMPL, PHASE, ORIGIN)" - print "first argument is required" + print("mkAngularSine(SIZE, HARMONIC, AMPL, PHASE, ORIGIN)") + print("first argument is required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) # OPTIONAL args: diff --git a/mkDisc.py b/mkDisc.py index 8529ed1..bdadf67 100644 --- a/mkDisc.py +++ b/mkDisc.py @@ -1,8 +1,8 @@ import numpy import sys -from mkR import mkR -from rcosFn import rcosFn -from pointOp import pointOp +from .mkR import mkR +from .rcosFn import rcosFn +from .pointOp import pointOp def mkDisc(*args): ''' IM = mkDisc(SIZE, RADIUS, ORIGIN, TWIDTH, VALS) @@ -18,15 +18,15 @@ def mkDisc(*args): Eero Simoncelli, 6/96. Python port by Rob Young, 7/15. ''' if len(args) == 0: - print "mkDisc(SIZE, RADIUS, ORIGIN, TWIDTH, VALS)" - print "first argument is required" + print("mkDisc(SIZE, RADIUS, ORIGIN, TWIDTH, VALS)") + print("first argument is required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) # OPTIONAL args: diff --git a/mkFract.py b/mkFract.py index 0b28637..c3e163d 100644 --- a/mkFract.py +++ b/mkFract.py @@ -1,6 +1,6 @@ import numpy -from mkR import mkR -from var2 import var2 +from .mkR import mkR +from .var2 import var2 def mkFract(*args): ''' Make a matrix of dimensions SIZE (a [Y X] 2-vector, or a scalar) @@ -13,9 +13,9 @@ def mkFract(*args): Make this more efficient! ''' if len(args) == 0: - print 'Error: input parameter dims required' + print('Error: input parameter dims required') else: - if isinstance(args[0], (int, long)) or len(args[0]) == 1: + if isinstance(args[0], int) or len(args[0]) == 1: dims = (args[0], args[0]) elif args[0] == 1: dims = (args[1], args[1]) @@ -42,7 +42,7 @@ def mkFract(*args): fres = numpy.fft.ifft2(fres) if abs(fres.imag).max() > 1e-10: - print 'Symmetry error in creating fractal' + print('Symmetry error in creating fractal') else: res = numpy.real(fres) res = res / numpy.sqrt(var2(res)) diff --git a/mkGaussian.py b/mkGaussian.py index 922fa6e..84e89f2 100644 --- a/mkGaussian.py +++ b/mkGaussian.py @@ -14,15 +14,15 @@ def mkGaussian(*args): Eero Simoncelli, 6/96. Python port by Rob Young, 7/15. ''' if len(args) == 0: - print "mkRamp(SIZE, COVARIANCE, MEAN, AMPLITUDE)" - print "first argument is required" + print("mkRamp(SIZE, COVARIANCE, MEAN, AMPLITUDE)") + print("first argument is required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) # OPTIONAL args: @@ -46,14 +46,14 @@ def mkGaussian(*args): #--------------------------------------------------------------- - (xramp, yramp) = numpy.meshgrid(numpy.array(range(1,sz[1]+1))-mn[1], - numpy.array(range(1,sz[0]+1))-mn[0]) + (xramp, yramp) = numpy.meshgrid(numpy.array(list(range(1,sz[1]+1)))-mn[1], + numpy.array(list(range(1,sz[0]+1)))-mn[0]) - if isinstance(cov, (int, long, float)): + if isinstance(cov, (int, float)): if 'norm' == ampl: ampl = 1.0 / (2.0 * numpy.pi * cov) e = ( (xramp**2) + (yramp**2) ) / ( -2.0 * cov ) - elif len(cov) == 2 and isinstance(cov[0], (int, long, float)): + elif len(cov) == 2 and isinstance(cov[0], (int, float)): if 'norm' == ampl: if cov[0]*cov[1] < 0: ampl = 1.0 / (2.0 * numpy.pi * diff --git a/mkImpulse.py b/mkImpulse.py index d888fb6..9d4ac2e 100644 --- a/mkImpulse.py +++ b/mkImpulse.py @@ -4,8 +4,8 @@ def mkImpulse(*args): ''' create an image that is all zeros except for an impulse ''' if(len(args) == 0): - print "mkImpulse(size, origin, amplitude)" - print "first input parameter is required" + print("mkImpulse(size, origin, amplitude)") + print("first input parameter is required") return if(isinstance(args[0], int)): @@ -13,7 +13,7 @@ def mkImpulse(*args): elif(isinstance(args[0], tuple)): sz = args[0] else: - print "size parameter must be either an integer or a tuple" + print("size parameter must be either an integer or a tuple") return if(len(args) > 1): diff --git a/mkR.py b/mkR.py index 1f68802..4c5c372 100644 --- a/mkR.py +++ b/mkR.py @@ -8,12 +8,12 @@ def mkR(*args): Eero Simoncelli, 6/96. Ported to Python by Rob Young, 5/14. ''' if len(args) == 0: - print 'Error: first input parameter is required!' + print('Error: first input parameter is required!') return else: sz = args[0] - if isinstance(sz, (int, long)) or len(sz) == 1: + if isinstance(sz, int) or len(sz) == 1: sz = (sz, sz) # ----------------------------------------------------------------- @@ -31,8 +31,8 @@ def mkR(*args): # ----------------------------------------------------------------- - (xramp2, yramp2) = numpy.meshgrid(numpy.array(range(1,sz[1]+1))-origin[1], - numpy.array(range(1,sz[0]+1))-origin[0]) + (xramp2, yramp2) = numpy.meshgrid(numpy.array(list(range(1,sz[1]+1)))-origin[1], + numpy.array(list(range(1,sz[0]+1)))-origin[0]) res = (xramp2**2 + yramp2**2)**(expt/2.0) diff --git a/mkRamp.py b/mkRamp.py index 12ebe38..746851b 100644 --- a/mkRamp.py +++ b/mkRamp.py @@ -11,15 +11,15 @@ def mkRamp(*args): optional ''' if len(args) == 0: - print "mkRamp(SIZE, DIRECTION, SLOPE, INTERCEPT, ORIGIN)" - print "first argument is required" + print("mkRamp(SIZE, DIRECTION, SLOPE, INTERCEPT, ORIGIN)") + print("first argument is required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) # OPTIONAL args: @@ -49,8 +49,8 @@ def mkRamp(*args): xinc = slope * math.cos(direction) yinc = slope * math.sin(direction) - [xramp, yramp] = numpy.meshgrid( xinc * (numpy.array(range(sz[1]))-origin[1]), - yinc * (numpy.array(range(sz[0]))-origin[0]) ) + [xramp, yramp] = numpy.meshgrid( xinc * (numpy.array(list(range(sz[1])))-origin[1]), + yinc * (numpy.array(list(range(sz[0])))-origin[0]) ) res = intercept + xramp + yramp diff --git a/mkSine.py b/mkSine.py index b6a5a80..d43ad20 100644 --- a/mkSine.py +++ b/mkSine.py @@ -1,6 +1,6 @@ import numpy import math -from mkRamp import mkRamp +from .mkRamp import mkRamp def mkSine(*args): ''' IM = mkSine(SIZE, PERIOD, DIRECTION, AMPLITUDE, PHASE, ORIGIN) @@ -20,20 +20,20 @@ def mkSine(*args): # REQUIRED args: if len(args) < 2: - print "mkSine(SIZE, PERIOD, DIRECTION, AMPLITUDE, PHASE, ORIGIN)" - print " or" - print "mkSine(SIZE, FREQ, AMPLITUDE, PHASE, ORIGIN)" - print "first two arguments are required" + print("mkSine(SIZE, PERIOD, DIRECTION, AMPLITUDE, PHASE, ORIGIN)") + print(" or") + print("mkSine(SIZE, FREQ, AMPLITUDE, PHASE, ORIGIN)") + print("first two arguments are required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) - if isinstance(args[1], (int, float, long)): + if isinstance(args[1], (int, float)): frequency = (2.0 * numpy.pi) / args[1] # OPTIONAL args: if len(args) > 2: diff --git a/mkSquare.py b/mkSquare.py index 7c65554..4d09bbf 100644 --- a/mkSquare.py +++ b/mkSquare.py @@ -1,8 +1,8 @@ import numpy import math -from mkRamp import mkRamp -from rcosFn import rcosFn -from pointOp import pointOp +from .mkRamp import mkRamp +from .rcosFn import rcosFn +from .pointOp import pointOp def mkSquare(*args): ''' IM = mkSquare(SIZE, PERIOD, DIRECTION, AMPLITUDE, PHASE, ORIGIN, TWIDTH) @@ -26,20 +26,20 @@ def mkSquare(*args): #REQUIRED ARGS: if len(args) < 2: - print "mkSquare(SIZE, PERIOD, DIRECTION, AMPLITUDE, PHASE, ORIGIN, TWIDTH)" - print " or" - print "mkSquare(SIZE, FREQ, AMPLITUDE, PHASE, ORIGIN, TWIDTH)" - print "first two arguments are required" + print("mkSquare(SIZE, PERIOD, DIRECTION, AMPLITUDE, PHASE, ORIGIN, TWIDTH)") + print(" or") + print("mkSquare(SIZE, FREQ, AMPLITUDE, PHASE, ORIGIN, TWIDTH)") + print("first two arguments are required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) - if isinstance(args[1], (int, float, long)): + if isinstance(args[1], (int, float)): frequency = (2.0 * numpy.pi) / args[1] # OPTIONAL args: if len(args) > 2: diff --git a/mkZonePlate.py b/mkZonePlate.py index 6040575..9c6663d 100644 --- a/mkZonePlate.py +++ b/mkZonePlate.py @@ -1,5 +1,5 @@ import numpy -from mkR import mkR +from .mkR import mkR def mkZonePlate(*args): ''' IM = mkZonePlate(SIZE, AMPL, PHASE) @@ -14,15 +14,15 @@ def mkZonePlate(*args): # REQUIRED ARGS: if len(args) == 0: - print "mkZonePlate(SIZE, AMPL, PHASE)" - print "first argument is required" + print("mkZonePlate(SIZE, AMPL, PHASE)") + print("first argument is required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) #--------------------------------------------------------------------- diff --git a/modulateFlip.py b/modulateFlip.py index e2e4f75..d17367c 100644 --- a/modulateFlip.py +++ b/modulateFlip.py @@ -8,7 +8,7 @@ def modulateFlip(*args): (e.g., see Simoncelli90). ''' if len(args) == 0: - print "Error: filter input parameter required." + print("Error: filter input parameter required.") return lfilt = args[0] @@ -18,13 +18,13 @@ def modulateFlip(*args): elif lfilt.shape[0] == 1: lfilt = lfilt.reshape(lfilt.shape[1], 1) elif len(lfilt.shape) > 2 or lfilt.shape[1] != 1: - print 'Error: only 1D input supported.' + print('Error: only 1D input supported.') return sz = len(lfilt) sz2 = numpy.ceil(sz/2.0); - ind = numpy.array(range(sz-1,-1,-1)) + ind = numpy.array(list(range(sz-1,-1,-1))) hfilt = lfilt[ind].T * (-1)**((ind+1)-sz2) diff --git a/namedFilter.py b/namedFilter.py index 0b6e125..8af2894 100644 --- a/namedFilter.py +++ b/namedFilter.py @@ -1,4 +1,4 @@ -from binomialFilter import binomialFilter +from .binomialFilter import binomialFilter import math import numpy @@ -54,7 +54,7 @@ def namedFilter(name): elif name is "gauss3": # for backward-compatibility kernel = math.sqrt(2) * numpy.array([[0.25], [0.5], [0.25]]) else: - print "Error: Bad filter name: %s" % (name) + print("Error: Bad filter name: %s" % (name)) exit(1) return numpy.array(kernel) diff --git a/pyPyrTools.py b/pyPyrTools.py index f1e5b71..ebb4fed 100644 --- a/pyPyrTools.py +++ b/pyPyrTools.py @@ -1,13 +1,13 @@ import numpy #import pyPyrUtils as ppu -import pyPyrUtils +from . import pyPyrUtils #import pyPyrCcode import math import matplotlib.cm import os import scipy.misc import cmath -import JBhelpers +from . import JBhelpers import pylab import copy @@ -20,7 +20,7 @@ class pyramid: # pyramid # constructor def __init__(self): - print "please specify type of pyramid to create (Gpry, Lpyr, etc.)" + print("please specify type of pyramid to create (Gpry, Lpyr, etc.)") return # methods @@ -41,7 +41,7 @@ def __init__(self, *args): # (image height, filter file, edges) if len(args) > 0: self.image = numpy.array(args[0]) else: - print "First argument (image) is required." + print("First argument (image) is required.") return #------------------------------------------------ @@ -57,10 +57,10 @@ def __init__(self, *args): # (image height, filter file, edges) elif args[2] == 'sp5Filters': filters = pyPyrUtils.sp5Filters() elif os.path.isfile(args[2]): - print "Filter files not supported yet" + print("Filter files not supported yet") return else: - print "filter parameters value %s not supported" % (args[2]) + print("filter parameters value %s not supported" % (args[2])) return else: filters = pyPyrUtils.sp1Filters() @@ -77,8 +77,8 @@ def __init__(self, *args): # (image height, filter file, edges) if args[1] == 'auto': ht = max_ht elif args[1] > max_ht: - print "Error: cannot build pyramid higher than %d levels." % ( - max_ht) + print("Error: cannot build pyramid higher than %d levels." % ( + max_ht)) return else: ht = args[1] @@ -134,20 +134,20 @@ def __init__(self, *args): # (image height, filter file, edges) # methods def set(self, *args): if len(args) != 3: - print 'Error: three input parameters required:' - print ' set(band, location, value)' - print ' where band and value are integer and location is a tuple' - if isinstance(args[1], (int, long)): + print('Error: three input parameters required:') + print(' set(band, location, value)') + print(' where band and value are integer and location is a tuple') + if isinstance(args[1], int): self.pyr[args[0]][0][args[1]] = args[2] elif isinstance(args[1], tuple): self.pyr[args[0]][args[1][0]][args[1][1]] = args[2] else: - print 'Error: location parameter must be int or tuple!' + print('Error: location parameter must be int or tuple!') return def spyrLev(self, lev): if lev < 0 or lev > self.spyrHt()-1: - print 'Error: level parameter must be between 0 and %d!' % (self.spyrHt()-1) + print('Error: level parameter must be between 0 and %d!' % (self.spyrHt()-1)) return levArray = [] @@ -159,10 +159,10 @@ def spyrLev(self, lev): def spyrBand(self, lev, band): if lev < 0 or lev > self.spyrHt()-1: - print 'Error: level parameter must be between 0 and %d!' % (self.spyrHt()-1) + print('Error: level parameter must be between 0 and %d!' % (self.spyrHt()-1)) return if band < 0 or band > self.numBands()-1: - print 'Error: band parameter must be between 0 and %d!' % (self.numBands()-1) + print('Error: band parameter must be between 0 and %d!' % (self.numBands()-1)) return self.band( ((lev*self.numBands())+band)+1 ) @@ -203,10 +203,10 @@ def reconPyr(self, *args): elif args[0] == 'sp5Filters': filters = pyPyrUtils.sp5Filters() elif os.path.isfile(args[0]): - print "Filter files not supported yet" + print("Filter files not supported yet") return else: - print "filter %s not supported" % (args[0]) + print("filter %s not supported" % (args[0])) return else: filters = pyPyrUtils.sp1Filters() @@ -238,22 +238,22 @@ def reconPyr(self, *args): maxLev = 2 + self.spyrHt() if levs == 'all': - levs = numpy.array(range(maxLev)) + levs = numpy.array(list(range(maxLev))) else: levs = numpy.array(levs) if (levs < 0).any() or (levs >= maxLev).any(): - print "Error: level numbers must be in the range [0, %d]." % (maxLev-1) + print("Error: level numbers must be in the range [0, %d]." % (maxLev-1)) return else: levs = numpy.array(levs) if len(levs) > 1 and levs[0] < levs[1]: levs = levs[::-1] # we want smallest first if bands == 'all': - bands = numpy.array(range(self.numBands())) + bands = numpy.array(list(range(self.numBands()))) else: bands = numpy.array(bands) if (bands < 0).any() or (bands > bfilts.shape[1]).any(): - print "Error: band numbers must be in the range [0, %d]." % (self.numBands()-1) + print("Error: band numbers must be in the range [0, %d]." % (self.numBands()-1)) return else: bands = numpy.array(bands) @@ -383,10 +383,10 @@ def showPyr(self, prange = 'auto2', gap = 1, scale = 2, disp = 'qt'): av = numpy.mean(band) stdev = numpy.sqrt( numpy.var(band) ) prange[nind-1,:] = numpy.array([av-2*stdev, av+2*stdev]) - elif isinstance(prange, basestring): - print "Error:Bad RANGE argument: %s'" % (prange) + elif isinstance(prange, str): + print("Error:Bad RANGE argument: %s'" % (prange)) elif prange.shape[0] == 1 and prange.shape[1] == 2: - scales = numpy.power(scale, range(ht)) + scales = numpy.power(scale, list(range(ht))) scales = numpy.outer( numpy.ones((nbands,1)), scales ) scales = numpy.array([1, scales, numpy.power(scale, ht)]) prange = numpy.outer(scales, prange) @@ -405,11 +405,11 @@ def showPyr(self, prange = 'auto2', gap = 1, scale = 2, disp = 'qt'): ncols = int(numpy.ceil((nbands+1)/2)) nrows = int(numpy.ceil(nbands/2)) - a = numpy.array(range(1-nrows, 1)) + a = numpy.array(list(range(1-nrows, 1))) b = numpy.zeros((1,ncols))[0] ab = numpy.concatenate((a,b)) c = numpy.zeros((1,nrows))[0] - d = range(-1, -ncols-1, -1) + d = list(range(-1, -ncols-1, -1)) cd = numpy.concatenate((c,d)) relpos = numpy.vstack((ab,cd)).T @@ -462,7 +462,7 @@ def __init__(self, *args): # (image, height, order, twidth) if len(args) > 0: self.image = args[0] else: - print "First argument (image) is required." + print("First argument (image) is required.") return #------------------------------------------------ @@ -471,7 +471,7 @@ def __init__(self, *args): # (image, height, order, twidth) max_ht = numpy.floor( numpy.log2( min(self.image.shape) ) ) - 2 if len(args) > 1: if(args[1] > max_ht): - print "Error: cannot build pyramid higher than %d levels." % (max_ht) + print("Error: cannot build pyramid higher than %d levels." % (max_ht)) ht = args[1] else: ht = max_ht @@ -479,7 +479,7 @@ def __init__(self, *args): # (image, height, order, twidth) if len(args) > 2: if args[2] > 15 or args[2] < 0: - print "Warning: order must be an integer in the range [0,15]. Truncating." + print("Warning: order must be an integer in the range [0,15]. Truncating.") order = min( max(args[2],0), 15 ) else: order = args[2] @@ -490,7 +490,7 @@ def __init__(self, *args): # (image, height, order, twidth) if len(args) > 3: if args[3] <= 0: - print "Warning: twidth must be positive. Setting to 1." + print("Warning: twidth must be positive. Setting to 1.") twidth = 1 else: twidth = args[3] @@ -501,21 +501,21 @@ def __init__(self, *args): # (image, height, order, twidth) # steering stuff: if nbands % 2 == 0: - harmonics = numpy.array(range(nbands/2)) * 2 + 1 + harmonics = numpy.array(list(range(nbands/2))) * 2 + 1 else: - harmonics = numpy.array(range((nbands-1)/2)) * 2 + harmonics = numpy.array(list(range((nbands-1)/2))) * 2 steermtx = pyPyrUtils.steer2HarmMtx(harmonics, - numpy.pi*numpy.array(range(nbands))/nbands, + numpy.pi*numpy.array(list(range(nbands)))/nbands, 'even') #------------------------------------------------------ dims = numpy.array(self.image.shape) ctr = numpy.ceil((numpy.array(dims)+0.5)/2) - (xramp, yramp) = numpy.meshgrid((numpy.array(range(1,dims[1]+1))-ctr[1])/ + (xramp, yramp) = numpy.meshgrid((numpy.array(list(range(1,dims[1]+1)))-ctr[1])/ (dims[1]/2), - (numpy.array(range(1,dims[0]+1))-ctr[0])/ + (numpy.array(list(range(1,dims[0]+1)))-ctr[0])/ (dims[0]/2)) angle = numpy.arctan2(yramp, xramp) log_rad = numpy.sqrt(xramp**2 + yramp**2) @@ -556,7 +556,7 @@ def __init__(self, *args): # (image, height, order, twidth) Xrcos -= numpy.log2(2) lutsize = 1024 - Xcosn = numpy.pi * numpy.array(range(-(2*lutsize+1), (lutsize+2))) / lutsize + Xcosn = numpy.pi * numpy.array(list(range(-(2*lutsize+1), (lutsize+2)))) / lutsize order = nbands -1 const = (2**(2*order))*(scipy.misc.factorial(order, exact=True)**2)/float(nbands*scipy.misc.factorial(2*order, exact=True)) @@ -639,7 +639,7 @@ def reconSFpyr(self, *args): if len(args) > 2: if args[2] <= 0: - print "Warning: twidth must be positive. Setting to 1." + print("Warning: twidth must be positive. Setting to 1.") twidth = 1 else: twidth = args[2] @@ -651,20 +651,20 @@ def reconSFpyr(self, *args): nbands = self.numBands() maxLev = 1 + self.spyrHt() - if isinstance(levs, basestring) and levs == 'all': - levs = numpy.array(range(maxLev+1)) - elif isinstance(levs, basestring): - print "Error: %s not valid for levs parameter." % (levs) - print "levs must be either a 1D numpy array or the string 'all'." + if isinstance(levs, str) and levs == 'all': + levs = numpy.array(list(range(maxLev+1))) + elif isinstance(levs, str): + print("Error: %s not valid for levs parameter." % (levs)) + print("levs must be either a 1D numpy array or the string 'all'.") return else: levs = numpy.array(levs) - if isinstance(bands, basestring) and bands == 'all': - bands = numpy.array(range(nbands)) - elif isinstance(bands, basestring): - print "Error: %s not valid for bands parameter." % (bands) - print "bands must be either a 1D numpy array or the string 'all'." + if isinstance(bands, str) and bands == 'all': + bands = numpy.array(list(range(nbands))) + elif isinstance(bands, str): + print("Error: %s not valid for bands parameter." % (bands)) + print("bands must be either a 1D numpy array or the string 'all'.") return else: bands = numpy.array(bands) @@ -693,9 +693,9 @@ def reconSFpyr(self, *args): dims = numpy.array(self.pyrSize[0]) ctr = numpy.ceil((dims+0.5)/2.0) - (xramp, yramp) = numpy.meshgrid((numpy.array(range(1,dims[1]+1))-ctr[1])/ + (xramp, yramp) = numpy.meshgrid((numpy.array(list(range(1,dims[1]+1)))-ctr[1])/ (dims[1]/2), - (numpy.array(range(1,dims[0]+1))-ctr[0])/ + (numpy.array(list(range(1,dims[0]+1)))-ctr[0])/ (dims[0]/2)) angle = numpy.arctan2(yramp, xramp) log_rad = numpy.sqrt(xramp**2 + yramp**2) @@ -709,7 +709,7 @@ def reconSFpyr(self, *args): # from reconSFpyrLevs lutsize = 1024 - Xcosn = numpy.pi * numpy.array(range(-(2*lutsize+1), (lutsize+2))) / lutsize + Xcosn = numpy.pi * numpy.array(list(range(-(2*lutsize+1), (lutsize+2)))) / lutsize order = nbands -1 const = (2**(2*order))*(scipy.misc.factorial(order, exact=True)**2)/float(nbands*scipy.misc.factorial(2*order, exact=True)) @@ -852,7 +852,7 @@ def __init__(self, *args): # (image, height, order, twidth) if len(args) > 0: self.image = args[0] else: - print "First argument (image) is required." + print("First argument (image) is required.") return #------------------------------------------------ @@ -861,7 +861,7 @@ def __init__(self, *args): # (image, height, order, twidth) max_ht = numpy.floor( numpy.log2( min(self.image.shape) ) ) - 2 if len(args) > 1: if(args[1] > max_ht): - print "Error: cannot build pyramid higher than %d levels." % (max_ht) + print("Error: cannot build pyramid higher than %d levels." % (max_ht)) ht = args[1] else: ht = max_ht @@ -869,7 +869,7 @@ def __init__(self, *args): # (image, height, order, twidth) if len(args) > 2: if args[2] > 15 or args[2] < 0: - print "Warning: order must be an integer in the range [0,15]. Truncating." + print("Warning: order must be an integer in the range [0,15]. Truncating.") order = min( max(args[2],0), 15 ) else: order = args[2] @@ -880,7 +880,7 @@ def __init__(self, *args): # (image, height, order, twidth) if len(args) > 3: if args[3] <= 0: - print "Warning: twidth must be positive. Setting to 1." + print("Warning: twidth must be positive. Setting to 1.") twidth = 1 else: twidth = args[3] @@ -891,21 +891,21 @@ def __init__(self, *args): # (image, height, order, twidth) # steering stuff: if nbands % 2 == 0: - harmonics = numpy.array(range(nbands/2)) * 2 + 1 + harmonics = numpy.array(list(range(nbands/2))) * 2 + 1 else: - harmonics = numpy.array(range((nbands-1)/2)) * 2 + harmonics = numpy.array(list(range((nbands-1)/2))) * 2 steermtx = pyPyrUtils.steer2HarmMtx(harmonics, - numpy.pi*numpy.array(range(nbands))/nbands, + numpy.pi*numpy.array(list(range(nbands)))/nbands, 'even') #------------------------------------------------------ dims = numpy.array(self.image.shape) ctr = numpy.ceil((numpy.array(dims)+0.5)/2) - (xramp, yramp) = numpy.meshgrid((numpy.array(range(1,dims[1]+1))-ctr[1])/ + (xramp, yramp) = numpy.meshgrid((numpy.array(list(range(1,dims[1]+1)))-ctr[1])/ (dims[1]/2), - (numpy.array(range(1,dims[0]+1))-ctr[0])/ + (numpy.array(list(range(1,dims[0]+1)))-ctr[0])/ (dims[0]/2)) angle = numpy.arctan2(yramp, xramp) log_rad = numpy.sqrt(xramp**2 + yramp**2) @@ -946,7 +946,7 @@ def __init__(self, *args): # (image, height, order, twidth) Xrcos -= numpy.log2(2) lutsize = 1024 - Xcosn = numpy.pi * numpy.array(range(-(2*lutsize+1), (lutsize+2))) / lutsize + Xcosn = numpy.pi * numpy.array(list(range(-(2*lutsize+1), (lutsize+2)))) / lutsize order = nbands -1 const = (2**(2*order))*(scipy.misc.factorial(order, exact=True)**2)/float(nbands*scipy.misc.factorial(2*order, exact=True)) @@ -1010,7 +1010,7 @@ def reconPyr(self, *args): if len(args) > 2: if args[2] <= 0: - print "Warning: twidth must be positive. Setting to 1." + print("Warning: twidth must be positive. Setting to 1.") twidth = 1 else: twidth = args[2] @@ -1064,17 +1064,17 @@ def __init__(self, *args): # (image, height, filter1, filter2, edges) if len(args) > 0: self.image = args[0] else: - print "pyr = Lpyr(image, height, filter1, filter2, edges)" - print "First argument (image) is required" + print("pyr = Lpyr(image, height, filter1, filter2, edges)") + print("First argument (image) is required") return if len(args) > 2: filt1 = args[2] - if isinstance(filt1, basestring): + if isinstance(filt1, str): filt1 = pyPyrUtils.namedFilter(filt1) elif len(filt1.shape) != 1 and ( filt1.shape[0] != 1 and filt1.shape[1] != 1 ): - print "Error: filter1 should be a 1D filter (i.e., a vector)" + print("Error: filter1 should be a 1D filter (i.e., a vector)") return else: filt1 = pyPyrUtils.namedFilter('binom5') @@ -1085,11 +1085,11 @@ def __init__(self, *args): # (image, height, filter1, filter2, edges) if len(args) > 3: filt2 = args[3] - if isinstance(filt2, basestring): + if isinstance(filt2, str): filt2 = pyPyrUtils.namedFilter(filt2) elif len(filt2.shape) != 1 and ( filt2.shape[0] != 1 and filt2.shape[1] != 1 ): - print "Error: filter2 should be a 1D filter (i.e., a vector)" + print("Error: filter2 should be a 1D filter (i.e., a vector)") return else: filt2 = filt1 @@ -1102,8 +1102,8 @@ def __init__(self, *args): # (image, height, filter1, filter2, edges) else: self.height = args[1] if self.height > maxHeight: - print ( "Error: cannot build pyramid higher than %d levels" - % (maxHeight) ) + print(( "Error: cannot build pyramid higher than %d levels" + % (maxHeight) )) return else: self.height = maxHeight @@ -1192,16 +1192,16 @@ def catBands(self, *args): # set a pyramid value def set_old(self, *args): if len(args) != 3: - print 'Error: three input parameters required:' - print ' set(band, element, value)' - print 'band=%d element=%d value=%d' % (args[0],args[1],args[2]) - print self.pyr[args[0]].shape + print('Error: three input parameters required:') + print(' set(band, element, value)') + print('band=%d element=%d value=%d' % (args[0],args[1],args[2])) + print(self.pyr[args[0]].shape) self.pyr[args[0]][args[1]] = args[2] def set(self, *args): if len(args) != 3: - print 'Error: three input parameters required:' - print ' set(band, element(tuple), value)' + print('Error: three input parameters required:') + print(' set(band, element(tuple), value)') self.pyr[args[0]][args[1][0]][args[1][1]] = args[2] def reconPyr(self, *args): @@ -1223,14 +1223,14 @@ def reconPyr(self, *args): maxLev = self.height if levs == 'all': - levs = range(0,maxLev) + levs = list(range(0,maxLev)) else: if (levs > maxLev-1).any(): - print ( "Error: level numbers must be in the range [0, %d]." % - (maxLev-1) ) + print(( "Error: level numbers must be in the range [0, %d]." % + (maxLev-1) )) return - if isinstance(filt2, basestring): + if isinstance(filt2, str): filt2 = pyPyrUtils.namedFilter(filt2) else: if len(filt2.shape) == 1: @@ -1354,11 +1354,11 @@ def showPyr(self, pRange = None, gap = 1, scale = None, disp = 'qt'): av = numpy.mean(band) stdev = numpy.std(band) pRange[nind,:] = numpy.array([av-2*stdev, av+2*stdev]) - elif isinstance(pRange, basestring): - print "Error: band range argument: %s" % (pRange) + elif isinstance(pRange, str): + print("Error: band range argument: %s" % (pRange)) return elif pRange.shape[0] == 1 and pRange.shape[1] == 2: - scales = numpy.power( numpy.array( range(0,nind) ), scale) + scales = numpy.power( numpy.array( list(range(0,nind)) ), scale) pRange = numpy.outer( scales, pRange ) band = self.pyrLow() pRange[nind,:] = ( pRange[nind,:] + numpy.mean(band) - @@ -1405,7 +1405,7 @@ def showPyr(self, pRange = None, gap = 1, scale = None, disp = 'qt'): llpos[bnum,:] = ctr - numpy.floor(numpy.array(sz))/2.0 # make position list positive, and allocate appropriate image llpos = llpos - numpy.ones((nind,1))*numpy.min(llpos) - pind = range(self.height) + pind = list(range(self.height)) for i in pind: pind[i] = self.band(i).shape urpos = llpos + pind @@ -1433,8 +1433,8 @@ class Gpyr(Lpyr): def __init__(self, *args): # (image, height, filter, edges) self.pyrType = 'Gaussian' if len(args) < 1: - print "pyr = Gpyr(image, height, filter, edges)" - print "First argument (image) is required" + print("pyr = Gpyr(image, height, filter, edges)") + print("First argument (image) is required") return else: self.image = args[0] @@ -1442,10 +1442,10 @@ def __init__(self, *args): # (image, height, filter, edges) if len(args) > 2: filt = args[2] if not (filt.shape == 1).any(): - print "Error: filt should be a 1D filter (i.e., a vector)" + print("Error: filt should be a 1D filter (i.e., a vector)") return else: - print "no filter set, so filter is binom5" + print("no filter set, so filter is binom5") filt = pyPyrUtils.namedFilter('binom5') if self.image.shape[0] == 1: filt = filt.reshape(1,5) @@ -1460,8 +1460,8 @@ def __init__(self, *args): # (image, height, filter, edges) else: self.height = args[1] if self.height > maxHeight: - print ( "Error: cannot build pyramid higher than %d levels" - % (maxHeight) ) + print(( "Error: cannot build pyramid higher than %d levels" + % (maxHeight) )) return else: self.height = maxHeight @@ -1521,7 +1521,7 @@ def __init__(self, *args): # (image, height, order, twidth) if len(args) > 0: im = args[0] else: - print "First argument (image) is required." + print("First argument (image) is required.") return #------------------------------------------------ @@ -1531,11 +1531,11 @@ def __init__(self, *args): # (image, height, order, twidth) filt = args[2] else: filt = "qmf9" - if isinstance(filt, basestring): + if isinstance(filt, str): filt = pyPyrUtils.namedFilter(filt) if len(filt.shape) != 1 and filt.shape[0] != 1 and filt.shape[1] != 1: - print "Error: filter should be 1D (i.e., a vector)"; + print("Error: filter should be 1D (i.e., a vector)"); return hfilt = pyPyrUtils.modulateFlip(filt) #hfilt = pyPyrUtils.modulateFlip(filt).T @@ -1565,7 +1565,7 @@ def __init__(self, *args): # (image, height, order, twidth) if ht == 'auto': ht = max_ht elif(ht > max_ht): - print "Error: cannot build pyramid higher than %d levels." % (max_ht) + print("Error: cannot build pyramid higher than %d levels." % (max_ht)) else: ht = max_ht ht = int(ht) @@ -1678,28 +1678,28 @@ def reconPyr(self, *args): maxLev = int(self.wpyrHt() + 1) if levs == 'all': - levs = numpy.array(range(maxLev)) + levs = numpy.array(list(range(maxLev))) else: tmpLevs = [] for l in levs: tmpLevs.append((maxLev-1)-l) levs = numpy.array(tmpLevs) if (levs > maxLev).any(): - print "Error: level numbers must be in the range [0, %d]" % (maxLev) - allLevs = numpy.array(range(maxLev)) + print("Error: level numbers must be in the range [0, %d]" % (maxLev)) + allLevs = numpy.array(list(range(maxLev))) if bands == "all": if ( len(self.band(0)) == 1 or self.band(0).shape[0] == 1 or self.band(0).shape[1] == 1 ): bands = numpy.array([0]); else: - bands = numpy.array(range(3)) + bands = numpy.array(list(range(3))) else: bands = numpy.array(bands) if (bands < 0).any() or (bands > 2).any(): - print "Error: band numbers must be in the range [0,2]." + print("Error: band numbers must be in the range [0,2].") - if isinstance(filt, basestring): + if isinstance(filt, str): filt = pyPyrUtils.namedFilter(filt) hfilt = pyPyrUtils.modulateFlip(filt).T @@ -1858,25 +1858,25 @@ def reconPyr(self, *args): def set(self, *args): if len(args) != 3: - print 'Error: three input parameters required:' - print ' set(band, location, value)' - print ' where band and value are integer and location is a tuple' - if isinstance(args[1], (int, long)): + print('Error: three input parameters required:') + print(' set(band, location, value)') + print(' where band and value are integer and location is a tuple') + if isinstance(args[1], int): self.pyr[args[0]][0][args[1]] = args[2] elif isinstance(args[1], tuple): self.pyr[args[0]][args[1][0]][args[1][1]] = args[2] else: - print 'Error: location parameter must be int or tuple!' + print('Error: location parameter must be int or tuple!') return def set1D(self, *args): if len(args) != 3: - print 'Error: three input parameters required:' - print ' set(band, location, value)' - print ' where band and value are integer and location is a tuple' - print '%d %d %d' % (args[0], args[1], args[2]) - print self.pyr[args[0]][0][1] + print('Error: three input parameters required:') + print(' set(band, location, value)') + print(' where band and value are integer and location is a tuple') + print('%d %d %d' % (args[0], args[1], args[2])) + print(self.pyr[args[0]][0][1]) def pyrLow(self): return numpy.array(self.band(len(self.pyrSize)-1)) @@ -1967,10 +1967,10 @@ def showPyr(self, prange = None, gap = 1, scale = None, disp = 'qt'): av = numpy.mean(band) stdev = numpy.sqrt( numpy.var(band) ) prange[nind-1,:] = numpy.array([av-2*stdev, av+2*stdev]) - elif isinstance(prange, basestring): - print "Error:Bad RANGE argument: %s'" % (prange) + elif isinstance(prange, str): + print("Error:Bad RANGE argument: %s'" % (prange)) elif prange.shape[0] == 1 and prange.shape[1] == 2: - scales = numpy.power(scale, range(ht)) + scales = numpy.power(scale, list(range(ht))) scales = numpy.outer( numpy.ones((nbands,1)), scales ) scales = numpy.array([1, scales, numpy.power(scale, ht)]) prange = numpy.outer(scales, prange) diff --git a/pyPyrUtils.py b/pyPyrUtils.py index 6b6b7c1..ee9c6ab 100644 --- a/pyPyrUtils.py +++ b/pyPyrUtils.py @@ -11,10 +11,10 @@ import sys from PyQt4 import QtGui from PyQt4 import QtCore -import JBhelpers +from . import JBhelpers import PIL from PIL import ImageTk -import Tkinter +import tkinter import ctypes lib = ctypes.cdll.LoadLibrary('./wrapConv.so') @@ -37,7 +37,7 @@ def maxPyrHt_old(imsz, filtsz): imsz = (imsz[0], 1) filtsz = (filtsz[0], 1) elif len(imsz) == 1 and not any(f == 1 for f in filtsz): - print "Error: cannot have a 1D 'image' and 2D filter" + print("Error: cannot have a 1D 'image' and 2D filter") exit(1) elif len(imsz) == 1: imsz = (imsz[0], 1) @@ -109,7 +109,7 @@ def maxPyrHt(imsz, filtsz): # returns a vector of binomial coefficients of order (size-1) def binomialFilter(size): if size < 2: - print "Error: size argument must be larger than 1" + print("Error: size argument must be larger than 1") exit(1) kernel = numpy.array([[0.5], [0.5]]) @@ -171,7 +171,7 @@ def namedFilter(name): elif name is "gauss3": # for backward-compatibility kernel = math.sqrt(2) * numpy.array([[0.25], [0.5], [0.25]]) else: - print "Error: Bad filter name: %s" % (name) + print("Error: Bad filter name: %s" % (name)) exit(1) return numpy.array(kernel) @@ -181,15 +181,15 @@ def strictly_decreasing(L): def compareRecon(recon1, recon2): prec = -11 if recon1.shape != recon2.shape: - print 'shape is different!' - print recon1.shape - print recon2.shape + print('shape is different!') + print(recon1.shape) + print(recon2.shape) return 0 for i in range(recon1.shape[0]): for j in range(recon2.shape[1]): if numpy.absolute(recon1[i,j].real - recon2[i,j].real) > math.pow(10,-11): - print "real: i=%d j=%d %.15f %.15f diff=%.15f" % (i, j, recon1[i,j].real, recon2[i,j].real, numpy.absolute(recon1[i,j].real-recon2[i,j].real)) + print("real: i=%d j=%d %.15f %.15f diff=%.15f" % (i, j, recon1[i,j].real, recon2[i,j].real, numpy.absolute(recon1[i,j].real-recon2[i,j].real))) return 0 ## FIX: need a better way to test # if we have many significant digits to the left of decimal we @@ -200,9 +200,9 @@ def compareRecon(recon1, recon2): prec = prec + int(math.log(numpy.abs(recon1[i,j].imag), 10)) if prec > 0: prec = -1 - print prec + print(prec) if numpy.absolute(recon1[i,j].imag - recon2[i,j].imag) > math.pow(10, prec): - print "imag: i=%d j=%d %.15f %.15f diff=%.15f" % (i, j, recon1[i,j].imag, recon2[i,j].imag, numpy.absolute(recon1[i,j].imag-recon2[i,j].imag)) + print("imag: i=%d j=%d %.15f %.15f diff=%.15f" % (i, j, recon1[i,j].imag, recon2[i,j].imag, numpy.absolute(recon1[i,j].imag-recon2[i,j].imag))) return 0 return 1 @@ -221,7 +221,7 @@ def comparePyr(matPyr, pyPyr): pySz += sz[0] * sz[1] if(matSz != pySz): - print "size difference: %d != %d, returning 0" % (matSz, pySz) + print("size difference: %d != %d, returning 0" % (matSz, pySz)) return 0 # values are the same? @@ -236,15 +236,15 @@ def comparePyr(matPyr, pyPyr): matTmp = numpy.reshape(matTmp, bandSz, order='F') matStart = matStart+matLen if (matTmp != pyPyr.pyr[idx]).any(): - print "some pyramid elements not identical: checking..." + print("some pyramid elements not identical: checking...") for i in range(bandSz[0]): for j in range(bandSz[1]): if matTmp[i,j] != pyPyr.pyr[idx][i,j]: if ( math.fabs(matTmp[i,j] - pyPyr.pyr[idx][i,j]) > prec ): - print "failed level:%d element:%d %d value:%.15f %.15f" % (idx, i, j, matTmp[i,j], pyPyr.pyr[idx][i,j]) + print("failed level:%d element:%d %d value:%.15f %.15f" % (idx, i, j, matTmp[i,j], pyPyr.pyr[idx][i,j])) return 0 - print "same to at least %f" % prec + print("same to at least %f" % prec) return 1 @@ -260,15 +260,15 @@ def mkAngularSine(*args): # Eero Simoncelli, 2/97. Python port by Rob Young, 7/15. if len(args) == 0: - print "mkAngularSine(SIZE, HARMONIC, AMPL, PHASE, ORIGIN)" - print "first argument is required" + print("mkAngularSine(SIZE, HARMONIC, AMPL, PHASE, ORIGIN)") + print("first argument is required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) # OPTIONAL args: @@ -311,15 +311,15 @@ def mkGaussian(*args): # Eero Simoncelli, 6/96. Python port by Rob Young, 7/15. if len(args) == 0: - print "mkRamp(SIZE, COVARIANCE, MEAN, AMPLITUDE)" - print "first argument is required" + print("mkRamp(SIZE, COVARIANCE, MEAN, AMPLITUDE)") + print("first argument is required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) # OPTIONAL args: @@ -343,14 +343,14 @@ def mkGaussian(*args): #--------------------------------------------------------------- - (xramp, yramp) = numpy.meshgrid(numpy.array(range(1,sz[1]+1))-mn[1], - numpy.array(range(1,sz[0]+1))-mn[0]) + (xramp, yramp) = numpy.meshgrid(numpy.array(list(range(1,sz[1]+1)))-mn[1], + numpy.array(list(range(1,sz[0]+1)))-mn[0]) - if isinstance(cov, (int, long, float)): + if isinstance(cov, (int, float)): if 'norm' == ampl: ampl = 1.0 / (2.0 * numpy.pi * cov) e = ( (xramp**2) + (yramp**2) ) / ( -2.0 * cov ) - elif len(cov) == 2 and isinstance(cov[0], (int, long, float)): + elif len(cov) == 2 and isinstance(cov[0], (int, float)): if 'norm' == ampl: if cov[0]*cov[1] < 0: ampl = 1.0 / (2.0 * numpy.pi * @@ -391,15 +391,15 @@ def mkDisc(*args): # Eero Simoncelli, 6/96. Python port by Rob Young, 7/15. if len(args) == 0: - print "mkDisc(SIZE, RADIUS, ORIGIN, TWIDTH, VALS)" - print "first argument is required" + print("mkDisc(SIZE, RADIUS, ORIGIN, TWIDTH, VALS)") + print("first argument is required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) # OPTIONAL args: @@ -454,20 +454,20 @@ def mkSine(*args): # REQUIRED args: if len(args) < 2: - print "mkSine(SIZE, PERIOD, DIRECTION, AMPLITUDE, PHASE, ORIGIN)" - print " or" - print "mkSine(SIZE, FREQ, AMPLITUDE, PHASE, ORIGIN)" - print "first two arguments are required" + print("mkSine(SIZE, PERIOD, DIRECTION, AMPLITUDE, PHASE, ORIGIN)") + print(" or") + print("mkSine(SIZE, FREQ, AMPLITUDE, PHASE, ORIGIN)") + print("first two arguments are required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) - if isinstance(args[1], (int, float, long)): + if isinstance(args[1], (int, float)): frequency = (2.0 * numpy.pi) / args[1] # OPTIONAL args: if len(args) > 2: @@ -526,15 +526,15 @@ def mkZonePlate(*args): # REQUIRED ARGS: if len(args) == 0: - print "mkZonePlate(SIZE, AMPL, PHASE)" - print "first argument is required" + print("mkZonePlate(SIZE, AMPL, PHASE)") + print("first argument is required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) #--------------------------------------------------------------------- @@ -576,20 +576,20 @@ def mkSquare(*args): # REQUIRED ARGS: if len(args) < 2: - print "mkSquare(SIZE, PERIOD, DIRECTION, AMPLITUDE, PHASE, ORIGIN, TWIDTH)" - print " or" - print "mkSquare(SIZE, FREQ, AMPLITUDE, PHASE, ORIGIN, TWIDTH)" - print "first two arguments are required" + print("mkSquare(SIZE, PERIOD, DIRECTION, AMPLITUDE, PHASE, ORIGIN, TWIDTH)") + print(" or") + print("mkSquare(SIZE, FREQ, AMPLITUDE, PHASE, ORIGIN, TWIDTH)") + print("first two arguments are required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) - if isinstance(args[1], (int, float, long)): + if isinstance(args[1], (int, float)): frequency = (2.0 * numpy.pi) / args[1] # OPTIONAL args: if len(args) > 2: @@ -659,15 +659,15 @@ def mkRamp(*args): # optional if len(args) == 0: - print "mkRamp(SIZE, DIRECTION, SLOPE, INTERCEPT, ORIGIN)" - print "first argument is required" + print("mkRamp(SIZE, DIRECTION, SLOPE, INTERCEPT, ORIGIN)") + print("first argument is required") exit(1) else: sz = args[0] if isinstance(sz, (int)): sz = (sz, sz) elif not isinstance(sz, (tuple)): - print "first argument must be a two element tuple or an integer" + print("first argument must be a two element tuple or an integer") exit(1) # OPTIONAL args: @@ -697,8 +697,8 @@ def mkRamp(*args): xinc = slope * math.cos(direction) yinc = slope * math.sin(direction) - [xramp, yramp] = numpy.meshgrid( xinc * (numpy.array(range(sz[1]))-origin[1]), - yinc * (numpy.array(range(sz[0]))-origin[0]) ) + [xramp, yramp] = numpy.meshgrid( xinc * (numpy.array(list(range(sz[1])))-origin[1]), + yinc * (numpy.array(list(range(sz[0])))-origin[0]) ) res = intercept + xramp + yramp @@ -1568,8 +1568,8 @@ def nextSz(size, sizeList): def mkImpulse(*args): # create an image that is all zeros except for an impulse if(len(args) == 0): - print "mkImpulse(size, origin, amplitude)" - print "first input parameter is required" + print("mkImpulse(size, origin, amplitude)") + print("first input parameter is required") return if(isinstance(args[0], int)): @@ -1577,7 +1577,7 @@ def mkImpulse(*args): elif(isinstance(args[0], tuple)): sz = args[0] else: - print "size parameter must be either an integer or a tuple" + print("size parameter must be either an integer or a tuple") return if(len(args) > 1): @@ -1606,7 +1606,7 @@ def mkImpulse(*args): def steer2HarmMtx(*args): if len(args) == 0: - print "Error: first parameter 'harmonics' is required." + print("Error: first parameter 'harmonics' is required.") return if len(args) > 0: @@ -1617,19 +1617,19 @@ def steer2HarmMtx(*args): if len(args) > 1: angles = args[1] else: - angles = numpy.pi * numpy.array(range(numh)) / numh + angles = numpy.pi * numpy.array(list(range(numh))) / numh if len(args) > 2: - if isinstance(args[2], basestring): + if isinstance(args[2], str): if args[2] == 'even' or args[2] == 'EVEN': evenorodd = 0 elif args[2] == 'odd' or args[2] == 'ODD': evenorodd = 1 else: - print "Error: only 'even' and 'odd' are valid entries for the third input parameter." + print("Error: only 'even' and 'odd' are valid entries for the third input parameter.") return else: - print "Error: third input parameter must be a string (even/odd)." + print("Error: third input parameter must be a string (even/odd).") else: evenorodd = 0 @@ -1653,7 +1653,7 @@ def steer2HarmMtx(*args): r = numpy.rank(imtx) if r != numh and r != angles.shape[0]: - print "Warning: matrix is not full rank" + print("Warning: matrix is not full rank") mtx = numpy.linalg.pinv(imtx) @@ -1692,7 +1692,7 @@ def rcosFn(*args): sz = 256 # arbitrary! - X = numpy.pi * numpy.array(range(-sz-1,2)) / (2*sz) + X = numpy.pi * numpy.array(list(range(-sz-1,2))) / (2*sz) Y = values[0] + (values[1]-values[0]) * numpy.cos(X)**2; @@ -1715,8 +1715,8 @@ def mkAngle(*args): if not isinstance(sz, tuple): sz = (sz, sz) else: - print "Error: first input parameter 'size' is required!" - print "makeAngle(size, phase, origin)" + print("Error: first input parameter 'size' is required!") + print("makeAngle(size, phase, origin)") return # ------------------------------------------------------------ @@ -1734,8 +1734,8 @@ def mkAngle(*args): #------------------------------------------------------------------ - (xramp, yramp) = numpy.meshgrid(numpy.array(range(1,sz[1]+1))-origin[1], - (numpy.array(range(1,sz[0]+1)))-origin[0]) + (xramp, yramp) = numpy.meshgrid(numpy.array(list(range(1,sz[1]+1)))-origin[1], + (numpy.array(list(range(1,sz[0]+1))))-origin[0]) xramp = numpy.array(xramp) yramp = numpy.array(yramp) @@ -1754,7 +1754,7 @@ def mkAngle(*args): def modulateFlip(*args): if len(args) == 0: - print "Error: filter input parameter required." + print("Error: filter input parameter required.") return lfilt = args[0] @@ -1764,13 +1764,13 @@ def modulateFlip(*args): elif lfilt.shape[0] == 1: lfilt = lfilt.reshape(lfilt.shape[1], 1) elif len(lfilt.shape) > 2 or lfilt.shape[1] != 1: - print 'Error: only 1D input supported.' + print('Error: only 1D input supported.') return sz = len(lfilt) sz2 = numpy.ceil(sz/2.0); - ind = numpy.array(range(sz-1,-1,-1)) + ind = numpy.array(list(range(sz-1,-1,-1))) hfilt = lfilt[ind].T * (-1)**((ind+1)-sz2) @@ -1794,7 +1794,7 @@ def modulateFlip(*args): # function res = blurDn(im, nlevs, filt) def blurDn(*args): if len(args) == 0: - print "Error: image input parameter required." + print("Error: image input parameter required.") return im = numpy.array(args[0]) @@ -1807,7 +1807,7 @@ def blurDn(*args): if len(args) > 2: filt = args[2] - if isinstance(filt, basestring): + if isinstance(filt, str): filt = namedFilter(filt) else: filt = namedFilter('binom5') @@ -1827,7 +1827,7 @@ def blurDn(*args): # 1D image if len(filt.shape) > 1 and (filt.shape[1]!=1 and filt.shape[2]!=1): # >1D filter - print 'Error: Cannot apply 2D filter to 1D signal' + print('Error: Cannot apply 2D filter to 1D signal') return # orient filter and image correctly if im.shape[0] == 1: @@ -1869,8 +1869,8 @@ def blur(*args): # REQUIRED ARG: if len(args) == 0: - print "blur(IM, LEVELS, FILT)" - print "first argument is required" + print("blur(IM, LEVELS, FILT)") + print("first argument is required") exit(1) else: im = numpy.array(args[0]) @@ -1882,7 +1882,7 @@ def blur(*args): nlevs = 1 if len(args) > 2: - if isinstance(args[2], basestring): + if isinstance(args[2], str): filt = namedFilter(args[2]) else: filt = numpy.array(args[2]) @@ -1900,7 +1900,7 @@ def blur(*args): if len(im.shape) == 1 or im.shape[0] == 1 or im.shape[1] == 1: # 1D image if len(filt) == 2 and (numpy.asarray(filt.shape) != 1).any(): - print 'Error: can not apply 2D filter to 1D signal' + print('Error: can not apply 2D filter to 1D signal') return imIn = corrDn(im, filt, 'reflect1', len(im)) @@ -1941,7 +1941,7 @@ def rconv2(*args): # 1 (DIM/2)+1 if len(args) < 2: - print "Error: two matrices required as input parameters" + print("Error: two matrices required as input parameters") return if len(args) == 2: @@ -1956,7 +1956,7 @@ def rconv2(*args): large = args[1] small = args[0] else: - print 'one arg must be larger than the other in both dimensions!' + print('one arg must be larger than the other in both dimensions!') return ly = large.shape[0] @@ -1992,7 +1992,7 @@ def rconv2(*args): # compute minimum and maximum values of input matrix, returning them as tuple def range2(*args): if not numpy.isreal(args[0]).all(): - print 'Error: matrix must be real-valued' + print('Error: matrix must be real-valued') return (args[0].min(), args[0].max()) @@ -2017,7 +2017,7 @@ def var2(*args): # MEAN (optional) and VAR (optional) make the computation faster. def kurt2(*args): if len(args) == 0: - print 'Error: input matrix is required' + print('Error: input matrix is required') if len(args) < 2: mn = args[0].mean() @@ -2045,16 +2045,16 @@ def kurt2(*args): def imStats(*args): if len(args) == 0: - print 'Error: at least one input image is required' + print('Error: at least one input image is required') return elif len(args) == 1 and not numpy.isreal(args[0]).all(): - print 'Error: input images must be real-valued matrices' + print('Error: input images must be real-valued matrices') return elif len(args) == 2 and ( not numpy.isreal(args[0]).all() or not numpy.isreal(args[1]).all()): - print 'Error: input images must be real-valued matrices' + print('Error: input images must be real-valued matrices') return elif len(args) > 2: - print 'Error: maximum of two input images allowed' + print('Error: maximum of two input images allowed') return if len(args) == 2: @@ -2066,18 +2066,18 @@ def imStats(*args): snr = numpy.inf else: snr = 10 * numpy.log10(var2(args[0])/v) - print 'Difference statistics:' - print ' Range: [%d, %d]' % (mn, mx) - print ' Mean: %f, Stdev (rmse): %f, SNR (dB): %f' % (mean, numpy.sqrt(v), snr) + print('Difference statistics:') + print(' Range: [%d, %d]' % (mn, mx)) + print(' Mean: %f, Stdev (rmse): %f, SNR (dB): %f' % (mean, numpy.sqrt(v), snr)) else: (mn, mx) = range2(args[0]) mean = args[0].mean() var = var2(args[0]) stdev = numpy.sqrt(var.real) + numpy.sqrt(var.imag) kurt = kurt2(args[0], mean, stdev**2) - print 'Image statistics:' - print ' Range: [%f, %f]' % (mn, mx) - print ' Mean: %f, Stdev: %f, Kurtosis: %f' % (mean, stdev, kurt) + print('Image statistics:') + print(' Range: [%f, %f]' % (mn, mx)) + print(' Mean: %f, Stdev: %f, Kurtosis: %f' % (mean, stdev, kurt)) # makes image the same as read in by matlab def correctImage(img): @@ -2114,12 +2114,12 @@ def shift(mtx, offset): # Eero Simoncelli, 6/96. Ported to Python by Rob Young, 5/14. def mkR(*args): if len(args) == 0: - print 'Error: first input parameter is required!' + print('Error: first input parameter is required!') return else: sz = args[0] - if isinstance(sz, (int, long)) or len(sz) == 1: + if isinstance(sz, int) or len(sz) == 1: sz = (sz, sz) # ----------------------------------------------------------------- @@ -2137,8 +2137,8 @@ def mkR(*args): # ----------------------------------------------------------------- - (xramp2, yramp2) = numpy.meshgrid(numpy.array(range(1,sz[1]+1))-origin[1], - numpy.array(range(1,sz[0]+1))-origin[0]) + (xramp2, yramp2) = numpy.meshgrid(numpy.array(list(range(1,sz[1]+1)))-origin[1], + numpy.array(list(range(1,sz[0]+1)))-origin[0]) res = (xramp2**2 + yramp2**2)**(expt/2.0) @@ -2155,9 +2155,9 @@ def mkR(*args): def mkFract(*args): if len(args) == 0: - print 'Error: input parameter dims required' + print('Error: input parameter dims required') else: - if isinstance(args[0], (int, long)) or len(args[0]) == 1: + if isinstance(args[0], int) or len(args[0]) == 1: dims = (args[0], args[0]) elif args[0] == 1: dims = (args[1], args[1]) @@ -2185,7 +2185,7 @@ def mkFract(*args): #if any(max(max(abs(fres.imag))) > 1e-10): if abs(fres.imag).max() > 1e-10: - print 'Symmetry error in creating fractal' + print('Symmetry error in creating fractal') else: res = numpy.real(fres) res = res / numpy.sqrt(var2(res)) @@ -2213,7 +2213,7 @@ def mkFract(*args): def steer(*args): if len(args) < 2: - print 'Error: input parameters basis and angle are required!' + print('Error: input parameters basis and angle are required!') return basis = args[0] @@ -2222,34 +2222,34 @@ def steer(*args): #if ( any(size(angle) ~= [size(basis,1) 1]) & any(size(angle) ~= [1 1]) ) angle = args[1] - if isinstance(angle, (int, long, float)): + if isinstance(angle, (int, float)): angle = numpy.array([angle]) else: if angle.shape[0] != basis.shape[0] or angle.shape[1] != 1: - print 'ANGLE must be a scalar, or a column vector the size of the basis elements' + print('ANGLE must be a scalar, or a column vector the size of the basis elements') return # If HARMONICS are not passed, assume derivatives. if len(args) < 3: if num%2 == 0: - harmonics = numpy.array(range(num/2))*2+1 + harmonics = numpy.array(list(range(num/2)))*2+1 else: - harmonics = numpy.array(range((15+1)/2))*2 + harmonics = numpy.array(list(range((15+1)/2)))*2 else: harmonics = args[2] if len(harmonics.shape) == 1 or harmonics.shape[0] == 1: harmonics = harmonics.reshape(harmonics.shape[0], 1) elif harmonics.shape[0] != 1 and harmonics.shape[1] != 1: - print 'Error: input parameter HARMONICS must be 1D!' + print('Error: input parameter HARMONICS must be 1D!') return if 2*harmonics.shape[0] - (harmonics == 0).sum() != num: - print 'harmonics list is incompatible with basis size!' + print('harmonics list is incompatible with basis size!') return # If STEERMTX not passed, assume evenly distributed cosine-phase filters: if len(args) < 4: - steermtx = steer2HarmMtx(harmonics, numpy.pi*numpy.array(range(num))/num, + steermtx = steer2HarmMtx(harmonics, numpy.pi*numpy.array(list(range(num)))/num, 'even') else: steermtx = args[3] @@ -2257,12 +2257,12 @@ def steer(*args): steervect = numpy.zeros((angle.shape[0], num)) arg = angle * harmonics[numpy.nonzero(harmonics)[0]].T if all(harmonics): - steervect[:, range(0,num,2)] = numpy.cos(arg) - steervect[:, range(1,num,2)] = numpy.sin(arg) + steervect[:, list(range(0,num,2))] = numpy.cos(arg) + steervect[:, list(range(1,num,2))] = numpy.sin(arg) else: steervect[:, 1] = numpy.ones((arg.shape[0],1)) - steervect[:, range(0,num,2)] = numpy.cos(arg) - steervect[:, range(1,num,2)] = numpy.sin(arg) + steervect[:, list(range(0,num,2))] = numpy.cos(arg) + steervect[:, list(range(1,num,2))] = numpy.sin(arg) steervect = numpy.dot(steervect,steermtx) @@ -2277,33 +2277,33 @@ def steer(*args): def showIm_old(*args): # check and set input parameters if len(args) == 0: - print "showIm( matrix, range, zoom, label, nshades )" - print " matrix is string. It should be the name of a 2D array." - print " range is a two element tuple. It specifies the values that " - print " map to the min and max colormap values. Passing a value " - print " of 'auto' (default) sets range=[min,max]. 'auto2' sets " - print " range=[mean-2*stdev, mean+2*stdev]. 'auto3' sets " - print " range=[p1-(p2-p1)/8, p2+(p2-p1)/8], where p1 is the 10th " - print " percientile value of the sorted matix samples, and p2 is " - print " the 90th percentile value." - print " zoom specifies the number of matrix samples per screen pixel." - print " It will be rounded to an integer, or 1 divided by an " - print " integer." + print("showIm( matrix, range, zoom, label, nshades )") + print(" matrix is string. It should be the name of a 2D array.") + print(" range is a two element tuple. It specifies the values that ") + print(" map to the min and max colormap values. Passing a value ") + print(" of 'auto' (default) sets range=[min,max]. 'auto2' sets ") + print(" range=[mean-2*stdev, mean+2*stdev]. 'auto3' sets ") + print(" range=[p1-(p2-p1)/8, p2+(p2-p1)/8], where p1 is the 10th ") + print(" percientile value of the sorted matix samples, and p2 is ") + print(" the 90th percentile value.") + print(" zoom specifies the number of matrix samples per screen pixel.") + print(" It will be rounded to an integer, or 1 divided by an ") + print(" integer.") #print " A value of 'same' or 'auto' (default) causes the " #print " zoom value to be chosen automatically to fit the image into" #print " the current axes." #print " A value of 'full' fills the axis region " #print " (leaving no room for labels)." - print " label - A string that is used as a figure title." - print " NSHADES (optional) specifies the number of gray shades, " - print " and defaults to the size of the current colormap. " + print(" label - A string that is used as a figure title.") + print(" NSHADES (optional) specifies the number of gray shades, ") + print(" and defaults to the size of the current colormap. ") if len(args) > 0: # matrix entered matrix = numpy.array(args[0]) #print 'showIm range %f %f' % (matrix.min(), matrix.max()) if len(args) > 1: # range entered - if isinstance(args[1], basestring): + if isinstance(args[1], str): if args[1] is "auto": imRange = ( numpy.amin(matrix), numpy.amax(matrix) ) elif args[1] is "auto2": @@ -2316,10 +2316,10 @@ def showIm_old(*args): p2 = scipy.stats.scoreatpercentile(numpy.hstack(matrix), 90) imRange = (p1-(p2-p1)/8.0, p2+(p2-p1)/8.0) else: - print "Error: range of %s is not recognized." % args[1] - print " please use a two element tuple or " - print " 'auto', 'auto2' or 'auto3'" - print " enter 'showIm' for more info about options" + print("Error: range of %s is not recognized." % args[1]) + print(" please use a two element tuple or ") + print(" 'auto', 'auto2' or 'auto3'") + print(" enter 'showIm' for more info about options") return else: imRange = args[1][0], args[1][1] @@ -2363,7 +2363,7 @@ def showIm_old(*args): # make colormap incr = (256/nshades)+1 - colors = range(0,255,(256/nshades)+1) + colors = list(range(0,255,(256/nshades)+1)) colors[-1] = 255 colctr = -1 for i in range(256): @@ -2375,9 +2375,9 @@ def showIm_old(*args): # zoom #dims = (matrix.shape[0]*zoom, matrix.shape[1]*zoom) dims = (nRows*zoom, nCols*zoom) - print 'dims' - print dims - print 'nRows=%d nCols=%d' % (nRows, nCols) + print('dims') + print(dims) + print('nRows=%d nCols=%d' % (nRows, nCols)) #qim = qim.scaled(dims[0], dims[1]) qim = qim.scaled(nCols, nRows) #pixmap = QtGui.QPixmap() @@ -2417,33 +2417,33 @@ def showIm_old(*args): def showIm(*args): # check and set input parameters if len(args) == 0: - print "showIm( matrix, range, zoom, label, nshades )" - print " matrix is string. It should be the name of a 2D array." - print " range is a two element tuple. It specifies the values that " - print " map to the min and max colormap values. Passing a value " - print " of 'auto' (default) sets range=[min,max]. 'auto2' sets " - print " range=[mean-2*stdev, mean+2*stdev]. 'auto3' sets " - print " range=[p1-(p2-p1)/8, p2+(p2-p1)/8], where p1 is the 10th " - print " percientile value of the sorted matix samples, and p2 is " - print " the 90th percentile value." - print " zoom specifies the number of matrix samples per screen pixel." - print " It will be rounded to an integer, or 1 divided by an " - print " integer." + print("showIm( matrix, range, zoom, label, nshades )") + print(" matrix is string. It should be the name of a 2D array.") + print(" range is a two element tuple. It specifies the values that ") + print(" map to the min and max colormap values. Passing a value ") + print(" of 'auto' (default) sets range=[min,max]. 'auto2' sets ") + print(" range=[mean-2*stdev, mean+2*stdev]. 'auto3' sets ") + print(" range=[p1-(p2-p1)/8, p2+(p2-p1)/8], where p1 is the 10th ") + print(" percientile value of the sorted matix samples, and p2 is ") + print(" the 90th percentile value.") + print(" zoom specifies the number of matrix samples per screen pixel.") + print(" It will be rounded to an integer, or 1 divided by an ") + print(" integer.") #print " A value of 'same' or 'auto' (default) causes the " #print " zoom value to be chosen automatically to fit the image into" #print " the current axes." #print " A value of 'full' fills the axis region " #print " (leaving no room for labels)." - print " label - A string that is used as a figure title." - print " NSHADES (optional) specifies the number of gray shades, " - print " and defaults to the size of the current colormap. " + print(" label - A string that is used as a figure title.") + print(" NSHADES (optional) specifies the number of gray shades, ") + print(" and defaults to the size of the current colormap. ") if len(args) > 0: # matrix entered matrix = numpy.array(args[0]) #print 'showIm range %f %f' % (matrix.min(), matrix.max()) if len(args) > 1: # range entered - if isinstance(args[1], basestring): + if isinstance(args[1], str): if args[1] is "auto": imRange = ( numpy.amin(matrix), numpy.amax(matrix) ) elif args[1] is "auto2": @@ -2456,10 +2456,10 @@ def showIm(*args): p2 = scipy.stats.scoreatpercentile(numpy.hstack(matrix), 90) imRange = (p1-(p2-p1)/8.0, p2+(p2-p1)/8.0) else: - print "Error: range of %s is not recognized." % args[1] - print " please use a two element tuple or " - print " 'auto', 'auto2' or 'auto3'" - print " enter 'showIm' for more info about options" + print("Error: range of %s is not recognized." % args[1]) + print(" please use a two element tuple or ") + print(" 'auto', 'auto2' or 'auto3'") + print(" enter 'showIm' for more info about options") return else: imRange = args[1][0], args[1][1] @@ -2483,24 +2483,24 @@ def showIm(*args): # create window #master = Tkinter.Tk() - master = Tkinter.Toplevel() + master = tkinter.Toplevel() master.title('showIm') canvas_width = matrix.shape[0] * zoom canvas_height = matrix.shape[1] * zoom master.geometry(str(canvas_width+20) + "x" + str(canvas_height+60) + "+200+200") # put in top spacer - spacer = Tkinter.Label(master, text='').pack() + spacer = tkinter.Label(master, text='').pack() # create canvas - canvas = Tkinter.Canvas(master, width=canvas_width, height=canvas_height) + canvas = tkinter.Canvas(master, width=canvas_width, height=canvas_height) canvas.pack() #img = Image.fromarray(matrix) # FIX: shift matrix to 0.0-1.0 then to 0-255 if (matrix < 0).any(): matrix = matrix + math.fabs(matrix.min()) matrix = (matrix / matrix.max()) * 255.0 - print matrix.astype('uint8')[0,:] + print(matrix.astype('uint8')[0,:]) img = PIL.Image.fromarray(matrix.astype('uint8')) # make colormap - works without range @@ -2523,7 +2523,7 @@ def showIm(*args): #incr = int(numpy.ceil(float(imRange[1]-imRange[0]+1) / float(nshades))) incr = int(numpy.ceil(float(matrix.max()-matrix.min()+1) / float(nshades))) #colors = range(int(imRange[0]), int(imRange[1])+1, incr) - colors = range(int(matrix.min()), int(matrix.max())+1, incr) + colors = list(range(int(matrix.min()), int(matrix.max())+1, incr)) colors[0] = 0 colors[-1] = 255 colctr = -1 @@ -2543,21 +2543,21 @@ def showIm(*args): # apply image to canvas imgPI = ImageTk.PhotoImage(img) - canvas.create_image(0,0, anchor=Tkinter.NW, image=imgPI) + canvas.create_image(0,0, anchor=tkinter.NW, image=imgPI) # add labels rangeStr = 'Range: [%.1f, %.1f]' % (imRange[0], imRange[1]) - rangeLabel = Tkinter.Label(master, text=rangeStr).pack() + rangeLabel = tkinter.Label(master, text=rangeStr).pack() dimsStr = 'Dims: [%d, %d] / %d' % (matrix.shape[0], matrix.shape[1], zoom) - dimsLabel = Tkinter.Label(master, text=dimsStr).pack() + dimsLabel = tkinter.Label(master, text=dimsStr).pack() - Tkinter.mainloop() + tkinter.mainloop() def corrDn(image = None, filt = None, edges = 'reflect1', step = (1,1), start = (0,0), stop = None, result = None): if image == None or filt == None: - print 'Error: image and filter are required input parameters!' + print('Error: image and filter are required input parameters!') return else: image = image.copy() @@ -2570,8 +2570,8 @@ def corrDn(image = None, filt = None, edges = 'reflect1', step = (1,1), stop = (image.shape[0], image.shape[1]) if result == None: - rxsz = len(range(start[0], stop[0], step[0])) - rysz = len(range(start[1], stop[1], step[1])) + rxsz = len(list(range(start[0], stop[0], step[0]))) + rysz = len(list(range(start[1], stop[1], step[1]))) result = numpy.zeros((rxsz, rysz)) if edges == 'circular': @@ -2600,7 +2600,7 @@ def upConv(image = None, filt = None, edges = 'reflect1', step = (1,1), start = (0,0), stop = None, result = None): if image == None or filt == None: - print 'Error: image and filter are required input parameters!' + print('Error: image and filter are required input parameters!') return else: image = image.copy() @@ -2619,7 +2619,7 @@ def upConv(image = None, filt = None, edges = 'reflect1', step = (1,1), filt = numpy.append(filt,0.0); filt = numpy.reshape(filt, (1, len(filt))) else: - print 'Even sized 2D filters not yet supported by upConv.' + print('Even sized 2D filters not yet supported by upConv.') return if stop == None and result == None: @@ -2682,9 +2682,9 @@ def cconv2(*args): # Eero Simoncelli, 6/96. Modified 2/97. Python port by Rob Young, 8/15 if len(args) < 2: - print 'Error: cconv2 requires two input matrices!' - print 'Usage: cconv2(matrix1, matrix2, center)' - print 'where center parameter is optional' + print('Error: cconv2 requires two input matrices!') + print('Usage: cconv2(matrix1, matrix2, center)') + print('where center parameter is optional') return else: a = numpy.array(args[0]) @@ -2702,7 +2702,7 @@ def cconv2(*args): large = b small = a else: - print 'Error: one matrix must be larger than the other in both dimensions!' + print('Error: one matrix must be larger than the other in both dimensions!') return ly = large.shape[0] @@ -2748,8 +2748,8 @@ def clip(*args): # ported to Python by Rob Young, 8/15 if len(args) == 0 or len(args) > 3: - print 'Usage: clip(im, minVal or Range, maxVal)' - print 'first input parameter is required' + print('Usage: clip(im, minVal or Range, maxVal)') + print('first input parameter is required') return im = numpy.array(args[0]) @@ -2758,7 +2758,7 @@ def clip(*args): minVal = 0; maxVal = 1; elif len(args) == 2: - if isinstance(args[1], (int, long, float)): + if isinstance(args[1], (int, float)): minVal = args[1] maxVal = args[1]+1 else: @@ -2769,7 +2769,7 @@ def clip(*args): maxVal = args[2] if maxVal < minVal: - print 'Error: maxVal cannot be less than minVal!' + print('Error: maxVal cannot be less than minVal!') return im[numpy.where(im < minVal)] = minVal @@ -2781,7 +2781,7 @@ def clip(*args): # used in histo so we can unit test against matlab code # numpy version rounds to closest even number to remove bias def round(arr): - if isinstance(arr, (int, float, long)): + if isinstance(arr, (int, float)): arr = roundVal(arr) else: for i in range(len(arr)): @@ -2822,8 +2822,8 @@ def histo(*args): # called histo.c if len(args) == 0 or len(args) > 3: - print 'Usage: histo(mtx, nbins, binCtr)' - print 'first argument is required' + print('Usage: histo(mtx, nbins, binCtr)') + print('first argument is required') return else: mtx = args[0] @@ -2844,7 +2844,7 @@ def histo(*args): tmpNbins = ( round(float(mx-binCtr) / float(binSize)) - round(float(mn-binCtr) / float(binSize)) ) if tmpNbins != args[1]: - print 'Warning: Using %d bins instead of requested number (%d)' % (tmpNbins, args[1]) + print('Warning: Using %d bins instead of requested number (%d)' % (tmpNbins, args[1])) else: binSize = float(mx-mn) / 101.0 @@ -2857,7 +2857,7 @@ def histo(*args): # numpy.histogram uses bin edges, not centers like Matlab's hist #bins = firstBin + binSize * numpy.array(range(tmpNbins+1)) # compute bin edges - binsE = firstEdge + binSize * numpy.array(range(tmpNbins+1)) + binsE = firstEdge + binSize * numpy.array(list(range(tmpNbins+1))) [N, X] = numpy.histogram(mtx, binsE) @@ -2911,7 +2911,7 @@ def factorial(*args): # EPS, 11/02, Python port by Rob Young, 10/15 # if scalar input make it a single element array - if isinstance(args[0], (int, long, float)): + if isinstance(args[0], (int, float)): num = numpy.array([args[0]]) else: num = numpy.array(args[0]) @@ -2995,8 +2995,8 @@ def imGradient(*args): # Python port by Rob Young, 10/15 if len(args) == 0 or len(args) > 2: - print 'Usage: imGradient(image, edges)' - print "'edges' argument is optional" + print('Usage: imGradient(image, edges)') + print("'edges' argument is optional") elif len(args) == 1: edges = "dont-compute" elif len(args) == 2: @@ -3019,8 +3019,8 @@ def skew2(*args): # MEAN (optional) and VAR (optional) make the computation faster. if len(args) == 0: - print 'Usage: skew2(matrix, mean, variance)' - print 'mean and variance arguments are optional' + print('Usage: skew2(matrix, mean, variance)') + print('mean and variance arguments are optional') else: mtx = numpy.array(args[0]) @@ -3060,8 +3060,8 @@ def upBlur(*args): # REQUIRED ARGS if len(args) == 0: - print 'Usage: upBlur(image, levels, filter)' - print 'first argument is required' + print('Usage: upBlur(image, levels, filter)') + print('first argument is required') else: im = numpy.array(args[0]) @@ -3080,7 +3080,7 @@ def upBlur(*args): #------------------------------------------------------------------ - if isinstance(filt, basestring): + if isinstance(filt, str): filt = namedFilter(filt) if nlevs > 1: @@ -3125,8 +3125,8 @@ def zconv2(*args): #---------------------------------------------------------------- if len(args) < 2 or len(args) > 3: - print 'Usage: zconv2(matrix1, matrix2, center)' - print 'first two input parameters are required' + print('Usage: zconv2(matrix1, matrix2, center)') + print('first two input parameters are required') else: a = numpy.array(args[0]) b = numpy.array(args[1]) @@ -3148,7 +3148,7 @@ def zconv2(*args): large = b small = a else: - print 'Error: one arg must be larger than the other in both dimensions!' + print('Error: one arg must be larger than the other in both dimensions!') return ly = large.shape[0] diff --git a/pyramid.py b/pyramid.py index 6fcdd3a..6f5c793 100644 --- a/pyramid.py +++ b/pyramid.py @@ -9,7 +9,7 @@ class pyramid: # pyramid # constructor def __init__(self): - print "please specify type of pyramid to create (Gpry, Lpyr, etc.)" + print("please specify type of pyramid to create (Gpry, Lpyr, etc.)") return # methods diff --git a/range2.py b/range2.py index 078ae8e..ef86f73 100644 --- a/range2.py +++ b/range2.py @@ -5,6 +5,6 @@ def range2(*args): as tuple ''' if not numpy.isreal(args[0]).all(): - print 'Error: matrix must be real-valued' + print('Error: matrix must be real-valued') return (args[0].min(), args[0].max()) diff --git a/rconv2.py b/rconv2.py index e73902e..7a1bf99 100644 --- a/rconv2.py +++ b/rconv2.py @@ -13,7 +13,7 @@ def rconv2(*args): 1 (DIM/2)+1 ''' if len(args) < 2: - print "Error: two matrices required as input parameters" + print("Error: two matrices required as input parameters") return if len(args) == 2: @@ -28,7 +28,7 @@ def rconv2(*args): large = args[1] small = args[0] else: - print 'one arg must be larger than the other in both dimensions!' + print('one arg must be larger than the other in both dimensions!') return ly = large.shape[0] diff --git a/rcosFn.py b/rcosFn.py index e40b96b..1b5355b 100644 --- a/rcosFn.py +++ b/rcosFn.py @@ -33,7 +33,7 @@ def rcosFn(*args): sz = 256 # arbitrary! - X = numpy.pi * numpy.array(range(-sz-1,2)) / (2*sz) + X = numpy.pi * numpy.array(list(range(-sz-1,2))) / (2*sz) Y = values[0] + (values[1]-values[0]) * numpy.cos(X)**2; diff --git a/round.py b/round.py index a672b91..393f355 100644 --- a/round.py +++ b/round.py @@ -1,12 +1,12 @@ import numpy -from roundVal import roundVal +from .roundVal import roundVal def round(arr): ''' round equivalent to matlab function used in histo so we can unit test against matlab code numpy version rounds to closest even number to remove bias ''' - if isinstance(arr, (int, float, long)): + if isinstance(arr, (int, float)): arr = roundVal(arr) else: for i in range(len(arr)): diff --git a/showIm.py b/showIm.py index 6d97795..97bcf9a 100644 --- a/showIm.py +++ b/showIm.py @@ -2,39 +2,39 @@ from PIL import ImageTk import PIL import scipy.stats -import Tkinter +import tkinter import math -from round import round +from .round import round def showIm(*args): # check and set input parameters if len(args) == 0: - print "showIm( matrix, range, zoom, label, nshades )" - print " matrix is string. It should be the name of a 2D array." - print " range is a two element tuple. It specifies the values that " - print " map to the min and max colormap values. Passing a value " - print " of 'auto' (default) sets range=[min,max]. 'auto2' sets " - print " range=[mean-2*stdev, mean+2*stdev]. 'auto3' sets " - print " range=[p1-(p2-p1)/8, p2+(p2-p1)/8], where p1 is the 10th " - print " percientile value of the sorted matix samples, and p2 is " - print " the 90th percentile value." - print " zoom specifies the number of matrix samples per screen pixel." - print " It will be rounded to an integer, or 1 divided by an " - print " integer." + print("showIm( matrix, range, zoom, label, nshades )") + print(" matrix is string. It should be the name of a 2D array.") + print(" range is a two element tuple. It specifies the values that ") + print(" map to the min and max colormap values. Passing a value ") + print(" of 'auto' (default) sets range=[min,max]. 'auto2' sets ") + print(" range=[mean-2*stdev, mean+2*stdev]. 'auto3' sets ") + print(" range=[p1-(p2-p1)/8, p2+(p2-p1)/8], where p1 is the 10th ") + print(" percientile value of the sorted matix samples, and p2 is ") + print(" the 90th percentile value.") + print(" zoom specifies the number of matrix samples per screen pixel.") + print(" It will be rounded to an integer, or 1 divided by an ") + print(" integer.") #print " A value of 'same' or 'auto' (default) causes the " #print " zoom value to be chosen automatically to fit the image into" #print " the current axes." #print " A value of 'full' fills the axis region " #print " (leaving no room for labels)." - print " label - A string that is used as a figure title." - print " NSHADES (optional) specifies the number of gray shades, " - print " and defaults to the size of the current colormap. " + print(" label - A string that is used as a figure title.") + print(" NSHADES (optional) specifies the number of gray shades, ") + print(" and defaults to the size of the current colormap. ") if len(args) > 0: # matrix entered matrix = numpy.array(args[0]) if len(args) > 1: # range entered - if isinstance(args[1], basestring): + if isinstance(args[1], str): if args[1] is "auto": imRange = ( numpy.amin(matrix), numpy.amax(matrix) ) elif args[1] is "auto2": @@ -47,10 +47,10 @@ def showIm(*args): p2 = scipy.stats.scoreatpercentile(numpy.hstack(matrix), 90) imRange = (p1-(p2-p1)/8.0, p2+(p2-p1)/8.0) else: - print "Error: range of %s is not recognized." % args[1] - print " please use a two element tuple or " - print " 'auto', 'auto2' or 'auto3'" - print " enter 'showIm' for more info about options" + print("Error: range of %s is not recognized." % args[1]) + print(" please use a two element tuple or ") + print(" 'auto', 'auto2' or 'auto3'") + print(" enter 'showIm' for more info about options") return else: imRange = args[1][0], args[1][1] @@ -74,29 +74,29 @@ def showIm(*args): # create window #master = Tkinter.Tk() - master = Tkinter.Toplevel() + master = tkinter.Toplevel() master.title('showIm') canvas_width = matrix.shape[0] * zoom canvas_height = matrix.shape[1] * zoom master.geometry(str(canvas_width+20) + "x" + str(canvas_height+60) + "+200+200") # put in top spacer - spacer = Tkinter.Label(master, text='').pack() + spacer = tkinter.Label(master, text='').pack() # create canvas - canvas = Tkinter.Canvas(master, width=canvas_width, height=canvas_height) + canvas = tkinter.Canvas(master, width=canvas_width, height=canvas_height) canvas.pack() # shift matrix to 0.0-1.0 then to 0-255 if (matrix < 0).any(): matrix = matrix + math.fabs(matrix.min()) matrix = (matrix / matrix.max()) * 255.0 - print matrix.astype('uint8')[0,:] + print(matrix.astype('uint8')[0,:]) img = PIL.Image.fromarray(matrix.astype('uint8')) # make colormap colorTable = [0] * 256 incr = int(numpy.ceil(float(matrix.max()-matrix.min()+1) / float(nshades))) - colors = range(int(matrix.min()), int(matrix.max())+1, incr) + colors = list(range(int(matrix.min()), int(matrix.max())+1, incr)) colors[0] = 0 colors[-1] = 255 colctr = -1 @@ -115,12 +115,12 @@ def showIm(*args): # apply image to canvas imgPI = ImageTk.PhotoImage(img) - canvas.create_image(0,0, anchor=Tkinter.NW, image=imgPI) + canvas.create_image(0,0, anchor=tkinter.NW, image=imgPI) # add labels rangeStr = 'Range: [%.1f, %.1f]' % (imRange[0], imRange[1]) - rangeLabel = Tkinter.Label(master, text=rangeStr).pack() + rangeLabel = tkinter.Label(master, text=rangeStr).pack() dimsStr = 'Dims: [%d, %d] / %d' % (matrix.shape[0], matrix.shape[1], zoom) - dimsLabel = Tkinter.Label(master, text=dimsStr).pack() + dimsLabel = tkinter.Label(master, text=dimsStr).pack() - Tkinter.mainloop() + tkinter.mainloop() diff --git a/skew2.py b/skew2.py index 98d1309..6b8050b 100644 --- a/skew2.py +++ b/skew2.py @@ -1,13 +1,13 @@ import numpy -from var2 import var2 +from .var2 import var2 def skew2(*args): ''' Sample skew (third moment divided by variance^3/2) of a matrix. MEAN (optional) and VAR (optional) make the computation faster. ''' if len(args) == 0: - print 'Usage: skew2(matrix, mean, variance)' - print 'mean and variance arguments are optional' + print('Usage: skew2(matrix, mean, variance)') + print('mean and variance arguments are optional') else: mtx = numpy.array(args[0]) diff --git a/steer.py b/steer.py index f50adc7..ef84483 100644 --- a/steer.py +++ b/steer.py @@ -1,5 +1,5 @@ import numpy -from steer2HarmMtx import steer2HarmMtx +from .steer2HarmMtx import steer2HarmMtx def steer(*args): ''' Steer BASIS to the specfied ANGLE. @@ -22,7 +22,7 @@ def steer(*args): Eero Simoncelli, 7/96. Ported to Python by Rob Young, 5/14. ''' if len(args) < 2: - print 'Error: input parameters basis and angle are required!' + print('Error: input parameters basis and angle are required!') return basis = args[0] @@ -30,19 +30,19 @@ def steer(*args): num = basis.shape[1] angle = args[1] - if isinstance(angle, (int, long, float)): + if isinstance(angle, (int, float)): angle = numpy.array([angle]) else: if angle.shape[0] != basis.shape[0] or angle.shape[1] != 1: - print 'ANGLE must be a scalar, or a column vector the size of the basis elements' + print('ANGLE must be a scalar, or a column vector the size of the basis elements') return # If HARMONICS are not passed, assume derivatives. if len(args) < 3: if num%2 == 0: - harmonics = numpy.array(range(num/2))*2+1 + harmonics = numpy.array(list(range(num/2)))*2+1 else: - harmonics = numpy.array(range((15+1)/2))*2 + harmonics = numpy.array(list(range((15+1)/2)))*2 else: harmonics = args[2] @@ -50,17 +50,17 @@ def steer(*args): # reshape to column matrix harmonics = harmonics.reshape(harmonics.shape[0], 1) elif harmonics.shape[0] != 1 and harmonics.shape[1] != 1: - print 'Error: input parameter HARMONICS must be 1D!' + print('Error: input parameter HARMONICS must be 1D!') return if 2*harmonics.shape[0] - (harmonics == 0).sum() != num: - print 'harmonics list is incompatible with basis size!' + print('harmonics list is incompatible with basis size!') return # If STEERMTX not passed, assume evenly distributed cosine-phase filters: if len(args) < 4: steermtx = steer2HarmMtx(harmonics, - numpy.pi*numpy.array(range(num))/num, + numpy.pi*numpy.array(list(range(num)))/num, 'even') else: steermtx = args[3] @@ -68,19 +68,19 @@ def steer(*args): steervect = numpy.zeros((angle.shape[0], num)) arg = angle * harmonics[numpy.nonzero(harmonics)[0]].T if all(harmonics): - steervect[:, range(0,num,2)] = numpy.cos(arg) - steervect[:, range(1,num,2)] = numpy.sin(arg) + steervect[:, list(range(0,num,2))] = numpy.cos(arg) + steervect[:, list(range(1,num,2))] = numpy.sin(arg) else: - steervect[:, 1] = numpy.ones((arg.shape[0],1)) - steervect[:, range(0,num,2)] = numpy.cos(arg) - steervect[:, range(1,num,2)] = numpy.sin(arg) + steervect[:, 1] = numpy.ones((arg.shape[0],1)) + steervect[:, list(range(0,num,2))] = numpy.cos(arg) + steervect[:, list(range(1,num,2))] = numpy.sin(arg) steervect = numpy.dot(steervect,steermtx) if steervect.shape[0] > 1: - tmp = numpy.dot(basis, steervect) - res = sum(tmp).T + tmp = numpy.dot(basis, steervect) + res = sum(tmp).T else: - res = numpy.dot(basis, steervect.T) + res = numpy.dot(basis, steervect.T) return res diff --git a/steer2HarmMtx.py b/steer2HarmMtx.py index 48c731b..ba59116 100644 --- a/steer2HarmMtx.py +++ b/steer2HarmMtx.py @@ -11,7 +11,7 @@ def steer2HarmMtx(*args): mtx = steer2HarmMtx(harmonics, angles, evenorodd) ''' if len(args) == 0: - print "Error: first parameter 'harmonics' is required." + print("Error: first parameter 'harmonics' is required.") return if len(args) > 0: @@ -22,19 +22,19 @@ def steer2HarmMtx(*args): if len(args) > 1: angles = args[1] else: - angles = numpy.pi * numpy.array(range(numh)) / numh + angles = numpy.pi * numpy.array(list(range(numh))) / numh if len(args) > 2: - if isinstance(args[2], basestring): + if isinstance(args[2], str): if args[2] == 'even' or args[2] == 'EVEN': evenorodd = 0 elif args[2] == 'odd' or args[2] == 'ODD': evenorodd = 1 else: - print "Error: only 'even' and 'odd' are valid entries for the third input parameter." + print("Error: only 'even' and 'odd' are valid entries for the third input parameter.") return else: - print "Error: third input parameter must be a string (even/odd)." + print("Error: third input parameter must be a string (even/odd).") else: evenorodd = 0 @@ -58,7 +58,7 @@ def steer2HarmMtx(*args): r = numpy.rank(imtx) if r != numh and r != angles.shape[0]: - print "Warning: matrix is not full rank" + print("Warning: matrix is not full rank") mtx = numpy.linalg.pinv(imtx) diff --git a/upBlur.py b/upBlur.py index 7de84ff..f8bd39a 100644 --- a/upBlur.py +++ b/upBlur.py @@ -1,6 +1,6 @@ import numpy -from namedFilter import namedFilter -from upConv import upConv +from .namedFilter import namedFilter +from .upConv import upConv def upBlur(*args): ''' RES = upBlur(IM, LEVELS, FILT) @@ -20,8 +20,8 @@ def upBlur(*args): # REQUIRED ARGS if len(args) == 0: - print 'Usage: upBlur(image, levels, filter)' - print 'first argument is required' + print('Usage: upBlur(image, levels, filter)') + print('first argument is required') else: im = numpy.array(args[0]) @@ -40,7 +40,7 @@ def upBlur(*args): #------------------------------------------------------------------ - if isinstance(filt, basestring): + if isinstance(filt, str): filt = namedFilter(filt) if nlevs > 1: diff --git a/upConv.py b/upConv.py index 52b36d9..16fc74b 100644 --- a/upConv.py +++ b/upConv.py @@ -10,7 +10,7 @@ def upConv(image = None, filt = None, edges = 'reflect1', step = (1,1), start = (0,0), stop = None, result = None): if image is None or filt is None: - print 'Error: image and filter are required input parameters!' + print('Error: image and filter are required input parameters!') return else: image = image.copy() @@ -29,7 +29,7 @@ def upConv(image = None, filt = None, edges = 'reflect1', step = (1,1), filt = numpy.append(filt,0.0); filt = numpy.reshape(filt, (1, len(filt))) else: - print 'Even sized 2D filters not yet supported by upConv.' + print('Even sized 2D filters not yet supported by upConv.') return if stop is None and result is None: diff --git a/zconv2.py b/zconv2.py index f64ef09..6cf3c46 100644 --- a/zconv2.py +++ b/zconv2.py @@ -20,8 +20,8 @@ def zconv2(*args): #---------------------------------------------------------------- if len(args) < 2 or len(args) > 3: - print 'Usage: zconv2(matrix1, matrix2, center)' - print 'first two input parameters are required' + print('Usage: zconv2(matrix1, matrix2, center)') + print('first two input parameters are required') return else: a = numpy.array(args[0]) @@ -44,7 +44,7 @@ def zconv2(*args): large = b small = a else: - print 'Error: one arg must be larger than the other in both dimensions!' + print('Error: one arg must be larger than the other in both dimensions!') return ly = large.shape[0] From 39522887f093321289149015a10109190a015a92 Mon Sep 17 00:00:00 2001 From: anhduc1210 Date: Tue, 12 Dec 2017 16:48:21 +0900 Subject: [PATCH 3/3] bug fix --- SCFpyr.py | 48 +++++++++--------- __pycache__/Gpyr.cpython-35.pyc | Bin 0 -> 2144 bytes __pycache__/JBhelpers.cpython-35.pyc | Bin 0 -> 20458 bytes __pycache__/LB2idx.cpython-35.pyc | Bin 0 -> 484 bytes __pycache__/Lpyr.cpython-35.pyc | Bin 0 -> 8830 bytes __pycache__/SCFpyr.cpython-35.pyc | Bin 0 -> 10414 bytes __pycache__/SFpyr.cpython-35.pyc | Bin 0 -> 9391 bytes __pycache__/Spyr.cpython-35.pyc | Bin 0 -> 11277 bytes __pycache__/Wpyr.cpython-35.pyc | Bin 0 -> 11549 bytes __pycache__/__init__.cpython-35.pyc | Bin 0 -> 2403 bytes __pycache__/binomialFilter.cpython-35.pyc | Bin 0 -> 694 bytes __pycache__/blur.cpython-35.pyc | Bin 0 -> 2206 bytes __pycache__/blurDn.cpython-35.pyc | Bin 0 -> 2448 bytes __pycache__/cconv2.cpython-35.pyc | Bin 0 -> 2143 bytes __pycache__/clip.cpython-35.pyc | Bin 0 -> 1223 bytes __pycache__/comparePyr.cpython-35.pyc | Bin 0 -> 1456 bytes __pycache__/compareRecon.cpython-35.pyc | Bin 0 -> 1359 bytes __pycache__/corrDn.cpython-35.pyc | Bin 0 -> 1570 bytes __pycache__/entropy2.cpython-35.pyc | Bin 0 -> 1131 bytes __pycache__/factorial.cpython-35.pyc | Bin 0 -> 797 bytes __pycache__/histo.cpython-35.pyc | Bin 0 -> 2287 bytes __pycache__/histoMatch.cpython-35.pyc | Bin 0 -> 1813 bytes __pycache__/idx2LB.cpython-35.pyc | Bin 0 -> 556 bytes __pycache__/imGradient.cpython-35.pyc | Bin 0 -> 1583 bytes __pycache__/imStats.cpython-35.pyc | Bin 0 -> 1794 bytes __pycache__/kurt2.cpython-35.pyc | Bin 0 -> 912 bytes __pycache__/maxPyrHt.cpython-35.pyc | Bin 0 -> 1135 bytes __pycache__/mkAngle.cpython-35.pyc | Bin 0 -> 1221 bytes __pycache__/mkAngularSine.cpython-35.pyc | Bin 0 -> 1396 bytes __pycache__/mkDisc.cpython-35.pyc | Bin 0 -> 1880 bytes __pycache__/mkFract.cpython-35.pyc | Bin 0 -> 1645 bytes __pycache__/mkGaussian.cpython-35.pyc | Bin 0 -> 2453 bytes __pycache__/mkImpulse.cpython-35.pyc | Bin 0 -> 900 bytes __pycache__/mkR.cpython-35.pyc | Bin 0 -> 1159 bytes __pycache__/mkRamp.cpython-35.pyc | Bin 0 -> 1617 bytes __pycache__/mkSine.cpython-35.pyc | Bin 0 -> 2107 bytes __pycache__/mkSquare.cpython-35.pyc | Bin 0 -> 2680 bytes __pycache__/mkZonePlate.cpython-35.pyc | Bin 0 -> 1147 bytes __pycache__/modulateFlip.cpython-35.pyc | Bin 0 -> 1219 bytes __pycache__/namedFilter.cpython-35.pyc | Bin 0 -> 3951 bytes __pycache__/nextSz.cpython-35.pyc | Bin 0 -> 520 bytes __pycache__/pointOp.cpython-35.pyc | Bin 0 -> 795 bytes __pycache__/pyramid.cpython-35.pyc | Bin 0 -> 882 bytes __pycache__/range2.cpython-35.pyc | Bin 0 -> 514 bytes __pycache__/rconv2.cpython-35.pyc | Bin 0 -> 2047 bytes __pycache__/rcosFn.cpython-35.pyc | Bin 0 -> 1268 bytes __pycache__/round.cpython-35.pyc | Bin 0 -> 628 bytes __pycache__/roundVal.cpython-35.pyc | Bin 0 -> 521 bytes __pycache__/shift.cpython-35.pyc | Bin 0 -> 824 bytes __pycache__/showIm.cpython-35.pyc | Bin 0 -> 3832 bytes __pycache__/skew2.cpython-35.pyc | Bin 0 -> 1015 bytes __pycache__/sp0Filters.cpython-35.pyc | Bin 0 -> 5995 bytes __pycache__/sp1Filters.cpython-35.pyc | Bin 0 -> 7230 bytes __pycache__/sp3Filters.cpython-35.pyc | Bin 0 -> 9872 bytes __pycache__/sp5Filters.cpython-35.pyc | Bin 0 -> 6466 bytes __pycache__/steer.cpython-35.pyc | Bin 0 -> 2733 bytes __pycache__/steer2HarmMtx.cpython-35.pyc | Bin 0 -> 2083 bytes .../strictly_decreasing.cpython-35.pyc | Bin 0 -> 540 bytes __pycache__/upBlur.cpython-35.pyc | Bin 0 -> 1726 bytes __pycache__/upConv.cpython-35.pyc | Bin 0 -> 1950 bytes __pycache__/var2.cpython-35.pyc | Bin 0 -> 748 bytes __pycache__/zconv2.cpython-35.pyc | Bin 0 -> 1710 bytes 62 files changed, 23 insertions(+), 25 deletions(-) create mode 100644 __pycache__/Gpyr.cpython-35.pyc create mode 100644 __pycache__/JBhelpers.cpython-35.pyc create mode 100644 __pycache__/LB2idx.cpython-35.pyc create mode 100644 __pycache__/Lpyr.cpython-35.pyc create mode 100644 __pycache__/SCFpyr.cpython-35.pyc create mode 100644 __pycache__/SFpyr.cpython-35.pyc create mode 100644 __pycache__/Spyr.cpython-35.pyc create mode 100644 __pycache__/Wpyr.cpython-35.pyc create mode 100644 __pycache__/__init__.cpython-35.pyc create mode 100644 __pycache__/binomialFilter.cpython-35.pyc create mode 100644 __pycache__/blur.cpython-35.pyc create mode 100644 __pycache__/blurDn.cpython-35.pyc create mode 100644 __pycache__/cconv2.cpython-35.pyc create mode 100644 __pycache__/clip.cpython-35.pyc create mode 100644 __pycache__/comparePyr.cpython-35.pyc create mode 100644 __pycache__/compareRecon.cpython-35.pyc create mode 100644 __pycache__/corrDn.cpython-35.pyc create mode 100644 __pycache__/entropy2.cpython-35.pyc create mode 100644 __pycache__/factorial.cpython-35.pyc create mode 100644 __pycache__/histo.cpython-35.pyc create mode 100644 __pycache__/histoMatch.cpython-35.pyc create mode 100644 __pycache__/idx2LB.cpython-35.pyc create mode 100644 __pycache__/imGradient.cpython-35.pyc create mode 100644 __pycache__/imStats.cpython-35.pyc create mode 100644 __pycache__/kurt2.cpython-35.pyc create mode 100644 __pycache__/maxPyrHt.cpython-35.pyc create mode 100644 __pycache__/mkAngle.cpython-35.pyc create mode 100644 __pycache__/mkAngularSine.cpython-35.pyc create mode 100644 __pycache__/mkDisc.cpython-35.pyc create mode 100644 __pycache__/mkFract.cpython-35.pyc create mode 100644 __pycache__/mkGaussian.cpython-35.pyc create mode 100644 __pycache__/mkImpulse.cpython-35.pyc create mode 100644 __pycache__/mkR.cpython-35.pyc create mode 100644 __pycache__/mkRamp.cpython-35.pyc create mode 100644 __pycache__/mkSine.cpython-35.pyc create mode 100644 __pycache__/mkSquare.cpython-35.pyc create mode 100644 __pycache__/mkZonePlate.cpython-35.pyc create mode 100644 __pycache__/modulateFlip.cpython-35.pyc create mode 100644 __pycache__/namedFilter.cpython-35.pyc create mode 100644 __pycache__/nextSz.cpython-35.pyc create mode 100644 __pycache__/pointOp.cpython-35.pyc create mode 100644 __pycache__/pyramid.cpython-35.pyc create mode 100644 __pycache__/range2.cpython-35.pyc create mode 100644 __pycache__/rconv2.cpython-35.pyc create mode 100644 __pycache__/rcosFn.cpython-35.pyc create mode 100644 __pycache__/round.cpython-35.pyc create mode 100644 __pycache__/roundVal.cpython-35.pyc create mode 100644 __pycache__/shift.cpython-35.pyc create mode 100644 __pycache__/showIm.cpython-35.pyc create mode 100644 __pycache__/skew2.cpython-35.pyc create mode 100644 __pycache__/sp0Filters.cpython-35.pyc create mode 100644 __pycache__/sp1Filters.cpython-35.pyc create mode 100644 __pycache__/sp3Filters.cpython-35.pyc create mode 100644 __pycache__/sp5Filters.cpython-35.pyc create mode 100644 __pycache__/steer.cpython-35.pyc create mode 100644 __pycache__/steer2HarmMtx.cpython-35.pyc create mode 100644 __pycache__/strictly_decreasing.cpython-35.pyc create mode 100644 __pycache__/upBlur.cpython-35.pyc create mode 100644 __pycache__/upConv.cpython-35.pyc create mode 100644 __pycache__/var2.cpython-35.pyc create mode 100644 __pycache__/zconv2.cpython-35.pyc diff --git a/SCFpyr.py b/SCFpyr.py index 8bede10..2afee52 100644 --- a/SCFpyr.py +++ b/SCFpyr.py @@ -1,6 +1,5 @@ from .SFpyr import SFpyr import numpy as np -import cupy as cp from .rcosFn import rcosFn from .pointOp import pointOp import scipy @@ -12,7 +11,7 @@ class SCFpyr(SFpyr): edges = '' #constructor - def __init__(self, image, height, order, twidth, scale, n_scales): # (image, height, order, twidth, scale, n_scales) + def __init__(self, image, height, order, twidth, scale, n_scales, xp=np): # (image, height, order, twidth, scale, n_scales) self.pyrType = 'steerableFrequency' self.image = image self.ht = height @@ -22,8 +21,7 @@ def __init__(self, image, height, order, twidth, scale, n_scales): # (image, self.n_scales = n_scales self.nbands = self.order+1 - #------------------------------------------------------ - self.xp = cp.get_array_module(self.image) + self.xp = xp dims = np.array(self.image.shape) ctr = np.ceil((dims+0.5)/2).astype('int') @@ -45,10 +43,10 @@ def __init__(self, image, height, order, twidth, scale, n_scales): # (image, lo0mask = pointOp(log_rad, YIrcos, Xrcos[0], Xrcos[1]-Xrcos[0], 0) hi0mask = pointOp(log_rad, Yrcos, Xrcos[0], Xrcos[1] - Xrcos[0], 0) else: - lo0mask = cp.array(pointOp(cp.asnumpy(log_rad), cp.asnumpy(YIrcos), cp.asnumpy(Xrcos)[0], - cp.asnumpy(Xrcos)[1] - cp.asnumpy(Xrcos)[0], 0)) - hi0mask = cp.array(pointOp(cp.asnumpy(log_rad), cp.asnumpy(Yrcos), cp.asnumpy(Xrcos)[0], - cp.asnumpy(Xrcos)[1] - cp.asnumpy(Xrcos)[0], 0)) + lo0mask = self.xp.array(pointOp(self.xp.asnumpy(log_rad), self.xp.asnumpy(YIrcos), self.xp.asnumpy(Xrcos)[0], + self.xp.asnumpy(Xrcos)[1] - self.xp.asnumpy(Xrcos)[0], 0)) + hi0mask = self.xp.array(pointOp(self.xp.asnumpy(log_rad), self.xp.asnumpy(Yrcos), self.xp.asnumpy(Xrcos)[0], + self.xp.asnumpy(Xrcos)[1] - self.xp.asnumpy(Xrcos)[0], 0)) self.pyr = [] self.pyrSize = [] @@ -81,8 +79,8 @@ def __init__(self, image, height, order, twidth, scale, n_scales): # (image, if self.xp.__name__ == 'numpy': himask = pointOp(log_rad_tmp, Yrcos, Xrcos[0], Xrcos[1]-Xrcos[0], 0) else: - himask = self.xp.array(pointOp(cp.asnumpy(log_rad_tmp), cp.asnumpy(Yrcos), cp.asnumpy(Xrcos)[0], - cp.asnumpy(Xrcos)[1] - cp.asnumpy(Xrcos)[0], 0)) + himask = self.xp.array(pointOp(self.xp.asnumpy(log_rad_tmp), self.xp.asnumpy(Yrcos), self.xp.asnumpy(Xrcos)[0], + self.xp.asnumpy(Xrcos)[1] - self.xp.asnumpy(Xrcos)[0], 0)) himask = himask.reshape(lodft.shape[0], lodft.shape[1]) for b in range(self.nbands): @@ -91,9 +89,9 @@ def __init__(self, image, height, order, twidth, scale, n_scales): # (image, if self.xp.__name__ == 'numpy': anglemask = pointOp(angle_tmp, Ycosn, Xcosn[0] + np.pi*b/self.nbands, Xcosn[1] - Xcosn[0], 0) else: - anglemask = self.xp.array(pointOp(cp.asnumpy(angle_tmp), cp.asnumpy(Ycosn), - cp.asnumpy(Xcosn)[0] + np.pi * b / self.nbands, - cp.asnumpy(Xcosn)[1] - cp.asnumpy(Xcosn)[0], 0)) + anglemask = self.xp.array(pointOp(self.xp.asnumpy(angle_tmp), self.xp.asnumpy(Ycosn), + self.xp.asnumpy(Xcosn)[0] + np.pi * b / self.nbands, + self.xp.asnumpy(Xcosn)[1] - self.xp.asnumpy(Xcosn)[0], 0)) anglemask = anglemask.reshape(lodft.shape[0], lodft.shape[1]) banddft = (self.xp.sqrt(-1 + 0j)**order) * lodft * anglemask * himask band = self.xp.negative(self.xp.fft.ifft2(self.xp.fft.ifftshift(banddft))) @@ -116,8 +114,8 @@ def __init__(self, image, height, order, twidth, scale, n_scales): # (image, if self.xp.__name__ == 'numpy': lomask = pointOp(log_rad_tmp, YIrcos, Xrcos[0], Xrcos[1]-Xrcos[0],0) else: - lomask = cp.array(pointOp(cp.asnumpy(log_rad_tmp), cp.asnumpy(YIrcos), cp.asnumpy(Xrcos)[0], - cp.asnumpy(Xrcos)[1] - cp.asnumpy(Xrcos)[0], 0)) + lomask = self.xp.array(pointOp(self.xp.asnumpy(log_rad_tmp), self.xp.asnumpy(YIrcos), self.xp.asnumpy(Xrcos)[0], + self.xp.asnumpy(Xrcos)[1] - self.xp.asnumpy(Xrcos)[0], 0)) lodft = lodft * lomask.reshape(lodft.shape[0], lodft.shape[1]) self.bands = self.xp.concatenate(self.bands, 0) @@ -221,16 +219,16 @@ def _reconSFpyr(self, levs='all', bands='all'): if self.xp.__name__ == 'numpy': lo0mask = pointOp(log_rad, YIrcos, Xrcos[0], Xrcos[1] - Xrcos[0], 0) else: - lo0mask = self.xp.array(pointOp(cp.asnumpy(log_rad), cp.asnumpy(YIrcos), cp.asnumpy(Xrcos)[0], - cp.asnumpy(Xrcos)[1] - cp.asnumpy(Xrcos)[0], 0)) + lo0mask = self.xp.array(pointOp(self.xp.asnumpy(log_rad), self.xp.asnumpy(YIrcos), self.xp.asnumpy(Xrcos)[0], + self.xp.asnumpy(Xrcos)[1] - self.xp.asnumpy(Xrcos)[0], 0)) resdft = resdft * lo0mask # residual highpass subband if self.xp.__name__ == 'numpy': hi0mask = pointOp(log_rad, Yrcos, Xrcos[0], Xrcos[1] - Xrcos[0], 0) else: - hi0mask = self.xp.array(pointOp(cp.asnumpy(log_rad), cp.asnumpy(Yrcos), cp.asnumpy(Xrcos)[0], - cp.asnumpy(Xrcos)[1] - cp.asnumpy(Xrcos)[0], 0)) + hi0mask = self.xp.array(pointOp(self.xp.asnumpy(log_rad), self.xp.asnumpy(Yrcos), self.xp.asnumpy(Xrcos)[0], + self.xp.asnumpy(Xrcos)[1] - self.xp.asnumpy(Xrcos)[0], 0)) hi0mask = hi0mask.reshape(resdft.shape[0], resdft.shape[1]) if 0 in levs: @@ -264,8 +262,8 @@ def _reconvSFpyr(self, pyr, pind, log_rad, Xrcos, Yrcos, angle, nbands, levs, ba if self.xp.__name__ == 'numpy': lomask = pointOp(nlog_rad, YIrcos, XXrcos[0], XXrcos[1] - XXrcos[0], 0) else: - lomask = cp.array(pointOp(cp.asnumpy(nlog_rad), cp.asnumpy(YIrcos), cp.asnumpy(XXrcos)[0], - cp.asnumpy(XXrcos)[1] - cp.asnumpy(XXrcos)[0], 0)) + lomask = self.xp.array(pointOp(self.xp.asnumpy(nlog_rad), self.xp.asnumpy(YIrcos), self.xp.asnumpy(XXrcos)[0], + self.xp.asnumpy(XXrcos)[1] - self.xp.asnumpy(XXrcos)[0], 0)) resdft = self.xp.zeros(dims).astype('complex128') resdft[lostart[0] - 1:loend[0], lostart[1] - 1:loend[1]] = nresdft * lomask @@ -282,8 +280,8 @@ def _reconvSFpyr(self, pyr, pind, log_rad, Xrcos, Yrcos, angle, nbands, levs, ba if self.xp.__name__ == 'numpy': himask = pointOp(log_rad, Yrcos, XXrcos[0], XXrcos[1] - XXrcos[0], 0) else: - himask = self.xp.array(pointOp(cp.asnumpy(log_rad), cp.asnumpy(Yrcos), cp.asnumpy(XXrcos)[0], - cp.asnumpy(XXrcos)[1] - cp.asnumpy(XXrcos)[0], 0)) + himask = self.xp.array(pointOp(self.xp.asnumpy(log_rad), self.xp.asnumpy(Yrcos), self.xp.asnumpy(XXrcos)[0], + self.xp.asnumpy(XXrcos)[1] - self.xp.asnumpy(XXrcos)[0], 0)) ind = 0 for b in range(nbands): @@ -291,8 +289,8 @@ def _reconvSFpyr(self, pyr, pind, log_rad, Xrcos, Yrcos, angle, nbands, levs, ba if self.xp.__name__ == 'numpy': anglemask = pointOp(angle, Ycosn, Xcosn[0] + np.pi*b/nbands, Xcosn[1] - Xcosn[0], 0) else: - anglemask = cp.asarray(pointOp(cp.asnumpy(angle), cp.asnumpy(Ycosn), cp.asnumpy(Xcosn)[0] + - np.pi * b / nbands, cp.asnumpy(Xcosn)[1] - cp.asnumpy(Xcosn)[0], 0)) + anglemask = self.xp.asarray(pointOp(self.xp.asnumpy(angle), self.xp.asnumpy(Ycosn), self.xp.asnumpy(Xcosn)[0] + + np.pi * b / nbands, self.xp.asnumpy(Xcosn)[1] - self.xp.asnumpy(Xcosn)[0], 0)) band = pyr[ind] banddft = self.xp.fft.fftshift(self.xp.fft.fft2(band)) resdft += (self.xp.power(-1 + 0j, 0.5)) ** (nbands - 1) * banddft * anglemask * himask diff --git a/__pycache__/Gpyr.cpython-35.pyc b/__pycache__/Gpyr.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba11661cf116c8a3767dd5c22ce26666ca918243 GIT binary patch literal 2144 zcmZuy-EJF26h1TiV|!yaY1*U>t=d&3Pz_O}wyHoCpi2EoFHnh;B2+7Awe?Qyb@#`a zU01bb-w=2MUV>X*foI@mZ@AzpuYeHno!PjJqOLRJnKS2n=R4ooajtYao-F=(`L9Rx z7oB-*tRG?&hnOP#2}+1kq8^dpy`)4?DyS#wy+w(nR8mi3Z&Tz@Vo}dBu`VSxr8f0! z61!1@q9*+Wh$bnbV|Y32zTa(~2qf!@%Km0N)%ae?!c;|1lu5F1@x%|Hvqj zOIr&`b4ep`10EI*9V6u*2DR}HE891QrZJSD-QpF;5{)bqj#M>-{@ox#Z_x4RSh8QX zzBGDluZ>ug&G!&B4;)=toFxoiAiO7-utbs-dfg;_Q_L+64O(>ca(PzonNy2!%yBP` zDsA3wE|tm5Y3=-8&yMkbYp^;H#-BXz(*ITTs6YD zMsSyffgQ9Vt^QNYVQCQ0=2d0ESP9oacr;owXBW8z%#{mSSz7DH&duxdIdZ?fDN2ZH zY6Z?!Fp4hmd;RzaTP&7Y7SPwUcY&Il=7l(Aqh)!CqE*fqAuoD$k)q2;Z7n>?el`V| ze%JoRFOuWA0d+OMeJFlo8UKXNp^q+`1e+ACQ*;Gx_F`q}13BL@xN01>jDvSZ7pU_A zU0^-0%iLo@kGAFadDTUEKQ4T&jwZ2Ik#+!i!k2$`_lefIeqccSVwg{o z$bY5$(7*He6c_+IYG)g!H>zLe8X2;Dc~&S8DBf+6<5isH>HW&BzfU+*Wrve8pWQi4 z)eo~QFa1}O7`aeSn8uMmL@i4DM%j-JC$Q9uWYWkvWrrU zE2k(!U7q}hrz?$Ax`iOD`O6s2*_n|M;GEBU`$n$;S}&$!RauG3Drcoq%bvUiuuqYYZIZX1f#CAMZSyb8m zoPBhd4U~2nOuXo}QKm``p`acVdJWcI3%~5oOzSJhw7lmc&!bXTGEOTwEPIeCC}zC| z%ft&S$?sM&$$usNDG>ht_R)ib?+T@hgV6-?Wy5IFKiHf0hoMgQbUuRC#la!^q5{;d z^f*t#GS0JLJiT}SU_9M}IC-8F2mChffOIo}V_XJ72k^xR6N#2s7al&g>_}d1U^JvB z+G0~|$aQ%g)-}T%SxhXCQPx`R5;C(~h5;v@Cq9w12 zmW4Cv$yvv+STcCtZ7?1FXBY&P7X)b@O%h(WgWzZqCiRJtQhx%XdW)xRo>-hS(`USG zVB%3UF}1-9AIn&~uI3wL-U8EneVw=5Idgsn$pAB4)%>#N^EF@U!o#$Nx}bwtlm7#0 C1IvE^ literal 0 HcmV?d00001 diff --git a/__pycache__/JBhelpers.cpython-35.pyc b/__pycache__/JBhelpers.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7d58bea790297e7b0615c7c888f7a48ccf27d4b GIT binary patch literal 20458 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 literal 0 HcmV?d00001 diff --git a/__pycache__/LB2idx.cpython-35.pyc b/__pycache__/LB2idx.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..00f6ad7b4e368639c307dbe5a73696a07b96b6d2 GIT binary patch literal 484 zcmYjM%SyvQ6upy4i?&uuDKze~v>+}N5qu$bD^gJxN}$Bdl%`E5VJ0n&q&t7cU&_{1 ze?eS$Z(7tL=j7binLC|EqsGnmbKL^?gntKPxJH;JlE9C_JHQJH3m&>WurW=ig5ZcA z!sJLfgPc>lbGk(N8%=D``6g(6QP46!0>%Mp9JsGKuH=dc)S0gbCynYspd_C>!cr1g| zcth<^u35gjw9pU-W;LxVUiWqwWO^~3kmoxYqFZP!?sz| h+T$%t*D-t7W##{GnYF56t=PJl#$p!9tI~x`egIV;YS#b& literal 0 HcmV?d00001 diff --git a/__pycache__/Lpyr.cpython-35.pyc b/__pycache__/Lpyr.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a496e723f73531b3b762902f16af25c86370c6df GIT binary patch literal 8830 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 literal 0 HcmV?d00001 diff --git a/__pycache__/SCFpyr.cpython-35.pyc b/__pycache__/SCFpyr.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a8de3279302347364e6ee66bd2c974d3fa07f8a GIT binary patch literal 10414 zcmb`MO>7)Tc7UsUe)um^oDpY8TGU9Qe(04YTh2yaMP6xbt=A45t-R9O)}0iWMHuYd@~T_l1uWvSKZAaEy>!& zk~44W=T*H|ud3c(Ri>uKf8D)M|Bttf`HdO+%TvC_H?)8jAJ24**)*nZjMwr_D`z^M zsZ*dYZ#p@%nKShqebfu4lQ)}rQ_p9(1ye65Zqam#X0vGOMdSUXHDX$$<_m_5n!uQ+ zOhHS|+*%p?+Jo?l7Z+~5*Wa;UQ!zKF7HzW^zSpHR((kpq(NFtQ+?t@Oy6s+_w zPvIKh@b3UjUiXB)a17r$g?SUelrH8A8jG?Ln1>%>gX)NuM}@uCn3l&(YuvOZv`k^r zw5GH?VOoduGi_Qk<_q7{>2fWHO>0(LrcA43T4lwj>j=x7i;K73l?BG8ISQZhx59Uv z@4I}%!i36x*O*mfc0D5npsxjBP7A=i7JvmU0E=2sxWRgTQ<1?VW|t3zQ4@`sjd3Y& zcxGe5JoU`LHBOpc7MwGcR^BYqyaDG0?H^P0QL}LGh=osj~luM@aLvGEG;luqECJ*vW6+M%Lg7D zjcURU{na(tdUmI;omY~1XJraES5#7BD&CE}nGpV*;N^w;babe^ zWOmEx_PCu}FdN5GgqqnsVm6MOr>HmGLQmLTR17-w+IhRPFQ6>qfw@^&m`nLRVYY7< zqmxPm{l)1OWrKin=K8%K6bBXAV>za?qPv7*L2vR~98nb5psJnADU(hMxckXTubMJb zRwgKLKIKZodYRhdfNf_oJ^9rES_Os4fSf6pqElw$wAnZ#H54SO@u}y@@h(SalR+6u zGA2VSGymdXA!TYF%~MP&JMvGZkAhNzru!?Sz$WkK!}?cZ^qmQ1&wQaW(H zk1ETK2?YBGJKvnhB|T7c*@9fj9p%B2+5S&2IXx%`k2CWtZ;%~XX<0kq7MzpV#~21iyQXqXX`US*%D0lO+AAW;$-VpQqCukWg*EgkITS)h(Bs z`V2~$R2`B~Jk0uBV&FEpXeYQ28X1|!l{#!ds<{jh0y9$$fIWQ6A=SfS@)XpFJaAP#A{-{ zWpU~`Y`8ln8U+y) z=9 zd#4}7h4yCSK@j`vQC#TRR$${|^jW(Vt;dD1+2{oEXm?c$VO;FqZ**H>>~HsDzuS)s z4Qm@a;H@{9DBld)ow(QtBbjz|GYHoo*mjE++vq}Jq+y#;qkA#VhmUL&=R3Uz7cEO+ z&1-8>JPHWc+m!N@F2g9KnM|)P4*}+uLIPiDs|cY(znq@5&0R3p#6dT2PDYLHogaWDirZvjR#2$^zy9 zalX~wWbS5U_*6p2xNt{*ig!Mc-#S~@LSA6KzS#&L z#v|)(E!2w?=&9%Utrt2y!SdQ5ZbhL;t?((syKw=|L*(7)tTmWh+UgSt$<+vMm`5k} z?$^hZBW-m>M^WS{v*)D{7a=7pf~2eo#=@w9tJkN zyRijccfGaMynAz}x!$mwH*IetXhz}PHRKVjaw!7a?{yG-ue;jcdGq^s`#U!|!M$E5 zyz8RS^K2uBrrm8vtE-0~5dIUucw_tiXZ$hmh*$G3d6)TJ0?y_xdQ1L-f5w~j&U)YT z-}c`07Df#y=CvbSMr`rCo4%;(G-;+fATB3K*Q<^1yOZ; zTnK}b^YHUM6peRdC8uZ0R>88T0V}?}%uhTbTXbVGtO6I`qaWUkoz8`%KMoM5RA>exUkq{P?1et?`1R0OY ztrh=p>M>)FRz4m4$Lp27jvU}uOM!Q8j&!p(Dd5XJdE zO6hMvNtrm5-5>2j*L6BgnNAYD}T@aI93RsBBB%Dkev~zaTL+oyaZ6=_<`i6 za>AsfU>pLzl8hykNt*c?^8DU{u{LTm;3@mOCc^PGZe2s8AMVNwW$0V`lt#2thbsirCTBA(Tm=`AyA zQF19{gr-f^wO63%N`#DxS;eE1NYk+ky82VDPuP=iupoQDvNS|tQP03)t`w_6{sqn? z9A`1lUYG071PYd{Hfhxyq?5F?Cale9K&w$jlHh?88eQP;*r!S+N)syTlM}}imV!Zq z&vqs=k)v=Zh>KDpz9N*0f`5r4@o3ijAPip2GdQlF!1L82zpnj9yr#ZdJI>L&=wIrF1tqE8ZpqBielr9KZ5Fj?) z>D{7~UKb#W#s0B?;{r|ykR+)+Dc~F+o>;X3mRNJeD`lsw^PS*vXwOS`zTfV)>bVd#q2bK> zTAagwI;gTom7SYA_HUUi6yA+D=KaJgWBf|qA+L-nTf(4~FlVUXnE z9TVmCc$047@{!HKRB#>KXW*Ic8~X?UmEqE&mY8A=q|d>aPUfJA7RCrQ-z3z&lyXAt z%l*_;VwlY)CZq;V8IBpWom+(*chy>A$T{lLin`+H7ttu(c$y`* zH>!-XUhv6mI5k6oJB8ptmzynufC8y5YSpxrNi>%|j9u7=O--?-Rj`@lE;n`5pji`w zC>hFdLAz6@Oh?qHuM8zosbfhl8wJM)9vqEo!Vdi|m;KC63~j1hm=|5;a{H)emuPhv z?UK{cPIAo8GWX@OCpDAqBt&LF(s^m--Eo_BX{ua$GeNpY8nm)lGRdy7pv3x%W@4zz zl+Fp+#PXojhbpWLgTRc8*W<=HkZ~3Bl>8+UbmYlUPUuNKmy1ZDF^cKQULh~}Ve67w zl_p7p&!o{e+;MJPK9ll7BBo?ss;Wr$swx1T*HH$;H3^LaO>zbtJrN7iP_t5g2HU?$ z*=D6LV*Bt*v#q=F42BLieJ9%-91`GU#-}B3peuJJM#{;>6ml*+^RQ^_zvN|!P6|iO z1_{Wl?9z&CG(tfde3-U;X-^ilA>`vjeUap-A zYu#Q{d)(->TeY>Gt%>Td^@*A{1EQYuuD(f#RJ$M4f_AhX*jl6Z#`PLnzrRz{AiTyn zI%;8L+uaAXGq`YP&Od2BkA(R4`)Ig^--pO>j^eAUnRRuRbIAODbJdE3a7;i= z0EQ)ryTypblg`dQRzvFyvs&?GL6andJtg3*0CBp9EcQvMim`UK`&CLSB^U49msT;< z_6Q&@ZZ@_*3?AF2v|JG&CfWW_z*Pa)1pG+AI|AMna2>$wa1ato+aF8Idw}{_Z!1a~ zC14(k*&0;;nQwR-V7y6x##Cxs;akW7y?`;qEN`r~T`>BzPsb-3wzU zy*K^Wy(hD2D7xpHG-dzfPXv~k?|(;fPP13!!Bg$!JpORRCE~iE7lz(q>2+_hPTS@* zaByBOWp&fhnPTenT@iJNS>cvq3vu8P!TkB)_53@J$K%C8$3j92 z_0KZxKWKiO*aF#M?cs&2qVrB9!jaXx=9UY2@O#B-pv;&IuR!G`&&J46jLi|#J*RpJ zE;a5E<>tzmsEkOW-9S(Jvkk(pU}MF^(OKdr8%6R@KDpUhlrwSOzn|H3^MuP==Mz6J~i%bp3FrMsI^t z=)5T2d{}UW2!zt_vU^v$&KrS|bXJ}vlf%lEy2JXb0UTlyrCnf`CRNxa}WV&$l_`3Fq;YeKUIkXUxdS>sJ< zyC+~Tl0GR_HTYuT?Vcsq?5CLXxbP&fz0d{Y>Lk1&m=^`SDd778)X(6FA$ic~_dW~k z%Ca-?8o@UO>wwk1CT(K$?Vb-H4n>_jH)-hBp82mAKh*@j{h46j5^!6<&jow5o21<9 z#jYmV>m%L7>Wg1sKNipv@V5>2ad>(iix0mccmWJt^(;Ae`5AV`W-5DIQ;4-R!ltI=t`Tm#se9YINLd53fJ%4lf2l>j9Yw z&Ai-!O}89z8lC(27gAakur5ISA*%;uZ?Rg^4EG4Va*D$_z$7au=B6J_=92&X?1|Z{ yR&Z8EtZ#GRj$jVSG$Rv_UU5tMp$A4d37GLFy&3+2x&H@To^rJS literal 0 HcmV?d00001 diff --git a/__pycache__/SFpyr.cpython-35.pyc b/__pycache__/SFpyr.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e6a3d69177ddc36d46d8ca16e3754c236f9d6ec9 GIT binary patch literal 9391 zcmbVS%X1q?dhY=SPl6ATAOVPa4D}!hiKax_daPEp*4kRxu5uJ5^hOp}S{lR*$)Q1j z>>1jm3aCm&n?p`1SI*f(PR?HTw3TBnIi)K9!0cr!Iq9}l$!RO8_E2VZ)YBhy1@Mcsit#;CCHErIrs%5JkTdmstxf!*ZQ6ITE<>u8dFeR@%rCwo5 zmZDech1V7o*R9B2**(;+(N~Z0HXMYWrU{)01m0Jq{3lk#-;}&SjMbMFQ?jb66!(DjH)8U$GO27j;JnLh#fsSr7yS)P1DF2 zv8ko*r~M zo`ytwV;X2Ojboe!na{CUL#l^x!NGCWEvYWt0C89-6MO~l1P1u1z=j?If)C6vI;ycn z7_V-CbowBoi^2O;gESnWGY}M(RTr;WHRKMf*bRt<<(tOev{*Q*dM0+TXH2FhuP!VZ z6Vs}chzL%Kb!Sv})a*7qxH-&Q6~bR3Z^p&DDYacmI@Nf`nIQKj)TWY+TuVA<6VYSe zEgBxd%Cg#?W(OOXVTyY&1hFmmCKIjalFoV6os1W_HzlUj)b<4#y{NiV@sP!&I?Dl& z%-LXd$G<}r9Hlkm&{?p80G|9l_$a(wS7r# zUzURd>wE^9EDTPR!z-N8ACD)v2~QaoP4~`=EeODQT1acJs_r@VA$_9UGXcgzjW9{j zCd*}d3DJmy==MY{}|5-gdtB;9s)?&U9lvs4u`YueA}`$fsa63lG<}!YGBmj4XSU zZLc@lZV+Y7;zflmlp3A3-wdL>r07m~5ZSK36F^0%qs#$PYd6X;!|*_AwBQQ@x~3a$ zl=+^|p}ufP0WU@Tqtahsh5zv6!+Xzv8hAQ*zKxC3Xm7du&F4=Jn+)F*-P!h< zVeotdLGsqPo%C*}g-z3Guk9Ybd+Yh`;S(flr_&0aOBJ<<^~$e-(+}6yh9N)r7c|N$ zq{gkWRME0C^A>v6h&7zbS|v~&t7u(J;Vo4p58euV%ZypqQgh&0uqQ1iwPcm7>sA$W zr>%R|XnMgKO;xP<)J&=X{`u4u>q4q#O{5?#HDS$Jlc@>Jy$y|@LPH5s%hpA!V9jE* zV9nrf%BrTE)Me`e=oM(L$Zrwz7cBld!iPDKe!-fzUXB?8_b)qFDOpRYmD<~s-mOA*5)zu&qOE6c?VyT~4Oky_5$QsHY6pXLTxRCBZ!rmqI zloeoFRaaPL*6qi-2*q;l%4u3p>oX+Gp~3!XwdyH-n}naT`J&%6(2MdoQ$FC{`6b?h z5j4u0v~0w$iYScqJx|zx&Qn zRl?EN;-CI6v9dp!{CBM5d2O|%(1+eOZrvgSB+SGdP5@+p3pzCXmVI25sqMGNwaE?M zCUpD_pDWGKto=G4KA1s4bnAP^`gP5!y#%AH_|{P2acSSA}& zg{7NEWh8e$UhgbiUhzOu<1U8c`^%ite`BGujq>#5IHp+?gKo$#0n9i`-P7hnDO@SxE(sm@4B;**_d_uh_jMS`3W8?iL9=azY6t}qDq9+V z*FuNJk1`n6-d*ddAz%(Z#226e(20puO+>vxG=eE04#gWBwBQY*31bo_tfEAmDnR3H zdmuO!AYVj4P6jVYEFwO6$!W7baQ3K@BMty%0x{r8QPUJIc-GN0D1KuaXflmsoQ8BI zGBG9>Vu--~9@kuy{ve`u2Sr}7loJ@>Ly!qndicN$qeGAhT9S{EiBku0G$PIJQ>awS zjLL)x!Hdn41~LJIj2jRO%a0)wWyNCN*dqme{}pf$N_v_m$ix)O6I`^(Tb8yT7VLIZ zS&YdLI+$@3(lQ9ssMAr3VZ4e`9K-l@Yb=f@)wVzwcmsTbVuHmn6qZAo(I1Z|^m$Bi z3_!!!eU^F0eob|&>_Z-kV-z9C6mXe+EL=3A#$p{Ka-`8}oHk!(m0rqF#eR1E>H~GJtM{Brqf-bcJ-1%aMtva$|_I;+=0+ z7zdsJn0I?+wb#o$rL(XGx{$Lxn=GCZNVM1>Ja7)OCXLO(10Ezb>5N1R_RmlkT0~JC zF+HeH&)YRB2Z1paZZp7LzA4CRYVGA`OSCSd0a1Uh0EMWq;v-eHzDc2p2Q4k(+0MVl|JoOc;RVFhSaa#>_=8J`3X2iw_QNxOgC5 zX%6&*dLI*kK=L{VL01@m z?mN7MZ38;P9rHIsarEjEy?Q@-rZ*71MTy=bzgNC|vyw|BGnbnoZbiKpZRnisqQUt`q-V6S&0$k z$}M1~u*=B$o;ACzy0=Bvh5p)@9%4<2x49N^wEm$)Ur$6xg3a}c19eBW0oYyeV?(7B|8^YB6(b_V&b>fS{GIsMpRb~7iCuZELgUk<9jbx$u!^(1xF z%SMdYT@4%}c3(AGK^6uQ05DiI?+GmD`GDfI({Pp^Qs(X<5JCV|0Ph5& z3qs&ro6a0+*15%(%|E6>fR#ZVhVcJU62o=Bd*9U1H57v}=_Hh=SsT9zOUzsT`yBM_$?QfAm(Vl%}?Fv1J$EwZ`6<|dmZ zHp^^g*<5CGh0Rqq@35(|nP)?g5f}lQ_s{^UXdmi#`MSWS&gL4L`VR!Y0Gf%^(vM00 zA)9+>B7%XRdS9&;);s%c_fz1Vt2v-y(#fLpiF=@bL~cS98vhMKY5u1I{hZAUG*MP& z2KoUhKW6g*n-AGMWb+d?kJvn6^Ji>`9Oyr1vw~*TZUYC6a%_pqW#ebscLjFb*Z|HF z!*Hvmq(@j!uW`Bndax87dJ!xoo#oZMP&j5hT*jo;LLy@6sJjdhRM5iJ;be4KG!XSU zqAdySGt!ENUkFb@(9cNCHup6Gsy`>?BQ~FqoZ0f}S)sEZ8s|=eFh%VF(-gqv*O(AY z5hAmy=~8M8u-zqV)XD<(8%<3Ebc_3T7PMJ_ac9Bd$S)u`@RqDIfa%UzchXa*!+%yK z-3R#6XCYyRARZu}%K-AuL*_K*R{#So03w_LfJbQXLArt`b4~;TS-|NysQd@&mw?Bk4;R8y^@QkHJL)D2~gls@Rf-j`8#aK+3aLF+C4xvV?xk z8Ud{Na?HR|M*(|WFA_Ly6K7qEifd~-9e2OQerauOZ@r*mkCj|t3IVkFX~Z%V~dZt|aGte(?E^vr2NjO^&&0?aAJA4=8}(`_Ap^ z>G_G0RRlBLw{P8h?z!ilbMCq4oLj~5@mwPKulIlbQzHK)BYz3hU&A-}E{X;|mUtp9 zk*bK*u%+RMXGzu4zJz$Tv}~!`=mTt0JV#oNR2}o25-%aGgj5seIW1mNT1lxUhqzKw zO)0L7cxh>+rJ6RdS@AN`%1AXcgw0AdtFSroa?;94H8<=Vlj@lEjft0+R$i)kgC{TE zxU?puI$@s2#VbgwAk~6cZ#O2SQIIcy^n$n|&p`Slmw3N2`P>2nDpr*4ZuzxVv+*2{ zvWSLU(7p0j(+gccFi%(aJiWB%>E+$0Osm$rx8>gnF)CH>`2OuSYj@wc)@<}x3)VVM z-)W(iefNzu*Xx=IQk&gdo%WMDr;q~<8uRi6Xh1<4$HCSUQQ|%r8cCh(<=-5>WB9&}Z}1&QHEu^_StPV%$C77I zHCrAh#Q&s(wyZmBM9UmH2$zudgoIe4Lr|*W{oR2H9cWn`l8`y@;IS=!SHhG$6Y1Ns zksJ1v^RW6N57UUzAD!#Z-dkTnunD zZf$3G3D|)^$7HULC8L%{Eupn>)RJ18KrN-U0%~ckO`?{OaGcy(PssX&?4(#ev!xH@ zL#7^4-u#KK{|I<9rR(^zwUd>8PBy+Cci@@a|9y*0o)$a~i6vVx6yR-8q2qS(&*-p! zP&6|D8Y2+21eKjM3DTi?SrwIIA+AhH@1}%DWCzU2%M9dJ1aodbJTHB-rh=?b5tuCF z8Yf4dH;VR>S$7}np5Qcns2-L+Dd9AA6OB;M9jv7!J7W-;)5l!+08>GBCgmm`$TY>Q z&#Ls-_hZ188e*7|o^2VLmDYckJ~%a{)6YnV&#bH;)e>`?)f*KCI6nPZ>HV56ddL~Y z^CjtnV(e3F3z09{vU5}(Vccf`3G3G1{m}l@qj=FTS!=Fi_KP4OAw3i0^b86pA%7$(FE(4XRku=Z24&yf*lhZ4?UX7Bv?kJ)2B;CfU8$=24s#~%B zNv@Yg<(QsK?`?J6$no5Elx%Odx?54Q=KHlR{}@pwyMD7B9>%T6?f_@E7Oq99W`K!Y zKcgdpwHgu9MDyUg-`sYiq+e^Vx>2gu?YixTpCzCJ#8IL}1j$EUr{jad4Ig~+U4z1U zuQG==*LwuU_^V(gmjkZ*M=;)>VlmBPhQ%z3D5LrSenu%AmCI{kWUqz(adxHJE46kb zh^%&GH(TV;aj~oamvb|1ZHLFRl!>+Uu&vs<3`18b&AcEf${|!8R_a|=M zc<|W(#5`Ev48mG_t+82uaBr(l!Qb;c>kvcm;1Ts?8S8ZYZpW*I%}#r{yY>N9GhALi3iQDTD8$NIQ`VfFvl7WEYtqW^`5v{6 zzg@zZNsOGdQdR~K<8}&AC==s$7VY!snbBIxp0~%XNjqoHThmt7K4%}Z&Y}OPwO~!) z>8Q0muGGbp)#C$~JBS-d58OXTC4>Ps=d2}<9r3U5kbudAxv*F>2PEz zP)Yfxh~YGfDAx>{ZK`J7^)IpY0$Y;`2{Uk&P1jgZpG|R#5DwM`c}l=-CD10LThrEA zXvr1m+IB{@0$_D20{^HCG^Rul`~nJc9jbt*)2vgfIBjtR*;1k_@Tv*|Udd?3&?&&l z49BYXk_sFU&=EbWZ$CUG#+89r!l7_sfLv9GBHdV$CHQ6Q>cyY|NZ|I|uOt@rcu@9k zUx}GY)440)AxBr-@Tu#z%U4uN=Nb!@3><6h(mSCt)~{fFQ3kg14Tv%DU(iPa@Yyfp z(O*DONhptLTAx%iC|*~y`lIaM$MQ5s-*umS9(@5#vskCC5;kwjnzK$=1$#ShSZ=`T z4ngq8U$XudzQM1c_~F=27tsjqXUI1)7+ZK(Xgw90;ry^eg+@^Is)u7{fS?Fz)A71r zN&Zj**pBys?x=%%;Go13{vB|`i0d8JUPn=JjMD#j+^|m!{=4X)@&<8hy3%@$Lk3_1V*&vr-I9_4^tp-+xrT@gB%L7{}{ja_Jr#G5Ts5c$v+w&epUOCgwRt6ia0!oU}s+5-&h)I z=zQPOZ~~6KGVp%IS=_a~pjl1nMc_4yFeVcYNf(A-?*`Uo{{|ofxAjSAw_y!XwxIo&b5+pPcI|;Ep94?e% z8XBiFc)%JU8^eDb`>d!pfOVE&CGfdlu@?5C5} z1nc8IMCI$|)YMa3Qw_h(L?COf|#=(0*kQq(ic(Wl=M!h8$`p z)xboANi{GLk!HHXWI0$O(E%Ee2g1sY5KuA;F=WrUW&>W;Yyk5YS>3*f&VgnKR8XM0 z0x_YXc?IO0P}v1Cd5fQo(-VWd0)UX7LI4lNM6N@m*auO_UQH@Lziov`8z2X8M8YZN z6?Un_B)=r47x1JTi3beS!*qR`xPt$*Og7>%n5`}T5t}SlRLGQ-hD_auh-52L0MT`N z-!`b{_yaz`h78&?!f%|AFFLw#MDGLAzijUz9qXGRO}h&~V#SRYfP@AXfD8+Uk1pVw zHd+QU;)681G@L8Dfo@JIKT+AxN~)Y7G3}sl2f8vYMfTSQ{b)jNW(G1Wl7<0n?-JK?`{5a3nnn>3H2?^VR1JaY zr&t?n&JvI>ky}Wb6gV5~CO;<)R|~2|SVK|!hyxmz68~SFf!MTX<&>et6DeDhTP)f+3mY_Ge@VAGBi)CC-5aP>5V98j)c^ zW(VmhtO1Ewq;gJaGPTTns-X*cpSfp}0!ZjCTfn9fU*o)y=7h>Pk5`zX+6@$uG;+(Dh$;W{l^2mcdU$#J>L3_W&-w=% zqIn@rh-hBLKS3grh%=G8L5iuTyfmsq^W;zw9qW^tZ{1_ou;7EnY9uNj0U zq;qQREp_!wNS6qZ`O~1;rxO?@w_U#z_~RV<2^5vNkr?_VwjPp^!i@tu=$x7?R06^Y zq9oZJXpRa|Up2YN)@o`|o2yyht#{gYN!Kt`K?aSDQBs9l%_6&nk?%BmRV4j_``fJL z)kS8)6Hg{(We3~)JUJ!_f#}|r|1}V$w?E?ifY~MFgfx>hS|*s6I%yY>9hibsSg_6` zOOUtDqIO9`*n*R{^2kArYyN7|IgZ*n`?xb_owv^?rZH*?aL8>T-*f`M3&>k#ZQ_`) zW|#qUvep7{oPyJtjU%ym4aij@V|vY~iEambBdjwM!9R*Ei|;LbgP%iGLEEQk2sk8g zs`v=+1*REZ3F^jOioF~jEPrLePhyqe zf_t4`m8Fdjk!itD9K#4sP{GNHak&8$rXR40)>_>-z{hj?HiBm)Pp z`T#iLNW#XySxfEjI3&Y3)0Yw)r%H0Tdf@H`0FW4tLg<*`BRGed;nOhbX==DgnSqPa z`|iFGsfv~~%#*q)MKq#Ba9DAq&M?%#k5Re9l?iuLX3tG44&01k z0yqoWxQiQWz?~gd4s`Tz2GycLO_~qWvXo8nnrqn?lEi#a%RH5Z8IAdFKdkP`W2k9n z)!&OWTwfkoElJw1aS!3!K!Zp3(*No5(^d#q3>*8HX4&6OhVzW*(4s*~`=41I=q_YQ zOL;XlXo3=h$EJzvRznpYS7sq;Zz61%2cvaH1F?5-K^YrZ__Y+d0XU+@bEu*aq-OqC zv5%lXF%r7MzxWtTUWzj58;}(AGeo zLAP0LD}@EX!Nnsy(Do}5mUYO&U~NToQ0GZD+~Cp9-43{}m<8KQ`2~cySS{hl*bEMx zQwZoW`icXaM-$RNrX8nc2a-D$8^ie#=+Y=O@S7>%!WLx=*h;vVhl|fSPQ<9-ZJ&ry zoz%uNvIDRF*!nrrip5hpWoa)c9*7lkIXXBl_Q4F0 z03dZ3z=HI?afpTdY8!w2{b)E-P|CSiNEk}WWwh>l>5c?eoFWChiTk==l~pvfLEm!LpC zvPo`oKBcYLKdU2*k;Rd5mJ272xIS=-AmzOD&r9z&W6@x0Iy=9tR`EQiD{(u*w&_Oa zy&fM@)TO!7d>`z^2eZZp^$bH(G>yW|l!`m&lpVvNAZZs5qfpSkJBjHuGsXvakX>Sg zH=$PQPA;qnaAN&t$)IRXzmCl86CFilwO`fv5Me*e-iNvH1zG=i2r$$AN^#Nnu2)BV z*HjZJ@a|O~0E4iI_ma3?XY;k~6DC%Bqt+;Y=Jmz5-yFW?a0Aifh3E8oaZ%oD2G3tZ z6$uso{l}+#7eA5RUU~lC48vM@(n#yDqH@W^N17A9KuEnkDHB7Y({=;@(^|#bY;DYi zC`3c2YECb-KN~i^z-RVeQ>A!$pz{=gphI8>u!sydaTRWosrLx>fY_X1vt?p4Mrn8@ zz^wuP3Eo0@({zWviRs?wV-9Z&biGdKHCH0L-ip$1`|eh->}$jqCF*X|i^dS);8xac z;~S-(AULf*#+@`KWZ-7PIj7MNb0LWrHDe z!+jFjwI{e;wV5C zjJ#$Qt%~-Qteg0q#d85LSBGr{>j=WglfcWMGH<bCs8}*d=f7-j9V9+6oSk1_G7?aLw|gmYL>cKndHkCZN93p z9OagmTb;(H$9jHwd1JHYnVyl9$8E61Xa3&5%i>)Yi!3y^pgTsjn|sBtv*6v(2&?t( zf>Ei@>lD7t67X#st}x}~KbIfR=kwWoCZEpdzn%qA1d) z-}j#(IeU{Gpar^I9-hm8{`23?IsgC9%#DtYWWt|)>Af!~^^Yp`=c0ZM-|&4DHT+wu zp;S|;ic%KawrW_aX{m~3+Ky`2s%fi=ZQ8DCII8KWieuUt)o@kQRTbB?J=MslW=2&q zrkzy{Pc=PN@k~3X8d=rMsY(v*ysC|;MqX7=G4&Bu8R^%LsLBy_y>>*^3hJvMt)P6R z-p0}ePP<(meQbe=vK6~G+S?kx-i?Gvx>9B+&6-2n!F>L4Mg4b807bE<~_ywpVkV3+U^0=OKNIs`DLYU5Hz z=Y*;qm2y(mrc`ZOeHGFlWzX&MOzbX07O`5TX!tjQ?-;(<@eQBPD7B_kSE-dj1=L&8 zW2?wfT}!=<9$P(dmA=9z>hnEY1!F1#2M&j6D7S~et^ltIunS;E1>i5EP>C|Ci_%kX z+e&|3MOik1fkRl#Q5!i~&r=T^rT-@B;gS&1t}ZXtMMAPeLh^m2Zi<7P5cM-5DhHx6 zLR4O%VwROfTs2ExLEKYT%~d^5pgdOg(r2simX%CRh{3c!v${5!=#z}Dw*(3b^inH< zf6C>&O2BtvfEY$nu$XATqaz7;A}HX!KPIW=Zh_Lf-RyV8A)0wu> zi8?{2ZAuPEvuc)VgqjRgRNz$V#o+MN9BpJ&ZT-C+jU{7CcYkR2^0L0L3~(w5a#^?c zarJ#W8m9?k09Fk8VZvQ(2y}|^c3~l&Dne}cZS}Uw^hVUK37~T@0d@|XpAxVmDtKqV z$e(w1O-`>iEt74PEO^*z8(3km;Ec?f?JqcO9g2O9ko$Nk9L`HoP|pkM(LR{$bm}-w z#IYw6jtwtz-8E<7z&Y5tMi*usclSESWzGqqXuJ<;uN7Tk77*IITI#=xF zA=Z&SSOF+ILe9E!>1LdLRDI|-{78@BB;7gvT3v@xsjAmDn|=_L&efaMHNRY{hb8TI zHtX82U3hE*GIl%7`=8M~j(47YRqK|%Qo1kqQYl<-Z8mD9dw%KS5)fSQFPtw`OAr0k zsHMw~9Zt?^|9%4<7h|`&8MSsUB^Xw#LC}gy_crT5fCInUtk+8G^|f_hm!kD*P&!j9 zHGI$;UWhY7TI_PwIOEsW{4jRI$ZyA)FskaPY-?T+LgJn}sTO|GFLeU$sZ$&W%}wL{ zIC#?d(>M?ApNbvcb6FI(>pQ+w-rR2cvD5H_IMdekAc{xoVLbqk!7BR0NNX3gg6s7v zu6A67D$Z)(w0Nn<4kvl*KI8~V>1wd%>nsPXH)F5bZu>zkc2`^N?eYX9=r`^|D|#)A z?RryB3+iK_`edWrX-w5G=+}YS92kW)X)jPMgSJ$h$c}ur8U=!h;`_Q|;0-}B0Zo$2&w}O@S z_NQOC)84+dt>0|58sQzf0~gxcac%{G^=M^f3h2XkQ79|Vk3DIP+9Q^m;jd?nTLt^G z7TWlg9%l|Po^#HcvX0|BZ_l8A#42EJ!8(c=1#1-j=d7YNkMAVvtSwlRw&@v1oo#+u zAGgn16V|Lf0m$KZ!rB=XTKjaaQt|xbM&S1qe8Wd5BJp5wjKFc3=Pe{Rcz9io5!1_& zgSzQhnEU<~r}Zqk?;TbKSPjNvggZl=p#_{3IN5HO-J7x(%ub+RRd)0Oe)K$wICHk$@IVF87*p0h;A_6d9EhzP+z3`D?#WFP`~ z>O*4xS49AR58~1ua*4f9_Vf!Z_OO);Hk&V#>9;T#atjX_>+7};F<@*KK$PTle8Ydv z8^(+aYKhBoN*p+7lP)NH2IvfaDh$8?IRdmKK+eGRgd+$4asZSOp!ZY+KNseaQS;C( zJgo2?Ix`z?zZZ({xvKLA{Wcn065b#j%KCAN&}{F7iqJMln) zEhBC*t~~g82x}ZQM_72ApbskvZTbZZb>m;5Zs>&j9Kk`uG~wRR8+@5AJsiWW)11C^ zcR{?ktlEHI4DuaSgl|^_u+@3lT243?_ZfU)27urk!UF{{`dtf7Cqfc*ii>#Y!f*sZ zE?6<--mvN2i94uo*pwFdgTK)y6lBm-oVU~c8*nqYQ4bq~M$MSMU>iaJz9uLs+TTe! zjaW=XU?f9Xzt~qthT=jG34~FBE@3r%OGp;uNSFsgFrODsfZV~-40nGjUNGuFgwAme zp$^}Rek+)jCM;`~D^rdKYfJhV~hbE?r zu$&?31Sc}HG+Km_9)?78WC;Lj1}y`Co;kB}vcrbJ#AcXXGbVJjZ<>9W!5X{aCRG>y z@3g|k>_N{7m!dEIAQK@>LD+~CfC&>ZjCc#N5BNeSQUaVXS*s_t2Djo>A}|wqpQU8f~MoThvQMMsbznL8_@@Dq1MHuc4v^+2CAW(eLI_G4a zL=;G}bn~foO?$u`#>P|+`jVraC(xPPkg7AegQ-F`AWap5&;!)XsB53P5oD!jA{52U z6McS$`-UdBPl}fzMaT}vItl$CMd$~I5SrEzf?2F}O4j;FQ!EkqfE_^FOQd-?iE{Ih zM4cbXQs)nrWtzlAA@M085jha9g&$Zi*7|5+o|f59{{q51WJ`TNf8dtd)jix&f1QVo zLo>W}pdUC0xE|#So~GHOdl@!%yL={brpMv=8ISrXYm6FWr`l*}x`jIzlXzER*%I8x zdkBe2O@u@Yo9h9BUB4uOTItKrok!Grcjr^d6#CyEIpfmZ3z`9ugl`hJX}Y9(j$|N$ zYqet!A>w8udi-Cd8nPyD+t&P`(E!}`;)?LHU|eiZ%#V4jFGq34M(f^*jR`6noV zlN3M(0!QeWscK!_){E@_CHA|GI-=>*Y@cDbPYfF%=pJt6Qk}jf% zGdsR+h59Tzawy8PCZ;&Yj%gMqeumD&I3r<{gwZz;J!hk48^2*}H7Z$H3G4b3obxOS z1n{*jeL-r_T7{~6qqZd~TnTq7*#hXS9==J8LgkClMcyBJv$aTs&qipyx88=o$N@J#Ia1ji4;p zdldLnP=Yy+$UceI`*KX zSVK5953g-L3Foc`zeZ2JAKc-z!L)Bnd*8GKh_n0Cxz<%a-vBkkoL>#kILi5(<{Ww^ zIaDGT4$qzTW>jidnSMd;Wtj52vU9vt3jOFDt@eDW(OQ+H%=yy8YGczc?_4RB9w9~N zm*jBb0VM-SBNA!kBi~eFZ+{}wiPciH*>3p5{F_NY_K&#%=zyHm@fej_$Om%zV%amh zo7+^&7MJ~OcBFvxV|&?$d+grU=@E%& zkwi6A$dfdYfru|Iy+~b{+)-Z_r>&ilz78%f4Ya_0$^G~Wz9ElnXacD-BQ@+WR%GMB zzhII8|F_HbO_R~h=&P8aUu1EO#UR~Pw#=cu$4)$Cwr;c@y-M;p&o+%* z@xU5WklO)m=rI@&d%~I#PvDq(-zIYO;Hj{A7zTK;bv%oM#p8+F){mI>!6?%?HnK%F zvIgH{>S61Qb?JVJURDD8hDm+)tNX6ub43 z%N(BM-k0str8vLOo6Nb?4(rYd_Hl;?o3oKD3vE?>HnH zQ55vBkRj1xjfPz8!Jg!EdXsAFhX>ff2yqaJ0iN zk|P*FUcihanSo6s(z^^w5COr|HY7xyPii<1rZ0oO129ri2bgf@d(Lv_JI*p^z|I9N zX;>h2Q-UaEX~?D^%fi$Wf1YGemWQ}(k~ zRFvJ1hv%@=D_(@e2Mowc-evd+tBGMGr^;eB=}O)w!L-FJ`4+p27DQNsY&y=6nMC!3 z!6uMX!tC7c3|CD6upwYI2H2RenCP0gvI8Ul!1DW#CUo*lNbSSSJQwUsFRAZ?VwS6T z*||DAy#6>F9akGC)W%6UB4*Xr?L_~g`&SRr{VBCk>fc6kIgu6UmiG!?>54GEC|m3) zT8q_rBfFd|a+-@+!K*ggPpgeHs)s}ug8iaM&0Jxgyw8DMG_SV4Ih60x-9O|x!J7$J zN$;4PdARG3$qmn2ehxWwTv>qNOCfX9bG?Nj5PSOWz<$8vs*B8#&HDvqcYzi3mmV$e^(Z_TYv=4h}~Y{U&P~Naloka8FdY zj})%16Ul7OzyXI>EzBL(uO}8(gkU5q)jOrO{wS@;-xEb5SH-K?Y(=?n=oC|Tl9Qb; zF7!&Oi+^*`%Wj`$Y7kv%xas0t7Y+>Q8%zaF!v-Xj3?_@1LDNWXy3S;N83|D&<#=m+ zkdMwP;N+`4*arj)r*;JywpW{R_PX}B!xbHS?0TcA z>2#MDlc&{f$)Uy0T9t2wtX3O-?AGdG+dSyyL+scMAoPC$(vow*P+nce;l1(IRUS}xs4*#VEcZ zQ>Y-BAE!_)94X`r-z`=)*0cZu3X?Tckwa%4LtCn_^bWlB{nh=eVO-2?)Fw&_DId78Wu zuQ~Y@QaNOrBbVbmK)8J9uQAh@84Spwd_EHo{{AJA0{+CmUNId%(cd7WqpJQyKmY>@ zh=_N9BH##A#CR0c0q%h6FdhR%!BMEF@i-_3jzPtYCqQv<94c-+2}*zyPzmEHP!gPk zN*YgtQs5L+%6JBp2B)FY#JSYdwLFJ5hg7V-zRNi>N4H~>IQd1bsO&m^?-YzdW`phdcnO=y~g`Nec(Q*KH~$ResDijzwtrP z0C)gu!1xeo5IhJqXnYtn1RjDKGCl$t1`k6G8y^LYfJdN4jE{jv!J|;4#>YWp;4!E% z;}f89@Ho`C@k!7Gcmis|_!MXoJP9>vd>S+bo`RY(J_DKtPeV-`p9Rf;XP{<`&w*ya zvrx0f=RtGeIjA|~3!r)MJk-4LMbH9x0cyec5@->;2(@T@8MFjmf?6_O04;-;p_YxW zfC}IORKfTvXa&3iwPJh?vpMZ|R$56-GPf>jYI)OUDLwpLQllr+m z13dztL7gFDpWyy6?w`Ou#r;#nQ1cSXrm$no?sQ*qg|eEYg7=W`GC+Scvb?Ooqg zNZIw!cfF?cO~0`!q3i2QX^B1e+FdhuP7u1Utgv#Yv+=e`1*iIGL+g9Mz z-|BRt;hjJ1tcG`?x0cSu-dVm3Cib%_n)ukB>?gfT@tw}6zdgUR$+P|7V{Y@kZ?*ev z1a9Hd@6b*Bs6hY6!H)|Pf}}wIBf?J$GJ>oiC&&vr1zmz}L64wU&?o2@3k+KjYD?1+=`NO`v?4&Qd#g<>Eih2$3WkjoBKu(TJ^hXqjGcItla4x zaqYYJb|nmM-slZ&m-Pm>eb3d8gX7lAUUO&f#%o?T{U2PHf}65F?}X*@hSzMRPTS9o beI`Ft!EYMfk^kY{@!xCYBDqL+bUyMAZZZzw literal 0 HcmV?d00001 diff --git a/__pycache__/binomialFilter.cpython-35.pyc b/__pycache__/binomialFilter.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ead7eb9811e336cb3794cfdc32317bbe705b9f4 GIT binary patch literal 694 zcmZ`#&2AGh5FR_bX&R*!Z~?)^#|DXr3UR6UlS(;4BtWRqqRQQMwoZ5LF!n}G)Sk)% z@ES-wkxxjR@(PFp!q;u59heVxeA5zoQ^JPdSqNEL_ zDOE^at_kcqT^d=1UT)38Rtpt2q-%-8PDtYWp?j*(s46i18SonEe?Q#c%icPLE}KzH z(wr1co{g9JiNt!0c1FK;*%W21j;ITTb6ZKTtvQ-6A3V(F%kdK5SX;U5&s1LMifAM1 zXZv3$q37H-1>ghLXMKK$-)19@HwYOf*rjbUXn!*L^%2}8s4cgxUJ2K!5PFYlTQrq= M66fTi`hX4iPu2adUjP6A literal 0 HcmV?d00001 diff --git a/__pycache__/blur.cpython-35.pyc b/__pycache__/blur.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2f46477baa16f8c014eed76c8cfe201e6cc75b8 GIT binary patch literal 2206 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 WjBfR-z6^$u_{I!~Hu24|Ip=@MW$wBF literal 0 HcmV?d00001 diff --git a/__pycache__/clip.cpython-35.pyc b/__pycache__/clip.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb774c5b3b59526b70459283fae118e62f9f92cc GIT binary patch literal 1223 zcmY*Y%Wl+45G{K=lZSW(gwRMV3JIZ%G=!HTp(r3C6rqTl+$aIWV*qu=JsBrrmjd?Qe}H8# z!^F4)N{L>=2`O&S7x;lc-0nn2h@g$WxBfyUYGOUYvX28INA!v4a~-}PlD#@{64HJ| zW|D}QOT zwX*SO72B2P*mh9Kl8?N$&Q5chNZyg|gOrN1L_HHJ3l$^g zBiyBN315c64QfF1i1h5oY~4{4BUT^yWGH!%80%P=-6E69abGAFsnu+A*-r)~?`Svl zj3;zm7M2CyzW!eJoi+<&>a_uDm6kB_ce%uJF07StmmSEAP`i?2IS@tate@-E&F-z& zzl-GBI2n6jvvfnPc&Fqoy~8hbp?14`_r|S7W&?%kr~z{@|I~_Ixir!_$+{=nXv15c z3kS7Aor5c*K@*i14m}x>Nhb}XK_lN4iIMTfQC-*nu?{+`#%Qy2ob6Rn+TjIoDlPgR zLZ#7LxYC)f8mUxOGdGEHRZ|sNURF(Ej3}$w#3sr*q586F)bJqH0#P4^(#TF!MG)Rr zVUoRUjq2f9H~fvvSv2zN?}tmhr&b!<+bevbVO;ckn`M6}OtxwC9$td&4g553QD2%| zr@|##z0J!zi@m(uEX@)kcLx*=Yf<3)m68vPThOz+*`HN?Y4dO_gB9+ zi2k5!&B6Rr4D~Kdgw7}>8eh&CjTuD_MJ{~{91}*Pfp-RP`Z6@prgbqo822&M7eF=9 z3~}h&^xUDfL)xJVpi9pgtzE;n_Gl53_DK6wF`6~Z7W!vjKcMvmRQc3jH>``@N8GVP zQc>km)u70u{zo7>xqA&TxJ&(;n~kH&HJisS$zMn}DFU}eVu#+qc?={YjCGS1-?LZg zS+M`=X<0ojBX*! zin_YQOqE_RbAA8Ac^AZ$L&u(tL1mE*ifhS?^h?%PofP|5)jxT`j!wQ|N9J}Ax4D;- zmvn^sjRu|74?HZgGLVAn(}I^v8DvSMc#ub23O$!Ozs-}F>#10B>opZz1)1QdiJtN# z=WV`ekx+>g5ig|(6O|OXCD}L8d7+1wey1|gTI4(~B%kMr=2|G7f%#IcYf55)oBi}+i2Vc*}#Gz9y#U&u(vnti_7R|Q0F^5G&CnaH&= zN_Y}snuI}mz{9Bsj}bZ?4p$$W=TrTJc*{CR$UKIqn77U*g1mc?o9s(DuXY8sTH_GOSi6}6j+ylz6=2x--RDU)2+ zem>92W!;qGUtbsdwHxHi+KYoHYS0}wKzg{8W4~OQpJysP_5qGoSS&}Y+D)QG?Wonb zWl$YRJ#IX~UBbZxKM=Y7Kg`OSB{iGFgUKT$q?*j;N(cEgnun9aWjGCF zb|{OP2(_BTcpKs|qzYLUX`pe%kIUtUcP3WO!=gylWb>FHZ-`vlS4$7asCzKv_uLz- z!QNzD)?=?Zx10{U$vpQ0={h~EcUhbDF?R61!`@?C>|@qpJxAUG!@!j{@RLnr3}BPE YX8OSD)+bpJ%~NsDydY)H@34;Z4?GQChyVZp literal 0 HcmV?d00001 diff --git a/__pycache__/compareRecon.cpython-35.pyc b/__pycache__/compareRecon.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01ecb88aed5c4b6de4a076258689fa46126c266b GIT binary patch literal 1359 zcmb7C%}*0S6o0cHrIc0^jq-6C4-o5t2+D%&g3@iUqjF_p6}U7p$~>DG zHh{z?uASJwAh$0yKCyiX+xuIvjs4fEQ-`NKOxszY1UKE32TBD!%>x;6B}_+2zQhyF zO+)n1hcOMobp3 z;!P6si%To>+QIJ4amml&aF~k$D#Pj>>*pk_pQ%I|>#IQS3hT>GJL}nE z@L8v=juF-)8rEwEreWPI?b;F!LuwPqP}m9TvLz0zOAu}=-L)=eT8}tY{hb2NE|p88 z_p-keX`ytz*&)ysErJnURdul69Te?2l`dg~Fh%J=I4IY-#Pf&ngVE0&wRq*FIb8L>iVjr33 x-(}C)GApwJ`p8mt)GS6RVG1(ob;HOL7OeUXs1!9C0^3@G}S62z+ZbRJd6MU literal 0 HcmV?d00001 diff --git a/__pycache__/corrDn.cpython-35.pyc b/__pycache__/corrDn.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..22cbc54823aa3572054d34330da80f73072999f1 GIT binary patch literal 1570 zcmb_cPmkL~6n``EzhtuwmAdMd1(Z^R6b?lQ!J(?EilqmnYFXHFAc|zo+OxY(9owB5 z(NTk0ht5Pt#zdgd`(cG54gL?qV8uT{!o2 zC=Dr%HcOw3v!@V4a9t za%8v+UACw!TnGIJfL{dPRsfIn zwJ9qb09>7$v8UeX1>{^WY{$&1KS&*b=)XT4KAQZb!G1EW;a6M$)8u%bTnIHgR^=3D zh@PCe62%RMs?3GS$|A1jUw$>I=ErmOqAYVgNlK-@EgqsCL94pcQGWwLoqg709`Cb0 z-(w$PejnpA-1~eF+I@D19bi0QA^Vs=Sg$ub2Q1|3Lqr+zwm+^(&|RAvG1^f$m`M#F zEJw+`B+YZX^Sl)4^Xya!HMd?R%mpf(q53mvaXN~;*^1&A1(b2DZn+pPPg9p`;sX~q YdOR!BI+sseTHS{L8`kf9!g^rvKLXlREdT%j literal 0 HcmV?d00001 diff --git a/__pycache__/entropy2.cpython-35.pyc b/__pycache__/entropy2.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..adc9df405b03a628f5b6124391657e531af58377 GIT binary patch literal 1131 zcmZ9M&2Aev5P)a@WZ7{pN!vt73(Tz+;Mk1{8)*82Acm0UP+5r7qBaBs^e*LHXO~=% zTsK=tC+AU;LyvtOUVF+b1U+=fNJ3D89Lx-7KF*NXy?6WePDlTH_IC{M4}3C0(x1@M zUy{gZ22cW=lM+G}!5h*8=bZH8_Y?u6)JZqCX%P*c(b8K1fC0D)VBs0Pn*f#pm=G2L zTtz@80bfO+&Q~5{_CC7wXzdEuu2obFH{daeiy+1J|9hUGiD;_2wFy&-wKgibu!+uD&F$8_WX6!)QA}L&flcP6WX2}cqmeeD z>J_(@^aAMwlUqfw$U|DZCD9fukF@FAv8VAc_N%Z`jpBKOhWCjq;6!|#LL@J@Iq*onUiJK^V1FZd!r& WT(a%{P|2(*`A_Z+wfmRshW`N!BOb;8 literal 0 HcmV?d00001 diff --git a/__pycache__/factorial.cpython-35.pyc b/__pycache__/factorial.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ed73a63bd9be66ef1db39a7579ee3c6b24f5d58 GIT binary patch literal 797 zcmY*X&2G~`5T0GzAr16E!%r=7*c-7_wM|hks30U%I1xonduSD@+Bi<^#P(XdYgI<+ zsXPWRz>VkG6B0tAuYfo(>ozD^c|Om6^X<&+*v~gNTMhO1{1*lI2`dZt@D5GAKp5jg zAO*NUhr-x_FX$6X4g&WU70?SU+U23SXdltkZv+jns1x{_fTl2^a6>^JfOcT!E@M*y zHw3N;m%Q_&xTgo0@m-^RO*ah9Rh*#Ri zDo+*^77iTg4M6X%4uyLY;PP{_d{Q$)S90^Y1^H+9qJYa9wgoj$lgr}X}*{7hz zaMfU)56c*vlzFHVkux20&8~!;D~7v_YngQIxUPQ*biX$1BjsLeZP8#KbXIw6)$~bt^I1=@kZ+y{E<)~L? z-#|Xbl7CL$zaE~cNUGtiv}NOQ84mkZ7;~BRrIO(pS#*irM6wVmx5K$Cs#k}@ zqUu-jREQKc%lYjVm3)Y)9W?a}0h&JXX`61*r?gFcvh8$8lh&Gm$_5H*zwT!RwlH9t SN0}IxY4q04N7=vs5&Z|wM7$IL literal 0 HcmV?d00001 diff --git a/__pycache__/histo.cpython-35.pyc b/__pycache__/histo.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5eea9dc8547d3895454c9d647d580429d45e4f2b GIT binary patch literal 2287 zcmZuy+iuiG7#@31$!0?liXb6sHLZ$>+vO|-O+!IY1V|-BB&cD#2uM1 zTpq&L)ZMER(};!q=VrK}%TB|OlP*o7j9>)wHaKDqECisV_=Ij6eCf=v#s;|1%Q{BKgK%tGGL+0CFL;O`@jQ_IP+Vb0mIn$s z8sx!)C=8KRs8zxr3-goMJD>B1kG6Ms*h_s1b(`}Y(wywqr?EM|z|ms$Hs`%G0+J-| zqlUtlfej2yaetIPO$q1UUb?_lCbcjKuTnDpcs!aMRWniqR7GFKy(E1b<>Mlbz0g!7 zJ-^FC0aeOB%d~nICGZOb0(?6#@Nn}o#Yy@+5q>vHrFRU@1pT=0KH3Lum>u<+n#i9# zoi=l3>Iuz{qXD{w@tLXh1n0Oo(}A0|^eEDF96lP8`%){u9VIIDWgJIMe(lnCH*j_` zr47n!6yNHbF3|4v`BSyWpX11Mn*8RaE7zf==@W8@W6ciuvs`rK`uJQY=H2*QkB+m^ z-oe>0(z)S6cY1VCsk&Oe?nPP#n}_su)3hAi_*v*QN;~WDhzCD6Zt_gO$V{Ro!K8p| z=K`+-V|*c>-x(1gJHIad@!;=+54XJ&MJbkPQOR_anxcZTXZ@lgv=)6$=!-I)hoTb3 zN*G-xPKh+jG2T-6EYb(En4g}(GSbS667nwGB*p!%Ri&C6-Kyca zjRV@6GfB2djc(1^QrwNw*1V6{Q?VVcms$VX^>)_Z>gye);=FCKU!<%pRe|&T zCKh)3Yp0HX*{wUDxu@Jy&Z67EdeS-Je&KxXdHZJT-Aa7` literal 0 HcmV?d00001 diff --git a/__pycache__/histoMatch.cpython-35.pyc b/__pycache__/histoMatch.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..77cd4b55caba465a1c5917ede15b0fa3eca70ab6 GIT binary patch literal 1813 zcmZuxU2oeq6up!z+p(P{=sF}>u#W98BnE<{LD79-8#)BVp5g^f3%G`XLXl`&o+Szt z-Ohvjl|*foFq#n!u53mFM!rS9P4D1`!RWMGyTEShd1f?i4IRkz1A6i&Ff~z{gKeEN zS~Aj%rdIBCV`>}b*gZuo;?OtGEn3z{Bf_F-oz6iO>$zce8G;rKv8hhWMuotqECu!@fzqrJ zC|!89ZxU$SBmm&s!IsTjhDIp{@{Jim#6m$cHYo*JcveWa%u`I^!LyA%vW&IFGIn1A zU8Xa_G|6bTSp_ba%cYHL6cDvbb(V#axl&LNezVjz3i?gj-YC|M%;oWHF2S$D;r3$e zycm>`8|0G>#$C$8p^RG~Wyei42FIaY4SLxU@le8&|~5(_UF1=x7D;BSPdrAm08 zyOD2_znusrc#nHB(ryr$SW!Xr)Sd|?`DqZ!$U}x;kAHFS)#v;CL@Ev0wB#oXJwXx( z_*|axR}f{q#}6MJ96s6S{KCf9O5upopC4xoPEGCD3)`%tSALH&?R&&)jK@bjPV2AqWjP)|s z&sv^T3YP{N4=mY3?++Y#sznU*Xy8PJ866F*sGrr$c?|3*>iO_CfyZu>0)5+GY9M{)m0Z?y`sMGxoshz<1BO3(qclz&^G&S;tZwv0YoO g;HB=F!8mgImEjZkvgS9?XFe0(nS)MDW&m3M13}NLa{vGU literal 0 HcmV?d00001 diff --git a/__pycache__/idx2LB.cpython-35.pyc b/__pycache__/idx2LB.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eadea8b901821a214626af5d8b716b95d4e2272d GIT binary patch literal 556 zcmYjOOH0E*5T4y^W6}CRMFlGJ*hv&zqD6R z`3oZGOjK~#nf>Oq^Vs$I`B~R|UcWMcclbvf@d>ioLLu=mNC0jSaF7nXAZBFr+oHk< z=tK@(NDXAdXUHZ+F|D&7IOrviP4H2lVy=LVDTh^jY@K}DAZNiZ00xXQ(6#x@;K}(_ z)+p{tz!VP$O6XB}vS5gSI}W~dv7Ncc1MfZ_tIP{C>BX5;6O={n$v7(FJPUQ{X;qAL z<|S&Zk~-{`Vm0mnEbqq^fr>U@d6IXkFQhitWYF%PKm$!$8`|88G%Wg7L@G|&4eP{m zVjCG2FxJiJbz>dWtRVabdI3{EF3t{vE2Fdt1|w61SznH#pj$@$P^Vp;4^&i`;7*6B z>fr=R5A!6X5qiUNZ$B88-BMrXd13;rwtIfMGc2w918M(e83i~kCfEiOe1$Er7IPVX f0suBYgIA5~UjB(iblB!mn#)n5j%gK!CU5a?U5S7H literal 0 HcmV?d00001 diff --git a/__pycache__/imGradient.cpython-35.pyc b/__pycache__/imGradient.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..31a7fe28b7268ae51e2eafe0da9dbdb5a456e47b GIT binary patch literal 1583 zcmZux&2Jk;6o0$^NMaHiQ4j(l@ro)Ew{Gf?1W2GUs5K>*Dk2FY!BA~Hy45N;Xmn#3pXwZREaYZLV^R!5ia=`fCF#VA91CQcE;oPe((1_cVC{HtCY=u`@fX{ z{(_0+)BOY5rbY*&$AbvqfG$3;0z@9f9vpb!u_CY%d`&u1c(79~pOXdLJNM|UdRe)x zw7w(TPUzMY?K17Vw9Rz_S%4FOGtXH+@WEW2kofSR2>Ly+q%Am%=WfOPCT~puOU_h( z3akvL9>_N)RK!85K3L!Rp;%ub9s=0{92IksHxT(l5t{-w4QwVqrywjjcSj{)6=!|s z!)alJd>+^(U~|A`fj##uWD#uHJtyS604E-t(OHC}sp0*!Gy$M!1^|j|3?SPQoRp#C zQ*GyiZ>cf(IqTPurC;DJ6!BdhFu|o=6mbnX3%RLc1!?7nyWCcB(z6_Gmt#0Yqw3`U zMI3}2dq&6*O{|pdBI8;-46Jy_u_GeOwHY(1#EMuPbA}zIF=)4YIv`>uG;dp>ByvLl zvQ=`)`Bj<;=@2G0md9frHxt|>N-~31p|OEvfo7P9K95jH#`_e|27ZP?Ul>f3kk+6U zVb?w)9C7cDxh4@zJ(5E}^UmGo4w{6wMJL5W)pH(F?2@O*CA(-i$H8olsa#SnMI}vj zDVL5_&F!5UF0Ze@GmyKoDvF1)i$+z#j#e>lNxKkH>av4dd2P3~YIEZXoD-~G5cCp8 zwV_%Ls*KC^n{UOh(y_c%Nk&okFk-d7e^ zs~fB9Z{Jv}zgxo(6D=Ynj}swnNh(RATvr+OfqFyTjDo}MRPQPknPH3*7Tc-qQsc?S z;$e!Ps6*VRV!LGPH<#BCwfhj9yYI>I>wAW#ZR6>oCCO-Rk6&BJ2Y3Mk9rj`xYNYND zIub-W=a^+m+8gb`NQd>`e?F*u{J0TT9`FCL`S&l4@U*e^<@Z~EHqPmb2H}rCef6(* z>4!!*y;;6~@4H_cAxZN!Qau@|o>Zr^Ld0cOqPj?%6^zwcN%rC-%}RmRL7Gj`&~}4_ z>jF_^-fnd&D^jE;E9GHlzK9R}FvgXWm_sKb@9z^+TbU#T~)>=tAYC!Aag%po0Ja literal 0 HcmV?d00001 diff --git a/__pycache__/imStats.cpython-35.pyc b/__pycache__/imStats.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f047cab3d3c7ab218dbf53f179619a6eddf76b0 GIT binary patch literal 1794 zcmZ`(&2A$_5U!pd+wnTtWLaf_J#qL@p!@QU*;1jOHFB4x|n=o!Q)n#D&y_ri=3eL`C=+u^y2$ zg3=8#!s!h|88B0jVb&E#sCmOs(!YN>kou@iUi6f4_&C1Cq0TTa4KM+?W<+=CfaIW2 zcW8xSXpN=av-T!v2YN1n5b+MW^*p!+s7SOR(*GZ1!6N@$hg83=SiC!&h*{6+f&9zb zi);7%jm_hvKcs$p%0T-tVT5QoFvTC{f=Lu8iKz#=IJZvG&9{M-tlS_-uMC#}@)@Hd z+=FQWvOS1q4i$@Clm)?$5%CaxC2Z3WrjMo=_V(>L;`WmgV0*oF?ZR}!hFl>x z8y-gWM#x(fGGZnhi%6+og8ShXHX}b5{ak7ur(sv{{WR1vz6!X~p^lY~+v=dq=g$up zBIE5aNkqi+jE7vsSvL`L=<&&6jmsHX8fP`0hF2&=h^o?&7}ofLDa;~H?VhW6J->dP z&!`pOM{-V}inl_RO8j?`MAdU30A+(s~uDubOe}lszh+RL`8_6+Ua=b*fzlO-0yNCMYZ#MTz!*s zPWH|GIB6Q}7&j4_@%u8)wDGe++8>!htf&yi#e}4b$rz8iLwcn8ojB{{rV!oenpM*67?h0{%C0iyjm6EJw*Y<2dvCIRYx15S{gI(h}&UDU{MmSmM%1D2G;DDuk#|)dQjm6p%oXDktkSyII>?+Z&N8 zJ;9&hS8(J%_{u4FPKX0zleDR|JD!>M{AT>Ixwh7*o4=oa6M$c^G%$vj_?sOxDSied(05md z=KreGu*K%~RSfd&GAm!b&GK;!&23-j&Mjgi5I3&%a!h#UCTdP&Jhhd}pY)W8vfy-7 zX{$_T=tTeQ8trdZ884 z$E-327oe0uLa(x!k`ycLx3AZ~IXXO{yQ=gMD_WGvlzu#Xx117e#Hk%}+E=2iEDI_F zW-QlOQsWiF<>Mo*l|G=EM8>=yUrFsG-rj2S>a93xFp0;=8{aX^H$;#rq7KdLb_<|V$IEW(DzaNPv_M^ z_k-cubo0tsCWmR&?{+5rA=9FxRnGg?bO)LVeumY#E>#hBc2-XIpLNSgXQJOLRhX{7 zpS?DAQwyGN-#kJCwe_e$)}tm_*sbU(c@njW-bA!TbOWd0hmMxa0|eaabD`3z;4l2C J7=J$Z$Un?o+&BOL literal 0 HcmV?d00001 diff --git a/__pycache__/maxPyrHt.cpython-35.pyc b/__pycache__/maxPyrHt.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eea28afdc51cc73858108d9cc48b5677759f7fb7 GIT binary patch literal 1135 zcmZuw%}x|S5bo~%0oNrV#Dt(8I`P6@I7qypF(h!%gN6h+NH!s}Gd;V#%%9youCoCT z;5+yXz5s844>4CyJc7o9U(GJ;g7!>Rx~i+buc~@xb!n;9w0}Mfml^xX=9a*I8)BbA z1$a4&7(2p7u%O1iV$aFB->F|Cg1z@CgH{dFgzP|U9bU)SDKuvng0-!zY<^>#O*%Z~ z?1V8hst}W1<^*{!z#!O(VCIlau&u!k1v>*AB7k@sF(Pv=0tEB4=JFoxB_RR_S!aB% zgm;{pO1=>@B2Jpj{JJ5h8U$N=G)W^e;;cOXfjGELn-qoy?OQ(WW12Yg0cG02KRz7M za3+=A?dqJ9JsajZ;lrl*bL!+wu;k0VQC!_iy5i`;)tIZZVWTR##-3oZz`>2J62wbt z^G*oe#UyN&hC-)4+|exiRM1y4{vmhLILn=qvG-ZWc`UQSc(D%TKe%Zm=_P>-b>x(hR*#k4Xvyi?&y=r2?R!yFY)LmzGRfl};?hw1sWH2WOfzLXr_;pZ z+;h_R64_JIs*kx!oTkiMID~>bR)HK1z;5%N_2MkjNniE~>B-RZ9clyk^9^Y@zUymJ zeF&}XPP1%js}t+I#8+j*GC^0L_Mi`~3>C}$uI=17ZCN*fs zWpgrv@65D-_~U6X zzUXEJC=b#!vfUf{4a}N;O8PnN78Gkp-sTHpg)ei+g5*s+@IY4ZVAojZ>%1-~?g5wl pnRv`sc}r9{9bpy#Qthjf=hQf&q5FJt^rKoWO7*3=DMzKW?v06KE925nNeg#I5`r;aPf;z5>U?Z-iwaF#3 zy9_KtIi&-s zw+fTu2`D2vh7(fSqJQ8Aym>f?E`XrD5nCQ@%ns%wO!q1v@8?q<)2< z4`>b>((91i0XtX%ije7(Z*e&+1NK^tmqv8>i7_T-e9}xfjYC4%M|2W5HX+|8-{JU2R7^dHg(y68$UtT2z53OfsydE6`)(QAYy1CWx?9KBEIv_*Cn%ux?jyS&-&rBK3Cv*t=+W+otfsDSyGgp$R6&|G!>3gD>h< zrcB+{P8;W?8L2w<75Z4mrPapQv8nQMR(EpcrW32vI+oVTSsi8CA<7L?bz9mIlDFy* z&1%q;ERIFo~R-@tm zY&4ZN-?zmHz5zEJb3dLzm9l)h9$(9|a(4fRVL98M*~dkZxnX|V^yCgSw?FtT6mZ}1 z$&=-v8{7zPgk8L&csW=KlaTFdbT9a^i7bcLgKtB73+O>;`M;y_8WHhGZmZ{f;`Yij37va)Q(`KK%)op^;a%577dgq^bjinJBKRsKPmB_8kaEGh zEYWOID7N6L&|C2~W9vv)*;dLYNtGGQ<3@~R>8d7n&VC(sR8^El6f((Hsn;xzK+Far zFXWhKndq{c*Y4dxn*Q9(3dzbs8Fnyd`^5o!QB-o;Wp}RKxD9}^Kg8nZ|KGym(}_^p zpr~n;b7>eRrTCAPP&`%kKV95?50F=YA7F~iye=5exC=8?iOFI%*rSk!Pq{j_;m3g$ zA;c6fuD`!MQRqQ@p$;-G>qe;%QiuGFFm+pCyV@j}Kpj|f!%^1_S>@%t4&YUmGj7%) ziq^HS7sJ*pQ5c#S55pucv)V6bb+lS;9Vo7UC$)i?e|~s)fAqcPN{jFx&XNDVyyAc1tB(;A2daaQYttEA@#n-x@Yb!b@*=G={*7I|wiz#Z HANv0RJg`sV literal 0 HcmV?d00001 diff --git a/__pycache__/mkDisc.cpython-35.pyc b/__pycache__/mkDisc.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5bf9dc362c026b466ec49e587378a6ef655a5cc GIT binary patch literal 1880 zcma)6&2k$>5bphvWN&P20#ykKhpCVP3xrJ)5(34KQzQfzBr$dZu_7w9){dmHc4x%Q zY!bO_F5%7-@Bq9EPq0@`=ERxez&9gXc5-4@+uJ?U{q@&9tvxe8pVZC2Tl)>7Kk393 zLSMyW9ztaJ1(XxDr+Pr`fU=OXi1Lt%klG;y&WbjW7u`d8uSZr zY7TI-IdcGXx_b~nHiIfEh8uX*byu0MB(%mz32E<*y3WmAvv@$2ZsRe3AEAqf4DgWTBH6kFL)tj-c3vPa4x6`V`TAo$L(l zp&#hVEbSz;Q>P)3{x#UciGhrJf#RWcb`J%HGz{qVGl-RU$)0lISbNd2A3FFBDrnID z4B0tykx12;z~SYlXX|#fwopi`q$}VKW3@>To-reKd5fin^^~51>~gKlQWJrbtZXUcy|m1&BPHaL3u>->*nA06 zr;RpQ~Iv8E=|FS`=$BDFiv*gRfyy&xbt;YUiG@L{GQK>;at%LO z#iI{emwrS6163k&+jal)`%ie+D$Tk|+Ehp(`;Pq-0)Kbz@W<>)nwOjj7#RX(##Cv& zepD=~JU-l8I2X1l3MIQd&qa$}Tlx6fGFu+UVjrzsx(WpC zK0Ukd{{MN}J=YW3SeEL3S)khtUC{ieQfQuO_to6J{*psc!rd2dpDM<4?!#<3$~i+L zQi&oh?{nQpG_J+f1BY{H{r$zELaPT6mJecxX6RFS^38=R%DJp+BMqD?=Ffz!5@FCe zo1z<49(mNGd5My%T;P03yC>*;JW7aYqBgxGoKbJD|7z28zGZG%ms77qPxTY0QQi<-v9sr literal 0 HcmV?d00001 diff --git a/__pycache__/mkFract.cpython-35.pyc b/__pycache__/mkFract.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81510f4c7f96f616b4bb6ec344aeed9329dbe69a GIT binary patch literal 1645 zcmY*Z&2Jk;6o30+C*CwPgi0Zbpu@)@i&BReQi&))piLo%(kKq7F@|Wep0&r`o!QQe z+d6ViLHrH;3miCdLY%pCK`aLjoN`0zt>VC&^+%JD=gph{~bLm z0sI4(hKu?RPQ8tyg+B)pfCefqv^+>0NF8W6;Mlzni3_O<4Hx$%XqDkR#CkTU9?o1K z1AKAepbVYdOM3^n_>ZZoMb=}-EKbY-KEtV>A<_U00nQyu(Q`rF1cSP3EsppBjBDNK zTQ(k?yP!WGM_7}M@`|YA32F?ET{v?D+t5i6))0V_1cok6Y@DQ*9wvu7`pK4+^`Jiqtj+=CPS0~Y~wQY z;Ra@4PsN<(?S7P#dCBVC>vr2+fOG8IEcAR(zd81vD%S3Z)gtocNfdxafsMNUj-q!cB){@(EK!XGo+F(6T3)fj!oA z*pw=kD%~O*>+!d%o40E3+&lQ>&f)Rhz58L6kiC?)8NuhwsfZZi8tGL^6Mo8C#7MGH zeYZL#nnvPDG3_Ttk0DdUE>n`!c`A`CN%$JMz5c=ND%qFHjQI8krXvM88IS{cLXKo# zwAaYy`o{a!U`lfM;O>Jh@)c7&9$+EVpuogzQ=<;k*kjRR$%&H2<{@mklNL?8{UYg6 zKZ|=QXi}*dVR6hO&V+db-OB#CPv72EN~$fwMblpX^;LcX_OU;yScKbH#POBd^_Xkmjs&rq;E H)`I&#TGo%^ literal 0 HcmV?d00001 diff --git a/__pycache__/mkGaussian.cpython-35.pyc b/__pycache__/mkGaussian.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ed2defc9058f717113d53bb0c5772d86b86169f GIT binary patch literal 2453 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 utp}fn{dgEW3O@1PXZ`eUg?|GugBm3O literal 0 HcmV?d00001 diff --git a/__pycache__/mkRamp.cpython-35.pyc b/__pycache__/mkRamp.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1c4239d78b1d0bff77be5fa2cfb908bc33e9492 GIT binary patch literal 1617 zcmb7E-EJF26h8aszr-zSBP9h1M&ia6ZiriuDg>w~M3n_fLXwI$aaB!s$Mz(S3y^ZXx`q}ZK z{tnwBdI)DB$X^|Kh~z$qiVcIx0#tFJKOCrnpumAbKxF}{I?&$^R7FtumML5U)f{Nm zv$fO^6oJ?RU9tJw+OXIS+mkwcaBak#mW;N>2&Nde3a2%g`nImMOZ1T^>SbOTOT zU|Mm?D(EKYTP_Y#qSx%5Mz+ECHrA#yhh-e*^9~Nr8*A9pJ|wd zVA{aBH|Xy;T#}s~(5z@3_KtTtl;gZt+!*17DET%v=DX-egS zD$a$bTyQZY3bRR>vSgGuWw}iBo2?^Ci zkJxpamhR?UEyXX`C*Ag^4?5(eOS&&Gk+QJyQ#R1;P4Z2el2_%7X27M=gvw!w9kmLZ z^W=qX2Th5@0m4Q1e~<9u{Tu9D5y^fkxn#+e<9u`jkd>IsD?4lbIwve;E-78&sN6&a z;X<<^lUMdn=qj)xL@~r|*W>nW6QoR-sE~*>AscgT8eDOqG!-#3fi*{t(L{qZrwGFD zYGi^qS0+H9iA0$d6I08W8Vw~+Ohl!m6BDLfp|7N3$l5C=#HK0Zs|!<4up;;Em`J60 z!A#wzDPvY>Q^_SCa&a7vxrmR$2}%=sLb|deu`mKe}Hc6r3+EyDYa92Sxg>&-Y+Km6M2;9sp`*$wTX39W~yzI zdSshazvDIVY5EQCwtMgt-obOlzbUuEyWU-Y)BDW7l5T85$N$l7Slmd;AU_^z8B{!i#EiF*gDha_VP0}P)n_yIJd~17?yIps8 zoyL~)1dlxNB@i!s8Q$)N2cGf`5JHIAjqN1;0}^+>xw)O0-_CDl?)-MST%0g}ZGTt< z_#Mt1A?bJMGB-&?^a~&c*cs~q>;w>n5M>|^Aqin8gdoa7l!NcdFXI9>EBRxJhSlSM zWF<)R$^HgQIt{nzj!C*`V_2cfNZQf@3;@0(o^a@zN3#|lB%Q&0YvSTfGqERY& zugQB3BbtDjqX29M1|-Ql1g)G-zh($zl2=AnLI}b9==Yj@4$T1&S{`Ny#O7VBgL)K1 z1+WvaHwl-9_IHlL^Z92%|K@`ON+km_?~)?rlw=Y1$tfE+gd#a*y;B}YIdz)yP8IJo zMNYX9QtpgX$vdrjrxH2k;pyK&R0dMyPd?EC>=j2;sE97vDcCEGmR!AtL>yV-crH_F z2W9$;$9HsIn&}ChU&nM_n&}ChKgM(@K`M;Tbl{bJD(`$apb}7d%V00~u2CC87*MBt z<1Zaefcy+z<>Y{f4-vWSRN~{*7PZa~i;Esi(0E>8KhV%&?LOYdWPejgKD$}lS+3&x z@HF97wIw|iNNX=trDH*hCSo8C+ zb2wZcV-2y5i?D5u4K6L$j;MPQ32X7WB97f_(ytp%#fh+~bW%mv92CY?W>`=c-qieQ zm&=BrvW+;;`?^%-ietQGt`%;IM9Bt^V^PH$^S5ry;d;-usa*$L`?l@&a6|3lw(81O z6+fB3cAbbEyYFuQ*8d*HeqlI_O82YhQ2t}u`q&iOShUX+GTrLZa9LunIXcQh^GLhY zwEL3xZ=U#${4nWK6$DQL0$>XdOITHN|sVo|9 zE7NHv<}%H7G=-#Dekg2O6f~N~GAd`9amzUmo#vXcV)P`tNvD^F9g*f^Az9o?vyz&a zX6bEdr#VKE3u%ThwA-~ZnPw?-lZK|B7DgTIrGAOegDF?Gc!%H#JN66GvZnl$&EE zpLBX3U$1w1>pi`tRBY-eeVQW<^ats_Larociv+xWF(?kta##$e{Yfj~Oz>uSF(`-m z;CWdH-wNJ;(UvU*AB2~KE1^chtz`8y-SityxT^S7&+CkMj|}PL=ZT8CG5^A~-sDM? Jf>Q8W_z!1@^aTI_ literal 0 HcmV?d00001 diff --git a/__pycache__/mkSquare.cpython-35.pyc b/__pycache__/mkSquare.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3f2c47376ee18dcbc22a037df884fb09180ee443 GIT binary patch literal 2680 zcmb_d+in{-5S_i~V%bVuBNrP1QuYc9knO}l(l%&=1h$h1X=2xM5L|5a{BL`xgx;t zaOU#SzK@UI#wNm_2QffxWP4EaAo3v!Aod~gq2_~U`ys>uBmvZdem?_o2uTRF5c^q( za_}SaWGrE|ls`pwcy{VxTk_IuaW2cYTw8Ks*4uT9wAUm)d3+w>qn`%= z2A~J<2E*~-06;wg<3hs`&su?iPCe}~NyAX^sZki=xIuci9gizdM2U_TF+2J_cW{I}x|LH*{OJq#rP z;S@t-oMZtG5EOcrp@5*!fwF+c7&PfXB?p>BP-e)KIRlzv}d# ztR<%Tr(4%*ac-J@EvEgU7U!nf*W$JVSuM^@v#&+Xfvgso#dY}aG<#T^A{+#ue)Y`- zw@t9_KJ+qRr!YOtYu1{Wo;B?@K>ghYK<%#0p5#Fgc*pk**6}TfL2+|V-|=`agh_mw z$QZybN;d%~1u)ZKK7d|+KyY`l>?}o3B=CYh|*rwpm$UEtA#C=Gw|uW&K&1Jb1eCZDs5Es-1oOpo)L% zo0UfuoY{I&S>1YEDv)z7sYb)+t@Chm?YsA;9x<)Rq}?%$P?Aui_z{r}67hry&7~kV z12Rv^_d8_!2eQ2In$?X|Wg-F!s7pS{#w}YcyO_TL;r(q|St4%BE_2JfTgt zNCt%@y3Ojm!BL7s9+}pN3(<;l&7uW-b92E6i<(w1;YjwVa@twKro!-0(s3#yl7x%- z<#L-TE~BMerD3R}`AVNnGptNR8d4=?Vs{DQ+LmQdO&fVbu~!`?>Ne1!+Dony1JV)a z8dH)~c_Kxf#W63FJ4;{PStJ`>)574}QW>(>C7W`O?8uI2mdO`OH*fbf9C2)|udd%E z52A=f9n&TCZaub=o!YPH@yh>je2ymu$49E;JMZwl=P@}Z4X(5y=1>xaD!W|t!@FUHdOf}KlUiVJ}Y)?bm zWUx8T32BIC<}{1F0V;pLG?NA~6KSTckRT1&5jSap;|9`(VnNct4rkm#X{HfNiapUu z+TGM|^EAK>lV)QsXxvOgf%_p1@zl4{3`O^4Wn)k_24!PN1G=Y6lWB-)>D1T9>BMlG zbkm6lC8!&GN2C+>taHA$pr?|*p z)s?%u&oxtecOONgq7`-OyBpnli>hQp$$eZz?=}=o*h{OKYD;@urFhxy-nzZp?rwC| zmXxvH9hP|!lg$r1Ib1@wuz|}nUSV(-{epMV-8kaUd6)eeujpsJ^V^U7E8fTdg18<| zAyf8P7hSD)irrL3C4KXuhMZ;R^YUFK(+&k&d9zfNS-iP=57qjUkADR0V~ HwzvNeHezlG literal 0 HcmV?d00001 diff --git a/__pycache__/mkZonePlate.cpython-35.pyc b/__pycache__/mkZonePlate.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c767fe2167a21e8fa00f547a260ef6e702a07623 GIT binary patch literal 1147 zcmaJ>-A>d%6h6~-7hE73f)X_`C+G#M8xRSgM2*A{C5qXIny_vpWjnh&Y}=_b)5vZX zZ}c^M0H47-AEUQk@d`#0&kPYZUO4TXesj)ue&%%A*{P|@nEtiAA0D1waFD`gM!97UJHYb5IQrVHdJ5rfQz9TUpFeF|X4#u1u2XoGr zLdmY0ibYY`Rxva5VV0CLM*$22YSmb{MqR?KZG3=9uOU-jk3+-fceWavHQd;)Kd)i^ z>Bi1xwSqL9uwXmvaSU;8KpvP`mpK$k*x~D^6ic%K@FupTo=5fW4&E9KW(juKT&OeN z5^cdXnl8sAG)f$z76V?xP-9yv9B@TpstY4kSZ|kNKH}{#j}7f&sfuA5o#eq0{cX}K zjxsYsreVBLIW2UP0^^QIWZL3!ENZyAcyE=`)cd9@Q_Q3?xZlT@avyhPo_1=uwz#xH z1Z5A{;M)KDHn`FjN*hYv$rGL$6dDzOp9{q!WzYEF?mvViC;Gl^ulXR6$K1J@Jd3G( zMY}_h8s6dR*t%CI3P0v)QOXpli+~>rQ&fZ&sWu_)sPL`2^MLyVtq9!LZj`s0^?s`xs-&*u z0dE=IY^yNgd$vB6NjetP>%FYMywc42^}c!~WvrVc{aT=6CPvou4*-3G1WZn|3SCoP zg`Ia7t%7M9`lFxjcJ=@l3nor0KqsG A7ytkO literal 0 HcmV?d00001 diff --git a/__pycache__/modulateFlip.cpython-35.pyc b/__pycache__/modulateFlip.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21d073e62fa1fb3432afe81b8a7bd6c37ca69f1b GIT binary patch literal 1219 zcmY*Y+iuf95FOu|Hk20vYO8|S7t};5;Uhm3#n2G zsl4zH`~Z)90srAwp85+231%GA%gSEQ&N*{tW_LYz`gFZ!{=EL?1N?$x!$tc(zUDkm zF+L8Y039@3h&}j%wnNVKmVbZ@coES|W2$-|z!OaRMC8gYr~n+F~&7R88buKh^r)DW*-v~B}^EW zAeQo&0Gn`1v7^$QG8~C1TuW|RZN@edjKL?AjDNCR8YD8+D`S-weIdh?#k?n^APs`B zqa|}F*5vJedzl%|*}51i8Syj~x37}6#;tJWIAHk990;fK0!IzdW@RJdlh^}ZrwfSEIJM6ywfb#vrfak$C1ZsFEug literal 0 HcmV?d00001 diff --git a/__pycache__/namedFilter.cpython-35.pyc b/__pycache__/namedFilter.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f1206573c97ff416e5a97064c35a75f5e5b47f2 GIT binary patch literal 3951 zcma)94~!Jm8GrllxH~umiw7tnuYlO&cGugx*w_*qN&3BScJ>AW z#Ld0meDmh}e((GD-ptLctE-)4ef8k?ZXx7f#PK2aw<|KvY6BLWT$lNI@cn zh#DY60aBKOWC$k1M2e7IpcLW?>4vKD0GKxfN>ek6ZfJ_A-lwRxY>vY$8OZX7{Kpr& z6-GAH z-;A9BqF)Meh6ov}Cgu~wj*!tRBCRA0bSEKJ`{et%%p%;F+a5yO8niv{+18@|D#U)o zI>f0yc>v|rh^WtMJkHI?c?)u;0%dU=kYY}fltoO-jlm`)Aeb;s!pJ8?0 zT3-Zt>@#t#mjhSj%+13rWLS@QJK`NabZ0i;3~I9KN?M;q>N!X~H+UWD2heOT;)94o zh~Gq<=RgTynN6uIxe%9}k4qlB-jWN@_&bQ35br|Vj3^>5LTvP*JCnhg zETU^Ap)4aJGn-a%WnX|NHj1vC4VH@-Lsdi;AGIwV?-MA7hdh+K-k2?`dflwcOI zClP4{r>KWS1?*}f#rV_mp4x#&K)OK{_eBVyX+x8#WsABbni5U)&=EY3=$LHkvTDWY zU{1DVDw?2`6;)ZHRw0|Cc22YbWW}VlwESDu9McU`ql!fn@uu3!Jf3s|o|b!!QSbbt zSwkKfQL>7x+uq{F2sKPeHt9etQK89+qIoq5r7_wknkL;QZk1KpuBdL&M%tqkFwyK@ z+PG@EsA;loDp|UwAWEia7a*v9#WW3*x~H&3H?A~tx@8-Bd(%S|I!P>KfQVmO+)FFa z^}wy1%_*|wtxq>j%(b^q*n=aB(T}9-O$&ta_1vkraBbl3{l>JS8G2S$RizyQp14c; zy!VF$%dVt7)C)37=XH5G9}zW0EmBFg6sAL&M<6Q&sJx<2RQMV%woIf^bJJLEo{XrE zS@WVaWg6KyUD4f@PN$+bq{-)Lb21TYPPRsABH7*)uS9)yKEe4FzN~}ut4%v+@SYP@ znh`Ci1awZ;(DGu|hFB^**Z57Lhx2*Ev?0uL>u_(o4NWWPahl?N(Us4uaoR81xhUOg zfY{m`y)hqzkZelElF2pW9mw7+G6hp_g`wdA}6`j#R*fY8UM+sdk z^BU0ki6(!^C-MbN4EeeyVMx|X`)C*NS%wZ>kS=7tR?eU^B=7(#?O6;~vKXb=oS26X zF$zs6OL5#Hbi+-;q#F!Ff`s3%7Pf&|S5}l{4bGNSA)_i*PB!5g9WcyousfkFUA!@p zO*iQw3Qd$~ZHdJa$>un8>^L0HWS|tmgL0gI5e|j<$=w+J`mVvg|3!m$3AfvZfD!aBLDtT@-cyRywn+5S`X{Z-!%QUx;K9% zu!YVA?fs2s%Ih_=?^=8J>{@IH?D4lUouBd~cj!Nld35rNGeV>9;u;;_J;Rc8F> zzdwCVU=1Ihla~JHfg3$4ihe9k?xzz$EE_C?hI#Qyk! zbk*gz!I$p62QPm<|A@d&v>l7|*FYTAFFd!Q@vYO~HGij={G)p)f`>dib*69msZUM| ztR;N@?+EPEb59=K`NSU~0(=p$J@2IS;>z~~R=jiPf~kKW7uYNB zUYfjLKP9kr=JDONeMbfM`_8(<+s{BKTg1EXiP!8e8@IAG+UJWRJO3=O&QkA%$k~qt zmKa}pD%x~jV8_4w;LA5(f(U+h`S_8emre+**_3C0^wbLio3l1|qW0vA0z2~LYfUo` z?G}crm{_o^#SB7#->X7d_^T(p@2RwupPUu8-`>k#c^&j#5l(scZLf=(+(GZOyxwvq zgmMo#UJv<%%A<1gI9{tbUaR?|e9j|^2L_L!}(&WXbu{NY7KL8$^EQ} zgA0>=_xxb7IsnM*Zv~=(DS;*!eK0n|SPg^0coaq>j72coVB8C1DU3vLYM?e~egmu< o!WgPq4YE0z1E0k>e8B&YEmbek45^^X%lKxqssN?|*OcJ@0SzBfz5oCK literal 0 HcmV?d00001 diff --git a/__pycache__/nextSz.cpython-35.pyc b/__pycache__/nextSz.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..758a13bd3ecb4dc24b6d04710733b5fe2a9b228c GIT binary patch literal 520 zcmY*V!AiqG5S>k8Qwx=%2kk}T&0GW#5k#a=@Fb-YMJ$05lC9k~P2%nbl9HaZ7r(-* zzm%(|{(=ZP8wGW;`{uow?8|Jno6UwPKJH!!z#IGt4S5H*Xdwi+2s{A{kZ9o8y07{w zjGx`bES?bxqTX#|l9hNwt-(%vY5+g1x;g~73|Q*WUSM|(7MeP<&>_2k0(lLl8t^3) z`mf0pstQrXb^)OLGUcZ<8eqcjoS?}=2X4{DvCa9uHDXaKD^bBePD(wbk!_TQ@)^_>UZTUmj8o~LD0LQOufR<_ z{(jXxb#Daa!kwf-deJyYeYc@Q?PAE;xmte?%|APwnx I<)Tc!06t`P0{{R3 literal 0 HcmV?d00001 diff --git a/__pycache__/pointOp.cpython-35.pyc b/__pycache__/pointOp.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39abe0ed441c3815cb90e419567efa672e5ebc12 GIT binary patch literal 795 zcmZ`%&1&2*5FYt|oeh*GC4|yLX)k+852cqi-~`WbzpWq zesv{jGZppM6D2a=I&lSPBeW@+`iYvi_SoS==P`6A z;g;L$RJIC`7tV9?lsrL;$(S5C@({g~J&A7;WQbrKoQId?oSVH5gg5S^7QOL627Xrc5b=%s>?OX;O8C6Gfd!I(NdR2aloS|>94>aKK<$u0dM zz2-0NHK+cC(nH^_s}f4q-lx&d?7TOlc`={Q4%P23KN!&iJz6g8Gi>z=kmJv&Bua=b za))x4zT?QHJBJcxe5-i!6M?kI435izafYof0Rq<%3v}oj=vthZ+lgm!O8;^vKIL$E zh9?Oqhs(G20p$VM4z%A6l2=8pDT8*q%+pYwW2+-TXLa8(VxV2c&SLkzEd^I1Qmx2} z%@B1%E23r-{Y@5iO_WK&I}yFUXytGcUBYt`i7q>hW2U`U7Ig<>qC~m5CpiVnuTSUi z)}NJ-YQ61M$LpKC&(_N!yWz50%4RFFPOUdkD^lDRvTaJ<6-}MC!<)D3c32Mbs%c6E z)0TAF4mwB?TXbo9Xo{Hth|SpUcnlfcPZvK&IEud|+A>1@tC%ffN4uq{wTl!nlO95> z{5|-1)zkVbuXA+_TbV`@+Z~OBdsk+U;W1A$BevJiVSo-?hS8y0MlVNJS9^6|p(2k< z$p<+@Z0uP2#5Z({zWQIs#GF4v;HV-TRoDyh%(SOA{Y>>NO{*sFOJj#=`mN{X-eZ~U zn5>GOu*Ma>w)TpOUke!^y)@00W>Ow0FrQSKcF3_tJ4>N6W%lQWUg%mM$_U4}rxNJk O!(Q4)GnuxQ(D?&|xV^go literal 0 HcmV?d00001 diff --git a/__pycache__/range2.cpython-35.pyc b/__pycache__/range2.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a089c28c11b5ca23138703ae47260f93f3193cdf GIT binary patch literal 514 zcmYjOOH0E*5S}D$(W*B=3LaKG71V>`MMM-4Z&FbaB_M0EZ4>qpW_P6#Z~ABaOSyXT zFNgjXKi2qeHgkr?s>-iSvbcs1;N zQUzRO0fUheB;@Dh_JqIzlo7nN8iUse${1cLwFxc>Y7~j)$+8nNf17UDjAI&+Jm0d+ zsLDIRRG|yy72`T*iqBg9#HAOOnK3Ig6;a$_G23D&oJU>g33F4SSf9;}TjqQv1!EXa z`@C_6Xz*a($CS5@Jql{)a=X>ehrOn&y{hV_SJ)755-w%at+3FpN$5}nd^U`l4#$ao z2V5lKuglYe^u`LbX-S$~PjjE8qdJ>%R3kK{$ec~b$dz~?9f6gR+!aPYRQ29|TGgW( zuZ@v5MXo1ecPGsMrQwBbj{rJ@s2}4Jv0;qi+gjev{|9|aGz*8yXb5JU)p!psN>Mj;axj4VZ!?y}uUyW3Q? z9XqmDVZMMBpTIBmmQ^-<078Ou%XW{Q%q-~cdfj{Oxv#Px)@tR7`RC`I5@Ua|xyQl& zYYelCDZs~B#MsMx&)G|d1^8U{E95Q#UepV>K(psQ&Gc+yco@$xOy6ZJWo*RQ4JY^| zV_L8jdxs<(R4*3v4%45rpuonQjIeq40uHgz$;(fd9@D?gBcPf?;Ix1kI~EJ^*ky4z zZ+M@YGyT^*;y!hbAi@bXXoz~n=2pye8#!zm|G2=W2Qu>5$jvpy*?}}mEQJPONI83m zoVQT7Z4_%i@VhliM^$D>M1}OpfT_b!{eJ zwQ}?jB&HnQDVf?y8p9MTuSD3P6jrO6&%|s`@+fcg~nNO5%PJ_0lkj zMbZ@MRU$ev)uFG)IhlAI>`#btx>FD(I&6iL$Z#?p8AVD@ z@gg)r8q@0_qBJ4qFg3zgajNu`3xPdNv`~E&iy-W%*dSgcMlnvQK@uofbix=s=R>PI zIz17)Ntd#dQC;LAN!^0GI6cfIHg$rFDdD0$G$_zw^!ast-pdMd5Sq;E%P0(P|HY$=VEq46y_~s`iZidP!#K@6 z)0SP8d2z4P9cErLN)nw_ecZoJd}dPVUuG3QiG7)>7z21e1h8nr7W$Btpu=VDtNJD) z)Gd>_eyTIi<^?d_j?9UM7=z3)Sj`}F&F}!z;2?A2tBl83RK~GWP-8JzAn>!IZ+ZS; z`hDd3_m4-1jh_rk+PFaZWZVvVe&cxPx25hJ>*NA=-!z(3_cNrXbT^44-IufO@RLs) z-Qn?2pC(CU8k(X$*rz-u+XCp#Q%tO~&da>utn;F?!*{T+VYaJ7@*2)~y=}hj9`Hx} zGmJgVd;HMZ;&>fs9Q_DP^@1*A$*Q(u`;&s{6^N|brZhKwK-kikoh0Z*>MOb}hN7zS Gs`DQ|!OhYD literal 0 HcmV?d00001 diff --git a/__pycache__/rcosFn.cpython-35.pyc b/__pycache__/rcosFn.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6c2b1cc4bf3a8889eb877223b9f4c80f55f7c255 GIT binary patch literal 1268 zcmYjRO>f&q5FIWlI&kV7S~p7I0v!Y?ASTX-UGx&TMT;hF1r&}NJFVR)4H$AI(V@A* z?lOT2`IP>d{v}>}^0~L7hrV5^k_hhX?C{N-HzQKrt*yw7G7J0P+|bE5Yi{w5;*sXHR|=0!kN z>t_6u4mHLy5f{erQXz2w(09qa?jL7>y4D=+DLvqlrALoz8*=;d;h)}@8`z2yF?_JX@qS=y$x^qH(I znA>7YlGR|==pKS@F%Mn~zj(O2_cCEKm02+=q;FwK^foPP7gAnzDKYf4%2^lViT%IB zRWIPz_@?O68~2r765LCCzmy37NV{mV(S)U}nod=pPiKvo7ELGBI-NC9Ss2@NFrBe% zLi`qhMyVc~rsJpDT$$npa06)KR$C*??@e&h1gC$J-Uj(UKYjaX_}oZshG(_0X*J2~ zY&e)@lT@D%v^tZSHN%lk&*iJa4R5MSKhjsz+2>yjr?bIKA1hUwVf&ijhr+mZL(m(B zp=%!oTOt-~Hj2f*xEo#zu8Z43Uk3&qyT2Rndu40pV?1cC9Gt7XF6CElT*eLN1Mwfb Cr!biS literal 0 HcmV?d00001 diff --git a/__pycache__/round.cpython-35.pyc b/__pycache__/round.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ab29155a97c6dfd321e4fd841f96c79678080f5 GIT binary patch literal 628 zcmYjOPiqx15T9h98}I{msm8GMR_7*>orTIr&Zie!(4~=pUknr)VU81Ps6_Iuv9D zhCoN)lmL+vkTrb67zPL&H(R$@0dH@S5gL-Wy-QYp;6@anNTHsf9-)R4G!ftmErCd3 zN#TZqe*&>8;0=Lm0Q(HS>_ePDtT!OyZ$3SSYpfabt_bWQh85@?T)u>l=pHxZ>kl^e zXX-NPH8;ve79Hz&Gr-_53OHlkXQNM8D8c->xbtr+J2Z1{+)9swBuXt_XD;oTPs@%Q#4RNAou7Vc|`pT|C%b- goP1*#{Z$^ZZW literal 0 HcmV?d00001 diff --git a/__pycache__/roundVal.cpython-35.pyc b/__pycache__/roundVal.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4f6f2b9444e69574a106b21aed0ce6244c6e3068 GIT binary patch literal 521 zcmYjNO-sW-5S`7oSZjL}uX}6`dJ$1XtkSbmsS1`rS(9zknr6f7Mv1g1{WJchoCHt( z3*y1q_(6y4kN^z-IfEgC$b*Q(E9pcS z4E)-Ps^Kyuw<P&eN#li(P@r=9n5`WA&q|NK8|!CJIF+(F#2l zk1`QrLYq;%chN1ra^Tm>+FaV0P)Fmkp62tcD7m~hJ})_S4I5*WVV`V<8)WLp8(@Q4 zKL@?z;KnF4!7Mjcrg4;qLB9xNiSs_{nF_55sC%wPZXL{YBJEVCqpa9J2(qGI;I-C? z393_WWwJ-38-GcSMwk`>@NKruTCD9g88#{RIl3Q?bq7wU)>(s1(#pmOU6d#4)SYRZ ITZ^^4Z<`Hx*#H0l literal 0 HcmV?d00001 diff --git a/__pycache__/shift.cpython-35.pyc b/__pycache__/shift.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e89babada2fc3922121025d3d642f756227f0468 GIT binary patch literal 824 zcmaJ<&2AGh5FUFsKmEHD1d8C`V;9;W6>&inA%*q^jYyDMSQNP%huw5{y|TS1i;`2} zVUTztUpe&^5C_JaNDUHT?Tp7W-+VhW_T8PG%`N@w{5u8s0c#7-@B&5OM>WQeKnm~< z4GLoqzMxH=zsvs0j2;83WmU(!d0DjNkJXeA>^z5NZgs! z;l+B62U8ym>ITe-OLi0#7NmAI9R>PbG6vlCmDUcjbl`>#sQy-bd6I~O0hNj?d?9m%xJ@{u+? zy0lx7%p-0@juJExYi717Clf7<^~Xu3t!HFmn-|g;nORQ>^9|H4{`+UY_cVN~h0@`) zM6x^{mr>ZSqL{0!ujEujMu!u{GcihXBUB+%tU%_YqI&!!EUJE`hEk?FtcTXcO0f$Z zpXc7-9aP|NkX_Ot8}uH1M7rc5d4QI>jgf#V_grhcu4YZ$!hmf*!>-FzJa=Q#?wN1X E-zoCCxBvhE literal 0 HcmV?d00001 diff --git a/__pycache__/showIm.cpython-35.pyc b/__pycache__/showIm.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd4048eb76db1d3c99c5d004bbe1248dc59f605f GIT binary patch literal 3832 zcmZ`*TW{OQ6+Wb{R;(nx#FskjOg3?BC9)DLy(EEmn_v^PE*61zonld~gMbz(i84hp z!%<=h($luTpy+!a+t)t!KlBd}C{Umeh5A;YPep<4cZL$}MYEDQK6CDuZ$?}#mrIwT z|NiPwYUE~go*H?w zGh}DUD^RaMjRNc;&eN~qyU0O~DuoFm(#whw7Y=$>+j(_5F~Gn+CxgCkH(AV|bvy+; zKf@FKBS)l&MnvBr4}(rkl7Aot+GLKwR3@deDV0m9d`cBks+dx9DOF0TODQ#S{t=%ri^!FQiQBW;l6dzK(Rq#)V=Q=oCs1O_kLe3$(6~HR@Y7*#diekxq*w zZyD?-Pa}iFFkP6^EtAG3y?u}xENO$T0o5*wgqvkn?V?Pg<+Ts9SO3q=HSOlFhAL6_ z5_RWw(DF2>y~0_JGxTBUs+OWA6t34bdyO{Mm_Fa0hvWgS&l<2Y8|e?y)^4QKbxi@6 zM{mDK3r1gO%|gSHLi|mg@Ao(C98k-82BCJhOzYzu`GE2QfjC$CNGttLD}4l|yjI#I z5a&uaw9=oo(hVpTw2~kY>N0hK6{2yGMn&pgCHtnXg~zd=u`$Zg@_0^<3Jg@D86~a0 zNWjHtj_i+V75%Yq(JC`aWZ%||ReMYSH#p7`o7i{A-b4hWyR5@r(kWciqHXPJhwZ;H z%<(*p<|$EQ(C`T(>SDq~^0ygq)GBq?bYknwL;|ZoF$A1E#zeGXSCBk36W#{dcUcXt z_zofZjY*gb!{1QXsrwOiH?{Fh5rT1<)!VQTaCMo~4Lw0Y>gIVI4ybcjLxZ>zEYxRu z0~_{oh1AESZn1f)%zDXICyOmxk1!8?ZHzGt_~4{xW72z|IUu!edY%Vt)c4)7n`3TG$KG{ z9WG(H|MpMWuSR9+ZcSsLUjPVHPctOr+@JwL{$sL4k9{U4UWV z)uTZlsu~ve$lj$9fMS}4U89l7;&uL)9H^D?HLW*8*6131&5*T1_I=%>DU1_9C-`k; zXl1Wj_6rRx@T1(Ex+wl#V`nZRpD7D zj#m|a)Uj+Q5|!a2F;x_9BqCV&?V31H0$%!_ElwPvI*#zIo+E;mutfd2u%xsGwc)2C zam|L7Q11ibcuvppl~DcAb814n37w|fauJH%ytBN%CM_j~p9p+-dgx+Q)jbL8>}R;i zS+nM2_QrlLx~UC+D)g8|^qsEz{oaWqIYaHgEaOP9Wo)%P*qCr7!t@c_O~v zs_nI^g4fr>rRQ!hVxA3-{aW0|I{6kK$?vC?-8kbpew+(&-5@9c8V=BZzE|Rsi*p_+ z1aaaFE+k9`rww<8oC^=~4KIiK(&W5mSveS}_F zC!P~$UB4;gyyiqu3%sU+y6T{$PHeah0Hu9+&?xGvk02{)O82@^uz?h2&M~2ReCrGIC^e-0d?UI(EN#d^l)!EZIAhLDy-j=(r{E)AU9UI1D`8oPqx)96bEd zaX2^}$X7w&MaK#9YvDj%hTl0n(eJU4xoDI={LO1Vk=Zaxkgglc#w}wbQ#KwOKh$ya<{e|*tb<-Ou4LvR zyJFnPtQi}Kw_)mRD|7NXQk8XH7!>g(4g8wMy}Zrr9bR^MVMu8+-N6gXFCd7E`@O*K Ud(Nl)q7ZQ}=26!C^n2C(AEjcjSpWb4 literal 0 HcmV?d00001 diff --git a/__pycache__/skew2.cpython-35.pyc b/__pycache__/skew2.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2eccb19e20dffeece56c0bc147ab2a67da305a3 GIT binary patch literal 1015 zcmah{&ubGw6n?Wm+B8k5G}>AO8N^~1N`(|JMYKi4lO?oPum;PRohF;?>@G8t+AZm+ z;=%vKe`&6sdJsH{c<{|6)f@ze%(vgX_sx6X%w)A*uP&-zZ}xqFuP`$_Uq1A-&~=J%?>JXJD!8ar0m$Yfw&5dJMn@O zA)=@{5#6-;1&9|hzj_fsw*H?&H58(59N;C^&p*=xCW@3(HRK;?Q}+`YQ;`dvX&NV| zNz7yVzNC1&3Cp_t-PXfaMDr8Ms9;(qXPZ?z9WS5n?$Ksm=p@fr8c~+T^!4ukY)G&n zr@GH+Hy6c7Gb^PhOldARDV6pq&+i{9*5ljGPpdg;vOxuB*~T9i(RtGbT#IXGl*!)6 z+E&Ooz4jsPKkUkZkF19iM`dS9V5gi!uJQZRY39d2NVI7DlxHR^WRhtUW+PFQCS+2w z(gfC$v`tJkQAwt>y)ZLx&zkZx6G+Zd6C{H5OlXlup$X8nGQQAf#uJ$#r^c6DeF1q3 z>-=m#+wL4HE>&kRvgP{msM~3m-9D3|E%O2IYSlTBOz>m$!)1}D?oN-3a_dp2DBGoc zmFKDI*vD;cTCa`;SX|w;M-G-rmDIh4w~SbGxa2L7d*p$)?#WeDM82%x#~sWCoV6KP W!K|q~7I{2M`4jtw%GR%u8{ThP%j=B* literal 0 HcmV?d00001 diff --git a/__pycache__/sp0Filters.cpython-35.pyc b/__pycache__/sp0Filters.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a41ce6b10edc54d30c3e6f3663fb1bf6fffa77b8 GIT binary patch literal 5995 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 literal 0 HcmV?d00001 diff --git a/__pycache__/sp3Filters.cpython-35.pyc b/__pycache__/sp3Filters.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c1436cf07e6f172dcd3ea99b68257e5fb04c42a9 GIT binary patch literal 9872 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 literal 0 HcmV?d00001 diff --git a/__pycache__/sp5Filters.cpython-35.pyc b/__pycache__/sp5Filters.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ad877373737ea26a83b87b369f30a28b9561e62 GIT binary patch literal 6466 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 literal 0 HcmV?d00001 diff --git a/__pycache__/steer.cpython-35.pyc b/__pycache__/steer.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..638894c76028aef7adf27c315cb5f0d316f7078c GIT binary patch literal 2733 zcmcIl&u<$=6rS0&^TSQrkR~lvt7-}o#FcSKXhD>MT1xsuq9LjSq9v%>?2hA2);rso zaaxDuRJd}iIB`VcFW^t$z<;n;P7ybbhy&l7UE3*?0|!>#_4v(u-}}Dz-mFhgPuG4k zf8I}~82gnSxjd||;WiCCB78VY7<+()$0DC4oOL;Sz!{G!EUL1vv4;)LTJ^C*M6lIE zj%S_c)5c1vmv0BUd)Gb*X^*ZN?g`wtaGRfe#w=s|j6LN9vcs4b%wp}4g(G1Ln@Dx$ zfU|whwvnrfA0EZHmCvlt_VKJRTV-v;c}(vxJI1!h$-c!2>A+{{d-Rh4fL20bwc|7M z-CzgM0EJ2a;8=_eS&UeYJC<{N-^o4&v>jypz07DQn4M(B-dQ9rK9DvC;L`^c_UJq> zxD}q!@zMp3Y)I4Tx^1?zo3X|S+Cd4_{as!1Rv`f!hN!+sm z!btBkPF0^A>IIh(*c_IH&h2CDDPu1~AL0Dsf@;H{QIU?hBF%bsieO0a^xq3KEY2Lz z&PG%0sm~6o1NGxjUv(kJ2hE|jd9K6g=NMT_=o7S{`oQDN_6&+R&g@I2QUB~w`dPL= zPCol%G{yLQ>m9kyP4+l)pRSG!y?*Y|+1f<_Os&f=mP8d2v!}xs0!szh-UqYl{ zp2Y4~=|E7qU@2ywW~RdQ_kQW*D3TLK_ZZusAkwJf!6ZxPoh$%39~j9E<2{Mvej@k^ zr&qM-l#36qx9+rrRl;_pFqsV7v5ds^)mtC0G=->%@@n_e(8ekiS{m`baBql(&A`N_ z5u{s*Y;^FpP-z^RhTH4fC-vGex=3O=s+UA!Q;I-z1FPdF;&DeADMFR>x~UO?mSR_i zR_S;TB($=D#doN(7+HsCsto{_CD=@)7*J~nrJV{;%v5R+Qg}*Biz5MXVx>0C+6dC= z6=9GT>`WLWfp&mF$*v?;lnL|*l1k=ka1`qH^?P?eS-o?kB^FdhB@2>IC+Emi?r9> zggOzYQ5+&L-5O#MUv#SnZDQyjs?^HVVZ2aJYkg(q-re=jUnD0mrq@NCLuKMrimVf$ zn@5nl=mW4#V@M%Lqf&>+5JdGs->q2A;*06x>hs!$LlTD_OiX5mFvPShhX8*iZmOP+ zG0q0%a)bt{L0hAS7^5%1@=c<;B*1oQRAQKx$+Rq*%_c2YzpP{STM`H2=s#hzJDTVf zsg-EO82L~pN!$?cEWZ18Q>-aX6AMCXecQot+3bsZYE#@-y>zP~E-x-!0`ejKRqtJ1 z(OT&%XjIm-A`5iTl{A;dNTE>?H46hy$AU&AhKdWTn*OD=L%36nZMTOJaHs0O&aIG% z>{5dc@j_sSCx}+##k9m|t_S&+KDw~CIOw(!ZW1xzaT=;_hRLJD`8c+nQjo!^xo}uP zj=Vxg;BW@ZE!?=owfd>tPh^@`GaaWkubNJf$-EY$9mWQza_&2OJ5d3)G38l5uLfEN z{k%e{^QuO4>P#glph_QR{kJY}Wc{_iURNqH8!l0k zq`MVW(|m>po15h|Uh!()v{&QveBOJ5e*3e0hF|nvfqlU{$6s?kua`Sx{8c`Mopby= zpW;jWlGng<$(!{~@>xFX&3pPHkn6stPPtM#gOhaRQO9mRakZU2hXd6rI^!JF$tOO(H>5BnB#xSc-yFR8>XLg1|r}2oa&BwNjypcWiI6-r3B| zrg3CHQT|6?`v>~apR%ug;;k=zXw^zRcfEFkh*<5%eB68Px#!;5i;YJ8oc;HQr5a;@ zuv3?Z@m)OjGF~BW&SJ*e7DBFZDQh$Z6qRv5-_tJksPG z8~IZWz_?pvFs>99Rd)0rN%Y{yzu0(=jd1&Hc?|96O0CTAoIn;z5QH1S)u;Q7$3|7c zyNwTMeKD@G1I0VH(4Ty7Yd2V?_;*NICVwEYv}8S{2I+G?(0FCIVGg9PAL;5 zJu#5ZL`Pz6AXAI=Ffyv+BAv)s>`EJ1VU-g)aay>(s*CcHNiU0~5f61{B4tEhnt@KD zj%{uT@%Y~Jr_VOOxxX#oF2x}LwGlQ|ov1scm}eo)5JU&jWR$2-L%J7QHGs${iUCKo9ye(Ec5HU;sMoMwR1C?sf+o*+%=oA#weN#dwSIm=z0 zIe2TVO$pkKng0vuVU(rlW#yy_Ry1-1O1uR4^Dki#FQq)syzi73dp8yTq5%?Ev z@Y!Qj@2NXloAF&Ijbdfj1?8uW4#TDphT|`Ie4}NIHn$*_u@2FU94M4Stj@ewNqnOY zGW1fovH6yMzi-Jm4+yRuw7zR?<~~5%{<8-Uj-Qr@I*Es+qKF@gRamSFQtS}wghC}~ zRY*)(QeU`!WT;8d(kDDNj=wD7&fFG*46Ju2N1!+WYsBdWWw>!HUP_Zdyj!QlO|*lE zaV(5X_M1z&AFCvyyy)~?M8)(#@nn4sdE_j7J?AM;JKtKIqMbbmB9nfYb#}If9m3r* zdJkvT?sTcPuaKxRsg6NSC$G}s&Chqz;nvW+&^op|?{v@x#Av*;;v<-Sf)}eV@;VQ^ zMZV-;<%_)GU8gY@yhe{#=W|}es|J^Ol{a9yz^~z3;DBj{lSPzRJUZfPE9;Fnjg0fn|ZrX0mewd`tE$yl5fAKHv z)sugrcyO{{>!D%ZB!u_oJ*Hl(?N{~B!v_F-Ay$Xt>k6R{u!UFz-T)r)L80q90l{y3 z?7f3%A@nIWQ*x1obVFbUwn7KOEqJGJw4iXkAb{0%D^rhgB^Z~I2`OTc7|qf?laV$| z8x;jc<}4I}5?n{gfUR5|G_ueZ$Jo&0sSZAcIe|Ha85&b~*@AoWiq?Q;r2Pr5Q&8`$ zAd`aR$|f({^0{^C-)W(=KN@SplVLax{7xPWxr#d~9f`nbzpr>KdQoD8%2LTqlqS6_ zKfmy^ypyZjG?m)_%iLRM_Og7r*BFRIOfuChGuzc}!}MemyCKtnOWpKVl5d-{?b5=* yH5JY@%3M;An{|9uK|*o3VVYHH>jqR+vA11P-v6}a63PL)jW`X*QZ!4I75xJIeS$Rr literal 0 HcmV?d00001 diff --git a/__pycache__/upBlur.cpython-35.pyc b/__pycache__/upBlur.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b11b12d4cc67e2b238e8257b576a7250e81378f GIT binary patch literal 1726 zcmaJ?U2oh(6rJ(fn`DzfX(UKMLW6{8EUi+uG(toz0!oT11qe-oNLZOg{KLi!ZLQw*d-^h6OZYTS=b(VI9V-c zfH#t! zzrv5en0T6rn(wnCbjR^gC~%tRNe4nmm_(uG<+W2$^amRQ(LmSZ7l_Vr%pJ&8?lTc=%{*H|z*pZXjc?G%_nwC1f6pLo9$Hl1v_{H6eC~%K3DX zABn_>xX6__OYBe#+{v7voG6{ERG3ml$skcc8aXnt8mob_PEqVq~b~|+T`o1kX~t%oGR2cZlJJ9rp#nd@Atx&ur`%0#7>eG zd8E=b>599zKlyk~Y>(^^8&DS7lD5aiq1Z2~{HQB>AKvb*qZpy-yYuY*J%h$?Tpt~G z47ws!&|tbv&%dsslt} z)5AH!g}Rlhybem70$T@pm6fA9kXp-8-APQ68!J&z-NHH1Er&fm+jU@uvQ+hqR?g5q z1^I5+u6?L8wU=bTgML%{bYiiF7W~TeGSdJ0?!iWX&nRvB#}yF`<0|TJkD{T} z*|si@A>H%`8lU4Qkf(H6q>|eBq#S*;-Y-YnBfVP`sp*e3t(7DF8gQvRvw?xVag%rW zqPG;>#Mt)S=)cYvyaoOy?hp797ktiZ^JQnR@OSuo-n+ YQqSJYinvPEr_@VBe-R7(2EXC`3o5yrfB*mh literal 0 HcmV?d00001 diff --git a/__pycache__/upConv.cpython-35.pyc b/__pycache__/upConv.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02959b1936e1f0cee31dc0ba7cd30731f32f6ac0 GIT binary patch literal 1950 zcmcIlPj4GV6n`_`UH?tfn1rN&U_+})=1@ct94ds6LJmk(2qZ|wvSdxX<7A!n?lLpm z)|PV$-+()JJ_TQZJJMb&4*3d*1MkhOT_4&WkXY}`ynXZj{NC@4#=9FEt+xK>$6s0i zFJSFyqWl#O{S2oFUj_+4eJT-SpFTtZ{9K2Ai!>*_<_#u?qj~4!XG-J;S^D&W&dP?8<3x_kCpQdtM|HBn zhY;V!aeza=r~xc2*vkg!Jy=+FySLlH?IGI_Q!&Mzjt&&{< zmmJg_j7LRMR9+e2?wG?hx}Yzo(k^SDf3>o=Ci^6-F{4~)7Qh{(;B8znu>PY;g;Cek zFRe+<$x?M0K?p1aq}QfhfpU-?-W90ybQzp-x+qWH6y=qrrME19O=_p(51R%+%>K?6 z!J3S`y80H_WlXtEOrr*CAPp|ti0uklv~9mb3o4y1y>Hbn@Lv>o8O%v5!b0SeyhGzuIPcNTbA`k%`{=sqN6ow!=wWS=M6jG zs?Iq1zhSE)V3lOytus<_KuTn+B5uhK;(lFVM_pxjy#bc6O+rI|>2b5bdM+=Z8vV>QNX^#kmYc8inIHF;ay>$xz9kide}g zjMKa@VJ?)IO5D`@3U3Hd9H%mn&y7r@GEg#?!YH~{ZfNHmhkfP`51-03)bSicJ^Z@L zpu;pX;Y^xP7kQp3gPUiwuy8k3*%-xYR3t+6wn{%&acW9$l;yM1*B2s}Wi63u>8HgM zRdpquG7x!ASp2zEnJ#^yl$fDueAeH_2vVgY8PaVyl+SZ4whTsQmP=jMBVoi)pm6-{ zH%F(3-(&t^loe-*EZJ#)bLH&(dd5^7d@xiA+hiZ#rP#(+H d+7wdU#uw8pDiZl6rPY)VYh<0;J=Q|>{{mMpou>c* literal 0 HcmV?d00001 diff --git a/__pycache__/var2.cpython-35.pyc b/__pycache__/var2.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e86cccc87c82a13bdffe4b19cf8ca24ba57d7931 GIT binary patch literal 748 zcma)4!H&}~5FI;dcj?kgyV7pO9(+NNOAjCSu5GR&Og##$4vJ$sV)^;L0K^xRP zmCxV@_$6OC^~MIa1YPX?FmAPi+}|9 zhyjH(fUg)6e>jc84Km<7@#rl;@1Va%w|@{SfEB>HrC(4mcl{RIjB)~NfGYy}WQP=h zC!Mt<0wYXU6!PG@2>axruQT7E>iD(owjywh%7#e5Rdw64z3Xhgzg2LIqSqAeTv5=o z8|C>e|8BlR8s1Fx+Iq|$9%1Q<{?`pin?{{4pV*YEQVRB&n~dv3uwu?QQ@k?S<+#VT zHsRK0dcoejIy-0gi?YfJ&1HnV3t?Hc6fEH~sU`ObHs`hyX3W@z;E;`njsI#5`i}iP zjSgHOg?6D5T)U30RoS?1W{u#|1zaN7TDd^+OBa@=NL|M+c`01jGQv#pMHIM@n}u~$ zX%`q_zk?azEx+Erd=kI6!q_;kZN>F6t&@1tBuj48#1y$mDjUxYS7MfF)LRz+0H z;iI^0CXIPl6w<~xng?SP7W%;dL)Q0)a6pD+KzejUUeL$n9yNz}8d1~5M;o^~c3_AJ TxBpZXX)VPwKNjo9a-04IXLY9r literal 0 HcmV?d00001 diff --git a/__pycache__/zconv2.cpython-35.pyc b/__pycache__/zconv2.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01a05d97092d457672aee84443af16c993298234 GIT binary patch literal 1710 zcmZuy-EP}96h4wACvoCjv=?bmY~g?au`wfQycR>VZpe^j#eg+Sope|O1BEQnwj4_I zNGXjC`(o(!Fng5&djZ|;OmD;=1S^a*5W!92|$Hl z9c~Od9Ov)vziz!eZm}!wCsOSe+!hSaag9`A4~T{!Ryy*8z^ysaYZht{(rE-@i8RPz zqM6U*gwL@M=eJTZe#K)Jgb|N5!bN-rYz7UGfa63I#=z-}avRdcYI10jDE5rp&(&J)S^pHPT8H<&D`ZrJ zmz?=1SF?sJ?>8WtjUDYpe5d}Oq8=mR>@19A>~kT)25as;|9qFR(^1k#orh8-Cd8KP zu(zmgufg`8?Cn2;$Bp^S+>{{3J8!ht;|FX!yVG<9uAOBa%~YhgKHlkuN+)^igz+#< z*w9m8g=C^IiZjK3PD90m6NT>$-54=GJXT7o114h*pB{@+AfR-!eoD}3MRiajWtyoY z(TcaV`=kdHGY&JSn+j21$x4F9nLAWroMdjCM#E9&dP;eC>ApAQncEdoDy;kvwz3X; zsA{%s!js~P*Vi)#RCH!}nbpZkegfZ|5003Q%WN^iyv}Tmx4zCwdenrtZf0e_aJ2m2 zNqq!bf4@FDXur`&L3@DEytp5ve*1Lf_dOMzDmg%_>vq@V=^Y4jHI%|LefDlR`s`VI zI657vb18*x7wO+Mj0@EPynbq8f3R&;@N?{k)$#PSh=)~rE29rcgxzc yAKBZs+QPZIqww!S*;<~7-69cc4O_W658#gY*!V8Lh-8oo{*@`8HXPQhHTz$I52kkj literal 0 HcmV?d00001