def run_inversion(home, project_name, run_name, fault_name, model_name, GF_list, G_from_file, G_name, epicenter, rupture_speed, num_windows, reg_spatial, reg_temporal, nfaults, beta, decimate, bandpass, solver, bounds, weight=False, Ltype=2, target_moment=None, data_vector=None, weights_file=None, onset_file=None, GOD_inversion=False): ''' Assemble G and d, determine smoothing and run the inversion ''' from mudpy import inverse as inv from mudpy.forward import get_mu_and_area from numpy import zeros, dot, array, squeeze, expand_dims, empty, tile, eye, ones, arange, load, size, genfromtxt from numpy import where, sort, r_, diag from numpy.linalg import lstsq from scipy.linalg import norm from scipy.sparse import csr_matrix as sparse from scipy.optimize import nnls from datetime import datetime import gc from matplotlib import path t1 = datetime.now() #Get data vector if data_vector == None: d = inv.getdata(home, project_name, GF_list, decimate, bandpass=bandpass) else: d = load(data_vector) #Get GFs G = inv.getG(home, project_name, fault_name, model_name, GF_list, G_from_file, G_name, epicenter, rupture_speed, num_windows, decimate, bandpass, onset_file=onset_file) print(G.shape) gc.collect() #Get data weights if weight == True: print('Applying data weights') if weights_file == None: w = inv.get_data_weights(home, project_name, GF_list, d, decimate) else: # Remember weights are "uncertainties" alrger value is less trustworthy w = genfromtxt(weights_file) w = 1 / w #apply data weights wd = w * d.squeeze() #get norm after applying weights and normalize weghted data vector data_norm = norm(wd) wd = wd / data_norm #reshape for inversion wd = expand_dims(wd, axis=1) #Apply weights to left hand side of the equation (the GFs) W = empty(G.shape) #W=tile(w,(G.shape[1],1)).T #why this and not a diagonal matrix??? ANSWER: they have the same effect, don;t rememebr why I chose to do it this way W = diag(w) #Normalization effect W = W / data_norm WG = W.dot(G) #Clear up extraneous variables W = None w = None #Define inversion quantities x = WG.transpose().dot(wd) print('Computing G\'G') K = (WG.T).dot(WG) else: #Define inversion quantities if no weighted x = G.transpose().dot(d) print('Computing G\'G') K = (G.T).dot(G) #Get regularization matrices (set to 0 matrix if not needed) static = False #Is it jsut a static inversion? if size(reg_spatial) > 1: if Ltype == 2: #Laplacian smoothing Ls = inv.getLs(home, project_name, fault_name, nfaults, num_windows, bounds) elif Ltype == 0: #Tikhonov smoothing N = nfaults[0] * nfaults[ 1] * num_windows * 2 #Get total no. of model parameters Ls = eye(N) elif Ltype == 3: #moment regularization N = nfaults[0] * nfaults[ 1] * num_windows * 2 #Get total no. of model parameters Ls = ones((1, N)) #Add rigidity and subfault area mu, area = get_mu_and_area(home, project_name, fault_name, model_name) istrike = arange(0, N, 2) Ls[0, istrike] = area * mu idip = arange(1, N, 2) Ls[0, idip] = area * mu #Modify inversion quantities x = x + Ls.T.dot(target_moment) else: print('ERROR: Unrecognized regularization type requested') return Ninversion = len(reg_spatial) else: Ls = zeros(K.shape) reg_spatial = array([0.]) Ninversion = 1 if size(reg_temporal) > 1: Lt = inv.getLt(home, project_name, fault_name, num_windows) Ninversion = len(reg_temporal) * Ninversion else: Lt = zeros(K.shape) reg_temporal = array([0.]) static = True #Make L's sparse Ls = sparse(Ls) Lt = sparse(Lt) #Get regularization tranposes for ABIC LsLs = Ls.transpose().dot(Ls) LtLt = Lt.transpose().dot(Lt) #inflate Ls = Ls.todense() Lt = Lt.todense() LsLs = LsLs.todense() LtLt = LtLt.todense() #off we go dt = datetime.now() - t1 print('Preprocessing wall time was ' + str(dt)) print('\n--- RUNNING INVERSIONS ---\n') ttotal = datetime.now() kout = 0 for kt in range(len(reg_temporal)): for ks in range(len(reg_spatial)): t1 = datetime.now() lambda_spatial = reg_spatial[ks] lambda_temporal = reg_temporal[kt] print('Running inversion ' + str(kout + 1) + ' of ' + str(Ninversion) + ' at regularization levels: ls =' + repr(lambda_spatial) + ' , lt = ' + repr(lambda_temporal)) if static == True: #Only statics inversion no Lt matrix Kinv = K + (lambda_spatial**2) * LsLs Lt = eye(len(K)) LtLt = Lt.T.dot(Lt) else: #Mixed inversion Kinv = K + (lambda_spatial**2) * LsLs + (lambda_temporal** 2) * LtLt if solver.lower() == 'lstsq': sol, res, rank, s = lstsq(Kinv, x) elif solver.lower() == 'nnls': x = squeeze(x.T) try: sol, res = nnls(Kinv, x) except: print('+++ WARNING: No solution found, writting zeros.') sol = zeros(G.shape[1]) x = expand_dims(x, axis=1) sol = expand_dims(sol, axis=1) else: print('ERROR: Unrecognized solver \'' + solver + '\'') #Force faults outside a polygon to be zero # print('WARNING: Using fault polygon to force solutions to zero') # #load faulkt # fault=genfromtxt(home+project_name+'/data/model_info/'+fault_name) # polygon=genfromtxt('/Users/dmelgarm/Oaxaca2020/etc/zero_fault.txt') # polygon=path.Path(polygon) # i=where(polygon.contains_points(fault[:,1:3])==False)[0] # i=sort(r_[i*2,i*2+1]) # N=nfaults[0]*2 # i=r_[i,i+N,i+2*N,i+3*N] # sol[i]=0 #Compute synthetics ds = dot(G, sol) #Get stats L2, Lmodel = inv.get_stats(Kinv, sol, x, Ls) VR, L2data = inv.get_VR(home, project_name, GF_list, sol, d, ds, decimate, WG, wd) #VR=inv.get_VR(WG,sol,wd) #ABIC=inv.get_ABIC(WG,K,sol,wd,lambda_spatial,lambda_temporal,Ls,LsLs,Lt,LtLt) ABIC = inv.get_ABIC(G, K, sol, d, lambda_spatial, lambda_temporal, Ls, LsLs, Lt, LtLt) #Get moment Mo, Mw = inv.get_moment(home, project_name, fault_name, model_name, sol) #If a rotational offset was applied then reverse it for output to file if beta != 0: sol = inv.rot2ds(sol, beta) #Write log inv.write_log(home, project_name, run_name, kout, rupture_speed, num_windows, lambda_spatial, lambda_temporal, beta, L2, Lmodel, VR, ABIC, Mo, Mw, model_name, fault_name, G_name, GF_list, solver, L2data) #Write output to file if GOD_inversion == True: num = str(kout).rjust(4, '0') np.save( home + project_name + '/output/inverse_models/' + run_name + '.' + num + '.syn.npy', ds) inv.write_synthetics_GOD(home, project_name, run_name, GF_list, ds, kout, decimate) else: inv.write_synthetics(home, project_name, run_name, GF_list, G, sol, ds, kout, decimate) inv.write_model(home, project_name, run_name, fault_name, model_name, rupture_speed, num_windows, epicenter, sol, kout, onset_file=onset_file) kout += 1 dt1 = datetime.now() - t1 dt2 = datetime.now() - ttotal print('... inversion wall time was ' + str(dt1) + ', total wall time elapsed is ' + str(dt2))
def run_inversion(home, project_name, run_name, fault_name, model_name, GF_list, G_from_file, G_name, epicenter, rupture_speed, num_windows, reg_spatial, reg_temporal, nfaults, beta, decimate, bandpass, solver, bounds, weight=False, Ltype=2, target_moment=None, data_vector=None): ''' Assemble G and d, determine smoothing and run the inversion ''' from mudpy import inverse as inv from mudpy.forward import get_mu_and_area from numpy import zeros, dot, array, squeeze, expand_dims, empty, tile, eye, ones, arange, load, size from numpy.linalg import lstsq from scipy.sparse import csr_matrix as sparse from scipy.optimize import nnls from datetime import datetime import gc t1 = datetime.now() #Get data vector if data_vector == None: d = inv.getdata(home, project_name, GF_list, decimate, bandpass=bandpass) else: d = load(data_vector) #Get GFs G = inv.getG(home, project_name, fault_name, model_name, GF_list, G_from_file, G_name, epicenter, rupture_speed, num_windows, decimate, bandpass) gc.collect() #Get data weights if weight == True: print 'Applying data weights' w = inv.get_data_weights(home, project_name, GF_list, d, decimate) W = empty(G.shape) W = tile(w, (G.shape[1], 1)).T WG = empty(G.shape) WG = W * G wd = w * d.squeeze() wd = expand_dims(wd, axis=1) #Clear up extraneous variables W = None w = None #Define inversion quantities x = WG.transpose().dot(wd) print 'Computing G\'G' K = (WG.T).dot(WG) else: #Define inversion quantities if no weightd x = G.transpose().dot(d) print 'Computing G\'G' K = (G.T).dot(G) #Get regularization matrices (set to 0 matrix if not needed) static = False #Is it jsut a static inversion? if size(reg_spatial) > 1: if Ltype == 2: #Laplacian smoothing Ls = inv.getLs(home, project_name, fault_name, nfaults, num_windows, bounds) elif Ltype == 0: #Tikhonov smoothing N = nfaults[0] * nfaults[ 1] * num_windows * 2 #Get total no. of model parameters Ls = eye(N) elif Ltype == 3: #moment regularization N = nfaults[0] * nfaults[ 1] * num_windows * 2 #Get total no. of model parameters Ls = ones((1, N)) #Add rigidity and subfault area mu, area = get_mu_and_area(home, project_name, fault_name, model_name) istrike = arange(0, N, 2) Ls[0, istrike] = area * mu idip = arange(1, N, 2) Ls[0, idip] = area * mu #Modify inversion quantities x = x + Ls.T.dot(target_moment) else: print 'ERROR: Unrecognized regularization type requested' return Ninversion = len(reg_spatial) else: Ls = zeros(K.shape) reg_spatial = array([0.]) Ninversion = 1 if size(reg_temporal) > 1: Lt = inv.getLt(home, project_name, fault_name, num_windows) Ninversion = len(reg_temporal) * Ninversion else: Lt = zeros(K.shape) reg_temporal = array([0.]) static = True #Make L's sparse Ls = sparse(Ls) Lt = sparse(Lt) #Get regularization tranposes for ABIC LsLs = Ls.transpose().dot(Ls) LtLt = Lt.transpose().dot(Lt) #inflate Ls = Ls.todense() Lt = Lt.todense() LsLs = LsLs.todense() LtLt = LtLt.todense() #off we go dt = datetime.now() - t1 print 'Preprocessing wall time was ' + str(dt) print '\n--- RUNNING INVERSIONS ---\n' ttotal = datetime.now() kout = 0 for kt in range(len(reg_temporal)): for ks in range(len(reg_spatial)): t1 = datetime.now() lambda_spatial = reg_spatial[ks] lambda_temporal = reg_temporal[kt] print 'Running inversion ' + str(kout + 1) + ' of ' + str( Ninversion) + ' at regularization levels: ls =' + repr( lambda_spatial) + ' , lt = ' + repr(lambda_temporal) if static == True: #Only statics inversion no Lt matrix Kinv = K + (lambda_spatial**2) * LsLs Lt = eye(len(K)) LtLt = Lt.T.dot(Lt) else: #Mixed inversion Kinv = K + (lambda_spatial**2) * LsLs + (lambda_temporal** 2) * LtLt if solver.lower() == 'lstsq': sol, res, rank, s = lstsq(Kinv, x) elif solver.lower() == 'nnls': x = squeeze(x.T) try: sol, res = nnls(Kinv, x) except: print '+++ WARNING: No solution found, writting zeros.' sol = zeros(G.shape[1]) x = expand_dims(x, axis=1) sol = expand_dims(sol, axis=1) else: print 'ERROR: Unrecognized solver \'' + solver + '\'' #Compute synthetics ds = dot(G, sol) #Get stats L2, Lmodel = inv.get_stats(Kinv, sol, x) VR = inv.get_VR(home, project_name, GF_list, sol, d, ds, decimate) #VR=inv.get_VR(WG,sol,wd) #ABIC=inv.get_ABIC(WG,K,sol,wd,lambda_spatial,lambda_temporal,Ls,LsLs,Lt,LtLt) ABIC = inv.get_ABIC(G, K, sol, d, lambda_spatial, lambda_temporal, Ls, LsLs, Lt, LtLt) #Get moment Mo, Mw = inv.get_moment(home, project_name, fault_name, model_name, sol) #If a rotational offset was applied then reverse it for output to file if beta != 0: sol = inv.rot2ds(sol, beta) #Write log inv.write_log(home, project_name, run_name, kout, rupture_speed, num_windows, lambda_spatial, lambda_temporal, beta, L2, Lmodel, VR, ABIC, Mo, Mw, model_name, fault_name, G_name, GF_list, solver) #Write output to file inv.write_synthetics(home, project_name, run_name, GF_list, G, sol, ds, kout, decimate) inv.write_model(home, project_name, run_name, fault_name, model_name, rupture_speed, num_windows, epicenter, sol, kout) kout += 1 dt1 = datetime.now() - t1 dt2 = datetime.now() - ttotal print '... inversion wall time was ' + str( dt1) + ', total wall time elapsed is ' + str(dt2)
def run_inversion(home,project_name,run_name,fault_name,model_name,GF_list,G_from_file,G_name,epicenter, rupture_speed,num_windows,reg_spatial,reg_temporal,nfaults,beta,decimate,bandpass, solver,bounds,weight=False,Ltype=2,target_moment=None,data_vector=None): ''' Assemble G and d, determine smoothing and run the inversion ''' from mudpy import inverse as inv from mudpy.forward import get_mu_and_area from numpy import zeros,dot,array,squeeze,expand_dims,empty,tile,eye,ones,arange,load from numpy.linalg import lstsq from scipy.sparse import csr_matrix as sparse from scipy.optimize import nnls from datetime import datetime import gc t1=datetime.now() #Get data vector if data_vector==None: d=inv.getdata(home,project_name,GF_list,decimate,bandpass=None) else: d=load(data_vector) #Get GFs G=inv.getG(home,project_name,fault_name,model_name,GF_list,G_from_file,G_name,epicenter, rupture_speed,num_windows,decimate,bandpass) gc.collect() #Get data weights if weight==True: print 'Applying data weights' w=inv.get_data_weights(home,project_name,GF_list,d,decimate) W=empty(G.shape) W=tile(w,(G.shape[1],1)).T WG=empty(G.shape) WG=W*G wd=w*d.squeeze() wd=expand_dims(wd,axis=1) #Clear up extraneous variables W=None w=None #Define inversion quantities x=WG.transpose().dot(wd) print 'Computing G\'G' K=(WG.T).dot(WG) else: #Define inversion quantities if no weightd x=G.transpose().dot(d) print 'Computing G\'G' K=(G.T).dot(G) #Get regularization matrices (set to 0 matrix if not needed) static=False #Is it jsut a static inversion? if reg_spatial!=None: if Ltype==2: #Laplacian smoothing Ls=inv.getLs(home,project_name,fault_name,nfaults,num_windows,bounds) elif Ltype==0: #Tikhonov smoothing N=nfaults[0]*nfaults[1]*num_windows*2 #Get total no. of model parameters Ls=eye(N) elif Ltype==3: #moment regularization N=nfaults[0]*nfaults[1]*num_windows*2 #Get total no. of model parameters Ls=ones((1,N)) #Add rigidity and subfault area mu,area=get_mu_and_area(home,project_name,fault_name,model_name) istrike=arange(0,N,2) Ls[0,istrike]=area*mu idip=arange(1,N,2) Ls[0,idip]=area*mu #Modify inversion quantities x=x+Ls.T.dot(target_moment) else: print 'ERROR: Unrecognized regularization type requested' return Ninversion=len(reg_spatial) else: Ls=zeros(K.shape) reg_spatial=array([0.]) Ninversion=1 if reg_temporal!=None: Lt=inv.getLt(home,project_name,fault_name,num_windows) Ninversion=len(reg_temporal)*Ninversion else: Lt=zeros(K.shape) reg_temporal=array([0.]) static=True #Make L's sparse Ls=sparse(Ls) Lt=sparse(Lt) #Get regularization tranposes for ABIC LsLs=Ls.transpose().dot(Ls) LtLt=Lt.transpose().dot(Lt) #inflate Ls=Ls.todense() Lt=Lt.todense() LsLs=LsLs.todense() LtLt=LtLt.todense() #off we go dt=datetime.now()-t1 print 'Preprocessing wall time was '+str(dt) print '\n--- RUNNING INVERSIONS ---\n' ttotal=datetime.now() kout=0 for kt in range(len(reg_temporal)): for ks in range(len(reg_spatial)): t1=datetime.now() lambda_spatial=reg_spatial[ks] lambda_temporal=reg_temporal[kt] print 'Running inversion '+str(kout+1)+' of '+str(Ninversion)+' at regularization levels: ls ='+repr(lambda_spatial)+' , lt = '+repr(lambda_temporal) if static==True: #Only statics inversion no Lt matrix Kinv=K+(lambda_spatial**2)*LsLs Lt=eye(len(K)) LtLt=Lt.T.dot(Lt) else: #Mixed inversion Kinv=K+(lambda_spatial**2)*LsLs+(lambda_temporal**2)*LtLt if solver.lower()=='lstsq': sol,res,rank,s=lstsq(Kinv,x) elif solver.lower()=='nnls': x=squeeze(x.T) try: sol,res=nnls(Kinv,x) except: print '+++ WARNING: No solution found, writting zeros.' sol=zeros(G.shape[1]) x=expand_dims(x,axis=1) sol=expand_dims(sol,axis=1) else: print 'ERROR: Unrecognized solver \''+solver+'\'' #Compute synthetics ds=dot(G,sol) #Get stats L2,Lmodel=inv.get_stats(Kinv,sol,x) VR=inv.get_VR(home,project_name,GF_list,sol,d,ds,decimate) #VR=inv.get_VR(WG,sol,wd) #ABIC=inv.get_ABIC(WG,K,sol,wd,lambda_spatial,lambda_temporal,Ls,LsLs,Lt,LtLt) ABIC=inv.get_ABIC(G,K,sol,d,lambda_spatial,lambda_temporal,Ls,LsLs,Lt,LtLt) #Get moment Mo,Mw=inv.get_moment(home,project_name,fault_name,model_name,sol) #If a rotational offset was applied then reverse it for output to file if beta !=0: sol=inv.rot2ds(sol,beta) #Write log inv.write_log(home,project_name,run_name,kout,rupture_speed,num_windows,lambda_spatial,lambda_temporal,beta, L2,Lmodel,VR,ABIC,Mo,Mw,model_name,fault_name,G_name,GF_list,solver) #Write output to file inv.write_synthetics(home,project_name,run_name,GF_list,G,sol,ds,kout,decimate) inv.write_model(home,project_name,run_name,fault_name,model_name,rupture_speed,num_windows,epicenter,sol,kout) kout+=1 dt1=datetime.now()-t1 dt2=datetime.now()-ttotal print '... inversion wall time was '+str(dt1)+', total wall time elapsed is '+str(dt2)