123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675 |
- from akvo.tressel.SlidesPlot import *
- import numpy as np
- import sys
- import matplotlib.pyplot as plt
- import cmocean
- from pylab import meshgrid
- from akvo.tressel.logbarrier import *
- import yaml,os
-
- import multiprocessing
- import itertools
-
- from scipy.linalg import svd
-
- from matplotlib.backends.backend_pdf import PdfPages
- from matplotlib.colors import LogNorm
- from matplotlib.colors import LightSource
- from matplotlib.ticker import ScalarFormatter
- from matplotlib.ticker import MaxNLocator
- from matplotlib.ticker import AutoMinorLocator
- from matplotlib.ticker import LogLocator
- from matplotlib.ticker import FormatStrFormatter
- from matplotlib.colors import Normalize
-
- import cmocean
- from akvo.tressel.lemma_yaml import *
- from akvo.tressel import nonlinearinv as nl
-
- import pandas as pd
-
-
- import matplotlib.colors as colors
-
- # From https://stackoverflow.com/questions/18926031/how-to-extract-a-subset-of-a-colormap-as-a-new-colormap-in-matplotlib
- def truncate_colormap(cmap, minval=0.0, maxval=1.0, n=100):
- new_cmap = colors.LinearSegmentedColormap.from_list(
- 'trunc({n},{a:.2f},{b:.2f})'.format(n=cmap.name, a=minval, b=maxval),
- cmap(np.linspace(minval, maxval, n)))
- return new_cmap
-
- def buildKQT(K0,tg,T2Bins):
- """
- Constructs a QT inversion kernel from an initial amplitude one.
- """
- nlay, nq = np.shape(K0)
- nt2 = len(T2Bins)
- nt = len(tg)
- KQT = np.zeros( ( nq*nt,nt2*nlay), dtype=np.complex128 )
- for iq in range(nq):
- for it in range(nt):
- for ilay in range(nlay):
- for it2 in range(nt2):
- #KQT[iq*nt + it,ilay*nt2+it2] = K0[ilay,iq]*np.exp(-((10+tg[it])*1e-3)/(1e-3*T2Bins[it2]))
- KQT[iq*nt + it,ilay*nt2+it2] = K0[ilay,iq]*np.exp(-((10+tg[it])*1e-3)/(1e-3*T2Bins[it2]))
- return KQT
-
- def loadAkvoData(fnamein, chan):
- """ Loads data from an Akvo YAML file. The 0.02 is hard coded as the pulse length. This needs to be
- corrected in future kernel calculations. The current was reported but not the pulse length.
- """
- fname = (os.path.splitext(fnamein)[0])
- with open(fnamein, 'r') as stream:
- try:
- AKVO = (yaml.load(stream, Loader=yaml.Loader))
- except yaml.YAMLError as exc:
- print(exc)
- exit()
-
- Z = np.zeros( (AKVO.nPulseMoments, AKVO.Gated["Pulse 1"]["abscissa"].size ) )
- ZS = np.zeros( (AKVO.nPulseMoments, AKVO.Gated["Pulse 1"]["abscissa"].size ) )
- for q in range(AKVO.nPulseMoments):
- Z[q] = AKVO.Gated["Pulse 1"][chan]["Q-"+str(q) + " CA"].data
- if chan == "Chan. 1":
- ZS[q] = AKVO.Gated["Pulse 1"][chan]["STD"].data
- elif chan == "Chan. 2":
- ZS[q] = AKVO.Gated["Pulse 1"][chan]["STD"].data
- elif chan == "Chan. 3":
- ZS[q] = AKVO.Gated["Pulse 1"][chan]["STD"].data
- elif chan == "Chan. 4":
- ZS[q] = AKVO.Gated["Pulse 1"][chan]["STD"].data
- else:
- print("DOOM!!!")
- exit()
- #Z *= 1e-9
- #ZS *= 1e-9
-
- J = AKVO.Pulses["Pulse 1"]["current"].data
- J = np.append(J,J[-1]+(J[-1]-J[-2]))
- Q = AKVO.pulseLength[0]*J
- return Z, ZS, AKVO.Gated["Pulse 1"]["abscissa"].data, Q
-
- def catLayers(K0):
- K = np.zeros( (len(K0.keys()), len(K0["layer-0"].data)) , dtype=complex )
- for lay in range(len(K0.keys())):
- #print(K0["layer-"+str(lay)].data) # print (lay)
- K[lay] =K0["layer-"+str(lay)].data # print (lay)
- return 1e9*K # invert in nV
-
- def loadK0(fname):
- """ Loads in initial amplitude kernel
- """
- print("loading K0", fname)
- with open(fname) as f:
- K0 = yaml.load(f, Loader=yaml.Loader)
- K = catLayers(K0.K0)
- ifaces = np.array(K0.Interfaces.data)
- return ifaces, K
- #return ifaces, np.abs(K)
-
- def invertDelta(G, V_n, T2Bins, sig, alphastar):
- """ helper function that simply calls logBarrier, simplfies parallel execution
- """
- model = logBarrier(G, V_n, T2Bins, "Single", MAXITER=1, sigma=sig, alpha=alphastar, smooth="Smallest")
- return model
-
-
- def main():
-
- if (len (sys.argv) < 2):
- print ("akvoQT invertParameters.yaml")
- exit()
-
- with open(sys.argv[1], 'r') as stream:
- try:
- cont = (yaml.load(stream, Loader=yaml.Loader))
- except yaml.YAMLError as exc:
- print(exc)
-
- ###############################################
- # Load in data
- ###############################################
- V = []
- VS = []
- QQ = []
- tg = 0
- for dat in cont['data']:
- for ch in cont['data'][dat]['channels']:
- print("dat", dat, "ch", ch)
- v,vs,tg,Q = loadAkvoData(dat, ch)
- V.append(v)
- VS.append(vs)
- QQ.append(Q)
- for iv in range(1, len(V)):
- V[0] = np.concatenate( (V[0], V[iv]) )
- VS[0] = np.concatenate( (VS[0], VS[iv]) )
- V = V[0]
- VS = VS[0]
-
- ###############################################
- # Load in kernels
- ###############################################
- K0 = []
- for kern in cont["K0"]:
- ifaces,k0 = loadK0( kern )
- K0.append(k0)
- for ik in range(1, len(K0)):
- K0[0] = np.concatenate( (K0[0].T, K0[ik].T) ).T
- K0 = K0[0]
-
- #np.save("ifaces", ifaces)
- #exit()
-
- #plt.matshow(np.real(K0))
- #plt.show()
- #exit()
-
- ##############################################################
- # VERY Simple Sensitivity based calc. of noise per layer #
- # minimally useful, but retained for backwards compatibility #
- maxq = np.argmax(np.abs(K0), axis=1)
- maxK = .1 * np.abs(K0)[ np.arange(0,len(ifaces)-1), maxq ] # 10% water is arbitrary
- SNR = maxK / (VS[0][0])
-
- ###############################################
- # Build full kernel
- ###############################################
-
- T2Bins = np.logspace( np.log10(cont["T2Bins"]["low"]), np.log10(cont["T2Bins"]["high"]), cont["T2Bins"]["number"], endpoint=True, base=10)
- T2Bins2 = np.append( T2Bins, T2Bins[-1] + (T2Bins[-1]-T2Bins[-2]) )
- NT2 = len(T2Bins)
-
- KQT = np.real(buildKQT(np.abs(K0),tg,T2Bins))
-
- ###############################################
- # Linear Inversion
- ###############################################
- print("Calling inversion", flush=True)
- 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" )
-
-
- ################################
- # Summary plots, Data Space #
- ################################
-
- # TODO, need to clean this up for the case of multiple channels! Each channel should be a new row. It will be ugly, but important
- # TODO, loop over channels
-
- ich = 0
- for ch in cont['data'][dat]['channels']:
-
- figx = plt.figure( figsize=(pc2in(42.0),pc2in(22.)) )
- ax1 = figx.add_axes([.100, .15, .200, .70])
- ax2 = figx.add_axes([.325, .15, .200, .70]) # shifted to make room for shared colourbar
- axc1= figx.add_axes([.550, .15, .025, .70]) # shifted to make room for shared colourbar
- ax3 = figx.add_axes([.670, .15, .200, .70])
- axc2= figx.add_axes([.895, .15, .025, .70]) # shifted to make room for shared colourbar
-
- ax3.set_yscale('log')
- ax2.set_yscale('log')
- ax1.set_yscale('log')
-
- ax2.yaxis.set_ticklabels([])
- ax3.yaxis.set_ticklabels([])
-
- ax3.set_xscale('log')
- ax2.set_xscale('log')
- ax1.set_xscale('log')
-
- ax1.set_ylabel("Q (A $\cdot$ s)")
- ax1.set_xlabel("time (s)")
- ax2.set_xlabel("time (s)")
- ax3.set_xlabel("time (s)")
-
- #TT, QQQ = np.meshgrid(tg, np.ravel(QQ))
-
- TT, QQQ = np.meshgrid(tg, np.ravel(QQ[ich]))
- nq = np.shape(QQ[ich])[0] - 1 # to account for padding in pcolor
- nt = np.shape(tg)[0]
- ntq = nt*nq
-
- VV = V[ich*nq:ich*nq+nq,:] # slice this channel
- VVS = VS[ich*nq:ich*nq+nq,:] # slice this channel
-
- mmax = np.max(np.abs(VV))
- mmin = np.min(VV)
-
- obs = ax1.pcolor(TT, QQQ, VV, cmap=cmocean.cm.curl_r, vmin=-mmax, vmax=mmax, shading='auto') # pcolor edge not defined
- ax1.set_title("observed")
-
- pre = np.dot(KQT[ich*ntq:(ich+1)*ntq,:], inv)
-
- PRE = np.reshape( pre, np.shape(VV) )
- prem = ax2.pcolor(TT, QQQ, PRE, cmap=cmocean.cm.curl_r, vmin=-mmax, vmax=mmax,shading='auto' )
- ax2.set_title("predicted")
-
- cbar = plt.colorbar(prem, axc1)
- axc1.set_ylim( [np.min(VV), np.max(VV)] )
- cbar.outline.set_edgecolor(None)
- cbar.set_label('$V_N$ (nV)')
-
- DIFF = (PRE-VV) / VVS
- md = np.max(np.abs(DIFF))
- dim = ax3.pcolor(TT, QQQ, DIFF, cmap=cmocean.cm.balance, vmin=-md, vmax=md, shading='auto')
- ax3.set_title("misfit / $\widehat{\sigma}$")
-
- cbar2 = plt.colorbar(dim, axc2)
- #axc1.set_ylim( [np.min(V), np.max(V)] )
- cbar2.outline.set_edgecolor(None)
- cbar2.set_label('$V_N$ (nV)')
- #plt.colorbar(dim, ax3)
-
- figx.suptitle(ch + " linear Inversion")
- plt.savefig(ch + "dataspace.pdf")
-
- ich += 1
-
- ###############################################
- # Non-linear refinement!
- ###############################################
-
- nonLinearRefinement = cont['NonLinearRefinement']
- if nonLinearRefinement:
-
- KQTc = buildKQT(K0, tg, T2Bins)
- prec = np.abs(np.dot(KQTc, inv))
- phidc = np.linalg.norm(np.dot(Wd,prec-np.ravel(V)))**2
- print("PHID forward linear=", errn, "PHID forward nonlinear=", phidc/len(np.ravel(V)))
-
- res = nl.nonlinearinversion(inv, Wd, KQTc, np.ravel(V), Wm, alphastar )
- if res.success == True:
- INVc = np.reshape(res.x, (len(ifaces)-1,cont["T2Bins"]["number"]) )
- prec = np.abs(np.dot(KQTc, res.x))
- phidc = np.linalg.norm(np.dot(Wd,prec-np.ravel(V)))**2
- PREc = np.reshape( prec, np.shape(V) )
- print("PHID linear=", errn, "PHID nonlinear=", phidc/len(np.ravel(V)))
-
- while phidc/len(np.ravel(V)) > errn:
- phidc_old = phidc/len(np.ravel(V))
- #alphastar *= .9
- res = nl.nonlinearinversion(res.x, Wd, KQTc, np.ravel(V), Wm, alphastar )
- if res.success == True:
- INVc = np.reshape(res.x, (len(ifaces)-1,cont["T2Bins"]["number"]) )
- prec = np.abs(np.dot(KQTc, res.x))
- phidc = np.linalg.norm(np.dot(Wd,prec-np.ravel(V)))**2
- PREc = np.reshape( prec, np.shape(V) )
- print("PHID linear=", errn, "PHID nonlinear=", phidc/len(np.ravel(V)))
- else:
- break
-
- if phidc_old - phidc/len(np.ravel(V)) < 0.005:
- print("Not making progress reducing misfit in nonlinear refinement")
- break
-
- # Turn this into a nice figure w/ shared axes etc.
-
- # plt.matshow(PREc, cmap='Blues')
- # plt.gca().set_title("nonlinear predicted")
- # plt.colorbar()
- #
- # DIFFc = (PREc-V) / VS
- # md = np.max(np.abs(DIFF))
- # plt.matshow(DIFFc, cmap=cmocean.cm.balance, vmin=-md, vmax=md)
- # plt.gca().set_title("nonlinear misfit / $\widehat{\sigma}$")
- # plt.colorbar()
-
-
- ################################
- # Summary plots, Data Space #
- ################################
-
-
- ich = 0
- for ch in cont['data'][dat]['channels']:
-
- figx = plt.figure( figsize=(pc2in(42.0),pc2in(22.)) )
- ax1 = figx.add_axes([.100, .15, .200, .70])
- ax2 = figx.add_axes([.325, .15, .200, .70]) # shifted to make room for shared colourbar
- axc1= figx.add_axes([.550, .15, .025, .70]) # shifted to make room for shared colourbar
- ax3 = figx.add_axes([.670, .15, .200, .70])
- axc2= figx.add_axes([.895, .15, .025, .70]) # shifted to make room for shared colourbar
-
- ax3.set_yscale('log')
- ax2.set_yscale('log')
- ax1.set_yscale('log')
-
- ax2.yaxis.set_ticklabels([])
- ax3.yaxis.set_ticklabels([])
-
- ax3.set_xscale('log')
- ax2.set_xscale('log')
- ax1.set_xscale('log')
-
- ax1.set_ylabel("Q (A $\cdot$ s)")
- ax1.set_xlabel("time (s)")
- ax2.set_xlabel("time (s)")
- ax3.set_xlabel("time (s)")
-
- #TT, QQQ = np.meshgrid(tg, np.ravel(QQ))
-
- TT, QQQ = np.meshgrid(tg, np.ravel(QQ[ich]))
- nq = np.shape(QQ[ich])[0] - 1 # to account for padding in pcolor
- nt = np.shape(tg)[0]
- ntq = nt*nq
-
- VV = V[ich*nq:ich*nq+nq,:] # slice this channel
- VVS = VS[ich*nq:ich*nq+nq,:] # slice this channel
-
- mmax = np.max(np.abs(VV))
- mmin = np.min(VV)
-
- obs = ax1.pcolor(TT, QQQ, VV, cmap=cmocean.cm.curl_r, vmin=-mmax, vmax=mmax, shading='auto')
- ax1.set_title("observed")
-
- ## Here neds to change
- pre = np.abs(np.dot(KQTc[ich*ntq:(ich+1)*ntq,:], inv))
-
- PRE = np.reshape( pre, np.shape(VV) )
- prem = ax2.pcolor(TT, QQQ, PRE, cmap=cmocean.cm.curl_r, vmin=-mmax, vmax=mmax, shading='auto' )
- ax2.set_title("predicted")
-
- cbar = plt.colorbar(prem, axc1)
- axc1.set_ylim( [np.min(VV), np.max(VV)] )
- cbar.outline.set_edgecolor(None)
- cbar.set_label('$V_N$ (nV)')
-
- DIFF = (PRE-VV) / VVS
- md = np.max(np.abs(DIFF))
- dim = ax3.pcolor(TT, QQQ, DIFF, cmap=cmocean.cm.balance, vmin=-md, vmax=md, shading='auto')
- ax3.set_title("misfit / $\widehat{\sigma}$")
-
- cbar2 = plt.colorbar(dim, axc2)
- #axc1.set_ylim( [np.min(V), np.max(V)] )
- cbar2.outline.set_edgecolor(None)
- cbar2.set_label('$V_N$ (nV)')
- #plt.colorbar(dim, ax3)
-
- figx.suptitle(ch + " non-linear Inversion")
-
- plt.savefig(ch + "_NLdataspace.pdf")
-
- ich += 1
-
-
-
-
- ###############################################
- # Appraise DOI using simplified MRM
- ###############################################
-
- CalcDOI = cont['CalcDOI']
-
- if CalcDOI:
-
- pdf = PdfPages('resolution_analysis' + '.pdf' )
- MRM = np.zeros((len(ifaces)-1, len(ifaces)-1))
-
- # Build delta models
- DELTA = []
-
- for ilay in range(len(ifaces)-1):
- #for ilay in range(4):
- iDeltaT2 = len(T2Bins)//2
- deltaMod = np.zeros( (len(ifaces)-1, len(T2Bins)) )
- deltaMod[ilay][iDeltaT2] = 0.3
- dV = np.dot(KQT, np.ravel(deltaMod))
- #dinv, dibreak, derrn = logBarrier( KQT, dV, T2Bins, "single", MAXITER=1, sigma=np.ravel(VS), alpha=alphastar, smooth="Smallest" )
- #output = invertDelta(KQT, dV, T2Bins, np.ravel(VS), alphastar)
- DELTA.append(dV)
-
- print("Performing resolution analysis in parallel, printed output may not be inorder.", flush=True)
- with multiprocessing.Pool() as pool:
- invresults = pool.starmap(invertDelta, zip(itertools.repeat(KQT), DELTA, itertools.repeat(T2Bins), itertools.repeat(np.ravel(VS)), itertools.repeat(alphastar) ))
- # invresults = pool.starmap(logBarrier, zip(itertools.repeat(KQT), DELTA, itertools.repeat(T2Bins), itertools.repeat('single'), \
- # itertools.repeat('MAXITER=1'), itertools.repeat(np.ravel(VS)), itertools.repeat(alphastar))) #, itertools.repeat(u'smooth=\'Smallest\'')) )
-
- # This could be parallelized
- for ilay in range(len(ifaces)-1):
-
- # invert
- #dinv, dibreak, derrn = logBarrier(KQT, dV, T2Bins, "single", MAXITER=1, sigma=np.ravel(VS), alpha=alphastar, smooth="Smallest" )
- #print("Sum dinv from", str(ifaces[ilay]), "to", str(ifaces[ilay+1]), "=", np.sum(dinv))
- dinv, dibreak, derrn = invresults[ilay]
-
-
- DINV = np.reshape(dinv, (len(ifaces)-1,cont["T2Bins"]["number"]) )
- MRM[ilay,:] = np.sum(DINV, axis=1)
-
- Y,X = meshgrid( ifaces, T2Bins2 )
- fig = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
- ax1 = fig.add_axes( [.2,.15,.6,.7] )
- im = ax1.pcolor(X, Y, DINV.T, cmap=cmocean.cm.tempo, shading='auto')
- ax1.plot( T2Bins[iDeltaT2], (ifaces[ilay]+ifaces[ilay+1])/2, 's', markersize=6, markeredgecolor='black') #, markerfacecolor=None )
- im.set_edgecolor('face')
- ax1.set_xlabel(u"$T_2^*$ (ms)")
- ax1.set_ylabel(u"depth (m)")
- ax1.set_xlim( T2Bins2[0], T2Bins2[-1] )
- ax1.set_ylim( ifaces[-1], ifaces[0] )
-
- ax2 = ax1.twiny()
- ax2.plot( np.sum(DINV, axis=1), (ifaces[1:]+ifaces[0:-1])/2 , color='mediumblue' )
- ax2.set_xlabel(u"total water (m$^3$/m$^3$)", color='mediumblue')
- ax2.set_ylim( ifaces[-1], ifaces[0] )
- ax2.xaxis.set_major_locator( MaxNLocator(nbins = 3) )
- ax2.get_xaxis().set_major_formatter(FormatStrFormatter('%0.2f'))
-
- pdf.savefig(facecolor=[0,0,0,0])
- plt.close(fig)
-
- np.save("MRM", MRM)
- centres = (ifaces[0:-1]+ifaces[1:])/2
- X,Y = np.meshgrid(ifaces,ifaces)
-
- fig = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
- ax1 = fig.add_axes( [.2,.15,.6,.7] )
- ax1.pcolor(X,Y,MRM, cmap = cmocean.cm.ice)
- ax1.set_ylim(ifaces[-1], ifaces[0])
- maxDepth = np.argmax(MRM, axis=0)
-
- plt.plot(centres[maxDepth], centres, color='white')
-
- # Determine DOI
- DOIMetric = centres[maxDepth]/centres #> 0.9
- DOI = ifaces[ np.where(DOIMetric < 0.9 ) ][0]
- plt.axhline(y=DOI, color='white', linestyle='-.')
-
- ax1.set_ylim( ifaces[-1], ifaces[0] )
- ax1.set_xlim( ifaces[0], ifaces[-1] )
- ax1.set_xlabel(u"depth (m)")
- ax1.set_ylabel(u"depth (m)")
- plt.savefig("resolutionmatrix.pdf")
- pdf.close()
-
- INV = np.reshape(inv, (len(ifaces)-1,cont["T2Bins"]["number"]) )
-
-
- ############## LINEAR RESULT ##########################
-
- Y,X = meshgrid( ifaces, T2Bins2 )
- fig = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
- ax1 = fig.add_axes( [.2,.15,.6,.7] )
- im = ax1.pcolor(X, Y, INV.T, cmap=cmocean.cm.tempo) #cmap='viridis')
- im.set_edgecolor('face')
- ax1.set_xlim( T2Bins[0], T2Bins[-1] )
- ax1.set_ylim( ifaces[-1], ifaces[0] )
- cb = plt.colorbar(im, label = u"PWC (m$^3$/m$^3$)") #, format='%1.1f')
- cb.locator = MaxNLocator( nbins = 4)
- cb.ax.yaxis.set_offset_position('left')
- cb.update_ticks()
-
- ax1.set_xlabel(u"$T_2^*$ (ms)")
- ax1.set_ylabel(u"depth (m)")
-
- ax1.get_xaxis().set_major_formatter(FormatStrFormatter('%1.0f'))
- ax1.get_yaxis().set_major_formatter(FormatStrFormatter('%1.0f'))
- ax1.xaxis.set_major_locator( MaxNLocator(nbins = 4) )
-
-
- ax2 = ax1.twiny()
- ax2.plot( np.sum(INV, axis=1), (ifaces[1:]+ifaces[0:-1])/2 , color='mediumblue' )
- ax2.set_xlabel(u"NMR total water (m$^3$/m$^3$)", color='mediumblue')
- ax2.set_ylim( ifaces[-1], ifaces[0] )
- ax2.xaxis.set_major_locator( MaxNLocator(nbins = 3) )
- ax2.get_xaxis().set_major_formatter(FormatStrFormatter('%0.2f'))
- #ax2.axhline( y=ifaces[SNRidx], xmin=0, xmax=1, color='black', linestyle='dashed' )
- if CalcDOI:
- ax2.axhline( y=DOI, xmin=0, xmax=1, color='black', linestyle='dashed' )
-
- ax2.tick_params(axis='x', colors='mediumblue')
- plt.setp(ax2.get_xticklabels(), color="mediumblue")
-
- plt.savefig("akvoInversion.pdf")
-
- #############
- # water plot#
-
- fig2 = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
- ax = fig2.add_axes( [.2,.15,.6,.7] )
-
- # Bound water cutoff
- Bidx = T2Bins<33.0
- twater = np.sum(INV, axis=1)
- bwater = np.sum(INV[:,Bidx], axis=1)
-
- ax.plot( twater, (ifaces[0:-1]+ifaces[1::])/2, label="NMR total water", color='blue' )
- ax.plot( bwater, (ifaces[0:-1]+ifaces[1::])/2, label="NMR bound water", color='green' )
-
- ax.fill_betweenx((ifaces[0:-1]+ifaces[1::])/2 , twater, bwater, where=twater >= bwater, facecolor='blue', alpha=.5)
- ax.fill_betweenx((ifaces[0:-1]+ifaces[1::])/2 , bwater, 0, where=bwater >= 0, facecolor='green', alpha=.5)
-
- ax.set_xlabel(r"$\theta_N$ (m$^3$/m$^3$)")
- ax.set_ylabel(r"depth (m)")
-
- ax.set_ylim( ifaces[-1], ifaces[0] )
- ax.set_xlim( 0, ax.get_xlim()[1] )
-
- #ax.axhline( y=ifaces[SNRidx], xmin=0, xmax=1, color='black', linestyle='dashed' )
- if CalcDOI:
- ax.axhline( y=DOI, xmin=0, xmax=1, color='black', linestyle='dashed' )
-
- # Hide the right and top spines
- ax.spines['right'].set_visible(False)
- ax.spines['top'].set_visible(False)
- # Only show ticks on the left and bottom spines
- ax.yaxis.set_ticks_position('left')
- ax.xaxis.set_ticks_position('bottom')
-
- plt.savefig("akvoInversionWC.pdf")
- plt.legend()
-
- fr = pd.DataFrame( INV, columns=T2Bins ) #[0:-1] )
- fr.insert(0, "layer top", ifaces[0:-1] )
- fr.insert(1, "layer bottom", ifaces[1::] )
- fr.insert(2, "NMR total water", np.sum(INV, axis=1) )
- fr.insert(3, "NMR bound water", bwater )
- fr.insert(4, "Layer SNR", SNR )
- if CalcDOI:
- fr.insert(5, "Resolution", DOIMetric )
-
- fr.to_csv("akvoInversion.csv", mode='w+')
-
-
- ############## NONLINEAR RESULT ##########################
-
- if nonLinearRefinement:
- Y,X = meshgrid( ifaces, T2Bins2 )
- fig = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
- ax1 = fig.add_axes( [.2,.15,.6,.7] )
- im = ax1.pcolor(X, Y, INVc.T, cmap=cmocean.cm.tempo) #cmap='viridis')
- #im = ax1.pcolor(X[0:SNRidx,:], Y[0:SNRidx,:], INV.T[0:SNRidx,:], cmap=cmocean.cm.tempo) #cmap='viridis')
- #im = ax1.pcolor(X[SNRidx::,:], Y[SNRidx::,:], INV.T[SNRidx::,:], cmap=cmocean.cm.tempo, alpha=.5) #cmap='viridis')
- #im = ax1.pcolormesh(X, Y, INV.T, alpha=alphas) #, cmap=cmocean.cm.tempo) #cmap='viridis')
- #im = ax1.pcolormesh(X, Y, INV.T, alpha=alphas) #, cmap=cmocean.cm.tempo) #cmap='viridis')
- #ax1.axhline( y=ifaces[SNRidx], xmin=T2Bins[0], xmax=T2Bins[-1], color='black' )
- im.set_edgecolor('face')
- ax1.set_xlim( T2Bins[0], T2Bins[-1] )
- ax1.set_ylim( ifaces[-1], ifaces[0] )
- cb = plt.colorbar(im, label = u"PWC (m$^3$/m$^3$)") #, format='%1.1f')
- cb.locator = MaxNLocator( nbins = 4)
- cb.ax.yaxis.set_offset_position('left')
- cb.update_ticks()
-
- ax1.set_xlabel(u"$T_2^*$ (ms)")
- ax1.set_ylabel(u"depth (m)")
-
- ax1.get_xaxis().set_major_formatter(FormatStrFormatter('%1.0f'))
- ax1.get_yaxis().set_major_formatter(FormatStrFormatter('%1.0f'))
- ax1.xaxis.set_major_locator( MaxNLocator(nbins = 4) )
-
- #ax1.xaxis.set_label_position('top')
-
- ax2 = ax1.twiny()
- ax2.plot( np.sum(INVc, axis=1), (ifaces[1:]+ifaces[0:-1])/2 , color='mediumblue' )
- ax2.set_xlabel(u"NMR total water (m$^3$/m$^3$)", color='mediumblue')
- ax2.set_ylim( ifaces[-1], ifaces[0] )
- ax2.xaxis.set_major_locator( MaxNLocator(nbins = 3) )
- ax2.get_xaxis().set_major_formatter(FormatStrFormatter('%0.2f'))
- #ax2.axhline( y=ifaces[SNRidx], xmin=0, xmax=1, color='black', linestyle='dashed' )
- if CalcDOI:
- ax2.axhline( y=DOI, xmin=0, xmax=1, color='black', linestyle='dashed' )
- #ax2.xaxis.set_label_position('bottom')
- #fig.suptitle("Non linear inversion")
- ax2.tick_params(axis='x', colors='mediumblue')
- plt.setp(ax2.get_xticklabels(), color="mediumblue")
-
- plt.savefig("akvoInversionNL.pdf")
-
-
-
- #############
- # water plot#
-
- fig2 = plt.figure( figsize=(pc2in(20.0),pc2in(22.)) )
- ax = fig2.add_axes( [.2,.15,.6,.7] )
-
- # Bound water cutoff
- Bidx = T2Bins<33.0
- twater = np.sum(INVc, axis=1)
- bwater = np.sum(INVc[:,Bidx], axis=1)
-
- ax.plot( twater, (ifaces[0:-1]+ifaces[1::])/2, label="NMR total water", color='blue' )
- ax.plot( bwater, (ifaces[0:-1]+ifaces[1::])/2, label="NMR bound water", color='green' )
-
- ax.fill_betweenx((ifaces[0:-1]+ifaces[1::])/2 , twater, bwater, where=twater >= bwater, facecolor='blue', alpha=.5)
- ax.fill_betweenx((ifaces[0:-1]+ifaces[1::])/2 , bwater, 0, where=bwater >= 0, facecolor='green', alpha=.5)
-
- ax.set_xlabel(r"$\theta_N$ (m$^3$/m$^3$)")
- ax.set_ylabel(r"depth (m)")
-
- ax.set_ylim( ifaces[-1], ifaces[0] )
- ax.set_xlim( 0, ax.get_xlim()[1] )
-
- #ax.axhline( y=ifaces[SNRidx], xmin=0, xmax=1, color='black', linestyle='dashed' )
- if CalcDOI:
- ax.axhline( y=DOI, xmin=0, xmax=1, color='black', linestyle='dashed' )
-
- # Hide the right and top spines
- ax.spines['right'].set_visible(False)
- ax.spines['top'].set_visible(False)
- # Only show ticks on the left and bottom spines
- ax.yaxis.set_ticks_position('left')
- ax.xaxis.set_ticks_position('bottom')
-
- plt.savefig("akvoNLInversionWC.pdf")
- plt.legend()
-
-
- # Report results into a text file
- fr = pd.DataFrame( INVc, columns=T2Bins ) #[0:-1] )
- fr.insert(0, "layer top", ifaces[0:-1] )
- fr.insert(1, "layer bottom", ifaces[1::] )
- fr.insert(2, "NMR total water", np.sum(INVc, axis=1) )
- fr.insert(3, "NMR bound water", bwater )
- fr.insert(4, "Layer SNR", SNR )
- if CalcDOI:
- fr.insert(5, "Resolution", DOIMetric )
-
- fr.to_csv("akvoNLInversion.csv", mode='w+')
- #fr.to_excel("akvoInversion.xlsx")
-
-
- plt.show()
-
- if __name__ == "__main__":
- main()
|