Scheduled service maintenance on November 22


On Friday, November 22, 2024, between 06:00 CET and 18:00 CET, GIN services will undergo planned maintenance. Extended service interruptions should be expected. We will try to keep downtimes to a minimum, but recommend that users avoid critical tasks, large data uploads, or DOI requests during this time.

We apologize for any inconvenience.

blindschleiche_py3.py 74 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672
  1. # -*- coding: utf-8 -*-
  2. """
  3. filter module
  4. This file is located here:
  5. C:\\Users\aborst\.spyder2\blindschleiche.py
  6. """
  7. import numpy as np
  8. import scipy as scipy
  9. import matplotlib.pyplot as plt
  10. import math
  11. from scipy import ndimage
  12. from scipy.optimize import curve_fit
  13. # Import Bessel function.
  14. from scipy.special import jn
  15. from mpl_toolkits.mplot3d import Axes3D
  16. # Import colormaps.
  17. from matplotlib import cm
  18. # Import lighting object for shading surface plots.
  19. from matplotlib.colors import LightSource
  20. from scipy import sparse
  21. from scipy.sparse.linalg import spsolve
  22. from scipy.sparse import csr_matrix
  23. import itertools
  24. # --------------- GENERAl FUNCTIONS -----------------------------
  25. # Lowpass and highpass functions work with n-dimensional inputs
  26. # Always filters along the last axis
  27. def lowpass(x,tau):
  28. # swaps input dimension such as last dim becomes first
  29. x=x.transpose(np.roll(np.arange(x.ndim),1))
  30. n=x.shape[0]
  31. result=np.zeros_like(x)
  32. if tau<1:
  33. result=x
  34. if tau>=1:
  35. result[0]=x[0]
  36. for i in range(0,n-1):
  37. result[i+1]=1.0/tau*(x[i]-result[i])+result[i]
  38. # swaps output dimension such as first dimension becomes last again
  39. result=result.transpose(np.roll(np.arange(result.ndim),-1))
  40. return result
  41. def highpass(x,tau):
  42. result=x-lowpass(x,tau)
  43. return result
  44. def bandpass(x,tauhp,taulp):
  45. result=highpass(x,tauhp)
  46. result=lowpass(result,taulp)
  47. return result
  48. def normalize(x):
  49. mymax=np.nanmax(x)
  50. mymin=np.nanmin(x)
  51. if np.abs(mymax)>np.abs(mymin):
  52. absmax=np.abs(mymax)
  53. else:
  54. absmax=np.abs(mymin)
  55. result=x/absmax
  56. if mymax==mymin:
  57. result=x*0.0
  58. return result
  59. def equalize(image):
  60. image=image.astype(int)
  61. image=ceil(image,254)
  62. hist,bins=np.histogram(image,bins=255,range=[0,254])
  63. hist=blurr(1.0*hist/np.sum(hist),5)
  64. cdf=integrate(hist)*255.0
  65. eqimage=cdf[image]
  66. return eqimage
  67. def lowpass_amp_spectrum(tf,tau):
  68. w=2*np.pi*tf
  69. result=1.0/np.sqrt(1.0+(tau*w)**2)
  70. return result/np.max(result)
  71. def highpass_amp_spectrum(tf,tau):
  72. w=2*np.pi*tf
  73. result=tau*w/np.sqrt(1.0+(tau*w)**2)
  74. return result/np.max(result)
  75. def bandpass_amp_spectrum(tf,tauhp,taulp):
  76. result=lowpass_amp_spectrum(tf,taulp)*highpass_amp_spectrum(tf,tauhp)
  77. return result/np.max(result)
  78. def lowpass_phase_spectrum(tf,tau):
  79. w=2*np.pi*tf
  80. result=-np.arctan(tau*w)
  81. return result
  82. def highpass_phase_spectrum(tf,tau):
  83. w=2*np.pi*tf
  84. result=np.arctan(1.0/(tau*w))
  85. return result
  86. def bandpass_phase_spectrum(tf,tauhp,taulp):
  87. result=lowpass_phase_spectrum(tf,taulp)+highpass_phase_spectrum(tf,tauhp)
  88. return result
  89. # returns the integral (along the last axis) of the input function
  90. # if along another axis, use np.transpose before
  91. def integrate(x):
  92. if x.ndim==1:
  93. result=np.cumsum(x)
  94. if x.ndim==2:
  95. result=np.cumsum(x,axis=1)
  96. if x.ndim==3:
  97. result=np.cumsum(x,axis=2)
  98. return result
  99. # returns the differential (along the last axis) of the input function
  100. # if along another axis, use np.transpose before
  101. def differentiate(x):
  102. xshape=x.shape
  103. if x.ndim==1:
  104. interim=x-np.roll(x,1)
  105. result=interim[1:xshape[0]]
  106. if x.ndim==2:
  107. interim=x-np.roll(x,1,axis=1)
  108. result=interim[:,1:xshape[1]]
  109. if x.ndim==3:
  110. interim=x-np.roll(x,1,axis=2)
  111. result=interim[:,:,1:xshape[2]]
  112. return result
  113. def Gauss1D(FWHM,RFsize):
  114. myrange=RFsize/2
  115. sigma=FWHM/(2.0*np.sqrt(2*np.log(2)))
  116. x=np.arange(-myrange,(myrange+1),1)*1.0
  117. z=np.exp(-x**2/(2*(sigma**2)))
  118. z=z/np.sum(z)
  119. return z
  120. def Gauss2D(FWHM,RFsize):
  121. myrange=RFsize/2
  122. sigma=FWHM/(2.0*np.sqrt(2*np.log(2)))
  123. x=np.arange(-myrange,(myrange+1),1)
  124. y=np.arange(-myrange,(myrange+1),1)
  125. x,y=np.meshgrid(x,y)
  126. r=np.sqrt(x**2+y**2)
  127. z=np.exp(-r**2/(2*(sigma**2)))
  128. z=z/np.sum(z)
  129. return z
  130. # blurr calculates the convolution of an image with a Gaussian
  131. # The cross section FWHM is the full width at half-maximum
  132. # filter normalized so that integral of filter = 1.0
  133. def blurr(inp_image,FWHM):
  134. if inp_image.ndim==1: z=Gauss1D(FWHM,4*FWHM)
  135. if inp_image.ndim==2: z=Gauss2D(FWHM,4*FWHM)
  136. result=scipy.ndimage.convolve(inp_image,z)
  137. return result
  138. # calculates a rebinned array of input x
  139. # all new dims must be integer fractions or multiples of input dims
  140. def rebin(x,f0,f1=0,f2=0):
  141. mydim=x.ndim
  142. n=x.shape
  143. if mydim==1:
  144. result=np.zeros((f0))
  145. if f0 <= n[0]:
  146. result=x[0:n[0]:int(n[0]/f0)]
  147. if f0 > n[0]:
  148. result=np.repeat(x,int(f0/n[0]))
  149. if mydim==2:
  150. result=np.zeros((f0,f1))
  151. interim=np.zeros((f0,n[1]))
  152. #handling 1st dim
  153. if f0 <= n[0]:
  154. interim=x[0:n[0]:int(n[0]/f0),:]
  155. if f0 > n[0]:
  156. interim=np.repeat(x,int(f0/n[0]),axis=0)
  157. #handling 2nd dim
  158. if f1 <= n[1]:
  159. result=interim[:,0:n[1]:int(n[1]/f1)]
  160. if f1 > n[1]:
  161. result=np.repeat(interim,int(f1/n[1]),axis=1)
  162. if mydim==3:
  163. result=np.zeros((f0,f1,f2))
  164. interim1=np.zeros((f0,n[1],n[2]))
  165. interim2=np.zeros((f0,f1,n[2]))
  166. #handling 1st dim
  167. if f0 <= n[0]:
  168. interim1=x[0:n[0]:int(n[0]/f0),:,:]
  169. if f0 > n[0]:
  170. interim1=np.repeat(x,int(f0/n[0]),axis=0)
  171. #handling 2nd dim
  172. if f1 <= n[1]:
  173. interim2=interim1[:,0:n[1]:int(n[1]/f1),:]
  174. if f1 > n[1]:
  175. interim2=np.repeat(interim1,int(f1/n[1]),axis=1)
  176. #handling 3rd dim
  177. if f2 <= n[2]:
  178. result=interim2[:,:,0:n[2]:int(n[2]/f2)]
  179. if f2 > n[2]:
  180. result=np.repeat(interim2,int(f2/n[2]),axis=2)
  181. return result.copy()
  182. # Calculates the rectilinear fct of x: x=x if x > thrld, and x=thrld otherwise
  183. def rect(x,thrld):
  184. result=x-thrld
  185. result=result*(result>0)
  186. result=result+thrld
  187. return result
  188. # Calculates the ceiled fct of x: x=x if x < thrld, and x=thrld otherwise
  189. def ceil(x,thrld):
  190. result=x-thrld
  191. result=result*(result<0)
  192. result=result+thrld
  193. return result
  194. def limit(x,lowertrld,uppertrld):
  195. result=rect(x,lowertrld)
  196. result=ceil(result,uppertrld)
  197. return result
  198. def binomial(x,y):
  199. if y == x:
  200. result=1
  201. elif y == 1:
  202. result=x
  203. elif y > x:
  204. result=0
  205. else:
  206. a = math.factorial(x)
  207. b = math.factorial(y)
  208. c = math.factorial(x-y)
  209. div = a / (b * c)
  210. result=div
  211. return 1.0*result
  212. def binomial_distribution(n,p):
  213. probab=np.zeros(n+1)
  214. for i in range(n+1):
  215. probab[i]=binomial(n,i)*(p**i)*((1-p)**(n-i))
  216. return probab
  217. def draw_from_p(inp_p):
  218. p=inp_p/np.sum(inp_p)
  219. dim=p.shape[0]
  220. rand_num=np.random.choice(np.arange(dim),p=p)
  221. return rand_num
  222. def sigmoidal(x,center,slope,maximum):
  223. output=maximum/(1.0+np.exp(-(x-center)*slope))
  224. return output
  225. def saturate(x,max_fac,sat_fac):
  226. if sat_fac>7:
  227. sat_fac=7
  228. sat_strength=np.array([100,5,2,1,0.5,0.2,0.1,0.02])
  229. myx=np.linspace(0,100,101)*0.01
  230. transferfct=myx/(myx+sat_strength[sat_fac])
  231. transferfct=transferfct/np.max(transferfct)
  232. x=x*100.0/max_fac
  233. x=x*(x>0)
  234. x=x-100
  235. x=x*(x<0)+100
  236. result=max_fac*transferfct[x.astype(int)]
  237. return result
  238. # Calculates the Pearson Correlation Coefficient
  239. def calc_corr(a,b):
  240. a=a-np.mean(a)
  241. b=b-np.mean(b)
  242. cov=np.sum(a*b)
  243. sigma_a=np.sum(a*a)
  244. sigma_b=np.sum(b*b)
  245. corr=cov/np.sqrt(sigma_a*sigma_b)
  246. return corr
  247. # Calculates the Cross Covariance Fct
  248. def calc_cc(a,b,dt):
  249. a=a-np.mean(a)
  250. b=b-np.mean(b)
  251. if a.ndim==1:
  252. cc=np.zeros(dt*2)
  253. for i in range(dt*2):
  254. k=i-dt
  255. cc[i]=np.mean(a*np.roll(b,-k))
  256. if a.ndim==2:
  257. cc=np.zeros((dt*2,dt*2))
  258. for i in range(dt*2):
  259. k=i-dt
  260. print(k)
  261. yroll=np.roll(b,-k,axis=0)
  262. for j in range(dt*2):
  263. l=j-dt
  264. print(l)
  265. xroll=np.roll(yroll,-l,axis=1)
  266. cc[i,j]=np.mean(a*xroll)
  267. return cc
  268. # Calculates the mean and SEM along the first axis
  269. def calc_meanSEM(data):
  270. n=data.shape
  271. n=n[0]
  272. mean=np.mean(data,axis=0)
  273. var=mean*0.0
  274. for i in range(n):
  275. var+=(mean-data[i])**2
  276. SEM=np.sqrt(var/(n*(n-1)))
  277. return mean, SEM
  278. def calc_Ldir(data,plot_switch=0):
  279. # assumes first column to hold the angle in deg, and the second one the length
  280. # tranform to radian
  281. angle = np.pi*2.0/360.*data[:,0]
  282. # calc cartesian coords
  283. xcood = np.cos(angle)*data[:,1]
  284. ycood = np.sin(angle)*data[:,1]
  285. xcsum = np.sum(xcood)
  286. ycsum = np.sum(ycood)
  287. numer = np.sqrt(xcsum**2+ycsum**2)
  288. denom = np.abs(np.sum(data[:,1]))
  289. Ldir = numer/denom
  290. if plot_switch==1:
  291. plt.polar(angle,data[:,1],linewidth=2)
  292. return Ldir
  293. def calc_amp_phase(image):
  294. a=np.fft.fft2(image)
  295. amp=np.abs(a)
  296. phase=np.arctan2(a.imag,a.real)
  297. amp=1.0*amp/(1.0*image.size)
  298. plt.matshow(amp,cmap='gray',vmax=0.01)
  299. plt.matshow(phase,cmap='gray',vmin=-np.pi,vmax=np.pi)
  300. return amp, phase
  301. # Calculates the Membrane Potential
  302. # gleak=1.0
  303. def calc_Vm(gexc,ginh,gleak):
  304. gexc=rect(gexc,0)
  305. ginh=rect(ginh,0)
  306. Eexc=+50.0
  307. Einh=-30.0
  308. Vm=(Eexc*gexc+Einh*ginh)/(gexc+ginh+gleak)
  309. return Vm
  310. def calc_CaInd(Vm):
  311. n= Vm.size
  312. ca=np.zeros(n)
  313. caind=np.zeros(n)
  314. dt=0.001
  315. gamma=50.0
  316. kf=0.01
  317. kb=10.0
  318. kd=kb/kf # nMol
  319. ymax=100.0 # initial indicator conc in nMol
  320. ivacc=rect(Vm,0)*1000.0
  321. print('Kd = ',int(kd), ' nMol')
  322. print('[Ind] = ',int(ymax), ' nMol')
  323. x0=50.0 # initial free Ca at rest
  324. y0=ymax*x0/(x0+kd) # Indicator-bound Ca at rest
  325. ca[0]=x0
  326. caind[0]=y0
  327. for i in range(n-1):
  328. t=i+1
  329. icapump=(gamma*ca[t-1])
  330. indforward=kf*ca[t-1]*(ymax-caind[t-1])
  331. indbackward=kb*caind[t-1]
  332. ca[t]=((ivacc[t]-icapump-indforward+indbackward)*dt+ca[t-1])
  333. caind[t]=(indforward-indbackward)*dt+caind[t-1]
  334. return caind
  335. # Calculates HH model for current input
  336. # gleak=1.0
  337. def calc_HH(current):
  338. # spike threshold at current = 0.18
  339. noft_points=current.shape[0]
  340. deltat=0.0005
  341. Vm=np.zeros(noft_points)
  342. gNa=np.zeros(noft_points)
  343. gK=np.zeros(noft_points)
  344. Vm[0]=-0.07
  345. m=0
  346. n=0
  347. h=0
  348. Eleak=-0.07 # = -70 mV
  349. gleak=1.0
  350. memcap=0.01
  351. ENa=+0.020 # = + 20 mV
  352. EK =-0.100 # = -100 mV
  353. gNa=np.zeros(noft_points)
  354. gK =np.zeros(noft_points)
  355. gNamax=200.0
  356. gKmax =100.0
  357. mmidv=-55.0
  358. mslope=0.35
  359. mtau=0.001
  360. hmidv=-65.0
  361. hslope=-0.15
  362. htau=0.003
  363. nmidv=-55.0
  364. nslope=0.15
  365. ntau=0.004
  366. myx=np.linspace(0,200,201)-100
  367. mss=1.0/(1.0+np.exp((mmidv-myx)*mslope))
  368. hss=1.0/(1.0+np.exp((hmidv-myx)*hslope))
  369. nss=1.0/(1.0+np.exp((nmidv-myx)*nslope))
  370. for i in range(noft_points-1):
  371. t=i+1
  372. Vindex=int(1000.0*Vm[t-1])+100
  373. Vindex=limit(Vindex,-99,99)
  374. m=deltat/mtau*(mss[Vindex]-m)+m
  375. n=deltat/ntau*(nss[Vindex]-n)+n
  376. h=deltat/htau*(hss[Vindex]-h)+h
  377. gNa[t]=gNamax*(m**3)*h
  378. gK[t] =gKmax *(n**4)
  379. Vm[t]=(current[t]+ENa*gNa[t]+EK*gK[t]+Eleak*gleak+Vm[t-1]*memcap/deltat)/(gleak+gNa[t]+gK[t]+memcap/deltat)
  380. return Vm*1000.0
  381. # calculates the gradient of a scalar fct of 2 variables
  382. # returns the first derivatives along x and y respectively
  383. def gradient(myf):
  384. myshape=myf.shape
  385. if myf.ndim == 2:
  386. xshape=myshape[1]
  387. yshape=myshape[0]
  388. gradx=myf-np.roll(myf,1,axis=1)
  389. grady=myf-np.roll(myf,1,axis=0)
  390. gradx=gradx[1:yshape,1:xshape]
  391. grady=grady[1:yshape,1:xshape]
  392. result=gradx,grady
  393. else:
  394. print('not a 2-dim array')
  395. result=0
  396. return result
  397. # calculates the divergence of a vector field
  398. # returns the sum of the first derivatives
  399. def divergence(gradx,grady):
  400. myshape=gradx.shape
  401. xshape=myshape[1]
  402. yshape=myshape[0]
  403. divx=gradx-np.roll(gradx,1,axis=1)
  404. divy=grady-np.roll(grady,1,axis=0)
  405. result=divx+divy
  406. result=result[1:yshape,1:xshape]
  407. return result
  408. # calculates the laplacian of a scalar fct of 2 variables
  409. def laplace(myf):
  410. if myf.ndim == 2:
  411. u,v=gradient(myf)
  412. result=divergence(u,v)
  413. else:
  414. print('not a 2-dim array')
  415. result=0
  416. return result
  417. # --------------- MODELS OF MOTION DETECTORS -----------------------------
  418. def add_photonnoise(signal,meanlum):
  419. noisysignal=np.random.poisson(signal*meanlum)/(1.0*meanlum)
  420. noiselevel=np.sqrt(np.mean((noisysignal-signal)**2))/np.sqrt(np.mean((signal)**2))
  421. print('noiselevel=', noiselevel)
  422. return noisysignal
  423. # calculates the output of a 2dim array of EMDs
  424. # deltat determines temporal resolution in ms
  425. def calc_4QHR(R16,deltat):
  426. noff=40
  427. lp=lowpass(R16,250/deltat)
  428. hp=highpass(R16,250/deltat)
  429. Txa=lp[:,0:noff-1,:]*hp[:,1:noff,:]
  430. Txb=lp[:,1:noff,:]*hp[:,0:noff-1,:]
  431. mdout=Txa-Txb
  432. HS=np.mean(np.mean(mdout,axis=0),axis=0)
  433. return HS
  434. def calc_2QHR(lp,hp):
  435. noff=40
  436. Txa=rect(lp[:,0:noff-1,:]*hp[:,1:noff,:],0)
  437. Txb=rect(lp[:,1:noff,:]*hp[:,0:noff-1,:],0)
  438. return Txa, Txb
  439. def calc_HRBL(lp,hp):
  440. noff=40
  441. DC=0.02
  442. A=rect(lp[:,0:noff-2,:],0)
  443. B=rect(hp[:,1:noff-1,:],0)
  444. C=rect(lp[:,2:noff-0,:],0)
  445. Txa=rect(A*B/(DC+C),DC)
  446. A=rect(lp[:,2:noff-0,:],0)
  447. B=rect(hp[:,1:noff-1,:],0)
  448. C=rect(lp[:,0:noff-2,:],0)
  449. Txb=rect(A*B/(DC+C),DC)
  450. return Txa, Txb
  451. def calc_HR(lp,hp):
  452. noff=40
  453. DC=0.02
  454. A=rect(lp[:,0:noff-2,:],0)
  455. B=rect(hp[:,1:noff-1,:],0)
  456. Txa=rect(A*B/DC,DC)
  457. A=rect(lp[:,2:noff-0,:],0)
  458. B=rect(hp[:,1:noff-1,:],0)
  459. Txb=rect(A*B/DC,DC)
  460. return Txa, Txb
  461. def calc_BL(lp,hp):
  462. noff=40
  463. DC=0.02
  464. B=rect(hp[:,1:noff-1,:],0)
  465. C=rect(lp[:,2:noff-0,:],0)
  466. Txa=rect(B/(DC+C),DC)
  467. B=rect(hp[:,1:noff-1,:],0)
  468. C=rect(lp[:,0:noff-2,:],0)
  469. Txb=rect(B/(DC+C),DC)
  470. return Txa, Txb
  471. def calc_cb_HRBL(lp,hp):
  472. noff=40
  473. Eexc=+50.0
  474. Einh=-20.0
  475. gleak=1.0
  476. Mi9=rect(1.0-lp[:,0:noff-2,:],0)
  477. Mi1=rect(hp[:,1:noff-1,:],0)
  478. Mi4=rect(lp[:,2:noff-0,:],0)
  479. gexc=rect(Mi1,0)
  480. ginh=rect(Mi9+Mi4,0)
  481. Txa=(Eexc*gexc+Einh*ginh)/(gexc+ginh+gleak)
  482. Mi9=rect(1.0-lp[:,2:noff-0,:],0)
  483. Mi1=rect(hp[:,1:noff-1,:],0)
  484. Mi4=rect(lp[:,0:noff-2,:],0)
  485. gexc=rect(Mi1,0)
  486. ginh=rect(Mi9+Mi4,0)
  487. Txb=(Eexc*gexc+Einh*ginh)/(gexc+ginh+gleak)
  488. return Txa, Txb
  489. def calc_cb_HR(lp,hp):
  490. noff=40
  491. Eexc=+50.0
  492. Einh=-20.0
  493. gleak=1.0
  494. Mi9=rect(1.0-lp[:,0:noff-2,:],0)
  495. Mi1=rect(hp[:,1:noff-1,:],0)
  496. gexc=rect(Mi1,0)
  497. ginh=rect(Mi9,0)
  498. Txa=(Eexc*gexc+Einh*ginh)/(gexc+ginh+gleak)
  499. Mi9=rect(1.0-lp[:,2:noff-0,:],0)
  500. Mi1=rect(hp[:,1:noff-1,:],0)
  501. gexc=rect(Mi1,0)
  502. ginh=rect(Mi9,0)
  503. Txb=(Eexc*gexc+Einh*ginh)/(gexc+ginh+gleak)
  504. return Txa, Txb
  505. def calc_cb_BL(lp,hp):
  506. noff=40
  507. Eexc=+50.0
  508. Einh=-20.0
  509. gleak=1.0
  510. Mi1=rect(hp[:,1:noff-1,:],0)
  511. Mi4=rect(lp[:,2:noff-0,:],0)
  512. gexc=rect(Mi1,0)
  513. ginh=rect(Mi4,0)
  514. Txa=(Eexc*gexc+Einh*ginh)/(gexc+ginh+gleak)
  515. Mi1=rect(hp[:,1:noff-1,:],0)
  516. Mi4=rect(lp[:,0:noff-2,:],0)
  517. gexc=rect(Mi1,0)
  518. ginh=rect(Mi4,0)
  519. Txb=(Eexc*gexc+Einh*ginh)/(gexc+ginh+gleak)
  520. return Txa, Txb
  521. def calc_cb_eeiHRBL(lp,hp):
  522. noff=40
  523. Eexc=+50.0
  524. Einh=-20.0
  525. gleak=1.0
  526. Mi9=rect(lp[:,0:noff-2,:],0)
  527. Mi1=rect(hp[:,1:noff-1,:],0)
  528. Mi4=rect(lp[:,2:noff-0,:],0)
  529. gexc=rect(Mi1,0)+rect(Mi9,0)
  530. ginh=rect(Mi4,0)
  531. Txa=(Eexc*gexc+Einh*ginh)/(gexc+ginh+gleak)
  532. Mi9=rect(lp[:,2:noff-0,:],0)
  533. Mi1=rect(hp[:,1:noff-1,:],0)
  534. Mi4=rect(lp[:,0:noff-2,:],0)
  535. gexc=rect(Mi1,0)+rect(Mi9,0)
  536. ginh=rect(Mi4,0)
  537. Txb=(Eexc*gexc+Einh*ginh)/(gexc+ginh+gleak)
  538. return Txa, Txb
  539. def calc_cb_eeHR(lp,hp):
  540. noff=40
  541. Eexc=+50.0
  542. gleak=1.0
  543. Mi9=rect(lp[:,0:noff-2,:],0)
  544. Mi1=rect(hp[:,1:noff-1,:],0)
  545. gexc=rect(Mi1,0)+rect(Mi9,0)
  546. Txa=(Eexc*gexc)/(gexc+gleak)
  547. Mi9=rect(lp[:,2:noff-0,:],0)
  548. Mi1=rect(hp[:,1:noff-1,:],0)
  549. gexc=rect(Mi1,0)+rect(Mi9,0)
  550. Txb=(Eexc*gexc)/(gexc+gleak)
  551. return Txa, Txb
  552. def NewEMD(stimulus,deltat,det_switch,ret_switch,noisefac=0, resting_factor=0):
  553. n=stimulus.shape
  554. maxtime=n[2]
  555. noff=40
  556. ON_lptau=50.0/deltat
  557. OFF_lptau=50.0/deltat
  558. L1gain=1.0
  559. L2gain=1.0
  560. ONlpgain=1.0
  561. ONhpgain=1.0
  562. OFFlpgain=1.0
  563. OFFhpgain=1.0
  564. T4gain=1.0
  565. T5gain=1.0
  566. LPigain=1.0
  567. R16=rebin(stimulus,noff,noff,maxtime)
  568. # add noise
  569. if noisefac!=0:
  570. stimulus=add_photonnoise(stimulus,noisefac)
  571. # tilt the image slightly
  572. for i in range(3):
  573. j=10*i
  574. k=10*(i+1)
  575. R16[k:k+10,:,:]=np.roll(R16[j:j+10:,:],1,axis=1)
  576. if det_switch==0:
  577. print('4QD HR')
  578. HS=calc_4QHR(R16,deltat)
  579. result=HS
  580. print('HS cell')
  581. if det_switch > 0:
  582. interim=highpass(R16,250/deltat)
  583. interim=interim+0.1*R16
  584. L1=L1gain*rect(interim,0)
  585. L2=L2gain*rect(-(interim-0.05),0)
  586. ONlp=ONlpgain*lowpass(R16,ON_lptau)
  587. ONhp=ONhpgain*L1
  588. OFFlp=OFFlpgain*lowpass(1.0-R16,OFF_lptau)
  589. OFFhp=OFFhpgain*L2
  590. if det_switch==1:
  591. print('a*b/c HRBL')
  592. T4a,T4b=calc_HRBL(ONlp,ONhp)
  593. T5a,T5b=calc_HRBL(OFFlp,OFFhp)
  594. if det_switch==2:
  595. print('a*b HR')
  596. T4a,T4b=calc_HR(ONlp,ONhp)
  597. T5a,T5b=calc_HR(OFFlp,OFFhp)
  598. if det_switch==3:
  599. print('b/c BL')
  600. T4a,T4b=calc_BL(ONlp,ONhp)
  601. T5a,T5b=calc_BL(OFFlp,OFFhp)
  602. if det_switch==4:
  603. print('conduct based HRBL')
  604. T4a,T4b=calc_cb_HRBL(ONlp,ONhp)
  605. T5a,T5b=calc_cb_HRBL(OFFlp,OFFhp)
  606. if det_switch==5:
  607. print('conduct based HR')
  608. T4a,T4b=calc_cb_HR(ONlp,ONhp)
  609. T5a,T5b=calc_cb_HR(OFFlp,OFFhp)
  610. if det_switch==6:
  611. print('conduct based BL')
  612. T4a,T4b=calc_cb_BL(ONlp,ONhp)
  613. T5a,T5b=calc_cb_BL(OFFlp,OFFhp)
  614. if det_switch==7:
  615. print('conduct based exc-exc HRBL')
  616. T4a,T4b=calc_cb_eeiHRBL(ONlp,ONhp)
  617. T5a,T5b=calc_cb_eeiHRBL(OFFlp,OFFhp)
  618. if det_switch==8:
  619. print('conduct based exc-exc HR')
  620. T4a,T4b=calc_cb_eeHR(ONlp,ONhp)
  621. T5a,T5b=calc_cb_eeHR(OFFlp,OFFhp)
  622. T4rest=np.mean(T4a[:,:,0:50])
  623. #print 'T4 resting potential: ', T4rest
  624. T4a=T4gain*rect(T4a,T4rest*resting_factor)
  625. T4b=T4gain*rect(T4b,T4rest*resting_factor)
  626. T5a=T5gain*rect(T5a,T4rest*resting_factor)
  627. T5b=T5gain*rect(T5b,T4rest*resting_factor)
  628. T4a_mean=np.mean(np.mean(T4a,axis=0),axis=0)
  629. T4b_mean=np.mean(np.mean(T4b,axis=0),axis=0)
  630. T5a_mean=np.mean(np.mean(T5a,axis=0),axis=0)
  631. T5b_mean=np.mean(np.mean(T5b,axis=0),axis=0)
  632. synamp=0.05
  633. gexc=(T4a_mean+T5a_mean)*synamp
  634. ginh=(T4b_mean+T5b_mean)*synamp*LPigain
  635. HS=(40.0*gexc-20.0*ginh)/(gexc+ginh+1.0)
  636. #HS=T4a_mean+T5a_mean-LPigain*(T4b_mean+T5b_mean)
  637. detpos=19
  638. print('detector position =', detpos)
  639. if ret_switch == 0:
  640. result=T4a_mean
  641. print('T4a_mean')
  642. if ret_switch == 1:
  643. result=T4b_mean
  644. print('T4b_mean')
  645. if ret_switch == 2:
  646. result=HS
  647. print('HS cell')
  648. if ret_switch == 3:
  649. result=T4a[detpos,detpos,:]
  650. print('T4a')
  651. if ret_switch == 4:
  652. result=T5a[detpos,detpos,:]
  653. print('T5a')
  654. if ret_switch == 5:
  655. result=ONlp[detpos,detpos,:]
  656. print('ONlp')
  657. if ret_switch == 6:
  658. result=ONhp[detpos,detpos,:]
  659. print('ONhp')
  660. return result
  661. # --------------- STIMULUS GENERATION -----------------------------
  662. # calculates sine grating movie
  663. # velo is velocity function and determines length of movie
  664. # img_rot in degree determines the angle at which the grating is moving
  665. # spat_freq is the spatial frequency - a value of 5 = 40 deg wavelength
  666. def calc_singlewave(img_size,new_spat_freq,x,y):
  667. sinewave=np.sin((np.linspace(0,img_size-1,img_size)-x+y)/img_size*2.0*np.pi*new_spat_freq)
  668. return sinewave
  669. def calc_sinegrating(tf, img_rot, spat_freq, contrast):
  670. print()
  671. print('rot angle =', img_rot)
  672. n=tf.shape
  673. maxtime=n[0]
  674. img_size=200
  675. movie=np.zeros((img_size,img_size,maxtime))
  676. img_rot_rad=img_rot/360.0*2*np.pi
  677. new_spat_freq=spat_freq*np.cos(img_rot_rad)
  678. spat_wlength = img_size/spat_freq
  679. velo=tf*spat_wlength/100.0
  680. print('Spatial Wavelength =', spat_wlength)
  681. if np.min(velo)==0:
  682. print('Velocity (dt=10 msec) =', np.max(velo)*100, 'deg/s')
  683. print('Temp Freq (dt=10 msec) =', np.max(tf), 'Hz')
  684. if np.max(velo)==0:
  685. print('Velocity (dt=10 msec) =', np.min(velo)*100, 'deg/s')
  686. print('Temp Freq (dt=10 msec) =', np.min(tf), 'Hz')
  687. yshift=np.tan(img_rot_rad)
  688. new_velo=velo/np.cos(img_rot_rad)
  689. if img_rot==0:
  690. image=np.zeros((img_size,img_size))
  691. interim=calc_singlewave(img_size,spat_freq,0,0)
  692. for i in range(img_size):
  693. image[i,0::]=interim
  694. for i in range(maxtime):
  695. movie[:,:,i]=np.roll(image,int(sum(velo[0:i])),axis=1)
  696. else:
  697. for i in range(maxtime):
  698. for y in range(img_size):
  699. movie[y,:,i]=calc_singlewave(200,new_spat_freq,int(sum(new_velo[0:i])),int(yshift*y))
  700. movie=movie*contrast*0.5+0.5
  701. return movie
  702. def calc_1Dsinegrating(tf, spat_freq, contrast):
  703. n=tf.shape
  704. maxtime=n[0]
  705. img_size=200
  706. movie=np.zeros((img_size,maxtime))
  707. image=np.sin(np.linspace(0,img_size-1,img_size)/img_size*2.0*np.pi*spat_freq)
  708. image=image/2.0*contrast+0.5
  709. spat_wlength = img_size/spat_freq
  710. velo=tf*spat_wlength/100.0
  711. print('Spat Wlength =', spat_wlength)
  712. print('Velocity (dt=10 msec) =', np.max(velo)*100, 'deg/s')
  713. print('Temp Freq (dt=10 msec) =', np.max(tf), 'Hz')
  714. for i in range(maxtime):
  715. int_image=np.roll(image,int(sum(velo[0:i])),axis=0)
  716. movie[:,i]=int_image
  717. return movie
  718. # calculates motion noise movie
  719. def calc_motion_noise(maxtime,direction,perccoher,blurrindex):
  720. print()
  721. print('coherence [%]', perccoher)
  722. print()
  723. resol=100
  724. mostart=50
  725. mostop=maxtime-50
  726. movie=np.zeros((resol,resol,maxtime))
  727. nofdots=500
  728. seq=np.random.permutation(np.linspace(0,nofdots-1,nofdots))
  729. xpos=np.random.randint(resol, size=nofdots)
  730. ypos=np.random.randint(resol, size=nofdots)
  731. xvec=np.random.randint(-2,3, size=nofdots)
  732. yvec=np.random.randint(-2,3, size=nofdots)
  733. for i in range(maxtime):
  734. movie[xpos,ypos,i]=0
  735. if np.remainder(i,10) == 0:
  736. # ---------- new -----------
  737. xpos=np.random.randint(resol, size=nofdots)
  738. ypos=np.random.randint(resol, size=nofdots)
  739. # --------------------------
  740. xvec=np.random.randint(-2,3, size=nofdots)
  741. yvec=np.random.randint(-2,3, size=nofdots)
  742. if mostart<i<mostop:
  743. seq=np.random.permutation(np.linspace(0,nofdots-1,nofdots))
  744. xvec[seq.astype(int)[0:nofdots/100*perccoher]]=direction
  745. yvec[seq.astype(int)[0:nofdots/100*perccoher]]=0
  746. xpos=np.remainder(xpos+xvec,resol)
  747. ypos=np.remainder(ypos+yvec,resol)
  748. movie[ypos,xpos,i]=10.0
  749. movie=rebin(movie,200,200,maxtime)
  750. if blurrindex==1:
  751. for i in range(maxtime):
  752. print(i, end=' ')
  753. movie[:,:,i]=blurr(movie[:,:,i],5)
  754. plt.imshow(np.transpose(movie[0,:,:]), cmap='gray')
  755. return movie
  756. def calc_motion_noise_new(maxtime,direction,velo,perccoher,blurrindex):
  757. print()
  758. print('coherence [%]', perccoher)
  759. print()
  760. resol=100
  761. nofdots=5000 # total number of dots in whole movie
  762. mean_lifetime=20 # frames
  763. print('nof dots per frame', nofdots*mean_lifetime/maxtime)
  764. movie=np.zeros((resol,resol,maxtime))
  765. xpos=np.random.randint(0, resol, size=nofdots)
  766. ypos=np.random.randint(0, resol, size=nofdots)
  767. lifetime=np.random.randint(mean_lifetime-10,mean_lifetime+10, size=nofdots)
  768. tstart=np.random.randint(0, maxtime, size=nofdots)
  769. tstop=ceil(tstart+lifetime,maxtime)
  770. xdir=np.random.randint(-1,2, size=nofdots)
  771. ydir=np.random.randint(-1,2, size=nofdots)
  772. nofcoher_dots=perccoher/100.0*nofdots
  773. # correction
  774. # nofcoher_dots=(9*nofcoher_dots-nofdots)/8.0
  775. print(nofcoher_dots)
  776. xdir[0:nofcoher_dots]=direction
  777. ydir[0:nofcoher_dots]=0
  778. for i in range(nofdots):
  779. counter=0
  780. for t in range(tstart[i],tstop[i]):
  781. counter+=1
  782. velofac=int(counter*velo)
  783. myxpos=np.remainder(xpos[i]+velofac*xdir[i],resol)
  784. myypos=np.remainder(ypos[i]+velofac*ydir[i],resol)
  785. movie[myypos,myxpos,t]=10
  786. movie=rebin(movie,200,200,maxtime)
  787. if blurrindex==1:
  788. for i in range(maxtime):
  789. print(i, end=' ')
  790. movie[:,:,i]=blurr(movie[:,:,i],5)
  791. plt.imshow(np.transpose(movie[0,:,:]), cmap='gray')
  792. return movie
  793. def calc_PDND_motion_noise(maxtime,velo,perccoher,blurrindex):
  794. mystim1=calc_motion_noise_new(maxtime/2,1,velo,perccoher,blurrindex)
  795. mystim2=calc_motion_noise_new(maxtime/2,-1,velo,perccoher,blurrindex)
  796. output=np.concatenate((mystim1,mystim2),axis=2)
  797. return output
  798. # calculates motion field
  799. # switch = 1: coherent dot motion rightward
  800. # switch = 2: coherent dot motion leftward
  801. # switch = 3: coherent dot motion upward
  802. # switch = 4: coherent dot motion downward
  803. # switch = 5: expanding dot motion
  804. # switch = 6: contracting dot motion
  805. # switch = 7: cw rotating dot motion
  806. # switch = 8: ccw rotating dot motion
  807. def calc_motion_field(maxtime,switch):
  808. movie=np.zeros((200,200,maxtime))
  809. speed=2.0
  810. movie=np.zeros((200,200,maxtime))
  811. nofdots=500
  812. print('number of dots:', nofdots)
  813. xpos=np.random.random_sample(nofdots)*200
  814. ypos=np.random.random_sample(nofdots)*200
  815. for i in range(maxtime):
  816. print(i, end=' ')
  817. movie[ypos.astype(int),xpos.astype(int),i]=0
  818. for j in range(nofdots):
  819. if switch==1:
  820. xpos[j]=np.remainder(xpos[j]+speed,200)
  821. if switch==2:
  822. xpos[j]=np.remainder(xpos[j]-speed,200)
  823. if switch==3:
  824. ypos[j]=np.remainder(ypos[j]-speed,200)
  825. if switch==4:
  826. ypos[j]=np.remainder(ypos[j]+speed,200)
  827. if switch==5:
  828. alpha=np.arctan2(ypos[j]-100,xpos[j]-100)
  829. xvec=speed*np.cos(alpha)
  830. yvec=speed*np.sin(alpha)
  831. xpos[j]=xpos[j]+xvec
  832. ypos[j]=ypos[j]+yvec
  833. if xpos[j] > 199 or xpos[j] < 0:
  834. xpos[j]=np.random.random_sample()*50+75
  835. if ypos[j] > 199 or ypos[j] < 0:
  836. ypos[j]=np.random.random_sample()*50+75
  837. if switch==6:
  838. alpha=np.arctan2(ypos[j]-100,xpos[j]-100)
  839. xvec=speed*np.cos(alpha)
  840. yvec=speed*np.sin(alpha)
  841. xpos[j]=xpos[j]-xvec
  842. ypos[j]=ypos[j]-yvec
  843. if (xpos[j]>97 and xpos[j]<103) and (ypos[j]>97 and ypos[j]<103):
  844. xpos[j]=np.random.random_sample()*200
  845. ypos[j]=np.random.random_sample()*200
  846. if switch==7:
  847. xvec=speed*0.05*(ypos[j]-100)
  848. yvec=speed*0.05*(xpos[j]-100)
  849. xpos[j]=xpos[j]-xvec
  850. ypos[j]=ypos[j]+yvec
  851. if (xpos[j]>199 or xpos[j]<0):
  852. xpos[j]=np.random.random_sample()*200
  853. if (ypos[j]>199 or ypos[j]<0):
  854. ypos[j]=np.random.random_sample()*200
  855. if switch==8:
  856. xvec=speed*0.05*(ypos[j]-100)
  857. yvec=speed*0.05*(xpos[j]-100)
  858. xpos[j]=xpos[j]+xvec
  859. ypos[j]=ypos[j]-yvec
  860. if (xpos[j]>199 or xpos[j]<0):
  861. xpos[j]=np.random.random_sample()*200
  862. if (ypos[j]>199 or ypos[j]<0):
  863. ypos[j]=np.random.random_sample()*200
  864. movie[ypos.astype(int),xpos.astype(int),i]=10.0
  865. for i in range(100):
  866. movie[:,:,i]=movie[:,:,100]
  867. movie[:,:,maxtime-100+i]=movie[:,:,maxtime-101]
  868. for i in range(maxtime):
  869. print(i, end=' ')
  870. movie[:,:,i]=blurr(movie[:,:,i],5)
  871. plt.imshow(np.transpose(movie[0,:,:]), cmap='gray')
  872. return movie
  873. # calculates transparent motion
  874. def calc_transparent_motion(maxtime):
  875. rightward = calc_motion_field(maxtime,1)
  876. leftward = calc_motion_field(maxtime,2)
  877. movie=rightward+leftward
  878. plt.imshow(np.transpose(movie[0,:,:]), cmap='gray')
  879. return movie
  880. # Calculates Phi Motion
  881. #
  882. # switch=1: phi motion
  883. # switch=2: rev phi
  884. # switch=3: reiser phi
  885. def calc_phi_motion(switch,tstep,xstep,maxtime,wavel=50):
  886. movie=np.zeros((200,200,maxtime))
  887. image=np.zeros((200,200))
  888. counter=0
  889. if wavel==50:
  890. for i in range(4):
  891. image[:,0+i*50:25+i*50]=1.0
  892. if wavel==100:
  893. for i in range(2):
  894. image[:,0+i*100:50+i*100]=1.0
  895. if wavel==200:
  896. for i in range(1):
  897. image[:,0+i*200:100+i*200]=1.0
  898. image=np.roll(image,10)
  899. #image=blurr(image,5)
  900. image=np.roll(image,-10)
  901. movie[:,:,0]=image
  902. for i in range(maxtime-1):
  903. t=i+1
  904. movie[:,:,t]=movie[:,:,t-1]
  905. if np.remainder(t,tstep)==1:
  906. counter+=1
  907. movie[:,:,t]=np.roll(image,xstep*counter,axis=1)
  908. if np.remainder(counter,2)==0:
  909. if switch == 2:
  910. movie[:,:,t]=1-movie[:,:,t]
  911. if switch == 3:
  912. movie[:,:,t]=(-1)*movie[:,:,t]
  913. if switch==3: movie=0.5*(movie+1.0)
  914. plt.imshow(np.transpose(movie[0,:,:]), cmap='gray')
  915. return movie
  916. # calculates correlated motion
  917. # rule=1: no correlation
  918. # rule=2: Fourier motion
  919. # rule=3: 3-P correlation (converging)
  920. # rule=4: 3-P correlation (diverging)
  921. def calc_glider_motion(rule,parity,maxtime):
  922. speed=2
  923. movie=np.zeros((200,40,maxtime/speed))-1
  924. if rule==1:
  925. for t in range(maxtime/speed):
  926. for x in range(39):
  927. if np.random.randn()>0:
  928. movie[:,x,t]=+1
  929. if rule==2:
  930. for x in range(40):
  931. if np.random.randn()>0:
  932. movie[:,x,0]=+1
  933. for t in range(maxtime/speed-1):
  934. if np.random.randn()>0:
  935. movie[:,0,t+1]=+1
  936. for x in range(39):
  937. movie[:,x+1,t+1]=movie[:,x,t]*parity
  938. if rule==3:
  939. for x in range(40):
  940. if np.random.randn()>0:
  941. movie[:,x,0]=+1
  942. for t in range(maxtime/speed-1):
  943. if np.random.randn()>0:
  944. movie[:,0,t+1]=+1
  945. for x in range(39):
  946. movie[:,x+1,t+1]=movie[:,x,t]*movie[:,x+1,t]*parity
  947. if rule==4:
  948. for x in range(40):
  949. if np.random.randn()>0:
  950. movie[:,x,0]=+1
  951. for t in range(maxtime/speed-1):
  952. if np.random.randn()>0:
  953. movie[:,0,t+1]=+1
  954. for x in range(39):
  955. movie[:,x+1,t+1]=movie[:,x,t]*movie[:,x,t+1]*parity
  956. movie=np.repeat(movie,5,axis=1)
  957. movie=np.repeat(movie,speed,axis=2)
  958. for t in range(50):
  959. movie[:,:,t]=movie[:,:,50]
  960. movie[:,:,maxtime-50+t]=movie[:,:,maxtime-51]
  961. movie=(movie+1.0)*0.5
  962. for t in range(maxtime):
  963. print(t, end=' ')
  964. movie[:,:,t]=blurr(movie[:,:,t],5)
  965. plt.imshow(np.transpose(movie[0,:,:]), cmap='gray')
  966. return movie
  967. # calculates apparent motion movie
  968. def calc_app_motion(dphi,dt):
  969. maxtime=100
  970. movie=np.zeros((200,200,maxtime))
  971. movie[:,50:60,10:maxtime-1]=1.0
  972. movie[:,50+dphi:60+dphi,10+dt:maxtime-1]=1.0
  973. for i in range(maxtime):
  974. movie[:,:,i]=blurr(movie[:,:,i],5)
  975. return movie
  976. def calc_looming_square(maxtime,speed):
  977. movie=np.zeros((200,200,maxtime))+1.0
  978. size=40.0
  979. for t in range(maxtime):
  980. alpha=np.arctan(size/(1.0*(maxtime/speed+10-t/speed)))/(2.0*np.pi)*360.0
  981. print(alpha)
  982. lower=100-round(alpha)
  983. upper=100+round(alpha)
  984. movie[lower:upper,lower:upper,t]=0
  985. for t in range(100):
  986. movie[:,:,t]=movie[:,:,100]
  987. movie[:,:,maxtime-100+t]=movie[:,:,maxtime-101]
  988. for t in range(maxtime):
  989. print(t)
  990. movie[:,:,t]=blurr(movie[:,:,t],5)
  991. return movie
  992. # calculates sawtooth movie
  993. # velo is velocity function and determines length of movie
  994. # polarity 1/2 defines a positively or negatively going sawtooth
  995. # spat_freq is the spatial frequency - a value of 5 = 40 deg wavelength
  996. def calc_sawtooth(velo,polarity,spat_freq):
  997. n=velo.shape
  998. maxtime=n[0]
  999. img_size=200
  1000. movie=np.zeros((img_size,img_size,maxtime))
  1001. image=np.zeros((img_size,img_size))
  1002. interim=np.remainder(np.linspace(0,img_size-1,img_size),img_size/spat_freq)
  1003. interim=interim/np.max(interim)
  1004. if polarity == 2:
  1005. interim=interim[::-1]
  1006. for i in range(img_size):
  1007. image[i,0::]=interim
  1008. spat_wlength = img_size/spat_freq
  1009. print('Spat Wlength =', spat_wlength)
  1010. temp_freq = np.max(velo)*1000.0/spat_wlength
  1011. print('Temp Freq =', temp_freq)
  1012. for i in range(maxtime):
  1013. movie[:,:,i]=np.roll(image,int(sum(velo[0:i])),axis=1)
  1014. return movie
  1015. # calculates ON or OFF edge movie
  1016. # switch=1: ON edge, switch =2, OFF edge
  1017. # velo = deg_per_frame
  1018. def calc_edge(velo,onoffswitch):
  1019. maxtime=1000
  1020. img_size=200
  1021. movie=np.zeros((img_size,img_size,maxtime))
  1022. for i in range(maxtime):
  1023. movie[:,0:(i*velo),i]=1
  1024. if onoffswitch == 2:
  1025. movie=1-movie
  1026. return movie
  1027. # calculates ON or OFF bar movie
  1028. # switch=1: ON edge, switch =2, OFF edge
  1029. def calc_bar(switch,width):
  1030. if width>50:
  1031. width=50
  1032. maxtime=300
  1033. img_size=200
  1034. movie=np.zeros((img_size,img_size,maxtime))
  1035. for i in range(img_size):
  1036. movie[:,i,50+i:50+width+i]=1.0
  1037. if switch == 2:
  1038. movie=1.0-movie
  1039. for i in range(maxtime):
  1040. movie[:,:,i]=blurr(movie[:,:,i],5)
  1041. return movie
  1042. # calculates hopping ON or OFF bar
  1043. # switch=1: ON edge, switch =2, OFF edge
  1044. def calc_hopp_bar(switch):
  1045. maxtime=200
  1046. movie=np.zeros((200,200,maxtime))
  1047. for i in range(40):
  1048. movie[:,5*i:5*i+5,5*i:5*i+5]=1.0
  1049. if switch == 2:
  1050. movie=1.0-movie
  1051. #for i in range(maxtime):
  1052. #movie[:,:,i]=blurr(movie[:,:,i],5)
  1053. return movie
  1054. # --------------- test motion detector models -------------------------------
  1055. def calc_dphi_dependence(EMDswitch,celltype,resting_factor=0):
  1056. response=np.zeros((50))
  1057. for i in range(50):
  1058. print(i)
  1059. mymovie=calc_app_motion(i,10)
  1060. result=NewEMD(stimulus=mymovie,deltat=10,det_switch=EMDswitch,ret_switch=celltype,resting_factor=resting_factor)
  1061. response[i]=np.sum(result)
  1062. return response
  1063. # calculates orientation tuning of EMD
  1064. def calc_orientation_tuning(EMDswitch,celltype,spat_freq,plotit=1,resting_factor=0):
  1065. response=np.zeros(13)
  1066. myvelo=np.zeros(300)
  1067. myvelo[50:300]=1.0
  1068. for w in range(13):
  1069. print()
  1070. img_rot=w*30
  1071. print('angle=', img_rot)
  1072. movie=calc_sinegrating(myvelo,img_rot,spat_freq,1.0)
  1073. output=NewEMD(stimulus=movie,deltat=10,det_switch=EMDswitch,ret_switch=celltype,resting_factor=resting_factor)
  1074. response[w]=np.mean(output[200:300])-np.mean(output[0:50])
  1075. response=normalize(response)
  1076. if plotit==1:
  1077. myalpha=np.linspace(90,450,13)
  1078. plt.polar(myalpha/360.0*2*np.pi,rect(response,0),linewidth=4,color='black')
  1079. plt.ylim(0,1.2)
  1080. plt.yticks(np.arange(3)*0.5)
  1081. locs, labels=plt.yticks()
  1082. plt.yticks(locs, ('','',''))
  1083. return response
  1084. def calc_tf_dependence(EMDswitch,celltype,spat_freq=5,contrast=1,plotit=1,resting_factor=0):
  1085. grating_switch=0
  1086. ss_switch=1
  1087. if EMDswitch==0:
  1088. mylabel='4QD'
  1089. if EMDswitch==1:
  1090. mylabel='2QD'
  1091. if EMDswitch==2:
  1092. mylabel='ab/c HRBL'
  1093. if EMDswitch==3:
  1094. mylabel='cb HRBL'
  1095. if EMDswitch==4:
  1096. mylabel='cb HR'
  1097. if EMDswitch==5:
  1098. mylabel='cb BL'
  1099. if celltype==0: mylabel=mylabel+' T4a'
  1100. if celltype==1: mylabel=mylabel+' T4b'
  1101. if celltype==2: mylabel=mylabel+' HS'
  1102. maxvelo=np.array([0.1,0.2,0.5,1.0,2.0,5.0,10.0])
  1103. velofct=np.zeros(300)
  1104. velofct[50:250]=1.0
  1105. resp=np.zeros((2,7))
  1106. for j in range(2):
  1107. k=j*2-1
  1108. for i in range(7):
  1109. print()
  1110. movie=calc_sinegrating(k*velofct*maxvelo[i],0,spat_freq,contrast)
  1111. if grating_switch==1:
  1112. movie=movie>0.5
  1113. output=NewEMD(stimulus=movie,deltat=10,det_switch=EMDswitch,ret_switch=celltype,resting_factor=resting_factor)
  1114. if ss_switch==0:
  1115. resp[j,i]=np.mean(output[50:250])-np.mean(output[0:50])
  1116. if ss_switch==1:
  1117. resp[j,i]=np.mean(output[150:250])-np.mean(output[0:50])
  1118. if plotit==1:
  1119. plt.figure()
  1120. plt.plot(maxvelo, resp[1,:]/np.max(resp), linewidth=3, color='blue',label=mylabel+'PD')
  1121. plt.plot(maxvelo, resp[0,:]/np.max(resp), linewidth=3, color='red', label=mylabel+'ND')
  1122. plt.plot(maxvelo,maxvelo*0, color='black')
  1123. plt.xlabel('temp. frequency [Hz]',fontsize=8)
  1124. plt.ylabel('response',fontsize=8)
  1125. plt.xscale('log')
  1126. plt.xlim(0.1,10)
  1127. plt.legend(fontsize=8,loc=4, frameon=False)
  1128. plt.ylim(-1.1,1.1)
  1129. return resp
  1130. def calc_edgevelo_dependence(EMDswitch,celltype,onoffswitch,plotit=1,resting_factor=0):
  1131. if onoffswitch == 1: print('ON edge')
  1132. if onoffswitch == 2: print('OFF edge')
  1133. if EMDswitch==0:
  1134. mylabel='4QD'
  1135. if EMDswitch==1:
  1136. mylabel='2QD'
  1137. if EMDswitch==2:
  1138. mylabel='ab/c HRBL'
  1139. if EMDswitch==3:
  1140. mylabel='cb HRBL'
  1141. if EMDswitch==4:
  1142. mylabel='cb HR'
  1143. if EMDswitch==5:
  1144. mylabel='cb BL'
  1145. if celltype==0: mylabel=mylabel+' T4a'
  1146. if celltype==1: mylabel=mylabel+' T4b'
  1147. if celltype==2: mylabel=mylabel+' HS'
  1148. maxvelo=np.array([0.1,0.2,0.5,1.0,2.0,5.0,10.0])
  1149. resp=np.zeros((2,7))
  1150. for j in range(2):
  1151. for i in range(7):
  1152. stimperiod=200.0/maxvelo[i]
  1153. print('Velo=',maxvelo[i],'[deg/frame]')
  1154. print('stimperiod =', stimperiod, '[frames]')
  1155. movie=calc_edge(maxvelo[i],onoffswitch)
  1156. if j == 0: movie=movie[:,::-1,:]
  1157. output=NewEMD(stimulus=movie,deltat=10,det_switch=EMDswitch,ret_switch=celltype,resting_factor=resting_factor)
  1158. resp[j,i]=np.mean(output[0:int(stimperiod)])
  1159. if plotit==1:
  1160. plt.figure()
  1161. plt.plot(maxvelo*100,resp[1,:]/np.max(resp), linewidth=3, color='blue', label=mylabel+' PD')
  1162. plt.plot(maxvelo*100,resp[0,:]/np.max(resp), linewidth=3, color='red', label=mylabel+' ND')
  1163. plt.plot(maxvelo*100,maxvelo*0, color='black')
  1164. plt.xlabel('edge velocity [deg/sec]')
  1165. plt.ylabel('response')
  1166. plt.xscale('log')
  1167. plt.legend(fontsize=10, loc=4, frameon=False)
  1168. plt.ylim(-1.1,1.1)
  1169. return resp
  1170. def calc_contrast_dependence(EMDswitch,celltype,spat_freq, PDNDswitch,plotit=1,resting_factor=0):
  1171. if EMDswitch==0:
  1172. mylabel='4QD'
  1173. if EMDswitch==1:
  1174. mylabel='2QD'
  1175. if EMDswitch==2:
  1176. mylabel='ab/c HRBL'
  1177. if EMDswitch==3:
  1178. mylabel='cb HRBL'
  1179. if EMDswitch==4:
  1180. mylabel='cb HR'
  1181. if EMDswitch==5:
  1182. mylabel='cb BL'
  1183. if celltype==0: mylabel=mylabel+' T4a'
  1184. if celltype==1: mylabel=mylabel+' T4b'
  1185. if celltype==2: mylabel=mylabel+' HS'
  1186. contrast=np.linspace(0,1,6)
  1187. velo=np.zeros(500)
  1188. velo[50:500]=1.0*PDNDswitch
  1189. resp=np.zeros(6)
  1190. for i in range(6):
  1191. print()
  1192. print(contrast[i])
  1193. movie=calc_sinegrating(velo,0,spat_freq,contrast[i])
  1194. output=NewEMD(stimulus=movie,deltat=10,det_switch=EMDswitch,ret_switch=celltype,resting_factor=resting_factor)
  1195. output=output-np.mean(output[0:50])
  1196. resp[i]=np.mean(output[200:500])
  1197. if plotit==1:
  1198. plt.plot(contrast, resp, linewidth=3, color='black', label=mylabel)
  1199. plt.xlabel('contrast')
  1200. plt.ylabel('response')
  1201. plt.legend(fontsize=10, loc=4, frameon=False)
  1202. return resp
  1203. #---------------------------------------------------------------------------------
  1204. def fit_bandpass(stim,mydata,nofsteps,stepsize,wstart,wstop):
  1205. myerror=np.zeros((nofsteps,nofsteps))
  1206. for i in range(nofsteps):
  1207. hptc=(i)*stepsize
  1208. hp=highpass(stim,hptc)
  1209. for j in range(nofsteps):
  1210. lptc=(j+1)*stepsize
  1211. output=lowpass(hp,lptc)
  1212. output=normalize(output)
  1213. myerror[i,j]=np.nanmean((mydata[wstart:wstop]-output[wstart:wstop])**2)
  1214. opti=np.argmin(myerror)
  1215. indices=np.unravel_index(opti,(nofsteps,nofsteps))
  1216. hptc=(indices[0])*stepsize
  1217. lptc=(indices[1]+1)*stepsize
  1218. return np.array([hptc,lptc])
  1219. # calculates temp freq response of LP detector
  1220. def calc_LPresp(taulp,om):
  1221. denom=(1.0+(taulp*om)**2)
  1222. output=(taulp*om)/denom
  1223. return output
  1224. # calculates temp freq response of HP-LP or HP-In detector
  1225. def calc_HPLPresp(taulp,tauhp,om,switch):
  1226. denom=(1.0+(taulp*om)**2)*(1.0+(tauhp*om)**2)
  1227. output=tauhp*om*(switch*1.0+tauhp*taulp*om**2)/denom
  1228. return output
  1229. # determines temp freq optimum of HP-LP or HP-In detector
  1230. # between between 0.1 and 10 Hz
  1231. # as a function of taulp (from 1 to 200 ms) and tauhp (from 1 to 200 ms)
  1232. def calc_tfopt(switch):
  1233. if switch==0: print('HP-In Detector')
  1234. if switch==1: print('LP-HP Detector')
  1235. tf=np.linspace(0,99,100)*0.1
  1236. om=tf*2.0*np.pi
  1237. myrange=1000
  1238. opt=np.zeros((myrange,myrange))
  1239. for i in range(myrange):
  1240. taulp=(i+1)*0.001
  1241. for j in range(myrange):
  1242. tauhp=(j+1)*0.001
  1243. resp=calc_HPLPresp(taulp,tauhp,om,switch)
  1244. opt[i,j]=np.argmax(resp)*0.1
  1245. plt.imshow(np.log10(opt), cmap='hot',vmin=-0.5,vmax=1)
  1246. return opt
  1247. # Same as above, however explicit calculation
  1248. def calc_numtfopt(taulp, tauhp):
  1249. L=taulp**2
  1250. H=tauhp**2
  1251. x=np.sqrt(1.0/(L*H)*(L+H+np.sqrt((L+H)**2+12*H*L)))
  1252. tfopt=x/(2.0*np.pi)
  1253. return tfopt
  1254. # writes an mp4 movie to the disk
  1255. def make_movie(movie, name="my_movie.mp4", fps=30):
  1256. import matplotlib.animation as animation
  1257. n=movie.shape
  1258. fig = plt.figure()
  1259. im = plt.imshow(movie[:,:,0],cmap='gray',vmin=0,vmax=1)
  1260. def animate(i):
  1261. im.set_data(movie[:,:,i])
  1262. return im,
  1263. a = animation.FuncAnimation(fig, animate, frames=n[2])
  1264. mywriter = animation.FFMpegWriter(fps=fps,bitrate=1000)
  1265. a.save(name, writer=mywriter)
  1266. # removes motion artefact from a movie
  1267. def remove_motion(images):
  1268. n=images.shape
  1269. output=np.zeros((n[0],n[1],n[2]))
  1270. output[:,:,0]=images[:,:,0]
  1271. for i in range(n[2]-1):
  1272. myframe=i+1
  1273. myshift=cv2.phaseCorrelate(output[:,:,0],images[:,:,myframe])
  1274. print(myshift)
  1275. output[:,:,myframe]=np.roll(images[:,:,myframe],-np.int(np.round(myshift[1])), axis=0)
  1276. output[:,:,myframe]=np.roll(output[:,:,myframe],-np.int(np.round(myshift[0])), axis=1)
  1277. return output
  1278. # plots a flow-field
  1279. # switch=1: translation downward
  1280. # switch=2: expansion
  1281. # switch=1: rotation
  1282. # switch=4: random
  1283. def plot_flowfield(res,ffswitch,colorswitch):
  1284. n=res
  1285. myscale=8
  1286. x,y=np.mgrid[-n:n+1,-n:n+1]
  1287. if ffswitch==1:
  1288. u,v=0,-res
  1289. if ffswitch==2:
  1290. u,v=x,y
  1291. if ffswitch==3:
  1292. u,v=-y,x
  1293. if ffswitch==4:
  1294. u=(np.random.random_sample((2*n+1,2*n+1))-0.5)*res*2
  1295. v=(np.random.random_sample((2*n+1,2*n+1))-0.5)*res*2
  1296. if colorswitch==0:
  1297. plt.quiver(x,y,u,v,color='black',scale=myscale, scale_units='xy')
  1298. if colorswitch==1:
  1299. z=-v
  1300. plt.quiver(x,y,u,v,z,cmap='bwr',scale=myscale, scale_units='xy')
  1301. plt.xlim(-n-1,n+1)
  1302. plt.ylim(-n-1,n+1)
  1303. def nice2Dfct(switch):
  1304. if switch==1:
  1305. points = np.linspace(-10, 10, 101)
  1306. X,Y = np.meshgrid(points, points)
  1307. R = np.sqrt(X**2 + Y**2)
  1308. Z = jn(0,R)
  1309. if switch==2:
  1310. X,Y = np.mgrid[-4:2:100j, -4:2:100j]
  1311. Z = 10 * np.cos(X**2 - Y**2)
  1312. if switch==3:
  1313. X,Y = np.mgrid[-4:2:100j, -4:2:100j]
  1314. Z = 10 * np.cos(X**2 + Y**2)
  1315. return Z
  1316. def setmyaxes(myxpos,myypos,myxsize,myysize):
  1317. ax=plt.axes([myxpos,myypos,myxsize,myysize])
  1318. ax.xaxis.set_ticks_position('bottom')
  1319. ax.yaxis.set_ticks_position('left')
  1320. # plots either a 3D grid or 3D surface of f(x,y)
  1321. def plot3D(data,switch=1,color_switch=2):
  1322. fig = plt.figure(figsize=(9,6))
  1323. ax = fig.gca(projection='3d')
  1324. n=data.shape
  1325. X = np.linspace(1, n[1], n[1])
  1326. Y = np.linspace(1, n[0], n[0])
  1327. X, Y = np.meshgrid(X, Y)
  1328. Z = data
  1329. # Create a light source with 180 deg azimuth, 45 deg elevation.
  1330. light = LightSource(180,45)
  1331. if color_switch==1:
  1332. illuminated_surface = light.shade(Z, cmap=cm.copper)
  1333. mycolor='copper'
  1334. if color_switch==2:
  1335. illuminated_surface = light.shade(Z, cmap=cm.coolwarm)
  1336. mycolor='coolwarm'
  1337. # Set view parameters with 45 deg azimuth, 60 deg elevation.
  1338. ax.view_init(20,45)
  1339. if switch==1:
  1340. ax.plot_surface(X, Y, Z, cmap=mycolor,rstride=1, cstride=1,
  1341. linewidth=0, antialiased=True,facecolors=illuminated_surface)
  1342. if switch==2:
  1343. ax.plot_wireframe(X, Y, Z, rstride=1, cstride=1)
  1344. plt.show()
  1345. def plot3Dline(x,y,z):
  1346. fig = plt.figure()
  1347. ax = fig.gca(projection='3d')
  1348. ax.plot(x,y,z)
  1349. def plotShade(data):
  1350. n=data.shape
  1351. X = np.linspace(1, n[1], n[1])
  1352. Y = np.linspace(1, n[0], n[0])
  1353. X, Y = np.meshgrid(X, Y)
  1354. Z = data
  1355. cmap = plt.cm.copper
  1356. ls = LightSource(315, 45)
  1357. rgb = ls.shade(Z, cmap)
  1358. fig, ax = plt.subplots()
  1359. ax.imshow(rgb)
  1360. # Use a proxy artist for the colorbar...
  1361. im = ax.imshow(Z, cmap=cmap)
  1362. im.remove()
  1363. fig.colorbar(im)
  1364. plt.show()
  1365. def plot3DCube(data):
  1366. data=1.0*rebin(data,50,50,50)
  1367. # add black edges
  1368. data[:,0,0]=0
  1369. data[:,49,0]=0
  1370. data[:,49,49]=0
  1371. data[:,0,49]=0
  1372. data[0,:,0]=0
  1373. data[49,:,0]=0
  1374. data[49,:,49]=0
  1375. data[0,:,49]=0
  1376. data[0,0,:]=0
  1377. data[49,0,:]=0
  1378. data[49,49,:]=0
  1379. data[0,49,:]=0
  1380. fig = plt.figure()
  1381. ax = fig.gca(projection='3d')
  1382. xx, yy = np.meshgrid(np.arange(50), np.arange(50))
  1383. zz = np.arange(50)*0+50
  1384. roofdata=np.transpose(data[49,:,:])
  1385. ax.plot_surface(xx,yy,zz, rstride=1, cstride=1, facecolors=plt.cm.gray(roofdata), shade=False)
  1386. yy, zz = np.meshgrid(np.arange(50), np.arange(50))
  1387. xx = np.arange(50)*0+50
  1388. sidedata=data[:,49,:]
  1389. ax.plot_surface(xx,yy,zz, rstride=1, cstride=1, facecolors=plt.cm.gray(sidedata), shade=False)
  1390. xx, zz = np.meshgrid(np.arange(50), np.arange(50))
  1391. yy = np.arange(50)*0
  1392. frontdata=data[:,:,0]
  1393. ax.plot_surface(xx,yy,zz, rstride=1, cstride=1, facecolors=plt.cm.gray(frontdata), shade=False)
  1394. plt.axis('off')
  1395. plt.show()
  1396. def plot_polar(data,mycolor='black',mylabel='Cntrl',overplot=0):
  1397. if overplot==0:
  1398. plt.figure()
  1399. nofdim=data.ndim
  1400. if nofdim==1:
  1401. mean=1.0*data/np.max(data)
  1402. else:
  1403. mean=data[0]/np.max(data[0])
  1404. sem=data[1]/np.max(data[0])
  1405. n=mean.shape[0]
  1406. angle=np.arange(n)
  1407. plt.polar(angle/(1.0*n)*2*np.pi,mean,linewidth=3,color=mycolor,label=mylabel)
  1408. plt.yticks(np.arange(3)*0.5)
  1409. locs, labels=plt.yticks()
  1410. plt.yticks(locs, ('','',''))
  1411. plt.ylim(0,1.2)
  1412. plt.legend(loc=6,frameon=False)
  1413. # ---- color stuff --------------------------
  1414. def pickcolor(ccode,i):
  1415. mycolor=np.array(['11','33','55','77','99','BB','DD','FF'])
  1416. myclrar=np.array(['#FF0000','#FF8800','#888800','#008800','#00FF88','#00FFFF','#0088FF','#0000FF'])
  1417. if ccode==1: thecolor='#'+mycolor[i]+mycolor[i]+'00'
  1418. if ccode==2: thecolor='#'+mycolor[i]+'00'+mycolor[i]
  1419. if ccode==3: thecolor='#'+'00'+mycolor[i]+mycolor[i]
  1420. if ccode==4: thecolor=myclrar[i]
  1421. return thecolor
  1422. def getRGBvals(ccode,shift=0,view=0):
  1423. rgbvals=np.zeros((256,3))
  1424. if ccode<5:
  1425. for i in range(256):
  1426. if ccode==1: interim=plt.cm.hot(i)
  1427. if ccode==2: interim=plt.cm.rainbow(i)
  1428. if ccode==3: interim=plt.cm.bwr(i)
  1429. if ccode==4: interim=plt.cm.hsv(i)
  1430. for j in range(3):
  1431. rgbvals[i,j]=interim[j]
  1432. if ccode==5:
  1433. interim=(np.sin(np.linspace(0,2.0*np.pi,256))+1.0)*127.0
  1434. rgbvals[:,0]=np.roll(interim,+64)
  1435. rgbvals[:,1]=np.roll(interim,-64)
  1436. rgbvals[:,2]=np.roll(interim,128)
  1437. rgbvals=np.roll(rgbvals,shift,axis=0)
  1438. if view==1:
  1439. plt.figure()
  1440. plt.plot(rgbvals[:,0], linewidth=3, color='red')
  1441. plt.plot(rgbvals[:,1], linewidth=3, color='green')
  1442. plt.plot(rgbvals[:,2], linewidth=3, color='blue')
  1443. if ccode==1: plt.title('CMap HOT')
  1444. if ccode==2: plt.title('CMap Rainbow')
  1445. if ccode==3: plt.title('CMap BWR')
  1446. if ccode==4: plt.title('CMap HSV')
  1447. if ccode==5: plt.title('CMap Circular')
  1448. return rgbvals
  1449. def convim(image,ccode,shift=0,view=0):
  1450. n=image.shape
  1451. outim=np.zeros((n[0],n[1],3))
  1452. myimage=normalize(1.0*image)*255
  1453. myrgbvals=getRGBvals(ccode)
  1454. for i in range(3):
  1455. outim[:,:,i]=myrgbvals[myimage.astype(int),i]
  1456. outim=normalize(outim)
  1457. if view==1:
  1458. plt.figure()
  1459. plt.imshow(outim)
  1460. return outim
  1461. def create_colorwheel(ccode, satfac=0.3, shift=0, discr=0):
  1462. phase=np.zeros((256,256))
  1463. amp=np.zeros((256,256))
  1464. outim=np.zeros((256,256,3))
  1465. x,y=np.mgrid[-128:128,-128:128]
  1466. x=-1.0*x
  1467. amp=np.sqrt(x**2+y**2)
  1468. phase=np.arctan2(x,y)+np.pi
  1469. myrgbvals=getRGBvals(ccode,shift)
  1470. phase=normalize(phase)*255
  1471. if discr != 0:
  1472. interim=(phase+32)/64
  1473. phase=interim.astype(int)*64
  1474. phase=phase*(phase<200)
  1475. amp=normalize(amp)
  1476. amp=amp/(satfac+amp)
  1477. for i in range(3):
  1478. outim[:,:,i]=myrgbvals[phase.astype(int),i]*amp
  1479. outim=normalize(outim)
  1480. outim=outim[:,::-1,:]
  1481. plt.imshow(outim)
  1482. def createhuesat(satfac=10.0):
  1483. outim=np.zeros((256,256,3))
  1484. phase=np.zeros((256,256))
  1485. for i in range(256):
  1486. phase[i,:]=i
  1487. amp=np.transpose(phase)
  1488. myrgbvals=getRGBvals(4)+1
  1489. for i in range(3):
  1490. outim[:,:,i]=myrgbvals[phase.astype(int),i]*amp
  1491. outim=ceil(outim,satfac)
  1492. outim=normalize(outim)
  1493. plt.imshow(outim, origin='lower')
  1494. def showdirmap(amp,phase,ccode=4,satfac=0.1,shift=0):
  1495. outim=np.zeros((256,256,3))
  1496. myrgbvals=getRGBvals(ccode,shift)
  1497. phase=normalize(phase)*255
  1498. amp=normalize(amp)
  1499. amp=amp/(satfac+amp)
  1500. for i in range(3):
  1501. outim[:,:,i]=myrgbvals[phase.astype(int),i]*amp
  1502. outim=normalize(outim)
  1503. plt.imshow(outim)
  1504. def create_overlay(greyim,actim,thrld,ccode):
  1505. gshape=greyim.shape
  1506. ashape=actim.shape
  1507. outputim=np.zeros((gshape[0],gshape[1],3))
  1508. if gshape != ashape: print('images must have same shape')
  1509. if greyim.ndim !=2 or actim.ndim !=2: print('images must be 2D!')
  1510. convactim=convim(actim,ccode)
  1511. convactim=normalize(convactim)
  1512. greyim=normalize(greyim)
  1513. mask=actim>thrld
  1514. for k in range(3):
  1515. outputim[:,:,k]=(1-mask)*greyim+mask*convactim[:,:,k]
  1516. plt.imshow(outputim)
  1517. return outputim
  1518. # ------Compartmental Modeling ------------------------------
  1519. # ----- artificial test neurons -----------------------------
  1520. def build_cable(nofcomps,complength,compradius):
  1521. cable=np.zeros((nofcomps,7))
  1522. for i in range(nofcomps):
  1523. cable[i,0]=i+1
  1524. cable[i,2]=i*complength
  1525. cable[i,5]=compradius
  1526. cable[i,6]=i
  1527. cable[0,6]=-1
  1528. return cable
  1529. def build_tapered_cable(nofcomps,complength,compradius):
  1530. cable=np.zeros((nofcomps,7))
  1531. for i in range(nofcomps):
  1532. cable[i,0]=i+1
  1533. cable[i,2]=i*complength
  1534. cable[i,5]=compradius*i
  1535. cable[i,6]=i
  1536. cable[0,6]=-1
  1537. return cable
  1538. def build_tree(nofcomps,complength,compradius):
  1539. tree=np.zeros((nofcomps,7))
  1540. for i in range(nofcomps/2):
  1541. tree[i,0]=i+1
  1542. tree[i,2]=i*complength
  1543. tree[i,5]=compradius
  1544. tree[i,6]=i
  1545. for i in range(nofcomps/2,nofcomps):
  1546. tree[i,0]=i+1
  1547. tree[i,2]=nofcomps/4*complength
  1548. tree[i,3]=(i+2-nofcomps/2)*complength
  1549. tree[i,5]=compradius*0.5
  1550. tree[i,6]=i
  1551. tree[nofcomps/2,6]=nofcomps/4+1
  1552. tree[0,6]=-1
  1553. return tree
  1554. # --------calculate Adjancy and Conductance Matrices ---
  1555. def calc_AdjM(mycell):
  1556. interim=mycell.shape
  1557. nofcomps=interim[0]
  1558. IdenM=np.identity(nofcomps)
  1559. AdjM=np.zeros((nofcomps,nofcomps))
  1560. for i in range(nofcomps):
  1561. if mycell[i,6]!=-1:
  1562. AdjM[i,mycell[i,6]-1]=1
  1563. AdjM[:,:]=AdjM[:,:]+np.transpose(AdjM[:,:])+IdenM
  1564. return AdjM
  1565. def calc_Conductance_M(mycell, Rm=16000.0, Ra=200.0, Cm=0.6, deltat=0.001):
  1566. # Rm=16000.0 # Ohm cm^2
  1567. # Ra=0200.0 # Ohm cm
  1568. # Cm=0.6 # microFarad/(cm**2)
  1569. # deltat= 0.001 # = 1 msec
  1570. # --- define matrix M --------
  1571. interim=mycell.shape
  1572. nofcomps=interim[0]
  1573. M=np.zeros((nofcomps,nofcomps))
  1574. # -------------------------------------
  1575. compdiam=mycell[:,5]*2.0 # in micrometer
  1576. complength=np.zeros(nofcomps)
  1577. # complength defined backwards
  1578. for i in range(1,nofcomps,1):
  1579. aind=int(mycell[i,0]-1)
  1580. bind=int(mycell[i,6]-1)
  1581. axyz=mycell[aind,2:5]
  1582. bxyz=mycell[bind,2:5]
  1583. complength[i]=np.sqrt(np.sum((axyz-bxyz)**2)) # in micrometer
  1584. meandiam=(compdiam[aind]+compdiam[bind])*0.5
  1585. area=meandiam**2.0/4.0*np.pi
  1586. M[bind,aind]=-area/complength[aind]/Ra*10**(-4)
  1587. M[aind,bind]=M[bind,aind]
  1588. complength[0]=complength[1]
  1589. gleak=(compdiam*np.pi*complength)/(Rm*10**8)
  1590. memcap=(compdiam*np.pi*complength)*Cm*(10**-6)/(10**8)
  1591. for i in range(nofcomps):
  1592. M[i,i]=gleak[i]-np.sum(M[i])
  1593. M=sparse.csr_matrix(M)
  1594. return M,memcap,gleak
  1595. def calc_Vol_Surf(swcfile):
  1596. #swcfile='T4a_swc_deposit/85.swc'
  1597. mycell=np.loadtxt(swcfile)
  1598. mycell[:,2:6]=0.01*mycell[:,2:6]
  1599. interim=mycell.shape
  1600. nofcomps=interim[0]
  1601. # -------------------------------------
  1602. compdiam=mycell[:,5]*2.0 # in micrometer
  1603. complength=np.zeros(nofcomps)
  1604. compvol=np.zeros(nofcomps)
  1605. compsurf=np.zeros(nofcomps)
  1606. # complength defined backwards
  1607. for i in range(1,nofcomps,1):
  1608. aind=int(mycell[i,0]-1)
  1609. bind=int(mycell[i,6]-1)
  1610. axyz=mycell[aind,2:5]
  1611. bxyz=mycell[bind,2:5]
  1612. complength[i]=np.sqrt(np.sum((axyz-bxyz)**2)) # in micrometer
  1613. meandiam=(compdiam[aind]+compdiam[bind])*0.5
  1614. area=meandiam**2.0/4.0*np.pi
  1615. compvol[i]=area*complength[i]
  1616. compsurf[i]=compdiam[i]*np.pi*complength[i]
  1617. total_vol=np.sum(compvol)
  1618. total_surf=np.sum(compsurf)
  1619. print('Volume [micrometer^3]:', format(total_vol,'.2f'))
  1620. print('Surface [micrometer^2]:', format(total_surf,'.2f'))
  1621. # Compartmental Models of a T4 cell:
  1622. # low temporal resolution (LTR, deltat=10 ms), with Mi1,4,9,Tm3,C3 and CT1 inputs as a function of the stimulus
  1623. def MultiCompT4_LTR(gMi1,gMi4,gMi9,gTm3,gCT1,gC3,gIhswitch=1):
  1624. # 2.5 sec runtime for maxtime 1000
  1625. maxtime=1000
  1626. deltat=0.001 # 10 msec
  1627. # load T4 cell: soma=1735, axon=1998, dend=971
  1628. swcfile='T4a_swc_deposit/85.swc'
  1629. mycell=np.loadtxt(swcfile)
  1630. mycell[:,2:6]=0.01*mycell[:,2:6]
  1631. interim=mycell.shape
  1632. nofcomps=interim[0]
  1633. # passive membrane properties
  1634. Rm=16000.0
  1635. Ra=200.0
  1636. Cm=0.6
  1637. if gIhswitch==0:
  1638. IhComps=np.zeros(nofcomps)
  1639. if gIhswitch==1:
  1640. IhComps=np.zeros(nofcomps)+1 # everything has Ih
  1641. IhComps[1535:1736]=0 # except soma fibre and soma
  1642. # calculates the matrix (0.15 s computing time)
  1643. M,memcap=calc_Conductance_M(mycell, Rm=Rm, Ra=Ra, Cm=Cm, deltat=deltat)
  1644. # defines Vm and gIh
  1645. Vm = np.zeros((nofcomps,maxtime))
  1646. gIh= np.zeros((nofcomps,maxtime))
  1647. # Receptor Channel Reversal Potentials
  1648. EnAChR=+0.05
  1649. EGABAR=-0.03
  1650. EGluRa=-0.03
  1651. # Ih Parameters -----------
  1652. EIh=+0.050 # = +50 mV
  1653. gIhmax=100.0*10**(-12) # pico Siemens
  1654. umidv=-28.0
  1655. uslope=-0.25
  1656. utau=0.800
  1657. myx=np.linspace(0,200,201)-100
  1658. uss=1.0/(1.0+np.exp((umidv-myx)*uslope))
  1659. u=np.zeros(nofcomps)
  1660. gMi1=gMi1*(10**(-12)) # pS
  1661. gMi4=gMi4*(10**(-12)) # pS
  1662. gMi9=gMi9*(10**(-12)) # pS
  1663. gTm3=gTm3*(10**(-12)) # pS
  1664. gCT1=gCT1*(10**(-12)) # pS
  1665. gC3 = gC3*(10**(-12)) # pS
  1666. M_actual=1.0*M
  1667. for t in range(1,maxtime):
  1668. print('.', end=' ')
  1669. # calculate Ih
  1670. Vindex=rect(1000.0*Vm[:,t-1],-99)
  1671. Vindex=ceil(Vindex,+99)
  1672. Vindex=Vindex.astype(int)+100
  1673. u[:]=deltat/utau*(uss[Vindex]-u[:])+u[:]
  1674. gIh[:,t]=gIhmax*u*IhComps
  1675. M_actual.setdiag(M.diagonal()+gMi1[:,t]+gMi4[:,t]+gMi9[:,t]+gTm3[:,t]+gCT1[:,t]+gC3[:,t]+gIh[:,t]+memcap/deltat)
  1676. rightsideofeq=Vm[:,t-1]*memcap/deltat+EnAChR*(gMi1[:,t]+gTm3[:,t])+EGABAR*(gMi4[:,t]+gCT1[:,t]+gC3[:,t])+EGluRa*gMi9[:,t]+EIh*gIh[:,t]
  1677. Vm[:,t] = spsolve(M_actual,rightsideofeq)
  1678. Vm[:,:] = 1000.0*Vm # mV
  1679. print()
  1680. return Vm
  1681. # Two Compartmental Models of a T4: CClamp and VClamp
  1682. def MultiCompT4_CClamp(injcompswitch=1,HHon=1,Ihon=1,curramp=10*(10**(-12))):
  1683. # 25 sec runtime for maxtime 1000
  1684. maxtime=1000
  1685. deltat=0.0002 # 0.2 msec
  1686. # load T4 cell: soma=1735,dend=971
  1687. swcfile='T4a_swc_deposit/85.swc'
  1688. mycell=np.loadtxt(swcfile)
  1689. mycell[:,2:6]=0.01*mycell[:,2:6]
  1690. interim=mycell.shape
  1691. nofcomps=interim[0]
  1692. # Areas: mycell[:,1]=200
  1693. # mycell[1535:1736,1]=100 # soma fibre and soma
  1694. # mycell[1750:2012,1]=150 # axon
  1695. # Comp Numbers
  1696. soma=1735
  1697. dend=1107
  1698. axterm=2000
  1699. if injcompswitch==1: injcomp=soma
  1700. if injcompswitch==2: injcomp=dend
  1701. if injcompswitch==3: injcomp=axterm
  1702. # passive membrane properties
  1703. Rm=26000.0
  1704. Ra=400.0
  1705. Cm=0.6
  1706. # calculates the matrix
  1707. M,memcap,gleak=calc_Conductance_M(mycell, Rm=Rm, Ra=Ra, Cm=Cm, deltat=deltat)
  1708. # define Vm and currinj
  1709. Vm = np.zeros((nofcomps,maxtime))
  1710. currinj= np.zeros((nofcomps,maxtime))
  1711. tstart=200
  1712. tstop=800
  1713. currinj[injcomp,tstart:tstop]=curramp
  1714. # define active compartments
  1715. HHComps=np.zeros(nofcomps)
  1716. IhComps=np.zeros(nofcomps)
  1717. # only axon has HH
  1718. HHComps[1860:2012]=1.0
  1719. # only dendrite has Ih
  1720. IhComps[0:1535]=1.0
  1721. # set HH and Ih according to switches
  1722. if HHon==0:
  1723. HHComps=0*HHComps
  1724. if Ihon==0:
  1725. IhComps=0*IhComps
  1726. # Active Stuff -----------
  1727. ENa=+0.090 # = +90 mV
  1728. EK =-0.030 # = -30 mV
  1729. EIh=+0.050 # = +50 mV
  1730. gNa=np.zeros((nofcomps,maxtime))
  1731. gK =np.zeros((nofcomps,maxtime))
  1732. gIh=np.zeros((nofcomps,maxtime))
  1733. gNamax=200.0*10**(-12) # pico Siemens
  1734. gKmax = 50.0*10**(-12) # pico Siemens
  1735. gIhmax=100.0*10**(-12) # pico Siemens
  1736. mmidv=20.0
  1737. mslope=0.35
  1738. mtau=0.001
  1739. hmidv=10.0
  1740. hslope=-0.15
  1741. htau=0.003
  1742. nmidv=20.0
  1743. nslope=0.15
  1744. ntau=0.004
  1745. umidv=-28.0
  1746. uslope=-0.25
  1747. utau=0.800
  1748. myx=np.linspace(0,200,201)-100
  1749. mss=1.0/(1.0+np.exp((mmidv-myx)*mslope))
  1750. hss=1.0/(1.0+np.exp((hmidv-myx)*hslope))
  1751. nss=1.0/(1.0+np.exp((nmidv-myx)*nslope))
  1752. uss=1.0/(1.0+np.exp((umidv-myx)*uslope))
  1753. m=np.zeros(nofcomps)
  1754. h=np.zeros(nofcomps)
  1755. n=np.zeros(nofcomps)
  1756. u=np.zeros(nofcomps)
  1757. # end of initializing
  1758. def update_mnhu(Vm):
  1759. Vindex=rect(1000.0*Vm,-99)
  1760. Vindex=ceil(Vindex,+99)
  1761. Vindex=Vindex.astype(int)+100
  1762. m[:]=deltat/mtau*(mss[Vindex]-m[:])+m[:]
  1763. n[:]=deltat/ntau*(nss[Vindex]-n[:])+n[:]
  1764. h[:]=deltat/htau*(hss[Vindex]-h[:])+h[:]
  1765. u[:]=deltat/utau*(uss[Vindex]-u[:])+u[:]
  1766. return m,n,h,u
  1767. M_actual=1.0*M
  1768. for t in range(1, maxtime):
  1769. print('.', end=' ')
  1770. m,n,h,u=update_mnhu(Vm[:,t-1])
  1771. gNa[:,t]=gNamax*(m**3)*h*HHComps
  1772. gK[:,t] =gKmax *(n**4)*HHComps
  1773. gIh[:,t]=gIhmax*u*IhComps
  1774. M_actual.setdiag(M.diagonal()+gNa[:,t]+gK[:,t]+gIh[:,t]+memcap/deltat)
  1775. rightsideofeq=Vm[:,t-1]*memcap/deltat+currinj[:,t]+ENa*gNa[:,t]+EK*gK[:,t]+EIh*gIh[:,t]
  1776. Vm[:,t] = spsolve(M_actual,rightsideofeq)
  1777. Vm[:,:] = 1000.0*Vm # mV
  1778. return Vm
  1779. def MultiCompT4T5_VClamp(T4T5switch,injcompswitch=1,passive=0,plotswitch=1,ClampPot=-0.05):
  1780. # 25 sec runtime for maxtime 1000
  1781. maxtime=2000
  1782. deltat=0.0002 # 0.2 msec
  1783. # load T4 cell: soma=1735,dend=971
  1784. # load T5 cell: soma=264, dend=284
  1785. if T4T5switch==1:
  1786. swcfile='T4a_swc_deposit/85.swc'
  1787. soma=1735
  1788. dend=971
  1789. if T4T5switch==2:
  1790. swcfile='T5a_swc_deposit/365withsoma.swc'
  1791. soma=264
  1792. dend=284
  1793. if injcompswitch==1:
  1794. injcomp=soma
  1795. if injcompswitch==2:
  1796. injcomp=dend
  1797. mycell=np.loadtxt(swcfile)
  1798. mycell[:,2:6]=0.01*mycell[:,2:6]
  1799. interim=mycell.shape
  1800. nofcomps=interim[0]
  1801. # passive membrane properties
  1802. Rm=16000.0
  1803. Ra=200.0
  1804. Cm=0.6
  1805. # calculates the matrix
  1806. M,memcap=calc_Conductance_M(mycell, Rm=Rm, Ra=Ra, Cm=Cm, deltat=deltat)
  1807. # define Vm and currinj
  1808. Vm = np.zeros((nofcomps,maxtime))
  1809. currinj= np.zeros(nofcomps)
  1810. VmClamp=np.zeros(maxtime)
  1811. curramp=np.zeros(maxtime)
  1812. tstart=500
  1813. tstop=1500
  1814. currinj[injcomp]=1.0
  1815. VmClamp[tstart:tstop]=ClampPot
  1816. # define active compartments
  1817. HHComps=np.zeros(nofcomps)+1 # everything has HH
  1818. IhComps=np.zeros(nofcomps)+1 # everything has Ih
  1819. if T4T5switch==1:
  1820. HHComps[1535:1736]=0 # except soma fibre and soma
  1821. IhComps[1535:1736]=0 # except soma fibre and soma
  1822. if T4T5switch==2:
  1823. HHComps[85:264]=0 # except soma fibre and soma
  1824. IhComps[85:264]=0 # except soma fibre and soma
  1825. if passive==1:
  1826. HHComps=0*HHComps
  1827. IhComps=0*IhComps
  1828. # Active Stuff -----------
  1829. ENa=+0.090 # = +90 mV
  1830. EK =-0.060 # = -30 mV
  1831. EIh=+0.050 # = +50 mV
  1832. gNa=np.zeros((nofcomps,maxtime))
  1833. gK =np.zeros((nofcomps,maxtime))
  1834. gIh=np.zeros((nofcomps,maxtime))
  1835. gNamax=200.0*10**(-12) # pico Siemens
  1836. gKmax = 50.0*10**(-12) # pico Siemens
  1837. gIhmax=100.0*10**(-12) # pico Siemens
  1838. mmidv=20.0
  1839. mslope=0.35
  1840. mtau=0.002
  1841. hmidv=10.0
  1842. hslope=-0.15
  1843. htau=0.003
  1844. nmidv=20.0
  1845. nslope=0.15
  1846. ntau=0.004
  1847. umidv=-28.0
  1848. uslope=-0.25
  1849. utau=0.800
  1850. myx=np.linspace(0,200,201)-100
  1851. mss=1.0/(1.0+np.exp((mmidv-myx)*mslope))
  1852. hss=1.0/(1.0+np.exp((hmidv-myx)*hslope))
  1853. nss=1.0/(1.0+np.exp((nmidv-myx)*nslope))
  1854. uss=1.0/(1.0+np.exp((umidv-myx)*uslope))
  1855. m=np.zeros(nofcomps)
  1856. h=np.zeros(nofcomps)
  1857. n=np.zeros(nofcomps)
  1858. u=np.zeros(nofcomps)
  1859. # end of initializing
  1860. def update_mnhu(Vm):
  1861. Vindex=rect(1000.0*Vm,-99)
  1862. Vindex=ceil(Vindex,+99)
  1863. Vindex=Vindex.astype(int)+100
  1864. m[:]=deltat/mtau*(mss[Vindex]-m[:])+m[:]
  1865. n[:]=deltat/ntau*(nss[Vindex]-n[:])+n[:]
  1866. h[:]=deltat/htau*(hss[Vindex]-h[:])+h[:]
  1867. u[:]=deltat/utau*(uss[Vindex]-u[:])+u[:]
  1868. return m,n,h,u
  1869. gain=500.0
  1870. M_actual=1.0*M
  1871. print('busy ...')
  1872. for t in range(1, maxtime):
  1873. m,n,h,u=update_mnhu(Vm[:,t-1])
  1874. gNa[:,t]=gNamax*(m**3)*h*HHComps
  1875. gK[:,t] =gKmax *(n**4)*HHComps
  1876. gIh[:,t]=gIhmax*u*IhComps
  1877. curramp[t]=gain*(VmClamp[t]-Vm[injcomp,t-1])*10**(-12)+curramp[t-1]
  1878. M_actual.setdiag(M.diagonal()+gNa[:,t]+gK[:,t]+gIh[:,t]+memcap/deltat)
  1879. rightsideofeq=Vm[:,t-1]*memcap/deltat+currinj[:]*curramp[t]+ENa*gNa[:,t]+EK*gK[:,t]+EIh*gIh[:,t]
  1880. Vm[:,t] = spsolve(M_actual,rightsideofeq)
  1881. t=maxtime/2
  1882. Rin=Vm[injcomp,t]/curramp[t]/(10**9) # GOhm
  1883. Vm[:,:] = 1000.0*Vm # mV
  1884. if plotswitch==1:
  1885. plt.figure(figsize=(10,6))
  1886. myt=np.arange(maxtime)*deltat
  1887. plt.plot(myt,Vm[soma],linewidth=2,color='blue',label='Vm Soma [mV]')
  1888. plt.plot(myt,Vm[dend],linewidth=2,color='green',label='Vm Dendrite [mV]')
  1889. plt.plot(myt,VmClamp*1000.0,linewidth=2,color='black',label='Vm Clamp [mV]')
  1890. plt.plot(myt,curramp*10**(12),linewidth=2,color='red',label='I inj [pA]')
  1891. plt.xlabel('time [sec]')
  1892. plt.legend(loc=2,frameon=False, fontsize=10)
  1893. print('R input = ', Rin, ' [GOhm]')
  1894. return Vm
  1895. # -----------------------------------------------------------------------------------------------------
  1896. def add_colorbar(Vm,Vm_min,Vm_max):
  1897. myrange=(Vm_max-Vm_min)
  1898. setmyaxes(0.9,0.1,0.1,0.8)
  1899. mybar=np.arange(500)
  1900. mybar=mybar.reshape(100,5)
  1901. plt.imshow(mybar,origin='lower')
  1902. plt.xticks(np.arange(5),['','','','',''])
  1903. plt.yticks(np.arange(6)*20.0,np.arange(6)*0.2*myrange+Vm_min)
  1904. plt.text(-13,50,'Membrane Potential [mV]',verticalalignment='center',rotation=90)
  1905. def Rx(theta):
  1906. return np.array([[ 1, 0 , 0 ],
  1907. [ 0, np.cos(theta),-np.sin(theta)],
  1908. [ 0, np.sin(theta), np.cos(theta)]])
  1909. def Ry(theta):
  1910. return np.array([[ np.cos(theta), 0, np.sin(theta)],
  1911. [ 0 , 1, 0 ],
  1912. [-np.sin(theta), 0, np.cos(theta)]])
  1913. def Rz(theta):
  1914. return np.array([[ np.cos(theta), -np.sin(theta), 0 ],
  1915. [ np.sin(theta), np.cos(theta) , 0 ],
  1916. [ 0 , 0 , 1 ]])
  1917. def rot_tree(tree,rot_axis,angle):
  1918. angle=angle/360.0*2.*np.pi
  1919. if rot_axis==0:
  1920. M=Rx(angle)
  1921. if rot_axis==1:
  1922. M=Ry(angle)
  1923. if rot_axis==2:
  1924. M=Rz(angle)
  1925. nofcomps=tree.shape[0]
  1926. new_tree=1.0*tree
  1927. for i in range(nofcomps):
  1928. new_tree[i,2:5]=M.dot(tree[i,2:5])
  1929. return new_tree
  1930. def draw_Vm_tree(Vm,Vm_min,Vm_max,fname='T4a_swc_deposit/85.swc',dim1=2,dim2=3,sfac=10):
  1931. plt.figure(figsize=(15,7))
  1932. setmyaxes(0.1,0.1,0.75,0.8)
  1933. tree=np.loadtxt(fname)
  1934. tree[:,2:6]=0.01*tree[:,2:6]
  1935. n=tree.shape
  1936. nofcomps=n[0]
  1937. tree=rot_tree(tree,2,180)
  1938. tree=rot_tree(tree,1,80)
  1939. myrange=(Vm_max-Vm_min)
  1940. MyVm=limit(Vm,Vm_min,Vm_max)
  1941. MyVm=(Vm-Vm_min)/myrange*255
  1942. print(MyVm)
  1943. for i in range(1,nofcomps,1):
  1944. intensity=int(MyVm[i])
  1945. if tree[i,6]!=-1:
  1946. a=tree[i,0]-1
  1947. b=tree[i,6]-1
  1948. x1=tree[a,dim1]
  1949. x2=tree[b,dim1]
  1950. y1=tree[a,dim2]
  1951. y2=tree[b,dim2]
  1952. diam=tree[i,5]+tree[i-1,5]
  1953. mylw=int(sfac*diam)
  1954. plt.plot([x1,x2],[y1,y2],linewidth=mylw,color=plt.cm.rainbow(intensity))
  1955. add_colorbar(Vm,Vm_min,Vm_max)
  1956. def find_comp_number(mycell,dim1=2,dim2=3):
  1957. plt.scatter(mycell[:,dim1],mycell[:,dim2],c=mycell[:,0], cmap='viridis')
  1958. plt.colorbar()
  1959. def create_colorswcfile(Vm,inputfname,outputfname,Vm_min,Vm_max):
  1960. mycell=np.loadtxt(inputfname)
  1961. # need to keep original dimensions (i.e.100 times as large)
  1962. myrange=(Vm_max-Vm_min)
  1963. MyVm=rect(Vm,Vm_min)
  1964. MyVm=ceil(MyVm,Vm_max)
  1965. MyVm=(Vm-Vm_min)/myrange*255+20
  1966. MyVm=MyVm.astype(int)
  1967. mycell[:,1]=MyVm
  1968. np.savetxt(outputfname,mycell.astype(int),fmt='%-5d')
  1969. def test_compmod(swcfile,injcomp=0,injcurr=10**(-11)):
  1970. mycell=np.loadtxt(swcfile)
  1971. mycell[:,2:6]=0.01*mycell[:,2:6]
  1972. interim=mycell.shape
  1973. nofcomps=interim[0]
  1974. # passive membrane properties
  1975. Rm=8000.0
  1976. Ra=400.0
  1977. Cm=0.6
  1978. deltat=0.001
  1979. # calculates the matrix
  1980. M,memcap=calc_Conductance_M(mycell, Rm=Rm, Ra=Ra, Cm=Cm, deltat=deltat)
  1981. currvec=np.zeros(nofcomps)
  1982. currvec[injcomp]=injcurr
  1983. Vm=spsolve(M,currvec)
  1984. Vm=1000.0*Vm
  1985. return Vm
  1986. #-------------------------
  1987. # IMPORTANT STUFF
  1988. #-------------------------
  1989. # row first: Y-Axis!
  1990. # savefig('fname')
  1991. # ASCII
  1992. # np.savetxt('fname', arrayname)
  1993. # arrayname=np.loadtxt('fname')
  1994. # Binary File
  1995. # np.save('fname', arrayname)
  1996. # arrayname=np.load('fname')
  1997. # a=scipy.misc.imread(filename)
  1998. # ax = plt.Subplot(fig, 111)
  1999. # ax.xaxis.set_ticks_position('bottom')
  2000. # ax.yaxis.set_ticks_position('left')
  2001. # Cmaps:
  2002. # Diverging: bwr, seismic, coolwarm
  2003. # linear: hot, rainbow