CalcGM_Noise_LMU.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Fri Oct 05 15:49:46 2018
  4. @author: aemdlabs
  5. """
  6. #!/usr/bin/env python2
  7. # -*- coding: utf-8 -*-
  8. """
  9. Created on Wed Sep 5 12:05:21 2018
  10. @author: aguimera
  11. """
  12. from PhyREC.NeoInterface import NeoSegment#, ReadMCSFile
  13. import PhyREC.SignalAnalysis as Ran
  14. import PhyREC.PlotWaves as Rplt
  15. import quantities as pq
  16. import matplotlib.pyplot as plt
  17. import numpy as np
  18. import neo
  19. import csv
  20. from datetime import datetime
  21. from scipy import integrate
  22. def ReadMCSFile(McsFile, OutSeg=None, SigNamePrefix=''):
  23. import McsPy.McsData as McsData
  24. Dat = McsData.RawData(McsFile)
  25. Rec = Dat.recordings[0]
  26. NSamps = Rec.duration
  27. if OutSeg is None:
  28. OutSeg = NeoSegment()
  29. for AnaStrn, AnaStr in Rec.analog_streams.iteritems():
  30. if len(AnaStr.channel_infos) == 1:
  31. continue
  32. for Chn, Chinfo in AnaStr.channel_infos.iteritems():
  33. print 'Analog Stream ', Chinfo.label, Chinfo.sampling_frequency
  34. ChName = str(SigNamePrefix + Chinfo.label)
  35. print ChName
  36. Fs = Chinfo.sampling_frequency
  37. Var, Unit = AnaStr.get_channel_in_range(Chn, 0, NSamps)
  38. sig = neo.AnalogSignal(pq.Quantity(Var, Chinfo.info['Unit']),
  39. t_start=0*pq.s,
  40. sampling_rate=Fs.magnitude*pq.Hz,
  41. name=ChName)
  42. OutSeg.AddSignal(sig)
  43. return OutSeg
  44. def ReadLogFile(File):
  45. Fin = open(File)
  46. reader = csv.reader(Fin, delimiter='\t')
  47. LogVals = {}
  48. ValsPos = {}
  49. for il, e in enumerate(reader):
  50. if il == 0:
  51. for ih, v in enumerate(e):
  52. ValsPos[ih] = v
  53. LogVals[v] = []
  54. else:
  55. for ih, v in enumerate(e):
  56. par = ValsPos[ih]
  57. if (par=='Vgs') or (par=='Vds') or (par=='Vref'):
  58. LogVals[par].append(float(v.replace(',','.')))
  59. elif par == 'Date/Time':
  60. LogVals[par].append(datetime.strptime(v, '%d/%m/%Y %H:%M:%S'))
  61. else:
  62. LogVals[par].append(v)
  63. deltas = np.array(LogVals['Date/Time'])[:]-LogVals['Date/Time'][0]
  64. LogVals['Time'] = []
  65. for d in deltas:
  66. LogVals['Time'].append(d.total_seconds())
  67. Fin.close()
  68. return LogVals
  69. def GetSwitchTimes(Sig, Thres=-1e-4, Plot=True):
  70. s = Sig.GetSignal(None)
  71. ds = np.abs(np.diff(np.array(s), axis=0))
  72. if Plot:
  73. plt.figure()
  74. plt.plot(s.times, s)
  75. plt.plot(s.times[1:], ds)
  76. ds = Sig.duplicate_with_new_array(signal=ds)
  77. Times = Ran.threshold_detection(ds,
  78. threshold=Thres,
  79. RelaxTime=5*pq.s)
  80. return Times
  81. def MeanStd(Data, var):
  82. Arr = np.zeros([len(Data.keys()),len(Data[Data.keys()[0]][var])])
  83. for iT,TrtName in enumerate(Data.keys()):
  84. Arr[iT,:] = Data[TrtName][var][:,0]
  85. return np.mean(Arr,0), np.std(Arr,0)
  86. def MeanStdGM(Data):
  87. Arr = np.zeros([len(Data.keys()),len(Data[Data.keys()[0]])])
  88. for iT,TrtName in enumerate(Data.keys()):
  89. Arr[iT,:] = Data[TrtName]
  90. return np.mean(Arr,0), np.std(Arr,0)
  91. def Integrate(PSD, Freqs, Fmin, Fmax):
  92. indices = np.where((Freqs >= Fmin) & (Freqs<=Fmax))
  93. print( Freqs[indices])
  94. Irms = np.sqrt(integrate.trapz(PSD[indices], Freqs[indices]))
  95. return Irms
  96. MCSMapI={'SE1':'Ch03',
  97. 'SE2':'Ch05',
  98. 'SE3':'Ch01',
  99. 'SE4':'Ch02',
  100. 'SE5':'Ch22',
  101. 'SE6':'Ch06',
  102. 'SE7':'Ch16',
  103. 'SE8':'Ch37',
  104. 'SE9':'Ch20',
  105. 'SE10':'Ch10',
  106. 'SE11':'Ch24',
  107. 'SE12':'Ch08',
  108. 'SE13':'Ch14',
  109. 'SE14':'Ch04',
  110. 'SE15':'Ch18',
  111. 'SE16':'Ch33',
  112. 'SE17':'Ch34',
  113. 'SE18':'Ch60',
  114. 'SE19':'Ch38',
  115. 'SE20':'Ch64',
  116. 'SE21':'Ch40',
  117. 'SE22':'Ch56',
  118. 'SE23':'Ch42',
  119. 'SE24':'Ch70',
  120. 'SE25':'Ch66',
  121. 'SE26':'Ch65',
  122. 'SE27':'Ch68',
  123. 'SE28':'Ch67',
  124. 'SE29':'Ch55',
  125. 'SE30':'Ch62',
  126. 'SE31':'Ch58',
  127. 'SE32':'Ch69',
  128. 'ME1':'Ch57',
  129. 'ME2':'Ch61',
  130. 'ME3':'Ch53',
  131. 'ME4':'Ch63',
  132. 'ME5':'Ch52',
  133. 'ME6':'Ch41',
  134. 'ME7':'Ch49',
  135. 'ME8':'Ch51',
  136. 'ME9':'Ch46',
  137. 'ME10':'Ch45',
  138. 'ME11':'Ch44',
  139. 'ME12':'Ch39',
  140. 'ME13':'Ch54',
  141. 'ME14':'Ch43',
  142. 'ME15':'Ch50',
  143. 'ME16':'Ch47',
  144. 'ME17':'Ch32',
  145. 'ME18':'Ch27',
  146. 'ME19':'Ch30',
  147. 'ME20':'Ch29',
  148. 'ME21':'Ch28',
  149. 'ME22':'Ch25',
  150. 'ME23':'Ch26',
  151. 'ME24':'Ch07',
  152. 'ME25':'Ch21',
  153. 'ME26':'Ch11',
  154. 'ME27':'Ch17',
  155. 'ME28':'Ch15',
  156. 'ME29':'Ch13',
  157. 'ME30':'Ch31',
  158. 'ME31':'Ch19',
  159. 'ME32':'Ch09'}
  160. #Col, Row
  161. MCSMapFacingDown={'Ch58':(0,1),
  162. 'Ch57':(0,2),
  163. 'Ch56':(0,3),
  164. 'Ch55':(0,4),
  165. 'Ch54':(0,5),
  166. 'Ch53':(0,6),
  167. 'Ch52':(0,7),
  168. 'Ch51':(0,8),
  169. 'Ch50':(0,9),
  170. 'Ch49':(0,10),
  171. 'Ch60':(1,0),
  172. 'Ch61':(1,1),
  173. 'Ch62':(1,2),
  174. 'Ch63':(1,3),
  175. 'Ch64':(1,4),
  176. 'Ch65':(1,5),
  177. 'Ch43':(1,6),
  178. 'Ch44':(1,7),
  179. 'Ch45':(1,8),
  180. 'Ch46':(1,9),
  181. 'Ch47':(1,10),
  182. 'Ch70':(2,0),
  183. 'Ch69':(2,1),
  184. 'Ch68':(2,2),
  185. 'Ch67':(2,3),
  186. 'Ch66':(2,4),
  187. 'Ch42':(2,5),
  188. 'Ch41':(2,6),
  189. 'Ch40':(2,7),
  190. 'Ch39':(2,8),
  191. 'Ch38':(2,9),
  192. 'Ch37':(2,10),
  193. 'Ch01':(3,0),
  194. 'Ch02':(3,1),
  195. 'Ch03':(3,2),
  196. 'Ch04':(3,3),
  197. 'Ch05':(3,4),
  198. 'Ch06':(3,5),
  199. 'Ch30':(3,6),
  200. 'Ch31':(3,7),
  201. 'Ch32':(3,8),
  202. 'Ch33':(3,9),
  203. 'Ch34':(3,10),
  204. 'Ch11':(4,0),
  205. 'Ch10':(4,1),
  206. 'Ch09':(4,2),
  207. 'Ch08':(4,3),
  208. 'Ch07':(4,4),
  209. 'Ch29':(4,5),
  210. 'Ch28':(4,6),
  211. 'Ch27':(4,7),
  212. 'Ch26':(4,8),
  213. 'Ch25':(4,9),
  214. 'Ch24':(4,10),
  215. 'Ch12':None,
  216. 'Ch59':None,
  217. 'Ch13':(5,1),
  218. 'Ch14':(5,2),
  219. 'Ch15':(5,3),
  220. 'Ch16':(5,4),
  221. 'Ch17':(5,5),
  222. 'Ch18':(5,6),
  223. 'Ch19':(5,7),
  224. 'Ch20':(5,8),
  225. 'Ch21':(5,9),
  226. 'Ch22':(5,10)}
  227. if __name__ == '__main__':
  228. Path = '23072019/B12784O18-T3/'
  229. InFileM = Path + '2019-07-23T18-55-56B12784O18-T3-ACDC-PostEth-PostLong.h5' ############
  230. InFileS = Path + '2019-07-23T18-55-56B12784O18-T3-ACDC-PostEth-PostLong_2.h5' ##########
  231. LogFile = Path + 'B12784O18-T3-ACDC-PostEth-PostLong.txt'
  232. StartCycle = -1
  233. LogVals = ReadLogFile(LogFile)
  234. delta = np.mean([t-LogVals['Time'][it] for it, t in enumerate(LogVals['Time'][1:])])*pq.s
  235. Delay = delta * StartCycle
  236. DCch = ('ME5', 'ME7', 'ME29', 'ME31', 'SE5', 'SE7', 'SE29', 'SE31')
  237. TrigChannel = 'SE31'
  238. TrigThres = 5e-5
  239. Vgs = np.array(LogVals['Vgs'])
  240. Vds = LogVals['Vds'][0]
  241. ivgain1 = 12e3*pq.V
  242. ivgain2 = 101
  243. ACgain = 10*1
  244. DCgain = 1*pq.V
  245. Fsig = 10
  246. StabTime = 10*pq.s
  247. GuardTime = 1*pq.s
  248. BW = 100
  249. ivgainDC = 118.8*pq.V
  250. ivgainAC = 1188*pq.V
  251. Rec = ReadMCSFile(InFileM,
  252. OutSeg=None,
  253. SigNamePrefix='M')
  254. Rec = ReadMCSFile(InFileS,
  255. OutSeg=Rec,
  256. SigNamePrefix='S')
  257. # %%
  258. plt.close('all')
  259. plt.ion()
  260. SwTimes = GetSwitchTimes(Sig=Rec.GetSignal(TrigChannel),
  261. Thres=TrigThres,
  262. Plot=True)
  263. SlotsDC = []
  264. for sig in Rec.Signals():
  265. if sig.name not in DCch:
  266. continue
  267. if sig.name.startswith('M'):
  268. col = 'r'
  269. else:
  270. col = 'g'
  271. SlotsDC.append(Rplt.WaveSlot(sig,
  272. Position=0,
  273. Color=col,
  274. Alpha=0.5))
  275. SwTimes = LogVals['Time']*pq.s+SwTimes[0]+Delay
  276. #%% calc IV DC
  277. DevDCVals = {}
  278. fig, Axt = plt.subplots()
  279. Ids = {}
  280. for sl in SlotsDC:
  281. Ids[sl.name] = []
  282. for isw, (t, vg) in enumerate(zip(SwTimes, Vgs)):
  283. ts = SwTimes[isw]+delta
  284. TWind = (t+StabTime, ts-GuardTime)
  285. s = sl.GetSignal(TWind, Units='V')
  286. Axt.plot(s)
  287. vio = np.mean(s).magnitude
  288. ids = (vio*101-(-vg+Vds))/12e3
  289. Ids[sl.name].append(ids)
  290. #%% Calc GM
  291. GM = {}
  292. Irms = {}
  293. Urms = {}
  294. fig, (AxPsd, Axt) = plt.subplots(2,1)
  295. fig2, (AxPs, Axt) = plt.subplots(2,1)
  296. for sig in Rec.Signals():
  297. if sig.name[0:3] == 'SEn':
  298. continue
  299. #
  300. GM[sig.name] = []
  301. Irms[sig.name] = []
  302. Urms[sig.name] = []
  303. for isw, (t, vg) in enumerate(zip(SwTimes, Vgs)):
  304. if isw == len(SwTimes)-1:
  305. ts = SwTimes[isw]-Delay
  306. else:
  307. ts = SwTimes[isw+1]
  308. TWind = (t+StabTime, ts-GuardTime)
  309. s = sig.GetSignal(TWind, Units ='V')
  310. if s.name in DCch:
  311. s = (s*ivgain2-(-vg+Vds)*pq.V)/ivgain1
  312. else:
  313. s = s/(ivgain1*ACgain/ivgain2)
  314. Axt.plot(s.times, s, label=vg, alpha=0.5)
  315. PS = Ran.PlotPSD((s,),
  316. Time = TWind,
  317. Ax=AxPs,
  318. FMin=1,
  319. Label=str(vg),
  320. scaling='spectrum')
  321. ps = PS[sig.name]['psd']
  322. Fps = PS[sig.name]['ff']
  323. indicesPeak = np.where( ((Fps >= Fsig-4) & (Fps<=Fsig+4)))
  324. IDSpeak = np.sqrt(ps[np.argmax(ps[indicesPeak])+indicesPeak[0][0]]+
  325. ps[np.argmax(ps[indicesPeak])+indicesPeak[0][0]+1]+
  326. ps[np.argmax(ps[indicesPeak])+indicesPeak[0][0]-1])
  327. gm = IDSpeak*1000/0.707
  328. GM[sig.name] = np.append(GM[sig.name],gm)
  329. PSD = Ran.PlotPSD((s,),
  330. Time = TWind,
  331. Ax=AxPsd,
  332. FMin=1,
  333. Label=str(vg),
  334. scaling='density')
  335. psd = PSD[sig.name]['psd'][:,0]
  336. Fpsd = PSD[sig.name]['ff']
  337. # irms = Integrate(psd, Fpsd, 1.9, 1.9*3.2)
  338. # Irms[sig.name] = np.append(Irms[sig.name],irms*np.sqrt(2))
  339. irms = Integrate(psd, Fpsd, 63, 200)
  340. Irms[sig.name] = np.append(Irms[sig.name],irms*np.sqrt(2))
  341. Irms[sig.name] = Irms[sig.name]
  342. Urms[sig.name] = Irms[sig.name]/GM[sig.name]
  343. plt.figure(12)
  344. GMmean, GMstd = MeanStdGM(GM)
  345. plt.plot(Vgs, GMmean*1000/0.1,'k',label = '1 metal layer')
  346. plt.fill_between(Vgs, GMmean*1000/0.1-GMstd*1000/0.1, GMmean*1000/0.1+GMstd*1000/0.1,color = 'k',alpha =0.3)
  347. plt.xlabel('V$_{gs}$ - V$_{CNP}$ (V)')
  348. plt.ylabel('G$_m$ (mS/V)')
  349. plt.legend()
  350. plt.figure(7)
  351. IrmsMean, IrmsStd = MeanStdGM(Irms)
  352. plt.semilogy(Vgs, IrmsMean,'k',label = 'rms')
  353. plt.fill_between(Vgs, IrmsMean-IrmsStd, IrmsMean+IrmsStd ,color = 'k',alpha =0.3)
  354. plt.xlabel('V$_{gs}$ - V$_{CNP}$ (V)')
  355. plt.ylabel('I$_{rms}$ (A)')
  356. plt.legend()
  357. plt.figure(8)
  358. UrmsMean, UrmsStd = MeanStdGM(Urms)
  359. plt.semilogy(Vgs, UrmsMean,'k',label = '1 metal layer')
  360. plt.fill_between(Vgs, UrmsMean-UrmsStd, UrmsMean+UrmsStd ,color = 'k',alpha =0.3)
  361. plt.xlabel('V$_{gs}$ - V$_{CNP}$ (V)')
  362. plt.ylabel('U$_{rms}$ (A)')
  363. plt.legend()
  364. #%% plot map Urms
  365. plt.figure()
  366. A=np.log10(np.ones((11,6))*5e-17)
  367. import matplotlib.colors as colors
  368. for Trt in Urms.keys():
  369. ch = MCSMapI[Trt]
  370. # if Trt in DCch:
  371. # continue
  372. A[MCSMapFacingDown[ch][1],MCSMapFacingDown[ch][0]] = (Urms[Trt][9])*1e6
  373. plt.imshow(A, interpolation='nearest', vmin=1, vmax=15, norm=colors.LogNorm(vmin=1, vmax=15))
  374. plt.grid(True)
  375. cbar=plt.colorbar()
  376. plt.xlabel('column',fontsize=12)
  377. plt.ylabel('row',fontsize=12)
  378. cbar.set_label('U$_{gs-rms}$ ($\mu$V)', rotation=270, labelpad=15,fontsize=13)