Borehole NMR processing
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. # import matplotlib as mpl
  2. # mpl.use("pgf")
  3. # pgf_with_pdflatex = {
  4. # "pgf.texsystem": "pdflatex",
  5. # "pgf.preamble": [
  6. # r"\usepackage{amsmath}",
  7. # r"\usepackage{amssymb}",
  8. # r"\usepackage{timet}",
  9. # ]
  10. # }
  11. # #r"\usepackage[utf8x]{inputenc}",
  12. # #r"\usepackage[T1]{fontenc}",
  13. # #r"\usepackage{cmbright}",
  14. # mpl.rcParams.update(pgf_with_pdflatex)
  15. #
  16. # from matplotlib import rc
  17. # rc('font',**{'family':'serif','serif':['times']})
  18. # ## for Palatino and other serif fonts use:
  19. # #rc('font',**{'family':'serif','serif':['Palatino']})
  20. # #rc('text', usetex=True)
  21. #import matplotlib
  22. #from matplotlib import rc
  23. #matplotlib.rcParams['text.latex.preamble']=[r"\usepackage{timet,amsmath}"]
  24. #rc('font',**{'family':'serif','serif':['timet']})
  25. #rc('text', usetex=True)
  26. from GJIPlot import *
  27. import numpy as np
  28. import matplotlib.pyplot as plt
  29. from smooth import smooth
  30. #from invertColours import *
  31. from decay import *
  32. from scipy import signal
  33. from notch import *
  34. import rotate # why is it called loss?
  35. BLACK = False
  36. labs = 16
  37. if BLACK:
  38. labcol = 'white'
  39. else:
  40. labcol = 'black'
  41. def Kw(a, phi2, s, rT2, wL):
  42. return a*((np.sin(phi2)*s + ((1/rT2)*np.sin(phi2)) + wL*np.cos(phi2) ) / (wL**2+(s+1/rT2)**2 ))
  43. def quadDetect(T, vL, wL, dt, xn, DT):
  44. # decimate
  45. # blind decimation
  46. # 1 instead of T
  47. irsamp = (T) * int( (1./vL) / dt) # real
  48. iisamp = int( ((1./vL)/ dt) * ( .5*np.pi / (2.*np.pi) ) ) # imaginary
  49. dsamp = int( DT / dt) # real
  50. iisamp += dsamp
  51. ############################################################
  52. # simple quadrature-detection via sampling
  53. xr = xn[dsamp::irsamp]
  54. xi = xn[iisamp::irsamp]
  55. phase = np.angle( xr + 1j*xi )
  56. abse = np.abs( xr + 1j*xi )
  57. # times
  58. ta = np.arange(0, TT, dt)
  59. te = np.arange(DT, TT, TT/len(abse))
  60. #############################################################
  61. # hilbert transform
  62. ht = signal.hilbert(xn) #, 100))
  63. he = np.abs(ht) #, 100))
  64. he = ht*np.exp( -1j*wL*t ) # ht*e^{-jwLt} # phase envelope
  65. #hp = ((np.angle(ht[dsamp::irsamp])))
  66. #[Q, I, tt] = rotate.quadrature(T, vL, wL, dt, xn, DT, t)
  67. [E0,df,phi,T2] = quadratureDetect(np.imag(he), np.real(he), t)
  68. D = rotate.RotateAmplitude(np.real(he), np.imag(he), phi, df, t)
  69. he = D.imag
  70. #print ("df", df, "phi", phi)
  71. """
  72. plt.plot(xn)
  73. plt.plot(np.real(he))
  74. plt.plot(np.imag(he))
  75. plt.plot(D.imag)
  76. plt.plot(D.real)
  77. print ("phi", phi)
  78. plt.plot( np.unwrap(np.arctan(np.unwrap(np.angle( he ) + np.pi/2 ))) )
  79. # plt.plot(np.imag(ht))
  80. # plt.plot(xn)
  81. # plot FFT
  82. XN = np.fft.rfft(xn)
  83. plt.figure()
  84. plt.plot(XN.real, label='orig')
  85. #XNN = XN * np.exp(1j*phi-1.)
  86. """
  87. """
  88. phi = np.arange(-np.pi, np.pi, .001)
  89. best = 1e12
  90. bestPhi = 0
  91. for p in phi:
  92. XNN = XN * np.exp(1j*p)
  93. if ( (np.linalg.norm( XNN.real[XNN.real < 0] )) < best):
  94. best = np.linalg.norm( XNN.real[XNN.real < 0])
  95. bestPhi = p
  96. #print (len( XNN.real[XNN.real < 0] ))
  97. #best = min(best, -( np.sum(XNN.real[XNN.real < 0]) ))
  98. #print (XNN[XNN.real < 0])
  99. #plt.plot(XNN.real[XNN.real<0])
  100. print ("best", best, bestPhi)
  101. XNN = XN * np.exp(1j*bestPhi)
  102. """
  103. """
  104. plt.plot(XNN.real, label='phased')
  105. plt.plot(XNN.imag, label='imag')
  106. plt.legend()
  107. plt.figure()
  108. plt.plot(np.angle(XN))
  109. plt.plot(np.angle(XNN))
  110. plt.show()
  111. exit()
  112. """
  113. #############################################################
  114. # Resample ht, no gate integrate
  115. """
  116. htd = signal.decimate(he, 100, ftype='fir')
  117. td = signal.decimate(t, 100, ftype='fir')
  118. #[htd, td] = signal.resample(he, 21, t)
  119. #toss first, and use every third
  120. htd = htd[1::5]
  121. td = td[1::5]
  122. """
  123. #############################################################
  124. # Resample ht and gate integrate to 20 gates per decate
  125. GPD = 20 # Gates per decade
  126. GI = 15 # initial 15 times are just used
  127. # first just resample to 20 Gates per decade
  128. #nrs = (np.log(t[-1]) - np.log10(t[0]))
  129. tdd = np.logspace( np.log10(16*dt), np.log10(t[-1]), 80-GI, base=10, endpoint=True)
  130. tdl = tdd[0:-1] # these are left edges
  131. tdr = tdd[1::] # these are left edges
  132. td = (tdl+tdr) / 2.
  133. # Just use the first 20 datapoints
  134. td = np.concatenate( ([t[0:GI] , td]) )
  135. htd = np.zeros( len(td) )
  136. #htd[0:15] = he[0:15]
  137. htd[0:GI] = he[0:GI]
  138. ii = 15
  139. isum = np.zeros( len(td) )
  140. Vars = np.ones( len(td) ) * .15**2
  141. isum [0:15] = 1
  142. #Vars [0:15] = .15**2 # variance
  143. #var = .15**2
  144. for itd in range(GI, len(he)):
  145. #print (itd)
  146. if ( t[itd] > tdr[ii-GI] ):
  147. ii += 1
  148. isum[ii] += 1
  149. htd[ii] += he[ itd ]
  150. Vars[ii] += .15**2
  151. htd /= isum
  152. #Vars = ( Vars) / isum
  153. Stds = np.sqrt( Vars) / isum
  154. Vars = Stds**2
  155. #plt.figure()
  156. #plt.gca().errorbar( td, htd, fmt='o', yerr=Vars )
  157. #plt.gca().set_xscale('log', basex=10)
  158. # htd = he[itd] # (int)(dt*itd) ]
  159. #td = []
  160. # OK, so tdd are the desired time gates, but we might not be able to satisfy all of them
  161. #htdt = signal.decimate(he, 10, ftype='fir')
  162. ##tdt = signal.decimate(t, 10, ftype='fir')
  163. #tdt = t[::10]
  164. #[htd, td] = signal.resample(he, 21, t)
  165. ##toss first, and use every third
  166. #htd = [] # htdt[1::5]
  167. #td = tdt[1::15]
  168. #for ix in np.arange(1,len(htdt),15):
  169. # if ix>15 and ix<len(htdt)-15:
  170. # htd.append( np.mean(htdt[ix-7:ix+8]) ) # stupid could do recursive but who gives a shit
  171. # else:
  172. # htd.append( htdt[ix] ) # stupid could do recursive but who gives a shit
  173. ###############################################
  174. # Plots
  175. #plt.plot(ta, xn)
  176. #plt.plot(te, abse, '-.', linewidth=2, markersize=10)
  177. #plt.plot(ta, he, '.', markersize=10 )
  178. #plt.plot(td, htd, color='green', linewidth=2)
  179. # Phase Plots
  180. #ax2 = plt.twinx()
  181. #ax2.plot(te, hp, '.', markersize=10, color='green' )
  182. #ax2.plot(te, phase, '-.', linewidth=2, markersize=10, color='green')
  183. #plt.show()
  184. #exit()
  185. #####################################################################
  186. # regress raw signal
  187. #[peaks, times, ind] = peakPicker(xn, wL, dt)
  188. #[a0,b0,rt20] = regressCurve(peaks, times) #,sigma2=1,intercept=True):
  189. #plt.figure()
  190. #plt.plot(Vars)
  191. #plt.show()
  192. #exit()
  193. dsamp = 1 # int( DT / dt) # real
  194. # regress analytic signal
  195. [b0,rt20] = regressCurve(he, t, intercept=False) #, sigma2=(1./Stds)/np.max(1/Stds)) #,sigma2=1,intercept=True):
  196. #[a0,b0,rt20] = regressCurve(he, t, intercept=True, sigma2=(1./Vars)/np.max(1/Vars)) #,sigma2=1,intercept=True):
  197. #[b0,rt20] = regressCurve(he[dsamp::], t[dsamp::], intercept=False) #,sigma2=1,intercept=True):
  198. #[a0,b0,rt20] = regressCurve(he, t) #,sigma2=1,intercept=True):
  199. # regress downsampled
  200. #[a,b,rt2] = regressCurve(abse, t[dsamp::irsamp], intercept=True) #,sigma2=1,intercept=True):
  201. [b,rt2] = regressCurve(htd, td, intercept=False, sigma2=(1./Stds)/np.max(1/Stds) ) #,sigma2=1,intercept=True):
  202. return irsamp, iisamp, htd, b0, rt20, ta, b, rt2, phi, td, he, Stds
  203. #return irsamp, iisamp, abse, a0, b0, rt20, times, a, b, rt2, phase
  204. if __name__ == "__main__":
  205. dt = 1e-4
  206. TT = 1.5
  207. t = np.arange(0, TT, dt)
  208. vL = 2000.
  209. wL = 2.*np.pi*vL
  210. wL2 = 2.*np.pi*(vL+10 ) # 3 Hz off
  211. zeta = -np.pi/2 # .0 #np.pi/2.21
  212. t2 = .050
  213. # TODO, show boxplots of error of regressions parameters, and randomly sample T2 and Vn0 for realistic parameters.
  214. # do a lot of random realizations.
  215. N = 5000
  216. T2 = [.03, .075, .125, .2, .250] # <=== Final
  217. #T2 = [.3]
  218. NT2 = len(T2)
  219. RALL = np.zeros((N, NT2))
  220. RDEC = np.zeros((N, NT2))
  221. BALL = np.zeros((N, NT2))
  222. BDEC = np.zeros((N, NT2))
  223. RF = np.zeros((N, NT2))
  224. AF = np.zeros((N, NT2))
  225. RM = np.zeros((N, NT2))
  226. AM = np.zeros((N, NT2))
  227. RFC = np.zeros((N, NT2))
  228. AFC = np.zeros((N, NT2))
  229. sT2 = [str(int(1e3*i)) for i in T2]
  230. it2 = 0
  231. for t2 in T2:
  232. print(("simulating", t2))
  233. xe = np.exp(-t/t2)
  234. for it in range(N):
  235. zeta = (np.random.rand() - .5) #np.random.rand()
  236. #print ("zeta", zeta)
  237. # TODO, right here do distribution of phases
  238. xs = np.exp(-t/t2) * np.sin(wL*t + numpy.pi*zeta) #\
  239. # + np.exp(-t/t2) * np.sin(wL*t )
  240. # pretty low, highly-correlated noise
  241. #xn = ( (smooth(np.random.normal(0,.4,len(xs)) + \
  242. # np.random.random_integers(-1,1,len(xs))*0.5*np.random.lognormal(0, .25, len(xs)) + \
  243. # np.random.random_integers(-1,1,len(xs))*.0002*np.random.weibull(.25, len(xs)), 60)))
  244. #xn += np.random.normal( 0, .02,len(xs) )
  245. #print(np.std(xn))
  246. xc = np.random.normal(0,.01,len(xs)) + (np.sign(xs) * (smooth(np.random.normal(0,.25,len(xs)+160) + \
  247. np.random.random_integers(-1,1,len(xs)+160)*0.15*np.random.lognormal(0, .25, len(xs)+160) + \
  248. np.random.random_integers(-1,1,len(xs)+160)*.0002*np.random.weibull(.25, len(xs)+160), 80))[80:-80] )
  249. #print(np.std(xc))
  250. xn = xs + xc
  251. #xn += xs
  252. #nn = np.random.normal( 0, .15,len(xs) )
  253. #xn = xs + nn # np.random.normal(0,.15,len(xs))
  254. #xn = xs + (np.sign(xs) * np.absolute(smooth(np.random.normal(0,.5,len(xs))) )) #+ \
  255. #np.random.random_integers(-1,1,len(xs))*0.6*np.random.lognormal(0, .35, len(xs)) + \
  256. #np.random.random_integers(-1,1,len(xs))*.004*np.random.weibull(.25, len(xs)), 60)))
  257. ###################################################################
  258. # Bandpass filter, concatenate the two and run both directions
  259. #xraw = xn
  260. #plt.plot(xn)
  261. #xf = notch( xn[::-1], .925, 2000., dt )
  262. #xn = (xn[::-1]-xf)[::-1]
  263. #xf = notch( xn[::-1], .9, 2000., dt )
  264. #xn = (xn[::-1]-xf)[::-1]
  265. """
  266. print("sigma xf", np.std(xf))
  267. print("sigma nn", np.std(nn))
  268. print("sigma xn", np.std(xn[-100::]))
  269. #plt.plot(xraw)
  270. plt.plot(xn)
  271. plt.plot(xs)
  272. #plt.plot(xf)
  273. #plt.plot(xn[::-1]-xf)
  274. plt.show()
  275. exit()
  276. """
  277. # quadrature detection downsampling
  278. T = 50 # sampling period, grab every T'th oscilation
  279. DT = 0. #.002 #85 # dead time ms
  280. [irsamp, iisamp, abse, b0, rt20, times, b, rt2, phase, tdec, he, Stds] = quadDetect(T, vL, wL, dt, xn, DT)
  281. RALL[it, it2] = 1e2 * ((rt20-t2)/t2)
  282. BALL[it, it2] = 1e2*(b0 -1.)
  283. BDEC[it, it2] = 1e2*(b - 1.)
  284. RDEC[it, it2] = 1e2 * ((rt2-t2)/t2)
  285. # Fourier domain fitting
  286. dsamp = int( DT / dt) # real
  287. #X = np.fft.rfft(xn[dsamp::]) #* dt
  288. #V = np.fft.fftfreq(len(xn[dsamp::]), dt)
  289. X = np.fft.rfft(xn) #* dt
  290. V = np.fft.fftfreq(len(xn), dt)
  291. #V[len(X)-1] *= -1.
  292. w = V * 2.*np.pi
  293. # Just do a window
  294. nf = 50 # 150 = 200 Hz window
  295. ws = np.abs(w[0:len(X)])
  296. vs = ws/(2.*np.pi)
  297. iL = vL / vs[1]
  298. # Do complex fit
  299. [af, bf] = regressModulus(ws[iL-nf:iL+nf] , wL, dt*X[iL-nf:iL+nf] )
  300. AM[it, it2] = 1e2*(af - 1.) # backwards extrapolate
  301. RM[it, it2] = 1e2 * ((bf-t2)/t2)
  302. try:
  303. [af, bf, nb] = regressSpecComplex(ws[iL-nf:iL+nf], wL, dt*X[iL-nf:iL+nf], known=False)
  304. except:
  305. print("munged FD regression")
  306. af = 0
  307. bf=10.
  308. nb = 0
  309. cr = Kw(af, nb, 1j*ws[iL-nf:iL+nf], bf, wL)
  310. AFC[it, it2] = 1e2*(af - 1.) # backwards extrapolate
  311. afe = af # (af * np.exp(DT/bf)) #, af # backwards extrapolate
  312. RFC[it, it2] = 1e2 * ((bf-t2)/t2)
  313. """
  314. # rotate phase
  315. phi = np.arange(0, 2.*np.pi, .001)
  316. best = 1e12
  317. bestPhi = 0
  318. for p in phi:
  319. XNN = X * np.exp(1j*p)
  320. if ( (np.linalg.norm( XNN.real[XNN.real < 0] )) < best):
  321. best = np.linalg.norm( XNN.real[XNN.real < 0])
  322. bestPhi = p
  323. nb2 = bestPhi
  324. nb3 = nb
  325. """
  326. #print ("nb", nb, "zeta", zeta*pi, "nb2", nb2, np.pi/2-zeta*pi)
  327. Xc = X[iL-nf:iL+nf]
  328. #X = (X * np.exp(1j*(np.pi/2-zeta*pi) )).real # Correct
  329. X = (X * np.exp(1j*(np.pi/2-nb) )).real
  330. X = X[iL-nf:iL+nf]
  331. #print (phase, bestPhi, phase-bestPhi)
  332. #plt.plot(ws, np.abs(X))
  333. #plt.show()
  334. #exit()
  335. #[a, b] = regressSpec(w[0:len(X)], wL, dt*X)
  336. #[af, bf, nb] = regressSpecComplex(ws[iL-nf:iL+nf], wL, dt*X[iL-nf:iL+nf])
  337. #[af, bf, nb] = regressSpec(ws[iL-nf:iL+nf], wL, dt*X[iL-nf:iL+nf])
  338. [af, bf, nb] = regressSpec(ws[iL-nf:iL+nf], wL, dt*X)
  339. #AF[it, it2] = af - 1.
  340. #AF[it, it2] = 1e2*(af * np.exp(DT/bf) - 1.) # backwards extrapolate
  341. AF[it, it2] = 1e2*(af - 1.) # backwards extrapolate
  342. afe = af # (af * np.exp(DT/bf)) #, af # backwards extrapolate
  343. RF[it, it2] = 1e2 * ((bf-t2)/t2)
  344. # print af, bf, nb
  345. #
  346. # plt.figure()
  347. # plt.plot(xn)
  348. #
  349. # plt.figure()
  350. # plt.plot(V[0:len(X)], dt * np.abs(X), label='mod')
  351. # xp = af* np.abs( wL / (wL**2 + (-1j*ws[iL-nf:iL+nf] + 1./bf)**2 ) )
  352. # xpc = np.abs( wL / (wL**2 + (-1j*ws[iL-nf:iL+nf] + 1./t2)**2 ) )
  353. # #plt.plot(vs[iL-50:iL+50], dt*np.real(X[iL-50:iL+50]))
  354. # #plt.plot(vs[iL-50:iL+50], dt*np.imag(X[iL-50:iL+50]))
  355. # plt.plot(vs[iL-nf:iL+nf], xp, label='predicted')
  356. # plt.plot(vs[iL-nf:iL+nf], xpc, label='actual')
  357. # plt.legend()
  358. it2 += 1
  359. # a little plot
  360. if BLACK:
  361. quadfig = plt.figure(0, facecolor='black', figsize=[pc2in(20), pc2in(32)])
  362. else:
  363. quadfig = plt.figure(0, figsize=[ pc2in(20), pc2in(32) ])
  364. qa = quadfig.add_axes([.1, .6, .8, .375])
  365. if BLACK:
  366. qa.plot(1e3*t, xn, label = 'noisy signal', color='yellow')
  367. invertColours(qa)
  368. else:
  369. qa.plot(1e3*t, xn, color='blue', alpha=.25)
  370. #qa.plot(t, xn, label = 'noisy signal', color='blue')
  371. #fa.plot(X, V)
  372. #plt.plot(t[::irsamp], xn[::irsamp], '.-', marker = 'b', markersize=18, label='real envelope')
  373. #plt.plot(t[iisamp::irsamp], xn[iisamp::irsamp], '.-', marker = 'imaginary envelope', markersize=18, label='imaginary envelope')
  374. deSpine(plt.gca())
  375. if BLACK:
  376. l2 = plt.plot(1e3*times, he, color='red', label='CA')
  377. l1 = plt.plot(1e3*tdec, abse, '.', color='green', markersize=12, label='time gates')
  378. leg = plt.legend( frameon=False, scatterpoints=1, labelspacing=0.2, numpoints=1 )
  379. invertLegend(leg)
  380. else:
  381. l2 = qa.plot(1e3*times, he, color='red') #, label='CA')
  382. #l1 = qa.plot(1e3*tdec, abse, 'o', color='green', markersize=4, label='time gates')
  383. #leg = plt.legend( frameon=True, scatterpoints=1, numpoints=1, labelspacing=0.25 )
  384. #rect = leg.get_frame()
  385. #rect.set_facecolor(light_grey)
  386. #rect.set_linewidth(0.0)
  387. #rect.set_alpha(0.5)
  388. #qa.set_xlabel("time [s]")
  389. #qa.set_title("time-domain")
  390. # regress curve using all times
  391. re0 = b0 * np.exp(-times/rt20)
  392. # regress curve based on decimated data
  393. irsamp = 1
  394. re = b * np.exp(-t[::irsamp]/rt2)
  395. qa.plot(1e3*t, xe, label = 'true envelope', linewidth=2, color='blue')
  396. #qa.plot(1e3*t[::irsamp],re, linewidth=2, label='gated regression', color='green')
  397. qa.plot(1e3*t[::irsamp],re, linewidth=1, color='green')
  398. qa.plot(1e3*times,re0, '--',linewidth=1, label='CA regression', color='black')
  399. l1 = qa.errorbar( 1e3*tdec, abse, yerr=Stds, fmt='o', color='green', markersize=3, label='time gates (1 $\sigma$ EB)')
  400. qa.set_xscale('log', basex=10)
  401. leg = qa.legend(frameon=True, scatterpoints=1, numpoints=1, labelspacing=0.2)
  402. fixLeg(leg)
  403. # Frequency-domain axis, did not bring much information. So removed.
  404. #ff = plt.figure()
  405. #fa = quadfig.add_axes([.1, .05, .8, .25])
  406. fa = quadfig.add_axes([.1, .1, .8, .375])
  407. #ax2 = plt.gca().twinx()
  408. #l2 = ax2.plot(t[iisamp::irsamp], phase, '.-', marker = 'imaginary envelope', markersize=18, label='phase')
  409. #plt.legend([l1,l2])
  410. #invertColours(qa)
  411. #fa.plot(V[0:len(X)], dt * np.abs(X), label='mod')
  412. #fmla = robjects.Formula('XX ~ a*(.5/rT2) / ((1./rT2)^2 + (w-wL)^2 )')
  413. #xp = af * np.abs( wL / (wL**2 + (-1j*ws[iL-nf:iL+nf] + 1./bf)**2 ) )
  414. #xpc = np.abs( wL / (wL**2 + (-1j*ws[iL-nf:iL+nf] + 1./t2)**2 ) )
  415. xp = af * ( (.5/bf) / ( ((1./bf)**2 + (ws[iL-nf:iL+nf]-wL)**2 ) ) )
  416. xpc = ( (.5/t2) / ( ((1./t2)**2 + (ws[iL-nf:iL+nf]-wL)**2 ) ) )
  417. #print ("af", af)
  418. #plt.plot(vs[iL-50:iL+50], dt*np.real(X[iL-50:iL+50]))
  419. #plt.plot(vs[iL-50:iL+50], dt*np.imag(X[iL-50:iL+50]))
  420. #fa.plot(np.abs(V[0:len(X)]), dt * np.abs(X), color='red', linewidth=2, label='FT modulus')
  421. fa.plot(vs[iL-nf:iL+nf], dt*X, color='red', linewidth=2, label='phased')
  422. fa.plot(vs[iL-nf:iL+nf], xp, '--',linewidth=1, label='regressions', color='black')
  423. #fa.plot(vs[iL-nf:iL+nf], dt*Xc.real, color='red', '--', linewidth=2, label='real')
  424. fa.plot(vs[iL-nf:iL+nf], dt*Xc.real, '-', color='blue', linewidth=2, label=r'$\mathrm{Re}$ FFT ')
  425. fa.plot(vs[iL-nf:iL+nf], dt*Xc.imag, '--', color='blue', dashes=(1.5,.75), linewidth=2, label=r'$\mathrm{Im}$ FFT')
  426. fa.plot(vs[iL-nf:iL+nf], cr.real, '--', color='black', linewidth=1) #, label=r'reg')
  427. fa.plot(vs[iL-nf:iL+nf], cr.imag, '--', color='black', dashes=(1.5,.75), linewidth=1) #, label=r'reg')
  428. #ax.plot(dead_freqs[0:ni], np.imag(WSINDP2[0:ni]), "--", dashes=(1.5,.75), color='blue', linewidth=1, label=r"$\mathrm{Im} ( \mathrm{DP} )$")
  429. #fa.plot(vs[iL-nf:iL+nf], xpc, linewidth=2, label='actual', color='blue')
  430. leg = fa.legend(frameon=True, scatterpoints=1, numpoints=1, labelspacing=0.2)
  431. fixLeg(leg)
  432. fa.set_xlabel("frequency [Hz]")
  433. #fa.set_title("frequency-domain")
  434. fa.set_xlim([1950,2050])
  435. #leg = plt.legend()
  436. #rect = leg.get_frame()
  437. #rect.set_facecolor(light_grey)
  438. #rect.set_linewidth(0.0)
  439. #rect.set_alpha(0.5)
  440. #ra = quadfig.add_axes([.1, .1, .8, .25])
  441. #vs = .0125
  442. #ra = quadfig.add_axes([.1, .1-vs, .8, .375])
  443. #ra.set_title("decay envelope regressions")
  444. #plt.savefig('quadri.png',dpi=200, facecolor='black', edgecolor='black')
  445. # real imaginary plot
  446. #rfig = plt.figure(facecolor='black')
  447. #ra = rfig.add_axes([.1,.1,.8,.8])
  448. #ra.plot(t, xn, label = 'noisy signal', color='yellow')
  449. #ra.plot(t[::irsamp], xn[::irsamp], '.-', marker = 's', markersize=10, label='real signal')
  450. #ra.plot(t[iisamp::irsamp], xn[iisamp::irsamp], '.-', marker = 'v', markersize=10, label='imaginary envelope')
  451. #ra.plot(tdec, abse, '.-', color='green', markersize=18, label='decimated modulus')
  452. #ra.plot(t[iisamp::irsamp], phase, '.-', color='green', markersize=18, label='decimated phase')
  453. #leg = plt.legend()
  454. #invertLegend(leg)
  455. #invertColours(ra)
  456. #plt.savefig("quad2.png", dpi=200, facecolor='black', edgecolor='black')
  457. plt.figure(0)
  458. deSpine(plt.gca())
  459. if BLACK:
  460. ra.plot(t[iisamp::irsamp],re, linewidth=2, label='decimated regression', color='green')
  461. ra.plot(times,re0, linewidth=2, label='all data regression', color='cyan')
  462. ra.plot(t, xe, label = 'true', linewidth=4, color='magenta')
  463. ra.set_xlabel("time", fontsize=16, color='white')
  464. leg = plt.legend( labelspacing=0.2, scatterpoints=1,frameon=False )
  465. fixLeg(leg)
  466. invertLegend(leg)
  467. plt.savefig('noisytime.pdf',dpi=600, facecolor='black', edgecolor='black')
  468. else:
  469. #ra.plot(1e3*times, afe*np.exp(-times/bf), '-', color='purple', linewidth=2, label='FD modulus')
  470. qa.set_xlabel("time [ms]") #, fontsize=16)
  471. #rect = leg.get_frame()
  472. #rect.set_facecolor(light_grey)
  473. #rect.set_linewidth(0.0)
  474. #rect.set_alpha(0.5)
  475. qa.set_ylim([-1.25,3.25])
  476. plt.savefig('noisytime_corr.pdf',dpi=600)
  477. plt.savefig('noisytime_corr.eps',dpi=600)
  478. #plt.show()
  479. #exit()
  480. #plt.savefig('quadreg.png',dpi=200, facecolor='black', edgecolor='black')
  481. # Just show envelopes
  482. #efig = plt.figure(facecolor='black')
  483. #ea = efig.add_axes([.1,.1,.8,.8])
  484. #ea.plot(t[iisamp::irsamp],re, linewidth=2, label='decimated regression', color='yellow')
  485. #ea.plot(times,re0, linewidth=2, label='all data regression', color='cyan')
  486. #ea.plot(t, xe, label = 'clean envelope', linewidth=2, color='magenta')
  487. #leg = plt.legend()
  488. #invertLegend(leg)
  489. #invertColours(ea)
  490. #plt.savefig("envelopes.png", dpi=200, edgecolor='black', facecolor='black')
  491. # boxplot
  492. if BLACK:
  493. boxfig = plt.figure( facecolor='black', edgecolor='black')
  494. else:
  495. boxfig = plt.figure( figsize=[pc2in(20), pc2in(32)] )
  496. ##############
  497. # b2 r2 #
  498. # b1 r1 #
  499. # b0 r0 #
  500. ##############
  501. vs = 0 #-3*.0125
  502. vs2 = 0 #-2*.0125
  503. # Time domain
  504. b1 = boxfig.add_axes([.15,.075, .35, .15]) # bottom we want labels
  505. r1 = boxfig.add_axes([ .6,.075, .35, .15])
  506. b0 = boxfig.add_axes([.15,.25, .35, .15])
  507. r0 = boxfig.add_axes([ .6,.25, .35, .15])
  508. # Frequency domain
  509. b2 = boxfig.add_axes([.15,.425, .35, .15])
  510. r2 = boxfig.add_axes([ .6,.425, .35, .15])
  511. b4 = boxfig.add_axes([.15,.6, .35, .15])
  512. r4 = boxfig.add_axes([ .6,.6, .35, .15])
  513. b3 = boxfig.add_axes([.15,.775, .35, .15])
  514. r3 = boxfig.add_axes([ .6,.775, .35, .15])
  515. for ax in [b1,r1,b0,r0,b2,r2,b3,r3,b4,r4]:
  516. deSpine(ax)
  517. B0 = b0.boxplot( BALL , sym='', bootstrap=5000)# , notch=True )
  518. plt.setp(b0, 'xticklabels', [])
  519. R0 = r0.boxplot( RALL , sym='', bootstrap=5000)# , notch=True )
  520. plt.setp(r0, 'xticklabels', [])
  521. B1 = b1.boxplot( BDEC , sym='', bootstrap=5000)# , notch=True )
  522. plt.setp(b1, 'xticklabels', sT2)
  523. R1 = r1.boxplot( RDEC , sym='', bootstrap=5000)# , notch=True )
  524. plt.setp(r1, 'xticklabels', sT2)
  525. B2 = b2.boxplot( AF , sym='', bootstrap=5000)# , notch=True )
  526. R2 = r2.boxplot( RF , sym='', bootstrap=5000)# , notch=True )
  527. plt.setp(r2, 'xticklabels', [])
  528. plt.setp(b2, 'xticklabels', [])
  529. B3 = b3.boxplot( AFC , sym='', bootstrap=5000)# , notch=True )
  530. R3 = r3.boxplot( RFC , sym='', bootstrap=5000)# , notch=True )
  531. plt.setp(r3, 'xticklabels', [])
  532. plt.setp(b3, 'xticklabels', [])
  533. B4 = b4.boxplot( AM , sym='', bootstrap=5000)# , notch=True )
  534. R4 = r4.boxplot( RM , sym='', bootstrap=5000)# , notch=True )
  535. plt.setp(r4, 'xticklabels', [])
  536. plt.setp(b4, 'xticklabels', [])
  537. b1.set_xlabel(r"true $T_2^*$ [ms]", color=labcol) #, fontsize=12)
  538. r1.set_xlabel(r"true $T_2^*$ [ms]", color=labcol) #, fontsize=12)
  539. b2.set_ylabel(r"phased FD", color=labcol) #, fontsize=12)
  540. b3.set_ylabel(r"complex FD", color=labcol) #, fontsize=12)
  541. b4.set_ylabel(r"modulus FD", color=labcol) #, fontsize=12)
  542. b0.set_ylabel(r"CA", color=labcol) #, fontsize=12)
  543. b1.set_ylabel(r"gated CA", color=labcol) #, fontsize=12)
  544. #r0.set_ylabel(r"parameter estimate error")
  545. #b1.set_xlabel(r"$T_2^*$ decay parameter [ms]")
  546. if BLACK:
  547. for box in [B0, R0, B1, R1]:
  548. box['boxes'][0].set_color('w')
  549. box['boxes'][0].set_linewidth(2)
  550. box['medians'][0].set_color('y')
  551. box['medians'][0].set_linewidth(2)
  552. box['fliers'][0].set_color('w')
  553. box['fliers'][1].set_color('w')
  554. box['whiskers'][0].set_color('w')
  555. box['whiskers'][1].set_color('w')
  556. # else:
  557. #it2 = 0
  558. #for ax in B0, r0, b1, r1:
  559. #for line in ax.xaxis.get_ticklabels():
  560. # print line.get_text()
  561. # line.set_text(str(T2[it2]))
  562. # print line.get_text()
  563. #setp(gca(), 'xticklabels', ['first', 'second', 'third'])
  564. #line.set_fontsize(16)
  565. # it2 += 1
  566. # box['boxes'][0].set_color('red')
  567. # box['boxes'][0].set_linewidth(3)
  568. # box['medians'][0].set_color('y')
  569. # box['medians'][0].set_linewidth(3)
  570. # box['fliers'][0].set_color('w')
  571. # box['fliers'][1].set_color('w')
  572. # box['whiskers'][0].set_color('w')
  573. # box['whiskers'][1].set_color('w')
  574. #r0.set_title(r"analytic signal $T_2^*$", color=labcol)
  575. #b0.set_title(r"analytic signal $V_N^{(0)}$", color=labcol)
  576. r3.set_title(r"$\tilde{T}_2^*$ relative error [\%]", color=labcol) #, fontsize=12)
  577. b3.set_title(r"$\tilde{V}_N^{(0)}$ absolute error [\%]", color=labcol) #, fontsize=12)
  578. if BLACK:
  579. invertColours(b0)
  580. invertColours(r0)
  581. invertColours(b1)
  582. invertColours(r1)
  583. #plt.savefig("boxplot.png", dpi=200, facecolor='black', edgecolor='black')
  584. #else:
  585. #plt.figure()
  586. #plt.boxplot( BDEC, bootstrap=1000 )
  587. #plt.title("dec")
  588. #plt.savefig("boxplot.png", dpi=200)
  589. bylow = min(b0.get_ylim()[0], b1.get_ylim()[0])
  590. bylow = min(bylow, b2.get_ylim()[0])
  591. bylow = min(bylow, b3.get_ylim()[0])
  592. bylow = min(bylow, b4.get_ylim()[0])
  593. byhi = max(b0.get_ylim()[1], b1.get_ylim()[1])
  594. byhi = max(byhi, b2.get_ylim()[1])
  595. byhi = max(byhi, b3.get_ylim()[1])
  596. byhi = max(byhi, b4.get_ylim()[1])
  597. rylow = min(r0.get_ylim()[0], r1.get_ylim()[0])
  598. rylow = min(rylow, r2.get_ylim()[0])
  599. rylow = min(rylow, r3.get_ylim()[0])
  600. rylow = min(rylow, r4.get_ylim()[0])
  601. ryhi = max(r0.get_ylim()[1], r1.get_ylim()[1])
  602. ryhi = max(ryhi, r2.get_ylim()[1])
  603. ryhi = max(ryhi, r3.get_ylim()[1])
  604. ryhi = max(ryhi, r4.get_ylim()[1])
  605. b0.set_ylim((bylow, byhi))
  606. b1.set_ylim((bylow, byhi))
  607. b2.set_ylim((bylow, byhi))
  608. b3.set_ylim((bylow, byhi))
  609. b4.set_ylim((bylow, byhi))
  610. r0.set_ylim((rylow, ryhi))
  611. r1.set_ylim((rylow, ryhi))
  612. r2.set_ylim((rylow, ryhi))
  613. r3.set_ylim((rylow, ryhi))
  614. r4.set_ylim((rylow, ryhi))
  615. if BLACK:
  616. #plt.savefig("boxplotlim2.pdf", dpi=600, facecolor='black', edgecolor='black')
  617. plt.savefig("boxplotlim_2.pdf", dpi=600, facecolor='black', edgecolor='black')
  618. plt.savefig("boxplotlim_2.eps", dpi=600, facecolor='black', edgecolor='black')
  619. else:
  620. #plt.savefig("boxplotlim2.pdf", dpi=600)
  621. plt.savefig("boxplotlim_2_corr.pdf", dpi=600)
  622. plt.savefig("boxplotlim_2_corr.eps", dpi=600)
  623. #plt.savefig("boxplotlim2.tex", dpi=600)
  624. plt.show()
  625. exit()
  626. #########################################################
  627. #########################################################
  628. # # fft figure
  629. # plt.figure()
  630. # XS = np.fft.rfft(xs)
  631. # freqs = np.fft.fftfreq(len(xs), dt)
  632. # freqs[len(XS)-1] *= -1 # nyquist returned for negative freq
  633. # freqs = freqs[0:len(XS)]
  634. #
  635. # plt.plot(freqs[0:len(XS)], XS.real)
  636. # plt.plot(freqs[0:len(XS)], XS.imag)
  637. #
  638. # # truncate by T X
  639. # plt.figure()
  640. # dv = freqs[1] - freqs[0]
  641. # iLw = vL / dv
  642. # tr = int(len(freqs) / 35.)
  643. # plt.plot(freqs[iLw-tr:iLw + tr], XS.real[iLw-tr:iLw+tr], '-x')
  644. # plt.plot(freqs[iLw-tr:iLw + tr], XS.imag[iLw-tr:iLw+tr], '-x')
  645. # plt.twinx()
  646. # plt.plot(freqs[iLw-tr:iLw + tr], np.angle(XS)[iLw-tr:iLw+tr], '-x')
  647. #
  648. # print len(XS[iLw-tr:iLw+tr])
  649. # print len(t[iisamp::irsamp])
  650. #
  651. # plt.show()