Files
simpeg/simpegPF/Dev/MAG/Mag_Inv_Param.py
T
2016-04-22 15:24:22 -07:00

464 lines
15 KiB
Python

# -*- coding: utf-8 -*-
"""
Created on Wed Feb 03 21:34:50 2016
@author: dominiquef
"""
from SimPEG import *
import simpegPF as PF
from simpegPF import BaseMag as MAG
from numpy.polynomial import polynomial
import pylab as plt
import os
#home_dir = 'C:\Users\dominiquef.MIRAGEOSCIENCE\Documents\GIT\SimPEG\simpegpf\simpegPF\Dev'
#home_dir = 'C:\\Users\\dominiquef.MIRAGEOSCIENCE\\ownCloud\\Research\\Modelling\\Synthetic\\Parametric_plane'
#home_dir = 'C:\\LC\\Private\\dominiquef\\Projects\\4414_Minsim\\Modeling\\MAG\\Lalor'
#home_dir = 'C:\Users\dominiquef.MIRAGEOSCIENCE\ownCloud\Research\Nate\Modeling'
home_dir = 'C:\\Users\\dominiquef.MIRAGEOSCIENCE\\Google Drive\\DevDomNateDBE\\DomNate\\Fault_synthetic\\NE'
#home_dir = '.\\'
plt.close('all')
inpfile = 'PYMAG3D_inv.inp'
dsep = '\\'
os.chdir(home_dir)
## New scripts to be added to basecode
#from fwr_MAG_data import fwr_MAG_data
#from read_MAGfwr_inp import read_MAGfwr_inp
beta_in = 1e+0
ndv = -100
#%%
# Read input file
[mshfile, obsfile, topofile, m0_val, mref, magfile, wgtfile, chi, alphas, bounds, lpnorms] = PF.Magnetics.read_MAGinv_inp(home_dir + dsep + inpfile)
#obsfile = 'Synthetic.obs'
#obsfile ='Lalor_rtp_2pc_10nT_RegRem.obs'
#obsfile = 'Obs_ALL.obs'
# Discretization for new mesh
dx = 50.
# Load mesh file
mesh = Mesh.TensorMesh.readUBC(mshfile)
z0 = mesh.x0[2] + np.sum(mesh.hz)
#mesh = Utils.meshutils.readUBCTensorMesh(mshfile)
#V2D = polynomial.polyvander2d(mesh.vectorCCx,mesh.vectorCCy,[1,1])
# Load in observation file
survey = PF.Magnetics.readUBCmagObs(obsfile)
rxLoc_full = survey.srcField.rxList[0].locs
data = survey.dobs
wd = survey.std
npad = 10
#%% Pick points from dats and generate local mesh
PF.Magnetics.plot_obs_2D(rxLoc_full,data, levels = [0.])
#PF.Magnetics.plot_obs_2D(dobs[:,:3],dobs[:,3],dobs[:,4],'Observed Data')
gin = np.asarray(plt.ginput(100, timeout = 0))
#gin = np.asarray([[ -81.82517326, -167.83403552],
# [ -21.0157401 , 133.78075295]])
for ii in range(gin.shape[0]-1):
dl_len = np.sqrt( np.sum((gin[ii,:] - gin[ii+1,:])**2) )
dl_x = ( gin[ii,0] - gin[ii+1,0] ) / dl_len
dl_y = ( gin[ii+1,1] - gin[ii,1] ) / dl_len
azm = -np.arctan(dl_x/dl_y)
# Create rotation matrix
Rz = np.array([[np.cos(azm), -np.sin(azm)],
[np.sin(azm), np.cos(azm)]])
# Re-center the experiment
midx = np.median([gin[ii,0],gin[ii+1,0]])
midy = np.median([gin[ii+1,1],gin[ii,1]])
temp = np.vstack([rxLoc_full[:,0].T- midx, rxLoc_full[:,1].T- midy])
# Rotate
ROTxy = Rz.dot(temp)
# Grab data points within a box
indx = (np.abs(ROTxy[0,:]) < dl_len) & (np.abs(ROTxy[1,:]) < dl_len/2)
subrx = MAG.RxObs(np.c_[ROTxy[0,indx].T, ROTxy[1,indx].T, rxLoc_full[indx,2]])
d = data[indx]
uncert = wd[indx]
srcParam = np.asarray(survey.srcField.param)
srcParam[2] = srcParam[2] - np.rad2deg(azm)
srcField = MAG.SrcField([subrx],srcParam)
survey = MAG.LinearSurvey(srcField)
survey.dobs = d
survey.std = uncert
PF.Magnetics.writeUBCobs(home_dir+'\\Obsloc_local.dat',survey,survey.dobs)
rxLoc = survey.srcField.rxList[0].locs
PF.Magnetics.plot_obs_2D(rxLoc,d,'Observed Data')
ndata = rxLoc.shape[0]
# Get extent limits
xlim = np.max(np.abs(rxLoc[:,0]))
ylim = np.max(np.abs(rxLoc[:,1]))
ncx = int(4*xlim/dx)
ncy = int(2*ylim/dx)
ncz = int(np.min([ncx,ncy]))
hxind = [(dx,npad,-1.3),(dx, ncx),(dx,npad,1.3)]
hyind = [(dx,npad,-1.3),(dx, ncy),(dx,npad,1.3)]
hzind = [(dx,npad,-1.3),(dx, ncz)]
mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCN')
mesh.x0[2] = np.max(rxLoc[:,2]) - np.sum(mesh.hz) # Keep top of mesh at same location as before
Mesh.TensorMesh.writeUBC(mesh,home_dir+dsep+'Mesh_local.msh')
# Load in topofile or create flat surface
if topofile == 'null':
# All active
actv = np.asarray(range(mesh.nC))
else:
topo = np.genfromtxt(topofile,skip_header=1)
temp = np.vstack([topo[:,0].T- midx, topo[:,1].T- midy])
# Rotate
ROTxy = Rz.dot(temp)
ROT_topo = np.c_[ROTxy[0,:].T, ROTxy[1,:].T, topo[:,2]]
# Find the active cells
actv = PF.Magnetics.getActiveTopo(mesh,ROT_topo,'N')
nC = len(actv)
idenMap = Maps.IdentityMap(nP = nC)
# Create active map to go from reduce set to full
actvMap = Maps.InjectActiveCells(mesh, actv, ndv)
# Load starting model file
# if isinstance(mstart, float):
mstart = np.ones(nC) * m0_val
# else:
# mstart = Utils.meshutils.readUBCTensorModel(mstart,mesh)
# mstart = mstart[actv]
# Get magnetization vector for MOF
if magfile=='DEFAULT':
M_xyz = PF.Magnetics.dipazm_2_xyz(np.ones(nC) * survey.srcField.param[1], np.ones(nC) * survey.srcField.param[2])
else:
M_xyz = np.genfromtxt(magfile,delimiter=' \n',dtype=np.str,comments='!')
# Get index of the center
#==============================================================================
# midx = int(mesh.nCx/2)
# midy = int(mesh.nCy/2)
#==============================================================================
# Create forward operator
#F = PF.Magnetics.Intrgl_Fwr_Op(mesh,B,M_xyz,rxLoc,actv,'tmi')
#%% Run inversion
# First start with regular inversion for regional removal
prob = PF.Magnetics.MagneticIntegral(mesh, mapping = idenMap, actInd = actv)
prob.solverOpts['accuracyTol'] = 1e-4
survey.pair(prob)
#%%
pred = prob.fields(mstart)
wr = np.sum(prob.G**2.,axis=0)**0.5 / mesh.vol[actv]
wr = ( wr/np.max(wr) )
#IWr = Utils.sdiag(1/wr)
#wrMap = PF.BaseMag.WeightMap(mesh, wr)
#prob.mapping = wrMap
#prob._G = prob._G * IWr
reg = Regularization.Simple(mesh, indActive = actv, mapping = idenMap)
reg.mref = 0.
reg.wght = wr
#reg.alpha_s = 1.
# Create pre-conditioner
diagA = np.sum(prob.G**2.,axis=0) + beta_in*(reg.W.T*reg.W).diagonal()
PC = Utils.sdiag(diagA**-1.)
dmis = DataMisfit.l2_DataMisfit(survey)
dmis.Wd = 1./survey.std
opt = Optimization.ProjectedGNCG(maxIter=10,lower=0.,upper=1., maxIterCG= 20, tolCG = 1e-3)
opt.approxHinv = PC
# opt = Optimization.InexactGaussNewton(maxIter=6)
invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta = beta_in)
beta = Directives.BetaSchedule(coolingFactor=2, coolingRate=1)
#betaest = Directives.BetaEstimate_ByEig()
target = Directives.TargetMisfit()
inv = Inversion.BaseInversion(invProb, directiveList=[beta,target])
m0 = mstart
# Run inversion
mrec = inv.run(m0)
m_out = actvMap*mrec
#%% Temporary plotting scipts
yslice = 14
plt.figure()
ax = plt.subplot(221)
mesh.plotSlice(m_out, ax = ax, normal = 'Z', ind=-5, clim = (mrec.min(), mrec.max()))
plt.plot(np.array([mesh.vectorCCx[0],mesh.vectorCCx[-1]]), np.array([mesh.vectorCCy[yslice],mesh.vectorCCy[yslice]]),c='w',linestyle = '--')
plt.title('Z: ' + str(mesh.vectorCCz[-5]) + ' m')
plt.xlabel('x');plt.ylabel('z')
plt.gca().set_aspect('equal', adjustable='box')
ax = plt.subplot(222)
mesh.plotSlice(m_out, ax = ax, normal = 'Z', ind=-8, clim = ( mrec.min(), mrec.max()))
plt.plot(np.array([mesh.vectorCCx[0],mesh.vectorCCx[-1]]), np.array([mesh.vectorCCy[yslice],mesh.vectorCCy[yslice]]),c='w',linestyle = '--')
plt.title('Z: ' + str(mesh.vectorCCz[-8]) + ' m')
plt.xlabel('x');plt.ylabel('z')
plt.gca().set_aspect('equal', adjustable='box')
ax = plt.subplot(212)
mesh.plotSlice(m_out, ax = ax, normal = 'Y', ind=yslice, clim = ( mrec.min(), mrec.max()))
plt.title('Cross Section')
plt.xlabel('x');plt.ylabel('z')
plt.gca().set_aspect('equal', adjustable='box')
#%% Remove core cells and forward model
m_out = np.reshape(m_out,(mesh.nCx,mesh.nCy,mesh.nCz), order = 'F')
m_out[npad:-npad,npad:-npad,npad:] = m_out[npad:-npad,npad:-npad,npad:]*0.
m_out = mkvc(m_out)
m_pad = m_out[actv]
Mesh.TensorMesh.writeModelUBC(mesh,home_dir+'\\SimPEG_Inv_l2l2.sus',actvMap*mrec)
Mesh.TensorMesh.writeModelUBC(mesh,home_dir+'\\SimPEG_Scooped.sus',actvMap*m_pad)
# Forward model the fields and substract from data
fwr = prob.fields(m_pad)
d_res = survey.dobs - fwr
PF.Magnetics.plot_obs_2D(rxLoc,fwr,'Forward Scoop Data', levels = [0.])
PF.Magnetics.plot_obs_2D(rxLoc,d_res,'RegRem Data', levels = [0.])
survey.dobs = d_res
#%% Reduce the space to only the core region
# Create new mesh for local inversion
hxind = [(dx, ncx)]
hyind = [(dx, ncy)]
hzind = [(dx, ncz)]
x0 = mesh.x0
z0 = x0[2] + np.sum(mesh.hz)
mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCN')
mesh.x0[2] = z0 - np.sum(mesh.hz)
core = m_out==0
grnd = core[actv]
inds = np.asarray([inds for inds, elem in enumerate(grnd, 1) if elem], dtype = int) - 1
#%% Re-run with poly map
# Load in topofile or create flat surface
if topofile == 'null':
# All active
actv = np.asarray(range(mesh.nC))
else:
topo = np.genfromtxt(topofile,skip_header=1)
temp = np.vstack([topo[:,0].T- midx, topo[:,1].T- midy])
# Rotate
ROTxy = Rz.dot(temp)
ROT_topo = np.c_[ROTxy[0,:].T, ROTxy[1,:].T, topo[:,2]]
# Find the active cells
actv = PF.Magnetics.getActiveTopo(mesh,ROT_topo,'N')
nC = len(actv)
idenMap = Maps.IdentityMap(nP = nC)
# Create active map to go from reduce set to full
actvMap = Maps.InjectActiveCells(mesh, actv, ndv)
# Load starting model file
mstart = np.ones(nC) * m0_val
#%% Invert with polymap for plane
#
#
# Create active map to go from reduce set to full
#actvMap = Maps.ActiveCells(mesh, actv, -100)
#
## Creat reduced identity map
#idenMap = Maps.IdentityMap(nP = nC)
#
XYZ = mesh.gridCC
order = [1,1]
YZ = Utils.ndgrid(mesh.vectorCCy, mesh.vectorCCz)
V = polynomial.polyvander2d(YZ[:,0], YZ[:,1], order)
#f = polynomial.polyval2d(XYZ[:,1], XYZ[:,2], c.reshape((order[0]+1,order[1]+1))) - XYZ[:,0]
polymap = Maps.PolyMap(mesh, order, normal='X', logSigma=False, actInd = actv)
polymap.slope = 1.0
#polymap.actInd = actv
#m0 = np.r_[1e-2, 0., 0.0, -0.5, 0.2, 0.]
m0 = np.r_[1e-4, 0, 1., 0., 0., 0.]
#Mesh.TensorMesh.writeModelUBC(mesh,home_dir+dsep+'True_m.sus',polymap*m0)
#Mesh.TensorMesh.writeModelUBC(mesh,home_dir+dsep+'Starting_m.sus',actvMap*polymap*m0)
m1D = Mesh.TensorMesh([(order[0]+1)*(order[1]+1)+2])
weight = ((V**2).sum(axis=0))**0.5
weight = weight / weight.max()
prob_core = PF.Magnetics.MagneticIntegral(mesh, mapping = idenMap*polymap, actInd = actv)
prob_core.solverOpts['accuracyTol'] = 1e-4
survey.pair(prob_core)
#prob_core._G = prob.G[:,inds]
#%%
pred = prob_core.fields(m0)
wr = np.sum(prob_core.G**2.,axis=0)**0.5 / mesh.vol[actv]
wr = ( wr/np.max(wr) )
IWr = Utils.sdiag(1/wr)
wrMap = PF.BaseMag.WeightMap(mesh, wr)
prob_core.mapping = wrMap * polymap
prob_core._G = prob_core.G * IWr
reg = Regularization.Simple(m1D)
reg.alpha_x = 0.
reg.alpha_y = 0.
reg.alpha_z = 0.
reg.norms = [2., 2., 2., 2.]
#reg.mref = np.r_[0., 1., 421500., 1000., 10., 0.5]
reg.mref = np.zeros(6)
#==============================================================================
# reg.wght = np.asarray([ 1.00000000e+00 ,6.50176844e-01 ,4.20328370e-06 ,1.52004209e-03,
# 4.82475226e-05 ,1.37620903e-02])**2.
#==============================================================================
lower = np.r_[0.,0.,-1e+8,-1e+8,-1e+8,-1e+8]
upper = np.r_[1.,1.,1e+8,1e+8,1e+8,1e+8]
#reg.mref = mref
#reg.alpha_s = 1.
dmis = DataMisfit.l2_DataMisfit(survey)
dmis.Wd = 1./survey.std
opt = Optimization.ProjectedGNCG(maxIter=15,maxIterLS=50, maxIterCG = 10,tolCG = 1e-3, lower = lower,upper=upper)
#opt.approxHinv = sp.eye(6)
beta_in = 1e+2
# opt = Optimization.InexactGaussNewton(maxIter=6)
invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta = beta_in)
beta = Directives.BetaSchedule(coolingFactor=2, coolingRate=1)
#betaest = Directives.BetaEstimate_ByEig()
target = Directives.TargetMisfit()
up_Wj = Directives.Update_Wj()
up_Wj.itr = 2
inv = Inversion.BaseInversion(invProb, directiveList=[beta,target,up_Wj])
#m0 = mstart
#Utils.diagEst(prob.Jtvec,2)
# Run inversion
mrec = inv.run(m0)
sus = polymap*mrec
m_out = actvMap * sus
# Write result
Mesh.TensorMesh.writeModelUBC(mesh,'SimPEG_Param.sus',m_out)
Mesh.TensorMesh.writeUBC(mesh,'Working_mesh.msh')
m_out = actvMap *polymap*m0
Mesh.TensorMesh.writeModelUBC(mesh,'SimPEG_Param_m0.sus',m_out)
# Plot predicted
pred = prob_core.fields(mrec)
PF.Magnetics.plot_obs_2D(rxLoc,pred,'Predicted Data', vmin = np.min(survey.dobs), vmax = np.max(survey.dobs))
PF.Magnetics.plot_obs_2D(rxLoc,survey.dobs-pred,'Residual Data')
#PF.Magnetics.writeUBCobs(home_dir + dsep + 'Pred_Final.pre',B,M,rxLoc,pred,np.ones(len(d)))
print "Final misfit:" + str(np.sum( ((d-pred)/uncert)**2. ) )
#%% Write parametric surface
yz = Utils.ndgrid(np.r_[-ncy/2*dx,0,ncy/2*dx],np.r_[mesh.vectorCCz[-1],mesh.vectorCCz[0]])
xout = polynomial.polyval2d(yz[:,0],yz[:,1],np.reshape(mrec[2:],(2,2)))
xyz = np.c_[xout,yz]
# Rotate back to global coordinates
# Create rotation matrix
Rz = np.array([[np.cos(-azm), -np.sin(-azm)],
[np.sin(-azm), np.cos(-azm)]])
temp = Rz.dot( np.vstack([xyz[:,0].T, xyz[:,1].T]) )
if ii == 0:
# Rotate
ROTxyz = np.c_[temp[0,:].T + midx, temp[1,:].T + midy, xyz[:,2]]
else:
ROTxyz = np.vstack([ROTxyz,np.c_[temp[0,:].T + midx, temp[1,:].T + midy, xyz[:,2]]])
#Write out the surface
with file(home_dir + dsep + 'Surf.dat','w') as fid:
np.savetxt(fid, ROTxyz, fmt='%e',delimiter=' ',newline='\n')
#%% Right GOCAD ts file
with file(home_dir + dsep + 'Surf.ts','w') as fid:
fid.write('GOCAD TSurf 1\n')
fid.write('HEADER {name:Mag_Param}\n')
fid.write('TFACE\n')
for ii in range(ROTxyz.shape[0]):
fid.write('VRTX %i %6.2f %6.2f %6.2f\n' %(ii+1, ROTxyz[ii,0],ROTxyz[ii,1],ROTxyz[ii,2]) )
for ii in range(ROTxyz.shape[0]/3):
fid.write('TRGL %i %i %i\n' %(ii+1, ii+2, np.mod(ii+3,6)+1 ))
fid.write('TRGL %i %i %i\n' %(ii+2, np.mod(ii+3,6)+1, np.mod(ii+4,6)+1 ))
fid.write('END\n')