Browse Source

Addition of DOI metric based on incomplete resolution matrix construction

tags/1.6.1
Trevor Irons 3 years ago
parent
commit
15c297b36f
5 changed files with 288 additions and 175 deletions
  1. 2
    0
      akvo/gui/akvoGUI.py
  2. 91
    59
      akvo/gui/main.ui
  3. 189
    112
      akvo/tressel/invertTA.py
  4. 4
    4
      akvo/tressel/logbarrier.py
  5. 2
    0
      akvo/tressel/nonlinearinv.py

+ 2
- 0
akvo/gui/akvoGUI.py View File

440
         invDict["T2Bins"]["low"] = T2lo
440
         invDict["T2Bins"]["low"] = T2lo
441
         invDict["T2Bins"]["high"] = T2hi
441
         invDict["T2Bins"]["high"] = T2hi
442
         invDict["T2Bins"]["number"] = NT2       
442
         invDict["T2Bins"]["number"] = NT2       
443
+        invDict["NonLinearRefinement"] = self.ui.NLButton.isChecked()
444
+        invDict["CalcDOI"] = self.ui.DOIButton.isChecked()
443
  
445
  
444
         node = yaml.YAML()
446
         node = yaml.YAML()
445
         kpo = open( "invert.yml", 'w' )
447
         kpo = open( "invert.yml", 'w' )

+ 91
- 59
akvo/gui/main.ui View File

4143
               <rect>
4143
               <rect>
4144
                <x>0</x>
4144
                <x>0</x>
4145
                <y>0</y>
4145
                <y>0</y>
4146
-               <width>96</width>
4147
-               <height>26</height>
4146
+               <width>100</width>
4147
+               <height>30</height>
4148
               </rect>
4148
               </rect>
4149
              </property>
4149
              </property>
4150
              <attribute name="label">
4150
              <attribute name="label">
4156
               <rect>
4156
               <rect>
4157
                <x>0</x>
4157
                <x>0</x>
4158
                <y>0</y>
4158
                <y>0</y>
4159
-               <width>96</width>
4160
-               <height>26</height>
4159
+               <width>411</width>
4160
+               <height>67</height>
4161
               </rect>
4161
               </rect>
4162
              </property>
4162
              </property>
4163
              <attribute name="label">
4163
              <attribute name="label">
4255
                <string>QT Inversion</string>
4255
                <string>QT Inversion</string>
4256
               </property>
4256
               </property>
4257
               <layout class="QGridLayout" name="gridLayout_19">
4257
               <layout class="QGridLayout" name="gridLayout_19">
4258
-               <item row="2" column="1">
4259
-                <widget class="QComboBox" name="invChan">
4260
-                 <item>
4261
-                  <property name="text">
4262
-                   <string>Chan. 1</string>
4263
-                  </property>
4264
-                 </item>
4265
-                 <item>
4266
-                  <property name="text">
4267
-                   <string>Chan. 2</string>
4268
-                  </property>
4269
-                 </item>
4270
-                 <item>
4271
-                  <property name="text">
4272
-                   <string>Chan. 3</string>
4273
-                  </property>
4274
-                 </item>
4275
-                 <item>
4276
-                  <property name="text">
4277
-                   <string>Chan. 4</string>
4278
-                  </property>
4279
-                 </item>
4258
+               <item row="5" column="0">
4259
+                <widget class="QLabel" name="label_81">
4260
+                 <property name="text">
4261
+                  <string>initial alpha </string>
4262
+                 </property>
4280
                 </widget>
4263
                 </widget>
4281
                </item>
4264
                </item>
4282
                <item row="4" column="1">
4265
                <item row="4" column="1">
4307
                  </item>
4290
                  </item>
4308
                 </widget>
4291
                 </widget>
4309
                </item>
4292
                </item>
4310
-               <item row="3" column="0">
4311
-                <widget class="QLabel" name="label_80">
4312
-                 <property name="text">
4313
-                  <string>T2* model objective</string>
4314
-                 </property>
4315
-                </widget>
4316
-               </item>
4317
-               <item row="4" column="0">
4318
-                <widget class="QLabel" name="label_82">
4319
-                 <property name="text">
4320
-                  <string>Depth model objective</string>
4321
-                 </property>
4322
-                </widget>
4323
-               </item>
4324
                <item row="0" column="1">
4293
                <item row="0" column="1">
4325
                 <widget class="QTextBrowser" name="dataText">
4294
                 <widget class="QTextBrowser" name="dataText">
4326
                  <property name="maximumSize">
4295
                  <property name="maximumSize">
4337
                  </property>
4306
                  </property>
4338
                 </widget>
4307
                 </widget>
4339
                </item>
4308
                </item>
4340
-               <item row="6" column="0" colspan="2">
4309
+               <item row="1" column="0">
4310
+                <widget class="QPushButton" name="invKernelButton">
4311
+                 <property name="text">
4312
+                  <string>Select Kernel</string>
4313
+                 </property>
4314
+                </widget>
4315
+               </item>
4316
+               <item row="3" column="0">
4317
+                <widget class="QLabel" name="label_80">
4318
+                 <property name="text">
4319
+                  <string>T2* model objective</string>
4320
+                 </property>
4321
+                </widget>
4322
+               </item>
4323
+               <item row="4" column="0">
4324
+                <widget class="QLabel" name="label_82">
4325
+                 <property name="text">
4326
+                  <string>Depth model objective</string>
4327
+                 </property>
4328
+                </widget>
4329
+               </item>
4330
+               <item row="11" column="0" colspan="2">
4341
                 <widget class="QPushButton" name="invertButton">
