CalcUd0.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Sat Oct 13 18:50:52 2018
  4. @author: aemdlabs
  5. """
  6. from PhyREC.NeoInterface import NeoSegment, NeoSignal#, ReadMCSFile
  7. import PhyREC.SignalAnalysis as Ran
  8. import PhyREC.PlotWaves as Rplt
  9. import quantities as pq
  10. import matplotlib.pyplot as plt
  11. import numpy as np
  12. import neo
  13. import deepdish as dd
  14. import csv
  15. from datetime import datetime
  16. import PyGFET.DataClass as Gfetdat
  17. def ReadMCSFile(McsFile, OutSeg=None, SigNamePrefix=''):
  18. import McsPy.McsData as McsData
  19. Dat = McsData.RawData(McsFile)
  20. Rec = Dat.recordings[0]
  21. NSamps = Rec.duration
  22. if OutSeg is None:
  23. OutSeg = NeoSegment()
  24. for AnaStrn, AnaStr in Rec.analog_streams.iteritems():
  25. if len(AnaStr.channel_infos) == 1:
  26. continue
  27. for Chn, Chinfo in AnaStr.channel_infos.iteritems():
  28. print('Analog Stream ', Chinfo.label, Chinfo.sampling_frequency)
  29. ChName = str(SigNamePrefix + Chinfo.label)
  30. print(ChName)
  31. Fs = Chinfo.sampling_frequency
  32. Var, Unit = AnaStr.get_channel_in_range(Chn, 0, NSamps)
  33. sig = neo.AnalogSignal(pq.Quantity(Var, Chinfo.info['Unit']),
  34. t_start=0*pq.s,
  35. sampling_rate=Fs.magnitude*pq.Hz,
  36. name=ChName)
  37. OutSeg.AddSignal(sig)
  38. return OutSeg
  39. def ReadLogFile(File):
  40. Fin = open(File)
  41. reader = csv.reader(Fin, delimiter='\t')
  42. LogVals = {}
  43. ValsPos = {}
  44. for il, e in enumerate(reader):
  45. if il == 0:
  46. for ih, v in enumerate(e):
  47. ValsPos[ih] = v
  48. LogVals[v] = []
  49. else:
  50. for ih, v in enumerate(e):
  51. par = ValsPos[ih]
  52. if (par=='Vgs') or (par=='Vds') or (par=='Vref'):
  53. LogVals[par].append(float(v.replace(',','.')))
  54. elif par == 'Date/Time':
  55. LogVals[par].append(datetime.strptime(v, '%d.%m.%Y %H:%M:%S'))
  56. else:
  57. LogVals[par].append(v)
  58. deltas = np.array(LogVals['Date/Time'])[:]-LogVals['Date/Time'][0]
  59. LogVals['Time'] = []
  60. for d in deltas:
  61. LogVals['Time'].append(d.total_seconds())
  62. Fin.close()
  63. return LogVals
  64. def GetSwitchTimes(Sig, Thres=-1e-4, Plot=True):
  65. s = Sig.GetSignal(None)
  66. ds = np.abs(np.diff(np.array(s), axis=0))
  67. if Plot:
  68. plt.figure()
  69. plt.plot(s.times, s)
  70. plt.plot(s.times[1:], ds)
  71. ds = Sig.duplicate_with_new_array(signal=ds)
  72. Times = Ran.threshold_detection(ds,
  73. threshold=Thres,
  74. RelaxTime=5*pq.s)
  75. return Times
  76. def CalcVgeffAC(Sig, TACchar, Vgs, vgs):
  77. i = list(np.around(Vgs,3)).index(vgs)
  78. gm = TACchar[i]*pq.A/pq.V
  79. return neo.AnalogSignal(Sig/gm,
  80. units='V',
  81. t_start=Sig.t_start,
  82. sampling_rate=Sig.sampling_rate,
  83. name=str(Sig.name),
  84. file_origin=Sig.file_origin)
  85. if __name__ == '__main__':
  86. #### Test autosweep
  87. Path = '../../Day0/IV charact/'
  88. PBSInFileM = Path + '2019-07-30T15-39-02B12784O18-T3-ACDC-PreImplant-NoMemb.h5' ############
  89. PBSInFileS = Path + '2019-07-30T15-39-02B12784O18-T3-ACDC-PreImplant-NoMemb_2.h5' ##########
  90. PBSLogFile = Path + 'B12784O18-T3-ACDC-PBS-PreImplant-20s-NoMemb.txt'
  91. StartCycle = 0
  92. Directory = '../IV charact/'
  93. File = '20190731_033840 Current vs Vgs_5sStep.txt'
  94. Fin = open(Directory+File)
  95. LogVals = ReadLogFile(PBSLogFile)
  96. delta = np.mean([t-LogVals['Time'][it] for it, t in enumerate(LogVals['Time'][1:])])*pq.s
  97. Delay = delta * StartCycle
  98. DCch = ('ME5', 'ME7', 'ME29', 'ME31', 'SE5', 'SE7', 'SE29', 'SE31')
  99. TrigChannel = 'ME29'
  100. TrigThres = 1e-5
  101. Vgs = np.array(LogVals['Vgs'])
  102. VgsInt = np.linspace(Vgs[0],Vgs[-1],len(Vgs)*10)
  103. Vds = [LogVals['Vds'][0]]
  104. ivgain1 = 12e3*pq.V
  105. ivgain2 = 101
  106. ACgain = 10*1/pq.V
  107. DCgain = 1*pq.V
  108. Fsig = 10
  109. StabTime = 2*pq.s
  110. GuardTime = 1*pq.s
  111. BW = 100
  112. ivgainDC = 118.8*pq.V
  113. ivgainAC = 1188*pq.V
  114. Rec = ReadMCSFile(PBSInFileM,
  115. OutSeg=None,
  116. SigNamePrefix='M')
  117. Rec = ReadMCSFile(PBSInFileS,
  118. OutSeg=Rec,
  119. SigNamePrefix='S')
  120. # %% In vivo Ids
  121. plt.close('all')
  122. ChKo = {}
  123. reader = csv.reader(Fin, delimiter='\t')
  124. lenVgs = 1000
  125. Vgs = np.zeros(lenVgs)
  126. Ids = np.zeros([lenVgs,8])
  127. reader = csv.reader(Fin, delimiter='\t')
  128. for il, e in enumerate(reader):
  129. if il == 0:
  130. continue
  131. print(e)
  132. vg = e[0]
  133. vg = vg.replace(',','.')
  134. Vgs[il-1] = float(vg)
  135. for iids, ids in enumerate(e[1:]):
  136. ids = ids.replace(',','.')
  137. Ids[il-1,iids] = float(ids)
  138. color = ['m','r','orange','y','g','c','b','violet']
  139. plt.figure()
  140. Ud0 = []
  141. for i in range(8):
  142. Vgs = np.append(Vgs[0:2],np.trim_zeros(Vgs[2:]))
  143. ids = np.trim_zeros(Ids[:,i])
  144. plt.plot(Vgs,ids,color = color[i])
  145. if np.any(ids>=5.0):
  146. index = np.where(ids == np.amin(ids))
  147. print(ids, np.amin(ids), index)
  148. Ud0.append(Vgs[index[0][0]])
  149. Ud0meanInVivo = np.mean(np.array(Ud0))
  150. #%%
  151. SwTimes = GetSwitchTimes(Sig=Rec.GetSignal(TrigChannel),
  152. Thres=TrigThres,
  153. Plot=True)
  154. SlotsDC = []
  155. SlotsAC = []
  156. for sig in Rec.Signals():
  157. sig.__class__ = NeoSignal
  158. if sig.name in DCch:
  159. if sig.name.startswith('M'):
  160. col = 'r'
  161. else:
  162. col = 'g'
  163. SlotsDC.append(Rplt.WaveSlot(sig,
  164. Position=0,
  165. Color=col,
  166. Alpha=0.5))
  167. if sig.name.startswith('M'):
  168. col = 'k'
  169. else:
  170. col = 'b'
  171. SlotsAC.append(Rplt.WaveSlot(sig,
  172. Position=1,
  173. Color=col,
  174. Alpha=0.5))
  175. Splots = Rplt.PlotSlots(SlotsDC)
  176. Splots.PlotChannels(Time=None,
  177. Units='mV')
  178. Splots.PlotEvents(SwTimes,
  179. color='k')
  180. Splots.PlotEvents(LogVals['Time']*pq.s+SwTimes[0]+Delay,
  181. color='r')
  182. SwTimes = LogVals['Time']*pq.s+SwTimes[0]+Delay
  183. figId, Axiv = plt.subplots()
  184. fig, Axt = plt.subplots()
  185. Ids = {}
  186. for sl in SlotsDC:
  187. Ids[sl.name] = []
  188. for isw, (t, vg) in enumerate(zip(SwTimes, Vgs)):
  189. if isw == len(SwTimes)-1:
  190. ts = sl.Signal.t_stop
  191. else:
  192. ts = SwTimes[isw+1]
  193. TWind = (t+StabTime, ts-GuardTime)
  194. s = sl.GetSignal(TWind, Units='V')
  195. Axt.plot(s)
  196. vio = np.mean(s).magnitude
  197. ids = (vio*101-(-vg+Vds))/12e3
  198. if ids <= 7e-6:
  199. ChKo[sl.name] = True
  200. else:
  201. ChKo[sl.name] = False
  202. Ids[sl.name].append(ids)
  203. if ChKo[sl.name] == False:
  204. Axiv.plot(Vgs,Ids[sl.name], label=sl.name)
  205. DevACvals = {}
  206. Ud0mean = 0
  207. dev = Ids
  208. Ud0 = np.zeros(len(dev))
  209. for ich, (ch, ids) in enumerate(dev.iteritems()):
  210. if ChKo[ch] == False:
  211. print(ich)
  212. DevACvals[ch] = { 'Ids': np.array(ids[:-1]),
  213. 'Vgs': Vgs[:-1],
  214. 'Vds': Vds}
  215. DataDC = Gfetdat.DataCharDC(DevACvals[ch])
  216. Ud0[ich] = DataDC.GetUd0()
  217. print(Ud0[ich])
  218. Ud0mean=Ud0mean+Ud0[ich]
  219. Axiv.plot(VgsInt, DataDC.GetIds(VgsInt),'--')
  220. Ud0meanPBS = Ud0mean/(ich+1)
  221. #%% Calc GM
  222. GM = {}
  223. CalFile = {}
  224. figgm, axgm = plt.subplots()
  225. for sig in Rec.Signals():
  226. GM[sig.name] = []
  227. fig, (AxPsd, Axt) = plt.subplots(2,1)
  228. for isw, (t, vg) in enumerate(zip(SwTimes, Vgs)):
  229. if isw == len(SwTimes)-1:
  230. ts = sl.Signal.t_stop
  231. else:
  232. ts = SwTimes[isw+1]
  233. TWind = (t+StabTime, ts-GuardTime)
  234. s = sig.GetSignal(TWind, Units ='V')
  235. if s.name in DCch:
  236. s = (s*ivgain2-(-vg+Vds)*pq.V)/ivgain1
  237. else:
  238. s = s/(ivgain1*ACgain/ivgain2)
  239. Axt.plot(s.times, s, label=vg, alpha=0.5)
  240. PSD = Ran.PlotPSD((s,),
  241. Time = TWind,
  242. Ax=AxPsd,
  243. FMin=1,
  244. Label=str(vg),
  245. scaling='spectrum')
  246. psd = PSD[sig.name]['psd']
  247. Fpsd = PSD[sig.name]['ff']
  248. indicesPeak = np.where( ((Fpsd >= Fsig-4) & (Fpsd<=Fsig+4)))
  249. IDSpeak = np.sqrt(psd[np.argmax(psd[indicesPeak])+indicesPeak[0][0]]+
  250. psd[np.argmax(psd[indicesPeak])+indicesPeak[0][0]+1]+
  251. psd[np.argmax(psd[indicesPeak])+indicesPeak[0][0]-1])
  252. gm = IDSpeak*1000/0.707
  253. GM[sig.name]=np.append(GM[sig.name],gm)
  254. if np.any(GM[sig.name]>= 2e-5) :
  255. ChKo[sig.name] = False
  256. color = 'k'
  257. else:
  258. ChKo[sig.name] = True
  259. color = 'r'
  260. if sig.name in DCch:
  261. color = 'g'
  262. axgm.plot(Vgs, GM[sig.name], label=sig.name, color = color)
  263. plt.close(fig)
  264. axgm.legend()
  265. CalFile = {'GM': GM,
  266. 'Ud0PBS':Ud0meanPBS,
  267. 'Ud0InVivo':Ud0meanInVivo,
  268. 'DeltaUd0':Ud0meanPBS-Ud0meanInVivo,
  269. 'Vgs': Vgs-(Ud0meanPBS-Ud0meanInVivo)}
  270. CalFile['ChKo'] = ChKo
  271. dd.io.save('../Cal Data/'+'Cal-Gm'+File[:15]+'.h5', CalFile)