|
@@ -5,6 +5,7 @@ import pylab
|
5
|
5
|
import sys
|
6
|
6
|
import scipy
|
7
|
7
|
import copy
|
|
8
|
+import struct
|
8
|
9
|
from scipy.io.matlab import mio
|
9
|
10
|
from numpy import pi
|
10
|
11
|
from math import floor
|
|
@@ -183,13 +184,14 @@ class GMRDataProcessor(SNMRDataProcessor):
|
183
|
184
|
self.transFreq = HEADER[1]
|
184
|
185
|
self.maxBusV = HEADER[2]
|
185
|
186
|
self.pulseLength = pulseLengthDict.get((int)(HEADER[0]))(1e-3*HEADER[3])
|
186
|
|
- self.interpulseDelay = 1e-3*HEADER[4] # for T2, Spin Echo
|
187
|
|
- self.repetitionDelay = HEADER[5] # delay between first pulse
|
188
|
|
- self.nPulseMoments = (int)(HEADER[6]) # Number of pulse moments per stack
|
189
|
|
- self.TuneCapacitance = HEADER[7] # tuning capacitance in uF
|
190
|
|
- self.nTransVersion = HEADER[8] # Transmitter version
|
191
|
|
- self.nDAQVersion = HEADER[9] # DAQ software version
|
192
|
|
- self.nInterleaves = HEADER[10] # num interleaves
|
|
187
|
+ self.interpulseDelay = 1e-3*HEADER[4] # for T2, Spin Echo
|
|
188
|
+ self.repetitionDelay = HEADER[5] # delay between first pulse
|
|
189
|
+ self.nPulseMoments = (int)(HEADER[6]) # Number of pulse moments per stack
|
|
190
|
+ self.TuneCapacitance = HEADER[7] # tuning capacitance in uF
|
|
191
|
+ self.nTransVersion = HEADER[8] # Transmitter version
|
|
192
|
+ self.nDAQVersion = HEADER[9] # DAQ software version
|
|
193
|
+ self.nInterleaves = HEADER[10] # num interleaves
|
|
194
|
+
|
193
|
195
|
self.gain()
|
194
|
196
|
|
195
|
197
|
# default
|
|
@@ -198,7 +200,9 @@ class GMRDataProcessor(SNMRDataProcessor):
|
198
|
200
|
|
199
|
201
|
# newer header files contain 64 entries
|
200
|
202
|
if self.nDAQVersion >= 2:
|
201
|
|
- #print "new file format"
|
|
203
|
+ #self.deadtime = HEADER[11]
|
|
204
|
+ #self.unknown = HEADER[12]
|
|
205
|
+ #self.PreAmpGain = HEADER[13]
|
202
|
206
|
self.samp = HEADER[14] # sampling frequency
|
203
|
207
|
self.dt = 1./self.samp # sampling rate
|
204
|
208
|
self.deadTime = .0055 # instrument dead time before measurement
|
|
@@ -241,7 +245,7 @@ class GMRDataProcessor(SNMRDataProcessor):
|
241
|
245
|
# Current gain
|
242
|
246
|
if floor(self.nDAQVersion) == 1:
|
243
|
247
|
self.CurrentGain = 150.
|
244
|
|
- elif floor(self.nDAQVersion) ==2:
|
|
248
|
+ elif floor(self.nDAQVersion) == 2:
|
245
|
249
|
self.CurrentGain = 180.
|
246
|
250
|
|
247
|
251
|
def updateProgress(self):
|
|
@@ -1754,11 +1758,61 @@ class GMRDataProcessor(SNMRDataProcessor):
|
1754
|
1758
|
self.doneTrigger.emit()
|
1755
|
1759
|
self.updateProcTrigger.emit()
|
1756
|
1760
|
|
|
1761
|
+ def loadGMRBinaryFID( self, rawfname ):
|
|
1762
|
+ """ Reads a single binary GMR file and fills into DATADICT
|
|
1763
|
+ """
|
|
1764
|
+
|
|
1765
|
+ #################################################################################
|
|
1766
|
+ # figure out key data indices
|
|
1767
|
+ # Pulse
|
|
1768
|
+ nps = (int)((self.prePulseDelay)*self.samp)
|
|
1769
|
+ npul = (int)(self.pulseLength[0]*self.samp) #+ 100
|
|
1770
|
+
|
|
1771
|
+ # Data
|
|
1772
|
+ nds = nps+npul+(int)((self.deadTime)*self.samp); # indice pulse 1 data starts
|
|
1773
|
+ nd1 = (int)(1.*self.samp) # samples in first pulse
|
|
1774
|
+
|
|
1775
|
+ invGain = 1./self.RxGain
|
|
1776
|
+ invCGain = self.CurrentGain
|
|
1777
|
+
|
|
1778
|
+ pulse = "Pulse 1"
|
|
1779
|
+ chan = self.DATADICT[pulse]["chan"]
|
|
1780
|
+ rchan = self.DATADICT[pulse]["rchan"]
|
|
1781
|
+
|
|
1782
|
+ rawFile = open( rawfname, 'rb')
|
|
1783
|
+
|
|
1784
|
+ buf1 = rawFile.read(4)
|
|
1785
|
+ buf2 = rawFile.read(4)
|
|
1786
|
+
|
|
1787
|
+ N_chan = struct.unpack('>i', buf1 )[0]
|
|
1788
|
+ N_samp = struct.unpack('>i', buf2 )[0]
|
|
1789
|
+
|
|
1790
|
+ T = N_samp * self.dt
|
|
1791
|
+ TIMES = np.arange(0, T, self.dt) - .0002 # small offset in GMR DAQ?
|
|
1792
|
+
|
|
1793
|
+ DATA = np.zeros([N_samp, N_chan+1])
|
|
1794
|
+ for ichan in range(N_chan):
|
|
1795
|
+ DATADUMP = rawFile.read(4*N_samp)
|
|
1796
|
+ for irec in range(N_samp):
|
|
1797
|
+ DATA[irec,ichan] = struct.unpack('>f', DATADUMP[irec*4:irec*4+4])[0]
|
|
1798
|
+
|
|
1799
|
+ # Save into Data Cube
|
|
1800
|
+ for ichan in chan:
|
|
1801
|
+ self.DATADICT["Pulse 1"][ichan][ipm][istack] = DATA[:,eval(ichan)+3][nds:nds+nd1] * invGain
|
|
1802
|
+ self.DATADICT["Pulse 1"]["TIMES"] = TIMES[nds:nds+nd1]
|
|
1803
|
+ self.DATADICT["Pulse 1"]["CURRENT"][ipm][istack] = DATA[:,1][nps:nps+npul] * invCGain
|
|
1804
|
+ self.DATADICT["Pulse 1"]["PULSE_TIMES"] = TIMES[nps:nps+npul]
|
|
1805
|
+
|
|
1806
|
+ # plot reference channels?
|
|
1807
|
+ for ichan in rchan:
|
|
1808
|
+ self.DATADICT["Pulse 1"][ichan][ipm][istack] = DATA[:,eval(ichan)+3][nds:nds+nd1] * invGain
|
|
1809
|
+ self.DATADICT["Pulse 1"]["TIMES"] = TIMES[nds:nds+nd1]
|
|
1810
|
+
|
1757
|
1811
|
def loadFIDData(self, base, procStacks, chanin, rchanin, FIDProc, canvas, deadTime, plot):
|
1758
|
1812
|
'''
|
1759
|
|
- Loads a GMR FID dataset, reads OLD ASCII files
|
|
1813
|
+ Loads a GMR FID dataset, reads binary format files
|
1760
|
1814
|
'''
|
1761
|
|
- import struct
|
|
1815
|
+
|
1762
|
1816
|
canvas.reAx3(True,False)
|
1763
|
1817
|
|
1764
|
1818
|
chan = []
|
|
@@ -1774,18 +1828,7 @@ class GMRDataProcessor(SNMRDataProcessor):
|
1774
|
1828
|
self.deadTime = deadTime # instrument dead time before measurement
|
1775
|
1829
|
self.samp = 50000. # in case this is a reproc, these might have
|
1776
|
1830
|
self.dt = 1./self.samp # changed
|
1777
|
|
- invGain = 1./self.RxGain
|
1778
|
|
- invCGain = self.CurrentGain
|
1779
|
|
-
|
1780
|
|
- #################################################################################
|
1781
|
|
- # figure out key data indices
|
1782
|
|
- # Pulse
|
1783
|
|
- nps = (int)((self.prePulseDelay)*self.samp)
|
1784
|
|
- npul = (int)(self.pulseLength[0]*self.samp) #+ 100
|
1785
|
1831
|
|
1786
|
|
- # Data
|
1787
|
|
- nds = nps+npul+(int)((self.deadTime)*self.samp); # indice pulse 1 data starts
|
1788
|
|
- nd1 = (int)(1.*self.samp) # samples in first pulse
|
1789
|
1832
|
|
1790
|
1833
|
#################################################################################
|
1791
|
1834
|
# Data structures
|
|
@@ -1813,83 +1856,28 @@ class GMRDataProcessor(SNMRDataProcessor):
|
1813
|
1856
|
##############################################
|
1814
|
1857
|
# Read in binary (.lvm) data
|
1815
|
1858
|
iistack = 0
|
1816
|
|
- hack = False
|
1817
|
1859
|
for istack in procStacks:
|
1818
|
|
- rawFile = open(base + "_" + str(istack) + ".lvm", 'rb')
|
1819
|
|
- if hack:
|
1820
|
|
- subFile = open(base + "sub" + "_" + str(istack) + ".lvm", 'wb')
|
1821
|
|
- for ipm in range(self.nPulseMoments):
|
1822
|
|
-
|
1823
|
|
- # frequency cycing modulation
|
1824
|
|
- #mod = (-1)**(ipm%2) * (-1)**(istack%2)
|
1825
|
|
-
|
1826
|
|
- buf1 = rawFile.read(4)
|
1827
|
|
- buf2 = rawFile.read(4)
|
1828
|
|
-
|
1829
|
|
- if hack:
|
1830
|
|
- # hack to do some data analysis
|
1831
|
|
- subFile.write(buf1)
|
1832
|
|
- subFile.write(buf2)
|
1833
|
|
- # end hack
|
1834
|
|
-
|
1835
|
|
- #N_chan = struct.unpack('>i', rawFile.read(4))[0]
|
1836
|
|
- #N_samp = struct.unpack('>i', rawFile.read(4))[0]
|
1837
|
|
-
|
1838
|
|
- N_chan = struct.unpack('>i', buf1 )[0]
|
1839
|
|
- N_samp = struct.unpack('>i', buf2 )[0]
|
1840
|
|
-
|
1841
|
|
-
|
1842
|
|
- T = N_samp * self.dt
|
1843
|
|
- TIMES = np.arange(0, T, self.dt) - .0002 # small offset in GMR DAQ?
|
1844
|
|
-
|
1845
|
|
- DATA = np.zeros([N_samp, N_chan+1])
|
1846
|
|
- for ichan in range(N_chan):
|
1847
|
|
- DATADUMP = rawFile.read(4*N_samp)
|
1848
|
|
- #subFile.write(DATADUMP)
|
1849
|
|
- for irec in range(N_samp):
|
1850
|
|
- DATA[irec,ichan] = struct.unpack('>f', DATADUMP[irec*4:irec*4+4])[0]
|
|
1860
|
+
|
|
1861
|
+ if self.nDAQVersion < 2.3:
|
|
1862
|
+ rawfname = base + "_" + str(istack)
|
|
1863
|
+ else:
|
|
1864
|
+ self.loadGMRBinaryFID( base + "_" + str(istack) + ".lvm" )
|
1851
|
1865
|
|
1852
|
|
- if hack:
|
1853
|
|
- # hack to do some data analysis (array survey)
|
1854
|
|
- for ichan in range(5):
|
1855
|
|
- for irec in range(N_samp):
|
1856
|
|
- bdata = struct.pack( '>f', DATA[irec,ichan] )
|
1857
|
|
- subFile.write(bdata)
|
1858
|
|
- for ichan in range(5,6):
|
1859
|
|
- for irec in range(N_samp):
|
1860
|
|
- bdata = struct.pack( '>f', DATA[irec,ichan] + DATA[irec,ichan+2] )
|
1861
|
|
- #bdata = struct.pack( '>f', .23 )
|
1862
|
|
- subFile.write(bdata)
|
1863
|
|
- for ichan in range(6,N_chan):
|
1864
|
|
- for irec in range(N_samp):
|
1865
|
|
- bdata = struct.pack( '>f', DATA[irec,ichan] )
|
1866
|
|
- subFile.write(bdata)
|
|
1866
|
+ # Plotting
|
|
1867
|
+ if plot:
|
|
1868
|
+ canvas.ax1.clear()
|
|
1869
|
+ canvas.ax2.clear()
|
|
1870
|
+ canvas.ax3.clear()
|
1867
|
1871
|
|
1868
|
|
- if plot:
|
1869
|
|
- canvas.ax1.clear()
|
1870
|
|
- canvas.ax2.clear()
|
1871
|
|
- canvas.ax3.clear()
|
|
1872
|
+ for ipm in range(self.nPulseMoments):
|
1872
|
1873
|
|
1873
|
|
- # Save into Data Cube
|
1874
|
|
- for ichan in chan:
|
1875
|
|
- self.DATADICT["Pulse 1"][ichan][ipm][istack] = DATA[:,eval(ichan)+3][nds:nds+nd1] * invGain
|
1876
|
|
- self.DATADICT["Pulse 1"]["TIMES"] = TIMES[nds:nds+nd1]
|
1877
|
|
- self.DATADICT["Pulse 1"]["CURRENT"][ipm][istack] = DATA[:,1][nps:nps+npul] * invCGain
|
1878
|
|
- self.DATADICT["Pulse 1"]["PULSE_TIMES"] = TIMES[nps:nps+npul]
|
1879
|
|
- if plot:
|
1880
|
|
- #canvas.ax2.plot(self.DATADICT["Pulse 1"]["TIMES"], self.DATADICT["Pulse 1"][ichan][ipm][istack], label="Pulse 1 FID data ch. "+str(ichan)) #, color='blue')
|
|
1874
|
+ for ichan in chan:
|
1881
|
1875
|
canvas.ax1.plot(self.DATADICT["Pulse 1"]["PULSE_TIMES"], self.DATADICT["Pulse 1"]["CURRENT"][ipm][istack] , color='black')
|
1882
|
1876
|
canvas.ax3.plot(self.DATADICT["Pulse 1"]["TIMES"], self.DATADICT["Pulse 1"][ichan][ipm][istack], label="Pulse 1 FID data ch. "+str(ichan)) #, color='blue')
|
1883
|
|
- #canvas.draw()
|
1884
|
1877
|
|
1885
|
|
- # plot reference channels?
|
1886
|
|
- for ichan in rchan:
|
1887
|
|
- self.DATADICT["Pulse 1"][ichan][ipm][istack] = DATA[:,eval(ichan)+3][nds:nds+nd1] * invGain
|
1888
|
|
- self.DATADICT["Pulse 1"]["TIMES"] = TIMES[nds:nds+nd1]
|
1889
|
|
- if plot:
|
|
1878
|
+ for ichan in rchan:
|
1890
|
1879
|
canvas.ax2.plot(self.DATADICT["Pulse 1"]["TIMES"], self.DATADICT["Pulse 1"][ichan][ipm][istack], label="Pulse 1 FID ref ch. "+str(ichan)) #, color='blue')
|
1891
|
1880
|
|
1892
|
|
- if plot:
|
1893
|
1881
|
canvas.ax3.legend(prop={'size':6})
|
1894
|
1882
|
canvas.ax2.legend(prop={'size':6})
|
1895
|
1883
|
|
|
@@ -1906,16 +1894,14 @@ class GMRDataProcessor(SNMRDataProcessor):
|
1906
|
1894
|
canvas.ax3.ticklabel_format(style='sci', scilimits=(0,0), axis='y')
|
1907
|
1895
|
|
1908
|
1896
|
canvas.draw()
|
|
1897
|
+
|
1909
|
1898
|
percent = (int) (1e2*((float)((iistack*self.nPulseMoments+ipm+1)) / (len(procStacks)*self.nPulseMoments)))
|
1910
|
|
- #self.progressTrigger.emit(percent)
|
1911
|
1899
|
self.progressTrigger.emit(percent)
|
1912
|
1900
|
|
1913
|
1901
|
iistack += 1
|
1914
|
1902
|
|
1915
|
|
-
|
1916
|
1903
|
self.enableDSP()
|
1917
|
1904
|
self.doneTrigger.emit()
|
1918
|
|
-
|
1919
|
1905
|
|
1920
|
1906
|
def load4PhaseT1Data(self, base, procStacks, chan, rchan, FIDProc, canvas, deadTime, plot):
|
1921
|
1907
|
|