4331
                 <widget class="QPushButton" name="invertButton">
4342
                  <property name="styleSheet">
4332
                  <property name="styleSheet">
4343
                   <string notr="true">#invertButton {
4333
                   <string notr="true">#invertButton {
4352
                  </property>
4342
                  </property>
4353
                 </widget>
4343
                 </widget>
4354
                </item>
4344
                </item>
4355
-               <item row="2" column="0">
4356
-                <widget class="QLabel" name="label_79">
4357
-                 <property name="text">
4358
-                  <string>Data channel</string>
4359
-                 </property>
4345
+               <item row="2" column="1">
4346
+                <widget class="QComboBox" name="invChan">
4347
+                 <item>
4348
+                  <property name="text">
4349
+                   <string>Chan. 1</string>
4350
+                  </property>
4351
+                 </item>
4352
+                 <item>
4353
+                  <property name="text">
4354
+                   <string>Chan. 2</string>
4355
+                  </property>
4356
+                 </item>
4357
+                 <item>
4358
+                  <property name="text">
4359
+                   <string>Chan. 3</string>
4360
+                  </property>
4361
+                 </item>
4362
+                 <item>
4363
+                  <property name="text">
4364
+                   <string>Chan. 4</string>
4365
+                  </property>
4366
+                 </item>
4360
                 </widget>
4367
                 </widget>
4361
                </item>
4368
                </item>
4362
-               <item row="0" column="0">
4363
-                <widget class="QPushButton" name="invDataButton">
4369
+               <item row="6" column="0">
4370
+                <widget class="QRadioButton" name="NLButton">
4371
+                 <property name="toolTip">
4372
+                  <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The dephased (aka quadrature detected, aka corrected amplitude) inversion introduces non-linearity to the otherwise linear forward operator in that out of phase signals cannot destructively interefere with a real forward operator. Normally this impact is pretty minimal and can be ignored. However, in conductive media this is not always the case. Akvo can perform a non-linear inversion after the linear one to correct for this. The result of the linear inversion is used as an initial model in the non-linear inversion and the same level of regularisation is used. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
4373
+                 </property>
4364
                  <property name="text">
4374
                  <property name="text">
4365
-                  <string>Select Data</string>
4375
+                  <string>Non Linear refinement</string>
4376
+                 </property>
4377
+                 <property name="checked">
4378
+                  <bool>true</bool>
4379
+                 </property>
4380
+                 <property name="autoExclusive">
4381
+                  <bool>false</bool>
4366
                  </property>
4382
                  </property>
4367
                 </widget>
4383
                 </widget>
4368
                </item>
4384
                </item>
4369
-               <item row="5" column="0">
4370
-                <widget class="QLabel" name="label_81">
4385
+               <item row="2" column="0">
4386
+                <widget class="QLabel" name="label_79">
4371
                  <property name="text">
4387
                  <property name="text">
4372
-                  <string>initial alpha </string>
4388
+                  <string>Data channel</string>
4373
                  </property>
4389
                  </property>
4374
                 </widget>
4390
                 </widget>
4375
                </item>
4391
                </item>
4383
                  </property>
4399
                  </property>
4384
                 </widget>
4400
                 </widget>
4385
                </item>
4401
                </item>
4386
-               <item row="1" column="0">
4387
-                <widget class="QPushButton" name="invKernelButton">
4388
-                 <property name="text">
4389
-                  <string>Select Kernel</string>
4390
-                 </property>
4391
-                </widget>
4392
-               </item>
4393
                <item row="1" column="1">
4402
                <item row="1" column="1">
4394
                 <widget class="QTextEdit" name="kernelText">
4403
                 <widget class="QTextEdit" name="kernelText">
4395
                  <property name="maximumSize">
4404
                  <property name="maximumSize">
4406
                  </property>
4415
                  </property>
4407
                 </widget>
4416
                 </widget>
4408
                </item>
4417
                </item>
4418
+               <item row="0" column="0">
4419
+                <widget class="QPushButton" name="invDataButton">
4420
+                 <property name="text">
4421
+                  <string>Select Data</string>
4422
+                 </property>
4423
+                </widget>
4424
+               </item>
4425
+               <item row="6" column="1">
4426
+                <widget class="QRadioButton" name="DOIButton">
4427
+                 <property name="toolTip">
4428
+                  <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Geophysical inverse problems do not have a true, unambigous depth of investigation. &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;Akvo makes a calculation of the DOI based on a resolution analysis approach. A pseudo 1D total water point spread function is calculated by inverting kronecker delta models at the midpoint of the &lt;span style=&quot; font-style:italic;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot; font-style:italic; vertical-align:sub;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-style:italic; vertical-align:super;&quot;&gt;*&lt;/span&gt; distribution at he same regularisation level as the inversion. The recovered models are summed across the &lt;span style=&quot; font-style:italic;&quot;&gt;T&lt;/span&gt;&lt;span style=&quot; font-style:italic; vertical-align:sub;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-style:italic; vertical-align:super;&quot;&gt;*&lt;/span&gt; space in order to reduce variables in the analysis. hese models are then used as rows in the construction of the point spread function (Model Resolution Matrix). The point spread function is used to identify the point at which the peak depth in the recovered models deviates from the input model by at least 10 %. This is an arbitrary threshold, but is the same one used in[1] &lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;[1] Müller-Petke, M., &amp;amp; Yaramanci, U. (2008). Resolution studies for magnetic resonance sounding (MRS) using the singular value decomposition. &lt;span style=&quot; font-style:italic;&quot;&gt;Journal of Applied Geophysics&lt;/span&gt;, &lt;span style=&quot; font-style:italic;&quot;&gt;66&lt;/span&gt;(3-4), 165-175.   &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
4429
+                 </property>
4430
+                 <property name="text">
4431
+                  <string>Calculate DOI</string>
4432
+                 </property>
4433
+                 <property name="checked">
4434
+                  <bool>true</bool>
4435
+                 </property>
4436
+                 <property name="autoExclusive">
4437
+                  <bool>false</bool>
4438
+                 </property>
4439
+                </widget>
4440
+               </item>
4409
               </layout>
