def clip_modem_model(model_fn, clip): """ Read in ModEM model and clip to a smaller box """ m_obj = modem.Model() m_obj.read_model_file(model_fn) ### --> need to convert model coordinates into lat and lon utm_center = gis_tools.project_point_ll2utm(model_center[1], model_center[0]) lat = np.zeros_like(m_obj.grid_north[clip:-(clip + 1)]) lon = np.zeros_like(m_obj.grid_east[clip:-(clip + 1)]) depth = m_obj.grid_z[:-1] / 1000.0 for ii, north in enumerate(m_obj.grid_north[clip:-(clip + 1)]): m_lat, m_lon = gis_tools.project_point_utm2ll(utm_center[0], utm_center[1] + north, utm_center[2]) lat[ii] = m_lat for ii, east in enumerate(m_obj.grid_east[clip:-(clip + 1)]): m_lat, m_lon = gis_tools.project_point_utm2ll(utm_center[0] + east, utm_center[1], utm_center[2]) lon[ii] = m_lon res = np.log10(m_obj.res_model[clip:-clip, clip:-clip, :]) return lat, lon, depth, res
def interpolate_grid(self, pad_east=None, pad_north=None, cell_size=None): """ interpolate the irregular model grid onto a regular grid. """ model_obj = modem.Model() model_obj.model_fn = self.model_fn model_obj.read_model_file() self.grid_z = model_obj.grid_z.copy() if cell_size is not None: self.cell_size_east = cell_size self.cell_size_north = cell_size else: self.cell_size_east = np.median(model_obj.nodes_east) self.cell_size_north = np.median(model_obj.nodes_north) if pad_east is not None: self.pad_east = pad_east if self.pad_east is None: self.pad_east = np.where( model_obj.nodes_east[0:25] > self.cell_size_east * 1.1)[0][-1] if pad_north is not None: self.pad_north = pad_north if self.pad_north is None: self.pad_north = np.where( model_obj.nodes_north[0:25] > self.cell_size_north * 1.1)[0][-1] print 'Pad north = {0}'.format(self.pad_north) print 'Pad east = {0}'.format(self.pad_east) new_east = np.arange(model_obj.grid_east[self.pad_east], model_obj.grid_east[-self.pad_east - 2], self.cell_size_east) new_north = np.arange(model_obj.grid_north[self.pad_north], model_obj.grid_north[-self.pad_north - 2], self.cell_size_north) # needs to be -1 because the grid is n+1 as it is the edges of the # the nodes. Might need to change this in the future model_n, model_e = np.broadcast_arrays(model_obj.grid_north[:-1, None], model_obj.grid_east[None, :-1]) new_res_arr = np.zeros( (new_north.size, new_east.size, model_obj.nodes_z.size)) for z_index in range(model_obj.grid_z.shape[0] - 1): res = model_obj.res_model[:, :, z_index] new_res_arr[:, :, z_index] = interpolate.griddata( (model_n.ravel(), model_e.ravel()), res.ravel(), (new_north[:, None], new_east[None, :])) self.res_array = new_res_arr
def __init__(self): super(MeshWidget, self).__init__() self.model_obj = modem.Model() self.mpl_widget = MeshPlot() #sys.stdout = MyStream() self.setup_ui()
def get_model_fn(self): """ read in an existing model file """ fn_dialog = QtGui.QFileDialog() fn = str(fn_dialog.getOpenFileName(caption='Choose ModEM model file', filter='*.rho')) self.model_obj = modem.Model() self.model_obj.read_model_file(fn) self.dir_path = os.path.dirname(fn)
def load_edi_files(self): fn_list = QtGui.QFileDialog().getOpenFileNames( caption='Choose EDI Files', filter='*.edi') self.edi_list = [] for fn in fn_list: self.edi_list.append(str(fn)) self.model_obj = modem.Model(edi_list=self.edi_list) self.model_obj.get_station_locations() self.mpl_widget.plot_mesh(self.model_obj)
def __init__(self, model_fn, data_fn): ''' Class for extracting field values at arbitrary locations from a 3D MODEM model. The model-mesh is centered on the centre-point of station-locations. :param model_fn: name of model file :param data_fn: name of data file ''' # Read data and model files self._model_fn = model_fn self._data_fn = data_fn try: self._d = modem.Data() self._d.read_data_file(data_fn=self._data_fn) except Exception as err: print 'Failed to read %s' % (self._data_fn) logging.error(traceback.format_exc()) exit(-1) try: self._m = modem.Model(model_fn=self._model_fn, station_object=self._d.station_locations) self._m.read_model_file() except Exception as err: print 'Failed to read %s' % (self._model_fn) logging.error(traceback.format_exc()) exit(-1) # Re-orient model coordinates based on the centre of data locations self._mx = self._m.grid_east + self._d.center_point['east'] self._my = self._m.grid_north + self._d.center_point['north'] self._mz = self._m.grid_z # Compute cell-centre coordinates self._mcx = (self._mx[1:] + self._mx[:-1]) / 2. self._mcy = (self._my[1:] + self._my[:-1]) / 2. self._mcz = (self._mz[1:] + self._mz[:-1]) / 2. # Create mesh-grid based on cell-centre coordinates self._mgx, self._mgy, self._mgz = np.meshgrid(self._mcx, self._mcy, self._mcz) # List of xyz coodinates of mesh-grid self._mgxyz = np.vstack( [self._mgx.flatten(), self._mgy.flatten(), self._mgz.flatten()]).T # Create Kd-Tree based on mesh-grid coordinates self._tree = cKDTree(self._mgxyz)
def make_vtk_files(self): if self.model_type == 'ModEM': m_obj = modem.Model() m_obj.read_model_file(os.path.join(self.cwd, self.model_fn)) m_obj.write_vtk_file(vtk_save_path=self.cwd, vtk_fn_basename=self.vtk_model_fn) d_obj = modem.Data() d_obj.read_data_file(self.resp_fn) d_obj.write_vtk_station_file(vtk_save_path=self.cwd, vtk_fn_basename=self.vtk_station_fn) program = 'modem2vtk' elif self.model_type == 'WS': program = 'ws2vtk' subprocess.call([ program, self.model_fn, self.resp_fn, self.vtk_model_fn, self.vtk_station_fn ])
def _get_model(self): """ get model to put into array """ model_obj = modem.Model() model_obj.model_fn = self.model_fn model_obj.read_model_file() self.cell_size_east = np.median(model_obj.nodes_east) self.cell_size_north = np.median(model_obj.nodes_north) self.pad_east = np.where( model_obj.nodes_east[0:10] > self.cell_size_east * 1.1)[0][-1] self.pad_north = np.where( model_obj.nodes_north[0:10] > self.cell_size_north * 1.1)[0][-1] self.grid_z = model_obj.grid_z.copy() self.res_array = model_obj.res_model[self.pad_north:-self.pad_north, self.pad_east:-self.pad_east, :]
def get_model_lower_left_coord(self, model_fn=None, model_center=None, pad_east=0, pad_north=0): """ Find the models lower left hand corner in (lon, lat) decimal degrees """ if model_fn is not None: self.model_fn = model_fn if self.model_fn is None: raise IOError('Need to input a ModEM model file name to read in') self.pad_east = pad_east self.pad_north = pad_north model_obj = modem.Model() model_obj.model_fn = self.model_fn model_obj.read_model_file() if model_center: center_zone, center_east, center_north = gis_tools.project_point_ll2utm( model_center[1], model_center[0]) lower_left_east = center_east+model_obj.grid_center[1]+\ model_obj.nodes_east[0:pad_east].sum()-\ model_obj.nodes_east[pad_east]/2 lower_left_north = center_north+model_obj.grid_center[1]+\ model_obj.nodes_north[0:pad_north].sum()+\ model_obj.nodes_north[pad_north]/2 ll_lat, ll_lon = gis_tools.project_point_utm2ll( lower_left_north, lower_left_east, center_zone) print 'Lower Left Coordinates should be ({0:.5f}, {1:.5f})'.format( ll_lon, ll_lat) return (ll_lon, ll_lat) else: raise IOError('Need to input model center (lon, lat)')
data_obj = modem.Data(edi_list=inv_edi_list, period_list=inv_period_list) data_obj.error_type_z = 'eigen_floor' data_obj.error_type_tipper = 'absolute_floor' data_obj.error_value_z = 3.0 data_obj.error_value_tipper = .02 #--> here is where you can rotate the data data_obj.write_data_file( save_path=save_path, fn_basename="shz_modem_data_err{0:02.0f}_tip{1:02.0f}.dat".format( data_obj.error_value_z, data_obj.error_value_tipper)) #============================================================================== # First make the mesh #============================================================================== mod_obj = modem.Model(station_object=data_obj.station_locations) mod_obj.cell_size_east = 400 mod_obj.cell_size_north = 400 mod_obj.pad_east = 8 mod_obj.pad_north = 8 mod_obj.pad_method = 'extent1' mod_obj.pad_stretch_h = 1.8 mod_obj.pad_z = 5 mod_obj.n_layers = 50 mod_obj.z1_layer = 10 mod_obj.z_target_depth = 30000. #--> here is where you can rotate the mesh mod_obj.mesh_rotation_angle = 0 mod_obj.make_mesh()
#mont_model_center = (583337., 1849383.+1400.) pad = 5 dem_cell_size = 200. bathym_cell_size = 900 res_air = 1e12 elev_cell = 30 #starting model resistivity sm_res = 100 ##============================================================================== ## Do all the work ##============================================================================== m_obj = modem.Model() m_obj.read_model_file(model_fn) d_obj = modem.Data() d_obj.read_data_file(data_fn) mont_model_center = (d_obj.center_point.east + 1200, d_obj.center_point.north + 2900) m_obj.add_topography_to_model(dem_fn, model_center=mont_model_center, cell_size=dem_cell_size, elev_cell=30) #### 1.) read in the dem and center it onto the resistivity model #e_east, e_north, elevation = modem.read_dem_ascii(dem_fn, cell_size=dem_cell_size, # model_center=mont_model_center,
#--> here is where you can rotate the data data_obj.write_data_file(save_path=save_path, fn_basename="{1}_modem_data_err{0:02.0f}_tip{2:02.0f}.dat".format(data_obj.error_value_z, fn_stem, data_obj.error_value_tipper*100), elevation=True, fill=True, compute_error=True) #============================================================================== # Write model file #============================================================================== mod_obj = modem.Model(data_obj.station_locations) mod_obj.cell_size_east = 150 mod_obj.cell_size_north = 150 mod_obj.ew_ext = 300000 mod_obj.ns_ext = 300000 mod_obj.pad_east = 10 mod_obj.pad_north = 10 mod_obj.z1_layer = 30 mod_obj.z_target_depth = 25000 mod_obj.z_bottom = 300000 mod_obj.n_layers = 40 mod_obj.make_mesh() mod_obj.plot_mesh() mod_obj.write_model_file(save_path=save_path,
def interpolate_model_grid(old_model_fn, new_model_fn, save_path=None, new_fn_basename=None, pad=3, nan_rho=100, shift_east=0, shift_north=0): """ interpolate an old model onto a new model Arguments ------------------ **old_model_fn** : string full path to the old model file, or the file that contains the original model that will be interpolated onto a new grid, new_model_fn **new_model_fn** : string full path to the new model file to interpolate old_model_fn on to. **save_path** : string directory path to save new interpolated model file *default* is os.path.dirname(new_model_fn) **new_fn_basename** : string filename given to the new interpolated model *default* is os.path.basename(new_model_fn+'interp') **pad** : int number of cells which to pad outer values of the grid. Say new_model_fn is larger than old_model_fn, then there will be Nan where the model don't match up, pad will extend values from the given number of cells from the edge of new_model_fn. **nan_rho** : float if there are Nan in the new_model, they will be given this value. *default* is 100 Ohm-m **shift_east** : float shift east of new_model grid relative to the old model grid in meters. *Default* is 0 **shift_north** : float shift north of new_model grid relative to the old model grid in meters. *Default* is 0 """ print 'Interpolating {0} into {1}'.format(old_model_fn, new_model_fn) # check to see if the old model is modem or ws if old_model_fn[-4:] == '.rho': old_mod = modem.Model() old_mod.read_model_file(old_model_fn) else: old_mod = ws.WSModel(old_model_fn) old_mod.read_model_file() # check to see if the new model is modem or ws if new_model_fn[-4:] == '.rho': new_mod = modem.Model() new_mod.read_model_file(new_model_fn) new_ext = '.rho' new_fn_type = 'modem' else: try: new_mod = ws.WSModel(new_model_fn) new_mod.read_model_file() except ValueError: new_mod = ws.WSMesh() new_mod.read_initial_file(new_model_fn) new_ext = '' new_fn_type = 'ws' if save_path is None: save_path = os.path.dirname(new_model_fn) if new_fn_basename is None: fn = os.path.basename(new_model_fn) ext_find = fn.find('.') if ext_find == -1: ext_find = len(fn) - 1 new_fn_basename = '{0}_interp{1}'.format(fn[0:ext_find], new_ext) print 'Start Time = {0}'.format(time.ctime()) # make a grid of old model old_north, old_east = np.broadcast_arrays(old_mod.grid_north[:-1, None], old_mod.grid_east[None, :-1]) #2) do a 2D interpolation for each layer, much faster # make a new array of zeros to put values with shape of new model new_res = np.zeros((new_mod.nodes_north.shape[0], new_mod.nodes_east.shape[0], new_mod.nodes_z.shape[0])) for zz in range(new_mod.nodes_z.shape[0]): try: old_zz = np.where(old_mod.grid_z >= new_mod.grid_z[zz])[0][0] if old_zz >= old_mod.nodes_z.size - 1: old_zz = old_mod.nodes_z.size - 1 except IndexError: old_zz = -1 print 'New depth={0:.2f}; old depth={1:.2f}'.format( new_mod.grid_z[zz], old_mod.grid_z[old_zz]) new_res[:, :, zz] = spi.griddata( (old_north.ravel(), old_east.ravel()), old_mod.res_model[:, :, old_zz].ravel(), (new_mod.grid_north[:-1, None] + shift_north, new_mod.grid_east[None, :-1] + shift_east), method='linear') new_res[0:pad, pad:-pad, zz] = new_res[pad, pad:-pad, zz] new_res[-pad:, pad:-pad, zz] = new_res[-pad - 1, pad:-pad, zz] new_res[:, 0:pad, zz] = new_res[:, pad, zz].repeat(pad).reshape(new_res[:, 0:pad, zz].shape) new_res[:, -pad:, zz] = new_res[:, -pad - 1, zz].repeat(pad).reshape(new_res[:, -pad:, zz].shape) # new_res[np.where(np.nan_to_num(new_res) == 0.0)] = 100.0 if new_fn_type == 'modem': new_mod.write_model_file(save_path=save_path, model_fn_basename=new_fn_basename, res_model=new_res) else: nfid = file(os.path.join(save_path, new_fn_basename), 'w') nfid.write('# interpolated starting model for ws written by mtpy\n') nfid.write('{0} {1} {2} {3}\n'.format(new_mod.nodes_north.shape[0], new_mod.nodes_east.shape[0], new_mod.nodes_z.shape[0], 0)) # write S--> N block for ii, n_node in enumerate(new_mod.nodes_north): nfid.write('{0:>12.1f}'.format(abs(n_node))) if ii != 0 and np.remainder(ii + 1, 5) == 0: nfid.write('\n') elif ii == new_mod.nodes_north.shape[0] - 1: nfid.write('\n') # write W--> E block for jj, e_node in enumerate(new_mod.nodes_east): nfid.write('{0:>12.1f}'.format(abs(e_node))) if jj != 0 and np.remainder(jj + 1, 5) == 0: nfid.write('\n') elif jj == new_mod.nodes_east.shape[0] - 1: nfid.write('\n') # write top--> bottom block for kk, z_node in enumerate(new_mod.nodes_z): nfid.write('{0:>12.1f}'.format(abs(z_node))) if kk != 0 and np.remainder(kk + 1, 5) == 0: nfid.write('\n') elif kk == new_mod.nodes_z.shape[0] - 1: nfid.write('\n') for kk in range(new_mod.nodes_z.shape[0]): for jj in range(new_mod.nodes_east.shape[0]): for ii in range(new_mod.nodes_north.shape[0]): nfid.write('{0:.4e}\n'.format( new_res[(new_mod.nodes_north.shape[0] - 1) - ii, jj, kk])) nfid.close() print 'Wrote file to {0}'.format( os.path.join(save_path, new_fn_basename)) # new_mesh = ws.WSMesh() # new_mesh.write_initial_file(nodes_north=new_mod.nodes_north, # nodes_east=new_mod.nodes_east, # nodes_z=new_mod.nodes_z,/home/jpeacock/Documents/ModEM/LV/geo_err12/lv_geo_err03_cov5_NLCG_065.res # res_model=new_res, # save_path=save_path) print 'End Time = {0}'.format(time.ctime()) return os.path.join(save_path, new_fn_basename)
# mfn = r"c:\Users\jpeacock\OneDrive - DOI\Geothermal\GreatBasin\modem_inv\canv_01\canv_t03_c04_084.rho" mfn = r"c:\Users\jpeacock\OneDrive - DOI\Geothermal\GreatBasin\modem_inv\canv_01\canv_z10_c06_150.rho" # mfn = r"c:\Users\jpeacock\OneDrive - DOI\Geothermal\Umatilla\modem_inv\inv_06\um_z05_c03_083.rho" # model_center = (-118.704435 + .03, 45.597757000000001 + .02) model_center = (-119.015192, 38.615252) lower_left = (-124.2937861, 32.5799747) z_dict = { "surface": np.array((0, 5000)), "middle_crust": np.array((12000, 17000)), "lower_crust": np.array((17000, 35000)), } pad = 10 m = modem.Model() m.read_model_file(mfn) gx, gy = np.meshgrid(m.grid_east, m.grid_north) fig = plt.figure(1) fig.clf() for ii, key in enumerate(["surface", "middle_crust", "lower_crust"]): z = z_dict[key] index_min = np.where(m.grid_z <= z.min())[0][-1] index_max = np.where(m.grid_z >= z.max())[0][0] conductance = (1.0 / m.res_model[:, :, index_min:index_max]) * abs( m.grid_z[index_min:index_max]) conductance = np.log10(conductance.sum(axis=2))
#mb_model_fn = r"/home/jpeacock/Documents/ModEM/MB_MT/WS_StartingModel_03_tipper/cov3_mb_tipper_NLCG_028.rho" #mb_model_fn = r"c:\Users\jpeacock\Documents\MonoBasin\cov3_mb_tipper_NLCG_028.rho" #grid already made, use it to combine the models comb_model_fn = r"c:\Users\jpeacock\Documents\MonoBasin\modem_inv\inv_02\ml_sm02_lake.rho" #locate model centers (E, N) #mb_center = (327150., 4194900.) # lv_center old lv_center = (336800, 4167525) lv_center = (331534., 4179614.) #comb_center = (331515+5285, 4179690) # big center comb_center = (328520., 4201968.) #--> read in the model files lv_mod = modem.Model() lv_mod.read_model_file(lv_model_fn) #mb_mod = modem.Model() #mb_mod.read_model_file(mb_model_fn) comb_mod = modem.Model() comb_mod.read_model_file(comb_model_fn) #--> interpolate each grid onto the combined grid #mb_res = interp_grid(mb_mod, # comb_mod, # shift_east=-comb_center[0]+mb_center[0], # shift_north=-comb_center[1]+mb_center[1], # pad=1, # dim='2d',
#2) next interpolate ont the new mesh (3D interpolation, slow) new_res = spi.griddata((north.ravel(), east.ravel(), vert.ravel()), old_model_obj.res_model.ravel(), (new_model_obj.plot_north[:, None, None], new_model_obj.plot_east[None, :, None], new_model_obj.plot_z[None, None, :]), method='linear') print 'Shape of new res = {0}'.format(new_res.shape) return new_res # ============================================================================= # Shift modem grid # ============================================================================= mfn = r"c:\Users\jpeacock\Documents\Geysers\gz_sm50_topo_ocean.rho" m1_obj = modem.Model() m1_obj.read_model_file(mfn) m2_obj = modem.Model() m2_obj.read_model_file(mfn) m2_obj.res_model = interp_grid(m1_obj, m2_obj, shift_east=600) m2_obj.res_model[np.where(m1_obj.res_model < 49)] = m1_obj.res_model[np.where(m1_obj.res_model < 49)] m2_obj.write_model_file(model_fn_basename=r"gz_sm50_topo_ocean_shifted.rho") m2_obj.write_vtk_file(vtk_fn_basename='gz_sm_shifted_res') ### write new covariance file cov = modem.Covariance(grid_dimensions=m2_obj.res_model.shape) cov.write_covariance_file(save_path=m2_obj.save_path, model_fn=m2_obj.model_fn)
# ============================================================================== # interpolate all models onto the same grid # ============================================================================== dfn = r"/home/jpeacock/Documents/ModEM/LV/hs1000_no_tipper/lv_dp_23p_no_tipper.dat" mfn_no_tipper = ( r"/home/jpeacock/Documents/ModEM/LV/hs1000_no_tipper/hs1000_no_tipper_NLCG_070.rho" ) mfn_tipper = ( r"/home/jpeacock/Documents/ModEM/LV/hs1000_tipper/hs1000_tipper_NLCG_042.rho" ) modem_data = modem.Data() modem_data.read_data_file(dfn) modem_nt = modem.Model() modem_nt.read_model_file(mfn_no_tipper) modem_tip = modem.Model() modem_tip.read_model_file(mfn_tipper) # --> average all as a geometric mean avg_res = (modem_nt.res_model * modem_tip.res_model)**(1.0 / 2) # avg_res = (nr_ws_hs1*nr_ws_sm1*nr_ws_sm2*nr_nt*nr_tip)**(1./5) x, y = np.meshgrid(modem_tip.grid_east, modem_tip.grid_north) kk = 30 kwargs = {"cmap": "jet_r", "vmin": -1, "vmax": 4} fig = plt.figure(4) ax1 = fig.add_subplot(1, 3, 1, aspect="equal")
print "Shape of new res = {0}".format(new_res.shape) return new_res # ============================================================================== # interpolate all models onto the same grid # ============================================================================== dfn = r"C:\Users\jpeacock\Documents\iMush\modem_inv\shz_inv_02\shz_modem_data_err03_tip02_edit.dat" mfn_imush = r"c:\Users\jpeacock\Documents\iMush\modem_inv\paul_final_model\Z4T3_cov0p2x2_L1E2_NLCG_061.rho" mfn_shz = r"c:\Users\jpeacock\Documents\iMush\modem_inv\shz_inv_02\shz_smt_z04_t03_c02_NLCG_070.rho" modem_data = modem.Data() modem_data.read_data_file(dfn) modem_imush = modem.Model() modem_imush.read_model_file(mfn_imush) modem_shz = modem.Model() modem_shz.read_model_file(mfn_shz) imush_center = (46.450149, -122.032858) shz_center = (46.310461, -122.194629) imush_east, imush_north, zone = gis_tools.project_point_ll2utm( imush_center[0], imush_center[1] ) shz_east, shz_north, zone = gis_tools.project_point_ll2utm(shz_center[0], shz_center[1]) d_east = imush_east - shz_east + 8500 d_north = imush_north - shz_north + 8000