Browse Source

1.4.4, includes simple DOI estimate and logging of inversion results into CSV file

tags/1.6.1
Trevor Irons 4 years ago
parent
commit
aa4b3f4ef3
4 changed files with 83 additions and 5 deletions
  1. 75
    2
      akvo/tressel/invertTA.py
  2. 6
    1
      akvo/tressel/logbarrier.py
  3. 1
    1
      akvo/tressel/mrsurvey.py
  4. 1
    1
      setup.py

+ 75
- 2
akvo/tressel/invertTA.py View File

@@ -14,9 +14,13 @@ from matplotlib.ticker import MaxNLocator
14 14
 from matplotlib.ticker import AutoMinorLocator
15 15
 from matplotlib.ticker import LogLocator
16 16
 from matplotlib.ticker import FormatStrFormatter
17
+from matplotlib.colors import Normalize
18
+
17 19
 import cmocean
18 20
 from akvo.tressel.lemma_yaml import * 
19 21
 
22
+import pandas as pd
23
+
20 24
 def buildKQT(K0,tg,T2Bins):
21 25
     """ 
22 26
         Constructs a QT inversion kernel from an initial amplitude one.  
@@ -129,12 +133,23 @@ def main():
129 133
     K0 = K0[0]
130 134
     #plt.matshow(K0)
131 135
     
136
+    # VERY Simple DOI
137
+    SNR = np.sum(.01*K0, axis=1) / VS[0][0]
138
+    SNR[SNR>1] = 1
139
+    SNRidx = 0 
140
+    while SNR[SNRidx] >= 1:
141
+        SNRidx += 1
142
+    #print(SNR)
143
+    #plt.plot(ifaces[0:-1], SNR)
144
+    #plt.gca().axhline(y=VS[0][0], xmin=0, xmax=ifaces[-1], color='r')
145
+    #plt.gca().axhline(y=1, xmin=0, xmax=ifaces[-1], color='r')
146
+    #plt.show()
147
+
132 148
     ###############################################
133 149
     # Build full kernel
134 150
     ############################################### 
135 151
     T2Bins = np.logspace( np.log10(cont["T2Bins"]["low"]), np.log10(cont["T2Bins"]["high"]), cont["T2Bins"]["number"], endpoint=True, base=10)  
136 152
     KQT = buildKQT(K0,tg,T2Bins)
137
-
138 153
  
139 154
     ###############################################
140 155
     # Invert
@@ -145,7 +160,8 @@ def main():
145 160
 
146 161
     ###############################################
147 162
     # Appraise
148
-    ############################################### 
163
+    ###############################################
164
+ 
149 165
     pre = np.dot(KQT,inv) 
150 166
     PRE = np.reshape( pre, np.shape(V)  )
151 167
     plt.matshow(PRE, cmap='Blues')
@@ -165,10 +181,25 @@ def main():
165 181
     T2Bins = np.append( T2Bins, T2Bins[-1] + (T2Bins[-1]-T2Bins[-2]) )
166 182
     
167 183
     INV = np.reshape(inv, (len(ifaces)-1,cont["T2Bins"]["number"]) )
184
+
185
+    #alphas = np.tile(SNR, (len(T2Bins)-1,1))
186
+    #colors = Normalize(1e-6, np.max(INV.T), clip=True)(INV.T)
187
+    #colors = cmocean.cm.tempo(colors)
188
+    ##colors[..., -1] = alphas
189
+    #print(np.shape(colors)) 
190
+    #print(np.shape(INV.T)) 
191
+
192
+    #greys = np.full((*(INV.T).shape, 3), 70, dtype=np.uint8)
193
+
168 194
     Y,X = meshgrid( ifaces, T2Bins )
169 195
     fig = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
170 196
     ax1 = fig.add_axes( [.2,.15,.6,.7] )
171 197
     im = ax1.pcolor(X, Y, INV.T, cmap=cmocean.cm.tempo) #cmap='viridis')
198
+    #im = ax1.pcolor(X[0:SNRidx,:], Y[0:SNRidx,:], INV.T[0:SNRidx,:], cmap=cmocean.cm.tempo) #cmap='viridis')
199
+    #im = ax1.pcolor(X[SNRidx::,:], Y[SNRidx::,:], INV.T[SNRidx::,:], cmap=cmocean.cm.tempo, alpha=.5) #cmap='viridis')
200
+    #im = ax1.pcolormesh(X, Y, INV.T, alpha=alphas) #, cmap=cmocean.cm.tempo) #cmap='viridis')
201
+    #im = ax1.pcolormesh(X, Y, INV.T, alpha=alphas) #, cmap=cmocean.cm.tempo) #cmap='viridis')
202
+    #ax1.axhline( y=ifaces[SNRidx], xmin=T2Bins[0], xmax=T2Bins[-1], color='black'  )
172 203
     im.set_edgecolor('face')
173 204
     ax1.set_xlim( T2Bins[0], T2Bins[-1] )
174 205
     ax1.set_ylim( ifaces[-1], ifaces[0] )
@@ -192,10 +223,52 @@ def main():
192 223
     ax2.set_ylim( ifaces[-1], ifaces[0] )
193 224
     ax2.xaxis.set_major_locator( MaxNLocator(nbins = 3) )   
194 225
     ax2.get_xaxis().set_major_formatter(FormatStrFormatter('%0.2f'))
226
+    ax2.axhline( y=ifaces[SNRidx], xmin=0, xmax=1, color='black', linestyle='dashed'  )
195 227
     #ax2.xaxis.set_label_position('bottom') 
196 228
 
197 229
     plt.savefig("akvoInversion.pdf")
230
+
231
+    #############
232
+    # water plot#
233
+
234
+    fig2 = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
235
+    ax = fig2.add_axes( [.2,.15,.6,.7] )
198 236
     
237
+    # Bound water cutoff 
238
+    Bidx = T2Bins[0:-1]<33.0
239
+    twater = np.sum(INV, axis=1)
240
+    bwater = np.sum(INV[:,Bidx], axis=1)
241
+    
242
+    ax.plot( twater, (ifaces[0:-1]+ifaces[1::])/2, label="NMR total water", color='blue' )
243
+    ax.plot( bwater, (ifaces[0:-1]+ifaces[1::])/2, label="NMR bound water", color='green' )
244
+    
245
+    ax.fill_betweenx((ifaces[0:-1]+ifaces[1::])/2 , twater, bwater, where=twater >= bwater, facecolor='blue', alpha=.5)
246
+    ax.fill_betweenx((ifaces[0:-1]+ifaces[1::])/2 , bwater, 0, where=bwater >= 0, facecolor='green', alpha=.5)
247
+    
248
+    ax.set_xlabel(r"$\theta_N$ (m$^3$/m$^3$)")
249
+    ax.set_ylabel(r"depth (m)")
250
+    
251
+    ax.set_ylim( ifaces[-1], ifaces[0] )
252
+    ax.set_xlim( 0, ax.get_xlim()[1] )
253
+    
254
+    ax.axhline( y=ifaces[SNRidx], xmin=0, xmax=1, color='black', linestyle='dashed'  )
255
+    
256
+    plt.savefig("akvoInversionWC.pdf")
257
+    plt.legend()  
258
+ 
259
+
260
+    # Report results into a text file 
261
+    fr = pd.DataFrame( INV, columns=T2Bins[0:-1] )
262
+    fr.insert(0, "layer top", ifaces[0:-1] )
263
+    fr.insert(1, "layer bottom", ifaces[1::] )
264
+    fr.insert(2, "NMR total water", np.sum(INV, axis=1) )
265
+    fr.insert(3, "NMR bound water", bwater )
266
+    fr.insert(4, "Layer SNR", SNR )
267
+
268
+    fr.to_csv("akvoInversion.csv")    
269
+    #fr.to_excel("akvoInversion.xlsx")    
270
+
271
+ 
199 272
     plt.show()
200 273
 
201 274
 if __name__ == "__main__":

+ 6
- 1
akvo/tressel/logbarrier.py View File

@@ -146,8 +146,13 @@ def logBarrier(A, b, T2Bins, lambdastar, x_0=0, xr=0, alpha=10, mu1=10, mu2=10,
146 146
 
147 147
         xp = np.copy(x) # prior step x 
148 148
 
149
+        # quick and dirty solution
150
+        #b2a = np.dot(A.conj().transpose(), np.dot(WdTWd, b-b_pre) ) - alpha*np.dot(WmTWm,(x-xr))
151
+        #xg = nnls(ATWdTWdA + Phi_m, b2a)
152
+        #x = xg[0]
153
+
149 154
         while ( (phib / (phid+alpha*phim)) > EPSILON  or First==True ):
150
-        #while ( First==True ):
155
+        #while ( False ): # skip the hard stuff
151 156
 
152 157
             First = False
153 158
             # Log barrier, keep each element above minVal

+ 1
- 1
akvo/tressel/mrsurvey.py View File

@@ -1046,7 +1046,7 @@ class GMRDataProcessor(SNMRDataProcessor):
1046 1046
                     ht = signal.hilbert(xn)*np.exp(-1j*wL*self.DATADICT[pulse]["TIMES"])
1047 1047
                     #############################################################
1048 1048
                     # Quadrature signal 
1049
-                    RE[pulse][chan][ipm,:] = -np.real(ht[clip::])  # negative for consistency with VC  
1049
+                    RE[pulse][chan][ipm,:] =  np.real(ht[clip::])  # *-1 for negative for consistency with VC ??
1050 1050
                     IM[pulse][chan][ipm,:] =  np.imag(ht[clip::])
1051 1051
                     REmax[pulse] = max(REmax[pulse], np.max(np.real(ht[clip::])))
1052 1052
                     IMmax[pulse] = max(IMmax[pulse], np.max(np.imag(ht[clip::])))

+ 1
- 1
setup.py View File

@@ -21,7 +21,7 @@ with open("README.md", "r") as fh:
21 21
     long_description = fh.read()
22 22
 
23 23
 setup(name='Akvo',
24
-      version='1.4.3',
24
+      version='1.4.4',
25 25
       python_requires='>3.7.0', # due to pyLemma
26 26
       description='Surface nuclear magnetic resonance workbench',
27 27
       long_description=long_description,

Loading…
Cancel
Save