4441
               </layout>
4410
              </widget>
4442
              </widget>
4411
             </item>
4443
             </item>

+ 189
- 112
akvo/tressel/invertTA.py View File

7
 from akvo.tressel.logbarrier import *
7
 from akvo.tressel.logbarrier import *
8
 import yaml,os
8
 import yaml,os
9
 
9
 
10
+import multiprocessing 
11
+import itertools
12
+ 
13
+from scipy.linalg import svd 
14
+
15
+from matplotlib.backends.backend_pdf import PdfPages
10
 from matplotlib.colors import LogNorm
16
 from matplotlib.colors import LogNorm
11
 from matplotlib.colors import LightSource
17
 from matplotlib.colors import LightSource
12
 from matplotlib.ticker import ScalarFormatter
18
 from matplotlib.ticker import ScalarFormatter
134
         K0[0] = np.concatenate( (K0[0].T, K0[ik].T) ).T
140
         K0[0] = np.concatenate( (K0[0].T, K0[ik].T) ).T
135
     K0 = K0[0]
141
     K0 = K0[0]
136
 
142
 
143
+    #np.save("ifaces", ifaces)
144
+    #exit()
145
+
137
     #plt.matshow(np.real(K0))
146
     #plt.matshow(np.real(K0))
138
     #plt.show()
147
     #plt.show()
139
     #exit()
148
     #exit()
140
 
149
 
141
-    ###################    
142
-    # VERY Simple DOI #
150
+    ##########################################################    
151
+    # VERY Simple Sensitivity based calc. of noise per layer #
143
     maxq = np.argmax(np.abs(K0), axis=1)
152
     maxq = np.argmax(np.abs(K0), axis=1)
144
     maxK = .1 *  np.abs(K0)[ np.arange(0,len(ifaces)-1), maxq ] # 10% water is arbitrary  
153
     maxK = .1 *  np.abs(K0)[ np.arange(0,len(ifaces)-1), maxq ] # 10% water is arbitrary  
145
     SNR = maxK / (VS[0][0])
154
     SNR = maxK / (VS[0][0])
146
 
155
 
147
-    #SNR[SNR>1] = 1
148
-    SNRidx = len(ifaces)-3 
149
-    while SNR[SNRidx] > SNR[SNRidx+1] and SNRidx > 2:
150
-        SNRidx -= 1
151
-
152
-    #print("IDX", SNRidx)
153
-    #plt.plot(ifaces[0:-1], SNR)
154
-    #plt.plot(ifaces[0:-1][SNRidx], SNR[SNRidx], '.',markersize=12)
155
-    #plt.gca().axhline(y=VS[0][0], xmin=0, xmax=ifaces[-1], color='r')
156
-    #plt.gca().axhline(y=1, xmin=0, xmax=ifaces[-1], color='r')
157
-    #K0T = np.dot(K0, K0.T) 
158
-    #K0T = np.dot(K0, np.dot( VS[0][0]* np.eye(len(ifaces)-1,1), K0.T) )
159
-    #K0T = np.dot(K0, np.dot( 1/(VS[0][0]**2) * np.eye(np.shape(K0)[1]), K0.T) )
160
-    #plt.matshow(0.05 * np.sqrt(K0T))
161
-    #plt.colorbar()
162
-    #plt.plot(ifaces[0:-1], np.diag( 0.01* np.sqrt(K0T))) 
163
-    #print(np.shape(K0T), len(ifaces)-1)
164
-    #plt.show()
165
-    #exit()
166
-
167
     ###############################################
156
     ###############################################
168
     # Build full kernel
157
     # Build full kernel
169
     ############################################### 
158
     ############################################### 
170
-    T2Bins = np.logspace( np.log10(cont["T2Bins"]["low"]), np.log10(cont["T2Bins"]["high"]), cont["T2Bins"]["number"], endpoint=True, base=10)  
171
-    KQT = np.real(buildKQT(np.abs(K0),tg,T2Bins))
172
 
159
 
173
-    # model resolution matrix 
174
-    np.linalg.svd(KQT)
160
+    T2Bins = np.logspace( np.log10(cont["T2Bins"]["low"]), np.log10(cont["T2Bins"]["high"]), cont["T2Bins"]["number"], endpoint=True, base=10) 
161
+    T2Bins2 = np.append( T2Bins, T2Bins[-1] + (T2Bins[-1]-T2Bins[-2]) )
162
+    NT2 = len(T2Bins)
175
 
163
 
176
-    exit()
164
+    KQT = np.real(buildKQT(np.abs(K0),tg,T2Bins))
177
 
165
 
178
     ###############################################
166
     ###############################################
179
     # Linear Inversion 
167
     # Linear Inversion 
181
     print("Calling inversion", flush=True)
169
     print("Calling inversion", flush=True)
