CorrelationCorrection.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. from PyQt4 import QtCore
  2. from scipy.optimize import curve_fit, ridder
  3. from scipy.stats import chisquare
  4. from scipy.stats import chi2_contingency
  5. from scipy.special import erfc
  6. import h5py
  7. import os
  8. import ast
  9. import sys
  10. import traceback
  11. from time import time, sleep
  12. try:
  13. #for KCG
  14. from ..base import kcgwidget as kcgw
  15. except:
  16. #for Analysis GUI
  17. import kcgwidget as kcgw
  18. import matplotlib
  19. matplotlib.use("Qt4Agg")
  20. #matplotlib.use("Agg")
  21. import numpy as np, matplotlib.pyplot as plt
  22. from mpl_toolkits.mplot3d import Axes3D
  23. def gauss(x, sigma, mu, A):
  24. return A*np.exp(-0.5*((x-mu)/sigma)**2)
  25. def sinus(x,f):
  26. return np.sin(2*np.pi*f*x)
  27. def linear(x, a,b):
  28. return a*x+b
  29. def varianz(s,l):
  30. return np.sqrt(s**2 + 1/(l**2))
  31. def skewness(s,l):
  32. return 2.0/(s**3*l**3) * (1+ 1.0/(s**2*l**2))**(-3.0/2)
  33. def skewness2(s,v):
  34. return 2.0-2.0*(s/v)**3
  35. def sigma(v,t):
  36. return np.sqrt(v**2*(1-(t/2.0)**(2.0/3)))
  37. def lamda(v,t):
  38. return (2.0/t)**(1.0/3)/v
  39. def expgauss(x, s, m, a ,l):
  40. return a*l/2*np.exp(l/2*(2*m + l*s**2 - 2*x)) * erfc((m +l*s**2 -x)/(np.sqrt(2)*s))
  41. def poly2(x, a,b,c):#,d):#,e):
  42. return a + b*x+ c*x**2# + d*x**3# +e*x**4
  43. import itertools
  44. def polyfit1d(x, y, order=3):
  45. ncols = (order + 1)**1
  46. G = np.zeros((x.size, ncols))
  47. i = itertools.product(range(order+1))
  48. for k, (i) in enumerate(i):
  49. G[:,k] = x**i
  50. m, _, _, _ = np.linalg.lstsq(G, y)
  51. return m
  52. def polyval1d(x, m):
  53. order = int(np.sqrt(len(m))) - 1
  54. i = itertools.product(range(order+1))
  55. z = np.zeros_like(x)
  56. for a, (i) in zip(m, i):
  57. z += a * x**i
  58. return z
  59. def polyfit2d(x, y, z, order=3):
  60. ncols = (order + 1)**2
  61. G = np.zeros((x.size, ncols))
  62. ij = itertools.product(range(order+1), range(order+1))
  63. for k, (i,j) in enumerate(ij):
  64. G[:,k] = x**i * y**j
  65. m, _, _, _ = np.linalg.lstsq(G, z, rcond=None)
  66. return m
  67. def polyval2d(x, y, m):
  68. order = int(np.sqrt(len(m))) - 1
  69. ij = itertools.product(range(order+1), range(order+1),)
  70. z = np.zeros_like(x)
  71. for a, (i,j) in zip(m, ij):
  72. z += a * x**i * y**j
  73. return z
  74. def polyfit3d(x, y, z,f, order=3):
  75. ncols = (order + 1)**3
  76. #print(ncols)
  77. G = np.zeros((x.size, ncols))
  78. ijk = itertools.product(range(order+1), range(order+1),range(order+1))
  79. for n, (i,j,k) in enumerate(ijk):
  80. G[:,n] = x**i * y**j * z**k
  81. m, _, _, _ = np.linalg.lstsq(G, f, rcond=None)
  82. return m
  83. def polyval3d(x, y, z, m):
  84. order = int(len(m)**(1/3)) - 1
  85. #print(order)
  86. ijk = itertools.product(range(order+1), range(order+1), range(order+1))
  87. f = np.zeros_like(x)
  88. for a, (i,j,k) in zip(m, ijk):
  89. #print(i,j,k)
  90. f += a * x**i * y**j * z**k
  91. return f
  92. class CorrelationCorrection(QtCore.QObject):
  93. """docstring for CorrelationCorrection
  94. """
  95. stopSignal = QtCore.pyqtSignal()
  96. def __init__(self, path, scanX, scanY, delays, workingChannels=[0,1,2,3,4,5,6,7]):
  97. super(CorrelationCorrection, self).__init__()
  98. self.host = "ibpt-kapture1"
  99. self.remotePath = "/home/kapture/GPU-Analyse/PeakReconstruction/"
  100. self.remoteUser = 'kapture'
  101. self.remotePW = 'kapture123'
  102. #self.dirToReconstruction = '../PeakReconstruction/'
  103. self.workingChannels = workingChannels
  104. print(workingChannels)
  105. self.scanX = scanX
  106. self.scanY = scanY
  107. self.delays = delays
  108. self.path = os.path.join(path, 'simulationData' )
  109. if not os.path.exists(self.path):
  110. os.mkdir(self.path)
  111. self.nr=0
  112. filelist = np.sort(os.listdir(self.path))
  113. for file in filelist:
  114. if '.out' in file:
  115. if int(file[-6:-4]) >= self.nr:
  116. self.nr = int(file[-6:-4])+1
  117. #self.nr-=1
  118. self.file = 'simu_{:02d}.out'.format(self.nr)
  119. self.fileMuster = 'simu_{:02d}.npy'.format(self.nr)
  120. self.process = QtCore.QProcess()
  121. self.process.readyRead.connect(self._processOut)
  122. self.process.readyReadStandardOutput.connect(self._processOut)
  123. self.process.finished.connect(self._processFinished)
  124. self.process.error.connect(self._processError)
  125. self.process.setWorkingDirectory(self.remotePath)
  126. self.process.setProcessChannelMode(QtCore.QProcess.MergedChannels)
  127. def run(self, plotting=False):
  128. startx = self.scanX[np.where(self.scanY==np.max(self.scanY))]
  129. p0 = [2.2099e-11, startx, 1.03567844e-8, 2.15525657e+10]
  130. self.popt, pcov = curve_fit(expgauss, self.scanX, self.scanY, p0=p0)
  131. self.meanSigma = self.popt[0] #22e-11
  132. self.meanMean = self.popt[1]
  133. self.meanAmplitude = np.max(self.scanY)*2 #self.popt[2]
  134. self.meanVarianz = 45
  135. self.deltaVarianz = 15
  136. self.deltaMean = 10
  137. try:
  138. self._generateSimulationData(plotting)
  139. self._runReconstruction()
  140. self._calculateCorrections(plotting)
  141. if plotting:
  142. plt.show(block=False)
  143. except:
  144. traceback.print_exc()
  145. #popup = kcgw.PopupDialog("There was an error",
  146. # title='Reminder', okonly=True)
  147. #popup.exec_()
  148. #popup.deleteLater()
  149. #popup.get_return_value()
  150. pass
  151. self.stopSignal.emit()
  152. pass
  153. def save(self, file):
  154. with h5py.File(file, 'w') as f:
  155. f['Mean'] = self.poptMean
  156. f['Sigma'] = self.poptSigma
  157. f['Amplitude'] = self.poptAmpl
  158. def _generateSimulationData(self, plotting):
  159. print('_generateSimulationData')
  160. if plotting:
  161. self._plotScan()
  162. plt.show(block=False)
  163. fitx = np.linspace(np.min(self.delays)*0.8,np.max(self.delays)*1.2,2000)
  164. steps = 10
  165. steplength = 3000
  166. n = steps*steplength
  167. fh = np.memmap(os.path.join(self.path, self.file), mode='w+', dtype='uint32', shape=(n*184//2*8))
  168. ctr = np.left_shift(np.array(np.repeat(np.linspace(0,184-2,184//2),8), dtype=np.uint32), 24)
  169. master =[]
  170. for i in range(n):
  171. #print(i, end='\r')
  172. fh[i*184//2*8:(i+1)*184//2*8] = ctr + np.left_shift(2040,12) + 2040
  173. m = self.meanMean + self.deltaMean*sinus(i, 77.7777e-5)*1e-12
  174. v = (self.meanVarianz + self.deltaVarianz*sinus(i, 456.1e-5))*1e-12
  175. A = self.meanAmplitude +0.8*self.meanAmplitude*sinus(i, 3.33e-5)
  176. s = self.meanSigma
  177. t = skewness2(s,v)
  178. #s = sigma(v,t)
  179. l = lamda(v,t)
  180. popt = [s, m, self.popt[2], l]
  181. fity = expgauss(fitx, *popt)
  182. fityM = np.max(fity)
  183. m2 = fitx[np.where(fity==fityM)]
  184. m2 = m-(m2-m)
  185. popt = [s, m2, self.popt[2], l]
  186. #fity = expgauss(fitx, *popt)
  187. #fityM = np.max(fity)
  188. #m = fitx[np.where(fity==fityM)]
  189. data = expgauss(self.delays, *popt)
  190. data = data/fityM*A
  191. #print(data)
  192. master.append([v/2.0, m-self.meanMean, A, l])
  193. fh[i*184//2*8:i*184//2*8+8] += np.array(data, dtype=np.uint32)
  194. print('done')
  195. master = np.array(master)
  196. np.save(os.path.join(self.path, self.fileMuster), master)
  197. dataxb = self.delays*1e12
  198. #datax *= 1e12
  199. dataxb -= np.min(dataxb)-10
  200. f = open(os.path.join(self.path,'Measurement_board_6028.log'), 'a')
  201. f.write('\n---\n')
  202. f.write('2018-12-05 20:12:14\n')
  203. f.write('\tSimulation\n')
  204. f.write('\tFilename: {}\n'.format(self.file))
  205. f.write('\tNumber of Skipped Turns: 0\n')
  206. f.write('\tBeam Current (mA): 10\n')
  207. f.write('\tADC Delays: [0, 0, 0, 0, 0, 0, 0, 0]\n\tT/H Delay: 0\n\t25ps Delay: 0\n\tT/H Delay 2: 0\n\t25ps Delay 2: 0\n\tDelay Cascade: 0\n')
  208. f.write('\tdatax: ['+', '.join(str(x) for x in dataxb) + ']\n')
  209. f.write('\tWorking Channels: ['+', '.join(str(x) for x in self.workingChannels) + ']\n\n')
  210. f.close()
  211. def checkForCuda(self):
  212. #Check if CUDA available:
  213. cuda = True
  214. try:
  215. import pycuda.driver as cuda
  216. import pycuda.autoinit
  217. def printGPUstats(onlymem=True):
  218. (free,total)=cuda.mem_get_info()
  219. print("Global memory occupancy: %f%% free of %f"%(free*100/total, total/1024/1024))
  220. if onlymem:
  221. return
  222. for devicenum in range(cuda.Device.count()):
  223. device=cuda.Device(devicenum)
  224. attrs=device.get_attributes()
  225. #Beyond this point is just pretty printing
  226. print("\n===Attributes for device %d"%devicenum)
  227. for (key,value) in attrs.items():
  228. print("%s:%s"%(str(key),str(value)))
  229. printGPUstats()
  230. except Exception as e:
  231. print('no CUDA')
  232. cuda = False
  233. return cuda
  234. def _runReconstruction(self):
  235. print('_runReconstruction')
  236. cuda = self.checkForCuda()
  237. if cuda:
  238. param = ["-u", os.path.join("PeakReconstuction.py"), "-f", os.path.abspath(os.path.join(self.path, self.file)), "-c", 'd']
  239. self.process.start("python3", param)
  240. # -u is for python to force it to unbuffered print
  241. self.process.waitForStarted()
  242. self.process.waitForFinished()
  243. else:
  244. remoteFile = self.remotePath + "simulationData/"+ self.file
  245. localPath = os.path.abspath(self.path)
  246. localFile = os.path.abspath(os.path.join(self.path, self.file))
  247. import paramiko
  248. ssh = paramiko.SSHClient()
  249. ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  250. ssh.connect(self.host, username=self.remoteUser, password=self.remotePW)
  251. print('put')
  252. # Define progress callback that prints the current percentage completed for the file
  253. def progress(sent, size):
  254. sys.stdout.write("progress: %.2f%% \r" % (float(sent)/float(size)*100) )
  255. scp = ssh.open_sftp()
  256. scp.put(localFile, remoteFile)#, progress)
  257. scp.put(os.path.join(localPath, 'Measurement_board_6028.log'), self.remotePath+'simulationData/Measurement_board_6028.log', progress)
  258. print('calc')
  259. stdin, stdout, stderr = ssh.exec_command("cd {} ; python3 -u {} -f {} -c d -v -o '' ".format(self.remotePath, "PeakReconstruction.py", remoteFile))
  260. #stdout.channel.recv_exit_status()
  261. while not stdout.channel.exit_status_ready():
  262. o = stdout.readline()
  263. if o != '':
  264. print(o[:-1])
  265. lines = stdout.readlines()
  266. for line in lines:
  267. print(line[:-1])
  268. lines = stderr.readlines()
  269. for line in lines:
  270. print('e', line[:-1])
  271. print('get')
  272. scp.get(remoteFile[:-4]+'_fit.hdf', localFile[:-4]+'_fit.hdf', progress)
  273. scp.close()
  274. ssh.close()
  275. pass
  276. def _calculateCorrections(self, plotting):
  277. print('_calculateCorrections')
  278. filename = os.path.join(self.path, self.file[:-4]+'_fit.hdf')
  279. fitData={}
  280. with h5py.File(filename,'r') as fh:
  281. fitData['Amplitude'] = np.reshape(fh['Amplitude'][()]/10.0, -1)
  282. fitData['Mean'] = np.reshape(fh['Mean'][()]/10.0, -1)
  283. fitData['Sigma'] = np.reshape(fh['Sigma'][()]/10.0, -1)
  284. try:
  285. fitData['Error'] = fh['Error'][()]/10.0
  286. except:
  287. pass
  288. fitData['log'] = ast.literal_eval(fh['fit_info']['log'][()])
  289. fitData['selector'] = fh['fit_info']['selector'][()]
  290. fitData['filename'] = filename
  291. m = fitData['Mean'][:]
  292. a = fitData['Amplitude'][:]
  293. s = fitData['Sigma'][:]
  294. selector = np.where(a>0)
  295. m = m[selector]
  296. a = a[selector]
  297. s = s[selector]
  298. #m = m-np.mean(m)
  299. original = np.load(os.path.join(self.path, self.fileMuster))
  300. #print(original.shape)
  301. mo = original[:,1]*1e12
  302. ao = original[:,2]
  303. so = original[:,0]*1e12
  304. mo = mo[selector]
  305. ao = ao[selector]
  306. so = so[selector]
  307. #print(mo.shape)
  308. w = np.array([ao,mo,so])
  309. pov = np.corrcoef(w)
  310. print('Korrelation Original:')
  311. print('A-M: {:.5f}'.format(pov[0,1]))
  312. print('A-S: {:.5f}'.format(pov[0,2]))
  313. print('M-S: {:.5f}'.format(pov[1,2]))
  314. self.povOrg = pov
  315. w = np.array([a,m,s])
  316. pov = np.corrcoef(w)
  317. print('Korrelation unkorrigiert:')
  318. print('A-M: {:.5f}'.format(pov[0,1]))
  319. print('A-S: {:.5f}'.format(pov[0,2]))
  320. print('M-S: {:.5f}'.format(pov[1,2]))
  321. self.povUnCorr = pov
  322. if plotting:
  323. self._plotComparison(mo,ao,so,m,a,s)
  324. self.poptMean, pcov = curve_fit(poly2, m,mo)
  325. mc = poly2(m, *self.poptMean)
  326. self.poptSigma = polyfit2d(mc, s, so, order=3)
  327. sc = polyval2d(mc, s, self.poptSigma)
  328. self.poptAmpl = polyfit3d(mc, sc, a, ao, order=2)
  329. ac = polyval3d(mc, sc, a, self.poptAmpl)
  330. print(self.poptAmpl)
  331. w = np.array([ac,mc,sc])
  332. pov = np.corrcoef(w)
  333. print('Korrelation korrigiert:')
  334. print('A-M: {:.5f}'.format(pov[0,1]))
  335. print('A-S: {:.5f}'.format(pov[0,2]))
  336. print('M-S: {:.5f}'.format(pov[1,2]))
  337. self.povCorr = pov
  338. if plotting:
  339. self._plotComparison(mo,ao,so,mc,ac,sc)
  340. #plt.show()
  341. self.mo = mo
  342. self.so = so
  343. self.ao = ao
  344. self.a = a
  345. self.s = s
  346. self.m = m
  347. self.mc = mc
  348. self.sc = sc
  349. self.ac = ac
  350. pass
  351. def test(self):
  352. param = ["-u", os.path.join("PeakReconstuction.py"), "-f", os.path.abspath(os.path.join(self.path, self.file)), "-c", 'd', '-c2', 'd']
  353. self.process.start("python3", param)
  354. # -u is for python to force it to unbuffered print
  355. self.process.waitForStarted()
  356. self.process.waitForFinished()
  357. filename = os.path.join(self.path, self.file[:-4]+'_fit.hdf')
  358. fitData={}
  359. with h5py.File(filename,'r') as fh:
  360. fitData['Amplitude'] = np.reshape(fh['Amplitude'][()]/10.0, -1)
  361. fitData['Mean'] = np.reshape(fh['Mean'][()]/10.0, -1)
  362. fitData['Sigma'] = np.reshape(fh['Sigma'][()]/10.0, -1)
  363. try:
  364. fitData['Error'] = fh['Error'][()]/10.0
  365. except:
  366. pass
  367. fitData['log'] = ast.literal_eval(fh['fit_info']['log'][()])
  368. fitData['selector'] = fh['fit_info']['selector'][()]
  369. fitData['filename'] = filename
  370. m = fitData['Mean'][:]
  371. a = fitData['Amplitude'][:]
  372. s = fitData['Sigma'][:]
  373. selector = np.where(a>0)
  374. m = m[selector]
  375. a = a[selector]
  376. s = s[selector]
  377. original = np.load(os.path.join(self.path, self.fileMuster))
  378. mo = original[:,1]*1e12
  379. ao = original[:,2]
  380. so = original[:,0]*1e12
  381. mo = mo[selector]
  382. ao = ao[selector]
  383. so = so[selector]
  384. self._plotComparison(mo,ao,so,m,a,s)
  385. plt.show()
  386. pass
  387. def _plotFitOverOrg(self, mo,ao,so,m,a,s, titel=""):
  388. fig4, axs3 = plt.subplots(1, 3, figsize=(14, 9))
  389. axs3[0].plot(mo,m,'.')
  390. axs3[1].plot(so,s,'.')
  391. axs3[2].plot(ao,a,'.')
  392. axs3[0].set_ylabel('Ankunftszeit\n(ps)')
  393. axs3[1].set_ylabel('Breite\n(ps)')
  394. axs3[2].set_ylabel('Amplitude\n(ADC counts)')
  395. plt.title('Fit over Org '+titel)
  396. plt.tight_layout()
  397. def _plotComparison(self, mo,ao,so,m,a,s, titel=""):
  398. fig4, axs3 = plt.subplots(3, 1, figsize=(14, 9),sharex=True)
  399. axs3[0].plot(mo)
  400. axs3[1].plot(so)
  401. axs3[2].plot(ao)
  402. axs3[0].plot(m)
  403. axs3[1].plot(s)
  404. axs3[2].plot(a)
  405. axs3[0].set_ylabel('Ankunftszeit\n(ps)')
  406. axs3[1].set_ylabel('Breite\n(ps)')
  407. axs3[2].set_ylabel('Amplitude\n(ADC counts)')
  408. plt.tight_layout()
  409. plt.title(titel)
  410. #plt.savefig('plots/simu2.png', dpi=200)
  411. def _plotScan(self):
  412. plt.figure(figsize=(14,9))
  413. plt.plot(self.scanX*1e9, self.scanY, '.', markersize=16, label='Timescan')
  414. plt.plot(np.sort(self.scanX*1e9), expgauss(np.sort(self.scanX), *self.popt), linewidth=2, label='Fit')
  415. i=1
  416. ym = np.max(self.scanY)*1.06
  417. for xt in self.delays*1e9:
  418. if i in [5,6]:
  419. i += 1
  420. continue
  421. plt.plot([xt,xt],[0,ym], linewidth=1, color='black')#, label='ADC {}'.format(i))
  422. plt.text(xt, ym+1, '{}'.format(i), horizontalalignment='center', verticalalignment='bottom')#, rotation='vertical')
  423. i += 1
  424. plt.ylabel('ADC count')
  425. plt.xlabel('t (ns)')
  426. plt.ylim(-2, 132)
  427. plt.tight_layout()
  428. def _processOut(self):
  429. #print('out')
  430. print(self.process.readAll().data().decode('utf8'))#,end='')
  431. def _processFinished(self):
  432. print('Process Finished!')
  433. def _processError(self):
  434. print('Process Error!')