182
     inv, ibreak, errn, phim, phid, mkappa, Wd, Wm, alphastar = logBarrier(KQT, np.ravel(V), T2Bins, "lcurve", MAXITER=150, sigma=np.ravel(VS), alpha=1e6, smooth="Smallest" ) 
170
     inv, ibreak, errn, phim, phid, mkappa, Wd, Wm, alphastar = logBarrier(KQT, np.ravel(V), T2Bins, "lcurve", MAXITER=150, sigma=np.ravel(VS), alpha=1e6, smooth="Smallest" ) 
183
 
171
 
184
-    ###############################################
185
-    # Non-linear refinement! 
186
-    ###############################################   
187
- 
188
-    KQTc = buildKQT(K0, tg, T2Bins)
189
-    prec = np.abs(np.dot(KQTc, inv))
190
-    phidc = np.linalg.norm(np.dot(Wd,prec-np.ravel(V)))**2
191
-    #PREc = np.reshape( prec, np.shape(V)  )
192
-    print("PHID linear=", errn, "PHID complex=", phidc/len(np.ravel(V)))
193
-    
194
-    res = nl.nonlinearinversion(inv, Wd, KQTc, np.ravel(V), Wm, alphastar )   
195
-    if res.success == True:    
196
-        INVc = np.reshape(res.x, (len(ifaces)-1,cont["T2Bins"]["number"]) )
197
-        prec = np.abs(np.dot(KQTc, res.x))
198
-        phidc = np.linalg.norm(np.dot(Wd,prec-np.ravel(V)))**2
199
-        #PREc = np.reshape( prec, np.shape(V)  )
200
-        print("PHID linear=", errn, "PHID nonlinear=", phidc/len(np.ravel(V)))
201
-   
202
-    # Perform second fit around results of first  
203
-    res = nl.nonlinearinversion(res.x, Wd, KQTc, np.ravel(V), Wm, alphastar )   
204
-    if res.success == True:    
205
-        INVc = np.reshape(res.x, (len(ifaces)-1,cont["T2Bins"]["number"]) )
206
-        prec = np.abs(np.dot(KQTc, res.x))
207
-        phidc = np.linalg.norm(np.dot(Wd,prec-np.ravel(V)))**2
208
-        #PREc = np.reshape( prec, np.shape(V)  )
209
-        print("PHID linear=", errn, "PHID nonlinear=", phidc/len(np.ravel(V)))
210
-
211
-    #plt.matshow(INVc)
212
-    #KQTc = buildKQT(K0,tg,T2Bins)
213
-
214
-    #plt.matshow(PREc, cmap='Blues')
215
-    #plt.gca().set_title("complex predicted")
216
-    #plt.colorbar()
217
-
218
-    ###############################################
219
-    # Appraise
220
-    ###############################################
221
-
222
 
172
 
223
-
224
-
225
- 
173
+    ####################
174
+    # Summary plots    #
175
+    ####################
176
+    
226
     pre = np.dot(KQT,inv) 
177
     pre = np.dot(KQT,inv) 
227
     PRE = np.reshape( pre, np.shape(V)  )
178
     PRE = np.reshape( pre, np.shape(V)  )
228
     plt.matshow(PRE, cmap='Blues')
179
     plt.matshow(PRE, cmap='Blues')
229
-    plt.gca().set_title("predicted")
180
+    plt.gca().set_title("linear predicted")
230
     plt.colorbar()
181
     plt.colorbar()
231
 
182
 
232
     DIFF = (PRE-V) / VS
183
     DIFF = (PRE-V) / VS
233
     md = np.max(np.abs(DIFF))
184
     md = np.max(np.abs(DIFF))
234
     plt.matshow(DIFF, cmap=cmocean.cm.balance, vmin=-md, vmax=md)
185
     plt.matshow(DIFF, cmap=cmocean.cm.balance, vmin=-md, vmax=md)
235
-    plt.gca().set_title("misfit / $\widehat{\sigma}$")
186
+    plt.gca().set_title("linear misfit / $\widehat{\sigma}$")
236
     plt.colorbar()
187
     plt.colorbar()
237
     
188
     
238
     plt.matshow(V, cmap='Blues')
189
     plt.matshow(V, cmap='Blues')
239
     plt.gca().set_title("observed")
190
     plt.gca().set_title("observed")
240
     plt.colorbar()
191
     plt.colorbar()
241
 
192
 
193
+    ###############################################
194
+    # Non-linear refinement! 
195
+    ###############################################   
196
+
197
+    nonLinearRefinement = cont['NonLinearRefinement']
198
+    if nonLinearRefinement: 
199
+
200
+        KQTc = buildKQT(K0, tg, T2Bins)
201
+        prec = np.abs(np.dot(KQTc, inv))
202
+        phidc = np.linalg.norm(np.dot(Wd,prec-np.ravel(V)))**2
203
+        print("PHID forward linear=", errn, "PHID forward nonlinear=", phidc/len(np.ravel(V)))
204
+    
205
+        res = nl.nonlinearinversion(inv, Wd, KQTc, np.ravel(V), Wm, alphastar )   
206
+        if res.success == True:    
207
+            INVc = np.reshape(res.x, (len(ifaces)-1,cont["T2Bins"]["number"]) )
208
+            prec = np.abs(np.dot(KQTc, res.x))
209
+            phidc = np.linalg.norm(np.dot(Wd,prec-np.ravel(V)))**2
210
+            PREc = np.reshape( prec, np.shape(V)  )
211
+            print("PHID linear=", errn, "PHID nonlinear=", phidc/len(np.ravel(V)))
212
+
213
+        while phidc/len(np.ravel(V)) > errn:  
214
+            phidc_old = phidc/len(np.ravel(V))
215
+            #alphastar *= .9 
216
+            res = nl.nonlinearinversion(res.x, Wd, KQTc, np.ravel(V), Wm, alphastar )   
217
+            if res.success == True:    
218
+                INVc = np.reshape(res.x, (len(ifaces)-1,cont["T2Bins"]["number"]) )
219
+                prec = np.abs(np.dot(KQTc, res.x))
220
+                phidc = np.linalg.norm(np.dot(Wd,prec-np.ravel(V)))**2
221
+                PREc = np.reshape( prec, np.shape(V)  )
222
+                print("PHID linear=", errn, "PHID nonlinear=", phidc/len(np.ravel(V)))
223
+            else:
224
+                break
225
+
226
+            if phidc_old - phidc/len(np.ravel(V)) < 0.005:
227
+                print("Not making progress reducing misfit in nonlinear refinement")
228
+                break
229
+    
230
+        plt.matshow(PREc, cmap='Blues')
231
+        plt.gca().set_title("nonlinear predicted")
232
+        plt.colorbar()
233
+
234
+        DIFFc = (PREc-V) / VS
235
+        md = np.max(np.abs(DIFF))
236
+        plt.matshow(DIFFc, cmap=cmocean.cm.balance, vmin=-md, vmax=md)
237
+        plt.gca().set_title("nonlinear misfit / $\widehat{\sigma}$")
238
+        plt.colorbar()
239
+ 
240
+    ###############################################
241
+    # Appraise DOI using simplified MRM 
242
+    ###############################################
243
+
244
+    CalcDOI = cont['CalcDOI']
245
+
246
+    if CalcDOI:
247
+    
248
+        pdf = PdfPages('resolution_analysis' + '.pdf' )
249
+        MRM = np.zeros((len(ifaces)-1, len(ifaces)-1))
250
+
251
+    #with multiprocessing.Pool() as pool: 
252
+    #    invresults = pool.starmap(invert, zip(itertools.repeat(Time), GT[0:ni], GD[0:ni], SIG[0:ni], itertools.repeat(sys.argv[3]) )) 
253
+ 
254
+        # This could be parallelized 
255
+        for ilay in range(len(ifaces)-1):
256
+            iDeltaT2 = len(T2Bins)//2
257
+            deltaMod = np.zeros( (len(ifaces)-1, len(T2Bins)) )
258
+            deltaMod[ilay][iDeltaT2] = 0.3
259
+            dV = np.dot(KQT, np.ravel(deltaMod)) 
260
+            # invert 
261
+            dinv, dibreak, derrn = logBarrier(KQT, dV, T2Bins, "single", MAXITER=1, sigma=np.ravel(VS), alpha=alphastar, smooth="Smallest" ) 
262
+            print("Sum dinv from", str(ifaces[ilay]), "to", str(ifaces[ilay+1]), "=", np.sum(dinv))
263
+    
264
+            DINV = np.reshape(dinv, (len(ifaces)-1,cont["T2Bins"]["number"]) )
265
+            MRM[ilay,:] = np.sum(DINV, axis=1)
266
+
267
+            Y,X = meshgrid( ifaces, T2Bins2 )
268
+            fig = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
269
+            ax1 = fig.add_axes( [.2,.15,.6,.7] )
270
+            im = ax1.pcolor(X, Y, DINV.T, cmap=cmocean.cm.tempo, shading='auto')
271
+            ax1.plot( T2Bins[iDeltaT2], (ifaces[ilay]+ifaces[ilay+1])/2, 's', markersize=6, markeredgecolor='black') #, markerfacecolor=None )  
272
+            im.set_edgecolor('face')
273
+            ax1.set_xlabel(u"$T_2^*$ (ms)")
274
+            ax1.set_ylabel(u"depth (m)")
275
+            ax1.set_xlim( T2Bins2[0], T2Bins2[-1] )
276
+            ax1.set_ylim( ifaces[-1], ifaces[0] )
277
+
278
+            ax2 = ax1.twiny()
279
+            ax2.plot( np.sum(DINV, axis=1), (ifaces[1:]+ifaces[0:-1])/2 ,  color='red' )
280
+            ax2.set_xlabel(u"total water (m$^3$/m$^3$)")
281
+            ax2.set_ylim( ifaces[-1], ifaces[0] )
282
+            ax2.xaxis.set_major_locator( MaxNLocator(nbins = 3) )   
283
+            ax2.get_xaxis().set_major_formatter(FormatStrFormatter('%0.2f'))
284
+
285
+            pdf.savefig(facecolor=[0,0,0,0])
286
+            plt.close(fig)
287
+
288
+        np.save("MRM", MRM)
289
+        centres = (ifaces[0:-1]+ifaces[1:])/2
290
+        X,Y = np.meshgrid(ifaces,ifaces)
291
+
292
+        fig = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
293
+        ax1 = fig.add_axes( [.2,.15,.6,.7] )
294
+        ax1.pcolor(X,Y,MRM, cmap = cmocean.cm.ice)
295
+        ax1.set_ylim(ifaces[-1], ifaces[0])
296
+        maxDepth = np.argmax(MRM, axis=0)
297
+
298
+        plt.plot(centres[maxDepth], centres, color='white')
299
+
300
+        # Determine DOI 
301
+        DOIMetric =  centres[maxDepth]/centres #> 0.9 
302
+        DOI = ifaces[ np.where(DOIMetric < 0.9 ) ][0]
303
+        plt.axhline(y=DOI, color='white', linestyle='-.')
304
+
305
+        ax1.set_ylim( ifaces[-1], ifaces[0] )
306
+        ax1.set_xlim( ifaces[0], ifaces[-1] )
307
+        ax1.set_xlabel(u"depth (m)")
308
+        ax1.set_ylabel(u"depth (m)")
309
+
310
+        pdf.close()
311
+
312
+
242
 
313
 
243
-    T2Bins = np.append( T2Bins, T2Bins[-1] + (T2Bins[-1]-T2Bins[-2]) )
244
     INV = np.reshape(inv, (len(ifaces)-1,cont["T2Bins"]["number"]) )
314
     INV = np.reshape(inv, (len(ifaces)-1,cont["T2Bins"]["number"]) )
245
 
315
 
246
     #alphas = np.tile(SNR, (len(T2Bins)-1,1))
316
     #alphas = np.tile(SNR, (len(T2Bins)-1,1))
254
 
324
 
255
     ##############  LINEAR RESULT   ##########################
325
     ##############  LINEAR RESULT   ##########################
256
 
326
 
257
-    Y,X = meshgrid( ifaces, T2Bins )
327
+    Y,X = meshgrid( ifaces, T2Bins2 )
258
     fig = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
328
     fig = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
259
     ax1 = fig.add_axes( [.2,.15,.6,.7] )
329
     ax1 = fig.add_axes( [.2,.15,.6,.7] )
260
     im = ax1.pcolor(X, Y, INV.T, cmap=cmocean.cm.tempo) #cmap='viridis')
330
     im = ax1.pcolor(X, Y, INV.T, cmap=cmocean.cm.tempo) #cmap='viridis')
264
     #im = ax1.pcolormesh(X, Y, INV.T, alpha=alphas) #, cmap=cmocean.cm.tempo) #cmap='viridis')
334
     #im = ax1.pcolormesh(X, Y, INV.T, alpha=alphas) #, cmap=cmocean.cm.tempo) #cmap='viridis')
265
     #ax1.axhline( y=ifaces[SNRidx], xmin=T2Bins[0], xmax=T2Bins[-1], color='black'  )
335
     #ax1.axhline( y=ifaces[SNRidx], xmin=T2Bins[0], xmax=T2Bins[-1], color='black'  )
266
     im.set_edgecolor('face')
336
     im.set_edgecolor('face')
267
-    ax1.set_xlim( T2Bins[0], T2Bins[-1] )
337
+    ax1.set_xlim( T2Bins[0], T2Bins2[-1] )
268
     ax1.set_ylim( ifaces[-1], ifaces[0] )
338
     ax1.set_ylim( ifaces[-1], ifaces[0] )
269
     cb = plt.colorbar(im, label = u"PWC (m$^3$/m$^3$)") #, format='%1.1f')
339
     cb = plt.colorbar(im, label = u"PWC (m$^3$/m$^3$)") #, format='%1.1f')
270
     cb.locator = MaxNLocator( nbins = 4)
340
     cb.locator = MaxNLocator( nbins = 4)
286
     ax2.set_ylim( ifaces[-1], ifaces[0] )
356
     ax2.set_ylim( ifaces[-1], ifaces[0] )
287
     ax2.xaxis.set_major_locator( MaxNLocator(nbins = 3) )   
357
     ax2.xaxis.set_major_locator( MaxNLocator(nbins = 3) )   
288
     ax2.get_xaxis().set_major_formatter(FormatStrFormatter('%0.2f'))
358
     ax2.get_xaxis().set_major_formatter(FormatStrFormatter('%0.2f'))
289
-    ax2.axhline( y=ifaces[SNRidx], xmin=0, xmax=1, color='black', linestyle='dashed'  )
359
+    #ax2.axhline( y=ifaces[SNRidx], xmin=0, xmax=1, color='black', linestyle='dashed'  )
360
+    if CalcDOI:
361
+        ax2.axhline( y=DOI, xmin=0, xmax=1, color='black', linestyle='dashed'  )
290
     #ax2.xaxis.set_label_position('bottom') 
362
     #ax2.xaxis.set_label_position('bottom') 
291
 
363
 
292
     plt.savefig("akvoInversion.pdf")
364
     plt.savefig("akvoInversion.pdf")
294
 
366
 
295
     ##############  NONLINEAR RESULT   ##########################
367
     ##############  NONLINEAR RESULT   ##########################
296
 
368
 
297
-    Y,X = meshgrid( ifaces, T2Bins )
298
-    fig = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
299
-    ax1 = fig.add_axes( [.2,.15,.6,.7] )
300
-    im = ax1.pcolor(X, Y, INVc.T, cmap=cmocean.cm.tempo) #cmap='viridis')
301
-    #im = ax1.pcolor(X[0:SNRidx,:], Y[0:SNRidx,:], INV.T[0:SNRidx,:], cmap=cmocean.cm.tempo) #cmap='viridis')
302
-    #im = ax1.pcolor(X[SNRidx::,:], Y[SNRidx::,:], INV.T[SNRidx::,:], cmap=cmocean.cm.tempo, alpha=.5) #cmap='viridis')
303
-    #im = ax1.pcolormesh(X, Y, INV.T, alpha=alphas) #, cmap=cmocean.cm.tempo) #cmap='viridis')
304
-    #im = ax1.pcolormesh(X, Y, INV.T, alpha=alphas) #, cmap=cmocean.cm.tempo) #cmap='viridis')
305
-    #ax1.axhline( y=ifaces[SNRidx], xmin=T2Bins[0], xmax=T2Bins[-1], color='black'  )
306
-    im.set_edgecolor('face')
307
-    ax1.set_xlim( T2Bins[0], T2Bins[-1] )
308
-    ax1.set_ylim( ifaces[-1], ifaces[0] )
309
-    cb = plt.colorbar(im, label = u"PWC (m$^3$/m$^3$)") #, format='%1.1f')
310
-    cb.locator = MaxNLocator( nbins = 4)
311
-    cb.ax.yaxis.set_offset_position('left')                         
312
-    cb.update_ticks()
369
+    if nonLinearRefinement: 
370
+        Y,X = meshgrid( ifaces, T2Bins )
371
+        fig = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
372
+        ax1 = fig.add_axes( [.2,.15,.6,.7] )
373
+        im = ax1.pcolor(X, Y, INVc.T, cmap=cmocean.cm.tempo) #cmap='viridis')
374
+        #im = ax1.pcolor(X[0:SNRidx,:], Y[0:SNRidx,:], INV.T[0:SNRidx,:], cmap=cmocean.cm.tempo) #cmap='viridis')
375
+        #im = ax1.pcolor(X[SNRidx::,:], Y[SNRidx::,:], INV.T[SNRidx::,:], cmap=cmocean.cm.tempo, alpha=.5) #cmap='viridis')
376
+        #im = ax1.pcolormesh(X, Y, INV.T, alpha=alphas) #, cmap=cmocean.cm.tempo) #cmap='viridis')
377
+        #im = ax1.pcolormesh(X, Y, INV.T, alpha=alphas) #, cmap=cmocean.cm.tempo) #cmap='viridis')
378
+        #ax1.axhline( y=ifaces[SNRidx], xmin=T2Bins[0], xmax=T2Bins[-1], color='black'  )
379
+        im.set_edgecolor('face')
380
+        ax1.set_xlim( T2Bins[0], T2Bins[-1] )
381
+        ax1.set_ylim( ifaces[-1], ifaces[0] )
382
+        cb = plt.colorbar(im, label = u"PWC (m$^3$/m$^3$)") #, format='%1.1f')
383
+        cb.locator = MaxNLocator( nbins = 4)
384
+        cb.ax.yaxis.set_offset_position('left')                         
385
+        cb.update_ticks()
313
  
386
  
314
-    ax1.set_xlabel(u"$T_2^*$ (ms)")
315
-    ax1.set_ylabel(u"depth (m)")
387
+        ax1.set_xlabel(u"$T_2^*$ (ms)")
388
+        ax1.set_ylabel(u"depth (m)")
316
     
389
     
317
-    ax1.get_xaxis().set_major_formatter(FormatStrFormatter('%1.0f'))
318
-    ax1.get_yaxis().set_major_formatter(FormatStrFormatter('%1.0f'))
319
-    ax1.xaxis.set_major_locator( MaxNLocator(nbins = 4) )   
320
-
321
-    #ax1.xaxis.set_label_position('top') 
322
-
323
-    ax2 = ax1.twiny()
324
-    ax2.plot( np.sum(INVc, axis=1), (ifaces[1:]+ifaces[0:-1])/2 ,  color='red' )
325
-    ax2.set_xlabel(u"total water (m$^3$/m$^3$)")
326
-    ax2.set_ylim( ifaces[-1], ifaces[0] )
327
-    ax2.xaxis.set_major_locator( MaxNLocator(nbins = 3) )   
328
-    ax2.get_xaxis().set_major_formatter(FormatStrFormatter('%0.2f'))
329
-    #ax2.axhline( y=ifaces[SNRidx], xmin=0, xmax=1, color='black', linestyle='dashed'  )
330
-    #ax2.xaxis.set_label_position('bottom') 
331
-    fig.suptitle("Non linear inversion")
332
-    plt.savefig("akvoInversionNL.pdf")
333
-
334
-
390
+        ax1.get_xaxis().set_major_formatter(FormatStrFormatter('%1.0f'))
391
+        ax1.get_yaxis().set_major_formatter(FormatStrFormatter('%1.0f'))
392
+        ax1.xaxis.set_major_locator( MaxNLocator(nbins = 4) )   
393
+
394
+        #ax1.xaxis.set_label_position('top') 
395
+
396
+        ax2 = ax1.twiny()
397
+        ax2.plot( np.sum(INVc, axis=1), (ifaces[1:]+ifaces[0:-1])/2 ,  color='red' )
398
+        ax2.set_xlabel(u"total water (m$^3$/m$^3$)")
399
+        ax2.set_ylim( ifaces[-1], ifaces[0] )
400
+        ax2.xaxis.set_major_locator( MaxNLocator(nbins = 3) )   
401
+        ax2.get_xaxis().set_major_formatter(FormatStrFormatter('%0.2f'))
402
+        #ax2.axhline( y=ifaces[SNRidx], xmin=0, xmax=1, color='black', linestyle='dashed'  )
403
+        if CalcDOI:
404
+            ax2.axhline( y=DOI, xmin=0, xmax=1, color='black', linestyle='dashed'  )
405
+        #ax2.xaxis.set_label_position('bottom') 
406
+        fig.suptitle("Non linear inversion")
407
+        plt.savefig("akvoInversionNL.pdf")
335
 
408
 
336
     #############
409
     #############
337
     # water plot#
410
     # water plot#
340
     ax = fig2.add_axes( [.2,.15,.6,.7] )
413
     ax = fig2.add_axes( [.2,.15,.6,.7] )
341
     
414
     
342
     # Bound water cutoff 
415
     # Bound water cutoff 
343
-    Bidx = T2Bins[0:-1]<33.0
416
+    Bidx = T2Bins<33.0
344
     twater = np.sum(INV, axis=1)
417
     twater = np.sum(INV, axis=1)
345
     bwater = np.sum(INV[:,Bidx], axis=1)
418
     bwater = np.sum(INV[:,Bidx], axis=1)
346
     
419
     
357
     ax.set_xlim( 0, ax.get_xlim()[1] )
430
     ax.set_xlim( 0, ax.get_xlim()[1] )
358
     
431
     
359
     #ax.axhline( y=ifaces[SNRidx], xmin=0, xmax=1, color='black', linestyle='dashed'  )
432
     #ax.axhline( y=ifaces[SNRidx], xmin=0, xmax=1, color='black', linestyle='dashed'  )
433
+    if CalcDOI:
434
+        ax.axhline( y=DOI, xmin=0, xmax=1, color='black', linestyle='dashed'  )
360
     
435
     
361
     plt.savefig("akvoInversionWC.pdf")
436
     plt.savefig("akvoInversionWC.pdf")
362
     plt.legend()  
437
     plt.legend()  
363
  
438
  
364
 
439
 
365
     # Report results into a text file 
440
     # Report results into a text file 
366
-    fr = pd.DataFrame( INV, columns=T2Bins[0:-1] )
441
+    fr = pd.DataFrame( INV, columns=T2Bins ) #[0:-1] )
367
     fr.insert(0, "layer top", ifaces[0:-1] )
442
     fr.insert(0, "layer top", ifaces[0:-1] )
368
     fr.insert(1, "layer bottom", ifaces[1::] )
443
     fr.insert(1, "layer bottom", ifaces[1::] )
369
     fr.insert(2, "NMR total water", np.sum(INV, axis=1) )
444
     fr.insert(2, "NMR total water", np.sum(INV, axis=1) )
370
     fr.insert(3, "NMR bound water", bwater )
445
     fr.insert(3, "NMR bound water", bwater )
371
     fr.insert(4, "Layer SNR", SNR )
446
     fr.insert(4, "Layer SNR", SNR )
447
+    if CalcDOI:
448
+        fr.insert(5, "Resolution", DOIMetric )
372
 
449
 
373
     fr.to_csv("akvoInversion.csv")    
450
     fr.to_csv("akvoInversion.csv")    
374
     #fr.to_excel("akvoInversion.xlsx")    
451
     #fr.to_excel("akvoInversion.xlsx")    

+ 4
- 4
akvo/tressel/logbarrier.py View File

291
 
291
 
292
     if (i == MAXITER-1 ):
292
     if (i == MAXITER-1 ):
293
         ibreak = 2
293
         ibreak = 2
294
-        print("Reached max iterations!!", alpha, np.sqrt(phid/len(b)), ibreak)
295
-        kappa = curvaturefd(np.log(np.array(PHIM)), np.log(np.array(PHID)), ALPHA[0:-1])
296
-        x = MOD[ np.argmax(kappa) ]
294
+        #print("Reached max iterations!!", alpha, np.sqrt(phid/len(b)), ibreak)
295
+        #kappa = curvaturefd(np.log(np.array(PHIM)), np.log(np.array(PHID)), ALPHA[0:-1])
296
+        x = MOD[-1]
297
         b_pre = np.dot(A, x)
297
         b_pre = np.dot(A, x)
298
         phid = np.linalg.norm( np.dot(Wd, (b-b_pre)))**2
298
         phid = np.linalg.norm( np.dot(Wd, (b-b_pre)))**2
299
         phim = np.linalg.norm( np.dot(Phim_base, (x-xr)) )**2
299
         phim = np.linalg.norm( np.dot(Phim_base, (x-xr)) )**2
303
         #print("Returning L curve result")
303
         #print("Returning L curve result")
304
         return x, ibreak, np.sqrt(phid/len(b)), PHIM, PHID/len(b), np.argmax(kappa), Wd, Phim_base, alphastar
304
         return x, ibreak, np.sqrt(phid/len(b)), PHIM, PHID/len(b), np.argmax(kappa), Wd, Phim_base, alphastar
305
     else:
305
     else:
306
-        print("")
306
+        print("Returning max iteration result")
307
         return x, ibreak, np.sqrt(phid/len(b))
307
         return x, ibreak, np.sqrt(phid/len(b))
308
 
308
 
309
 
309
 

+ 2
- 0
akvo/tressel/nonlinearinv.py View File

38
     bounds = np.zeros((len(x0),2))
38
     bounds = np.zeros((len(x0),2))
39
     bounds[:,0] = x0*0.75
39
     bounds[:,0] = x0*0.75
40
     bounds[:,1] = x0*1.25
40
     bounds[:,1] = x0*1.25
41
+    #bounds[:,0] = 0
42
+    #bounds[:,1] = np.max(x0)*1.25
41
     return so.minimize(PHI, x0, args, 'L-BFGS-B', bounds=bounds)     # Works well 
43
     return so.minimize(PHI, x0, args, 'L-BFGS-B', bounds=bounds)     # Works well 
42
     #return so.minimize(PHI, x0, args, 'Powell', bounds=bounds)       # Slow but works 
44
     #return so.minimize(PHI, x0, args, 'Powell', bounds=bounds)       # Slow but works 
43
     #return so.minimize(PHI, x0, args, 'trust-constr', bounds=bounds) # very Slow 
45
     #return so.minimize(PHI, x0, args, 'trust-constr', bounds=bounds) # very Slow 

Loading…
Cancel
Save