def _read_model_data(self): """ read in the files to get appropriate information """ # --> read in model file if self.model_fn is not None and os.path.isfile(self.model_fn): md_model = Model() md_model.read_model_file(self.model_fn) self.res_model = md_model.res_model self.grid_east = md_model.grid_east / self.dscale self.grid_north = md_model.grid_north / self.dscale self.grid_z = md_model.grid_z / self.dscale self.nodes_east = md_model.nodes_east / self.dscale self.nodes_north = md_model.nodes_north / self.dscale self.nodes_z = md_model.nodes_z / self.dscale else: raise Exception('Error with the Model file: %s. Please check.' % (self.model_fn)) # --> Optionally: read in data file to get station locations if self.data_fn is not None and os.path.isfile(self.data_fn): md_data = Data() md_data.read_data_file(self.data_fn) self.station_east = md_data.station_locations[ 'rel_east'] / self.dscale # convert meters self.station_north = md_data.station_locations[ 'rel_north'] / self.dscale self.station_names = md_data.station_locations['station'] else: print(('Problem with the optional Data file: %s. Please check.' % self.data_fn)) total_horizontal_slices = self.grid_z.shape[0] print(("Total Number of H-slices=", total_horizontal_slices)) return total_horizontal_slices
def read_files(self): """ read in the files to get appropriate information """ # --> read in model file if self.model_fn is not None: if os.path.isfile(self.model_fn) == True: md_model = Model() md_model.read_model_file(self.model_fn) self.res_model = md_model.res_model self.grid_east = md_model.grid_east / self.dscale self.grid_north = md_model.grid_north / self.dscale self.grid_z = md_model.grid_z / self.dscale self.nodes_east = md_model.nodes_east / self.dscale self.nodes_north = md_model.nodes_north / self.dscale self.nodes_z = md_model.nodes_z / self.dscale else: raise mtex.MTpyError_file_handling( '{0} does not exist, check path'.format(self.model_fn)) # --> read in data file to get station locations if self.data_fn is not None: if os.path.isfile(self.data_fn) == True: md_data = Data() md_data.read_data_file(self.data_fn) self.station_east = md_data.station_locations.rel_east / self.dscale self.station_north = md_data.station_locations.rel_north / self.dscale self.station_elev = md_data.station_locations.elev / self.dscale self.station_names = md_data.station_locations.station else: print 'Could not find data file {0}'.format(self.data_fn)
def test_read_gocad_sgrid_file(self): if not os.path.isdir(self._model_dir): self._model_dir = None output_fn = os.path.basename(self._model_fn) # read data file to get centre position dObj = Data() dObj.read_data_file(data_fn=self._data_fn) # create a model object using the data object and read in gocad sgrid file mObj = Model(data_obj=dObj, save_path=self._output_dir) mObj.read_gocad_sgrid_file(self._sgrid_fn) mObj.write_model_file() output_data_file = os.path.normpath( os.path.join(self._output_dir, output_fn)) self.assertTrue(os.path.isfile(output_data_file), "output data file not found") expected_data_file = os.path.normpath(self._model_fn_old_z_mesh) self.assertTrue( os.path.isfile(expected_data_file), "Ref output data file does not exist, nothing to compare with") is_identical, msg = diff_files(output_data_file, expected_data_file) print(msg) self.assertTrue( is_identical, "The output file is not the same with the baseline file.")
def main(data_file, model_file, output_file, source_proj=None): """ Generate an output netcdf file from data_file and model_file :param data_file: modem.dat :param model_file: modem.rho :param output_file: output.nc :param source_proj: None by defult. The UTM zone infered from the input non-uniform grid parameters :return: """ # Define Data and Model Paths data = Data() data.read_data_file(data_fn=data_file) # create a model object using the data object and read in model data model = Model(data_obj=data) model.read_model_file(model_fn=model_file) center = data.center_point if source_proj is None: zone_number, is_northern, utm_zone = gis_tools.get_utm_zone( center.lat.item(), center.lon.item()) #source_proj = Proj('+proj=utm +zone=%d +%s +datum=%s' % (zone_number, 'north' if is_northern else 'south', 'WGS84')) epsg_code = gis_tools.get_epsg(center.lat.item(), center.lon.item()) print("Input data epsg code is infered as ", epsg_code) else: epsg_code = source_proj # integer source_proj = Proj(init='epsg:' + str(epsg_code)) resistivity_data = { 'x': center.east.item() + (model.grid_east[1:] + model.grid_east[:-1]) / 2, 'y': center.north.item() + (model.grid_north[1:] + model.grid_north[:-1]) / 2, 'z': (model.grid_z[1:] + model.grid_z[:-1]) / 2, 'resistivity': np.transpose(model.res_model, axes=(2, 0, 1)) } grid_proj = Proj( init='epsg:4326') # output grid Coordinate systems: 4326, 4283, 3112 grid_proj = Proj( init='epsg:4283') # output grid Coordinate system 4326, 4283, 3112 grid_proj = Proj( init='epsg:3112') # output grid Coordinate system 4326, 4283, 3112 result = interpolate(resistivity_data, source_proj, grid_proj, center, median_spacing(model.grid_east), median_spacing(model.grid_north)) nc.write_resistivity_grid(output_file, grid_proj, result['latitude'], result['longitude'], result['depth'], result['resistivity'], z_label='depth')
def test_make_z_mesh_new(self): z1_layer = 10 z_target_depth = 5000 n_layers = 30 n_airlayers = 10 pad_z = 4 pad_stretch_v = 1.4 mObj = Model(z1_layer=z1_layer, z_target_depth=z_target_depth, n_layers=n_layers, n_air_layers=n_airlayers, pad_z=pad_z, pad_stretch_v=pad_stretch_v) z_nodes, z_grid = mObj.make_z_mesh_new() expected_air_layers = [ 10., 10., 10., 20., 20., 20., 30., 30., 40., 50. ] self.assertTrue(np.all(z_nodes[:n_airlayers] == expected_air_layers)) expected_air_layers = [ 0., 10., 20., 30., 50., 70., 90., 120., 150., 190., 240. ] self.assertTrue(np.all(z_grid[:n_airlayers + 1] == expected_air_layers)) # check core model part testnodes10_5000_16 = [ 60., 70., 80., 100., 100., 100., 200., 200., 200., 300., 300., 400., 500., 600., 700., 800. ] testgrid10_5000_16 = [ 240., 300., 370., 450., 550., 650., 750., 950., 1150., 1350., 1650., 1950., 2350., 2850., 3450., 4150., 4950. ] self.assertTrue( np.all(z_nodes[n_airlayers:-pad_z] == testnodes10_5000_16)) self.assertTrue( np.all(z_grid[n_airlayers:-pad_z] == testgrid10_5000_16)) # check padding part testnodespad = np.around( testnodes10_5000_16[-1] * (pad_stretch_v**np.arange(1, pad_z + 1)), -2) testgridpad = np.array( [testnodespad[:i].sum() for i in range(1, pad_z + 1)]) + testgrid10_5000_16[-1] self.assertTrue(np.all(z_nodes[-pad_z:] == testnodespad)) self.assertTrue(np.all(z_grid[-pad_z:] == testgridpad))
def _test_func(self): if not os.path.isdir(edi_path): # input file does not exist, skip test after remove the output dir os.rmdir(self._output_dir) self.skipTest("edi path does not exist: {}".format(edi_path)) # generate data edi_list = glob.glob(edi_path + '/*.edi') period_list = EdiCollection(edi_list).select_periods() datob = Data(edi_list=edi_list, inv_mode='1', period_list=period_list, epsg=epsg_code, error_type_tipper='abs', error_type_z='egbert', comp_error_type=None, error_floor=10) datob.write_data_file(save_path=self._output_dir) # create mesh grid model object model = Model( stations_object=datob.station_locations, Data=datob, epsg=epsg_code, cell_size_east=10000, cell_size_north=10000, # GA_VIC pad_north= 8, # number of padding cells in each of the north and south directions pad_east=8, # number of east and west padding cells pad_z=8, # number of vertical padding cells pad_stretch_v= 1.5, # factor to increase by in padding cells (vertical) pad_stretch_h= 1.5, # factor to increase by in padding cells (horizontal) n_air_layers= 0, # number of air layers 0, 10, 20, depend on topo elev height res_model= 100, # halfspace resistivity value for initial reference model n_layers=50, # total number of z layers, including air and pad_z z1_layer=50, # first layer thickness metres, depend z_target_depth=500000) model.make_mesh( ) # the data file will be re-write in this method. No topo elev file used yet model.plot_mesh() model.plot_mesh_xy() model.plot_mesh_xz() # write a model file and initialise a resistivity model model.write_model_file(save_path=self._output_dir)
def test_make_z_mesh_new(self): z1_layer = 10 z_target_depth = 5000 n_layers = 30 n_airlayers = 10 pad_z = 4 pad_stretch_v = 1.4 mObj = Model(z1_layer=z1_layer, z_target_depth=z_target_depth, n_layers=n_layers, n_air_layers=n_airlayers, pad_z=pad_z, pad_stretch_v=pad_stretch_v) z_nodes, z_grid = mObj.make_z_mesh_new() # check air layer part self.assertTrue( np.all(z_nodes[:n_airlayers] == np.ones(n_airlayers) * z1_layer)) self.assertTrue( np.all(z_grid[:n_airlayers + 1] == np.linspace(0, n_airlayers * z1_layer, n_airlayers + 1))) # check core model part testnodes10_5000_16 = np.array([ 10., 10., 20., 30., 40., 50., 70., 100., 100., 200., 300., 400., 500., 700., 1000., 1400. ]) testgrid10_5000_16 = np.array([ testnodes10_5000_16[:i].sum() for i in range(len(testnodes10_5000_16) + 1) ]) + n_airlayers * z1_layer self.assertTrue( np.all(z_nodes[n_airlayers:-pad_z] == testnodes10_5000_16)) self.assertTrue( np.all(z_grid[n_airlayers:-pad_z] == testgrid10_5000_16)) # check padding part testnodespad = np.around( testnodes10_5000_16[-1] * (pad_stretch_v**np.arange(1, pad_z + 1)), -2) testgridpad = np.array( [testnodespad[:i].sum() for i in range(1, pad_z + 1)]) + testgrid10_5000_16[-1] self.assertTrue(np.all(z_nodes[-pad_z:] == testnodespad)) self.assertTrue(np.all(z_grid[-pad_z:] == testgridpad))
def list_depths(model_file, zpad=None): """ Return a list of available depth slices in the model. Args: model_file (str): Path to ModEM .rho file. zpad (int, optional): Number of padding slices to remove from bottom of model. If None, model pad_z value is used. Returns: list of float: A list of available depth slices. """ model = Model() model.read_model_file(model_fn=model_file) cz = _get_centers(model.grid_z) zpad = model.pad_z if zpad is None else zpad return cz[:-zpad]
def _read_model_data(self): self.datObj = Data() self.datObj.read_data_file(data_fn=self.datfile) self.modObj = Model(model_fn=self.rhofile) self.modObj.read_model_file() self.ew_lim = (self.modObj.grid_east[self.modObj.pad_east], self.modObj.grid_east[-self.modObj.pad_east - 1]) self.ns_lim = (self.modObj.grid_north[self.modObj.pad_north], self.modObj.grid_north[-self.modObj.pad_north - 1]) # logger.debug("ns-limit %s", self.ns_lim) # logger.debug("ew-limit %s", self.ew_lim) # logger.info("station name list %s", self.datObj.station_locations['station']) # logger.info("station Lat list %s", self.datObj.station_locations['lat']) return
def test_write_gocad_sgrid_file(self): if not os.path.exists(self._sgrid_fn): self._sgrid_fn = None output_fn = os.path.basename(self._sgrid_fn) # read data file to get centre position dObj = Data() dObj.read_data_file(data_fn=self._data_fn) # get centre coordinates centre = np.array([0., 0., 0.]) centre[0] = dObj.center_point['east'] centre[1] = dObj.center_point['north'] # create a model object using the data object and read in gocad sgrid file mObj = Model(data_obj=dObj) mObj.read_model_file(model_fn=self._model_fn) mObj.save_path = self._output_dir mObj.write_gocad_sgrid_file(origin=centre, fn=os.path.join(self._output_dir, output_fn[:-3])) output_data_file = os.path.normpath( os.path.join(self._output_dir, output_fn)) self.assertTrue(os.path.isfile(output_data_file), "output data file not found") expected_data_file = os.path.normpath(self._sgrid_fn) self.assertTrue( os.path.isfile(expected_data_file), "Ref output data file does not exist, nothing to compare with") is_identical, msg = diff_files(output_data_file, expected_data_file) print(msg) self.assertTrue( is_identical, "The output file is not the same with the baseline file.")
def _read_files(self): """ get information from files """ # --> read in data file self.data_obj = Data() self.data_obj.read_data_file(self.data_fn) # --> read response file if self.resp_fn is not None: self.resp_obj = Data() self.resp_obj.read_data_file(self.resp_fn) # --> read mode file if self.model_fn is not None: self.model_obj = Model() self.model_obj.read_model_file(self.model_fn) self._get_plot_period_list() self._get_pt()
# to create surface model. do.write_data_file() # create model file mo = Model( station_locations=do.station_locations, cell_size_east=8000, cell_size_north=8000, pad_north= 7, # number of padding cells in each of the north and south directions pad_east=7, # number of east and west padding cells pad_z=6, # number of vertical padding cells pad_stretch_v=1.6, # factor to increase by in padding cells (vertical) pad_stretch_h=1.4, # factor to increase by in padding cells (horizontal) pad_num= 3, # number of constant-width cells to add to outside of model before padding cells start # this number is currently multiplied by 1.5 internally n_air_layers= 10, #number of air layers, set to 0 to incorporate bathymetry only res_model=100, # halfspace resistivity value for reference model n_layers=100, # total number of z layers, including air z1_layer=10, # first layer thickness pad_method='stretch', # method for calculating padding z_mesh_method='new', z_target_depth= 120000 # depth to bottom of core model (padding after this depth) ) mo.make_mesh() mo.write_model_file(save_path=workdir)
def test_fun(self): edipath = EDI_DATA_DIR # path where edi files are located # period list (will not include periods outside of the range of the edi file) start_period = -2 stop_period = 3 n_periods = 17 period_list = np.logspace(start_period, stop_period, n_periods) # list of edi files, search for all files ending with '.edi' edi_list = [ os.path.join(edipath, ff) for ff in os.listdir(edipath) if (ff.endswith('.edi')) ] do = Data( edi_list=edi_list, inv_mode='1', save_path=self._output_dir, period_list=period_list, error_type_z='floor_egbert', error_value_z=5, error_type_tipper='floor_abs', error_value_tipper=.03, model_epsg=28354 # model epsg, currently set to utm zone 54 ) do.write_data_file() do.data_array['elev'] = 0. do.write_data_file(fill=False) # create model file mo = Model( station_locations=do.station_locations, cell_size_east=500, cell_size_north=500, pad_north= 7, # number of padding cells in each of the north and south directions pad_east=7, # number of east and west padding cells pad_z=6, # number of vertical padding cells pad_stretch_v= 1.6, # factor to increase by in padding cells (vertical) pad_stretch_h= 1.4, # factor to increase by in padding cells (horizontal) n_air_layers=10, # number of air layers res_model=100, # halfspace resistivity value for reference model n_layers=90, # total number of z layers, including air z1_layer=10, # first layer thickness pad_method='stretch', z_target_depth=120000) mo.make_mesh() mo.write_model_file(save_path=self._output_dir) # add topography to res model mo.add_topography_to_model2(AUS_TOPO_FILE) # mo.add_topography_to_model2(r'E:/Data/MT_Datasets/concurry_topo/AussieContinent_etopo1.asc') mo.write_model_file(save_path=self._output_dir) do.project_stations_on_topography(mo) co = Covariance() co.write_covariance_file(model_fn=mo.model_fn) for afile in ("ModEM_Data.dat", "covariance.cov", "ModEM_Model_File.rho"): output_data_file = os.path.normpath( os.path.join(self._output_dir, afile)) self.assertTrue(os.path.isfile(output_data_file), "output data file not found") expected_data_file = os.path.normpath( os.path.join(self._expected_output_dir, afile)) self.assertTrue( os.path.isfile(expected_data_file), "Ref output data file does not exist, nothing to compare with") # print ("Comparing", output_data_file, "and", expected_data_file) is_identical, msg = diff_files(output_data_file, expected_data_file) print msg self.assertTrue( is_identical, "The output file is not the same with the baseline file.")
def create_geogrid(data_file, model_file, out_dir, x_pad=None, y_pad=None, z_pad=None, x_res=None, y_res=None, center_lat=None, center_lon=None, epsg_code=None, depths=None, angle=None, rotate_origin=False, log_scale=False): """Generate an output geotiff file and ASCII grid file. Args: data_file (str): Path to the ModEM .dat file. Used to get the grid center point. model_file (str): Path to the ModEM .rho file. out_dir (str): Path to directory for storing output data. Will be created if it does not exist. x_pad (int, optional): Number of east-west padding cells. This number of cells will be cropped from the east and west sides of the grid. If None, pad_east attribute of model will be used. y_pad (int, optional): Number of north-south padding cells. This number of cells will be cropped from the north and south sides of the grid. If None, pad_north attribute of model will be used. z_pad (int, optional): Number of depth padding cells. This number of cells (i.e. slices) will be cropped from the bottom of the grid. If None, pad_z attribute of model will be used. x_res (int, optional): East-west cell size in meters. If None, cell_size_east attribute of model will be used. y_res (int, optional): North-south cell size in meters. If None, cell_size_north of model will be used. epsg_code (int, optional): EPSG code of the model CRS. If None, is inferred from the grid center point. depths (list of int, optional): A list of integers, eg, [0, 100, 500], of the depth in metres of the slice to retrieve. Will find the closes slice to each depth specified. If None, all slices are selected. center_lat (float, optional): Grid center latitude in degrees. If None, the model's center point will be used. center_lon (float, optional): Grid center longitude in degrees. If None, the model's center point will be used. angle (float, optional): Angle in degrees to rotate image by. If None, no rotation is performed. rotate_origin (bool, optional): If True, image will be rotated around the origin (upper left point). If False, the image will be rotated around the center point. log_scale (bool, optional): If True, the data will be scaled using log10. """ if not os.path.exists(out_dir): os.mkdir(out_dir) model = Model() model.read_model_file(model_fn=model_file) data = Data() data.read_data_file(data_fn=data_file) center = data.center_point center_lat = center.lat.item() if center_lat is None else center_lat center_lon = center.lon.item() if center_lon is None else center_lon if epsg_code is None: zone_number, is_northern, utm_zone = gis_tools.get_utm_zone( center_lat, center_lon) epsg_code = gis_tools.get_epsg(center_lat, center_lon) _logger.info( "Input data epsg code has been inferred as {}".format(epsg_code)) print("Loaded model") # Get the center point of the model grid cells to use as points # in a resistivity grid. ce = _get_centers(model.grid_east) cn = _get_centers(model.grid_north) cz = _get_centers(model.grid_z) print("Grid shape with padding: E = {}, N = {}, Z = {}".format( ce.shape, cn.shape, cz.shape)) # Get X, Y, Z paddings x_pad = model.pad_east if x_pad is None else x_pad y_pad = model.pad_north if y_pad is None else y_pad z_pad = model.pad_z if z_pad is None else z_pad print("Stripping padding...") # Remove padding cells from the grid ce = _strip_padding(ce, x_pad) cn = _strip_padding(cn, y_pad) cz = _strip_padding(cz, z_pad, keep_start=True) print("Grid shape without padding: E = {}, N = {}, Z = {}".format( ce.shape, cn.shape, cz.shape)) x_res = model.cell_size_east if x_res is None else x_res y_res = model.cell_size_north if y_res is None else y_res # BM: The cells have been defined by their center point for making # our grid and interpolating the resistivity model over it. For # display purposes, GDAL expects the origin to be the upper-left # corner of the image. So take the upper left-cell and shift it # half a cell west and north so we get the upper-left corner of # the grid as GDAL origin. origin = _get_gdal_origin(ce, x_res, center.east, cn, y_res, center.north) target_gridx, target_gridy = _build_target_grid(ce, x_res, cn, y_res) resgrid_nopad = _strip_resgrid(model.res_model, y_pad, x_pad, z_pad) indicies = _get_depth_indicies(cz, depths) for di in indicies: print("Writing out slice {:.0f}m...".format(cz[di])) data = _interpolate_slice(ce, cn, resgrid_nopad, di, target_gridx, target_gridy, log_scale) if log_scale: output_file = 'DepthSlice{:.0f}m_log10.tif'.format(cz[di]) else: output_file = 'DepthSlice{:.0f}m.tif'.format(cz[di]) output_file = os.path.join(out_dir, output_file) array2geotiff_writer(output_file, origin, x_res, -y_res, data[::-1], epsg_code=epsg_code, angle=angle, center=center, rotate_origin=rotate_origin) print("Complete!") print("Geotiffs are located in '{}'".format(os.path.dirname(output_file))) return output_file
def build_modem_inputfiles(edi_path, output_path): """ For a given se to edi files in edi_path, build the ModEM input files into output_path :param edi_path: # path where edi files are located r'C:\mtpywin\mtpy\examples\data\edi_files_2' :param output_path: # path to save to r'C:\test\ModEM' :return: """ # not nece os.chdir(r'C:\mtpywin\mtpy') # change this path to the path where mtpy is installed ## period list (won't include periods outside of the range of the edi file) ### ## comment/uncomment your desired method ###################################### ############################################################################### ## example to specify start, stop and total number of periods # start_period = 0.001 # stop_period = 1000 # n_periods = 25 # period_list = np.logspace(np.log10(start_period), # np.log10(stop_period), # n_periods) # example to specify a number of periods per decade start_period = 0.002 stop_period = 2000 periods_per_decade = 4 period_list = get_period_list(start_period, stop_period, periods_per_decade, include_outside_range=True) ## an example to use the periods from a particular edi file # edifile_periods = op.join(edipath,'Synth00.edi') # eobj = Edi(edifile_periods) # period_list = 1./eobj.freq ############################################################################### workdir = output_path edipath = edi_path # list of edi files, search for all files ending with '.edi' edi_list = [ op.join(edipath, ff) for ff in os.listdir(edipath) if (ff.endswith('.edi')) ] # make the save path if it doesn't exist if not op.exists(workdir): os.mkdir(workdir) do = Data( edi_list=edi_list, inv_mode='1', save_path=workdir, period_list=period_list, period_buffer= 2, # factor to stretch interpolation by. For example: if period_buffer=2 # then interpolated data points will only be included if they are # within a factor of 2 of a true data point error_type_z=np.array([ ['floor_percent', 'floor_egbert'], # error type, options are 'egbert', 'percent', 'mean_od', 'eigen', 'median', 'off_diagonals' ['floor_egbert', 'percent'] ]), # add floor to apply it as an error floor # can supply a 2 x 2 array for each component or a single value error_value_z=np.array([ [20., 5.], # error floor value in percent [5., 20.] ]), # can supply a 2 x 2 array for each component or a single value error_type_tipper='floor_abs', # type of error to set in tipper, # floor_abs is an absolute value set as a floor error_value_tipper=.03, model_epsg=28354 # model epsg, currently set to utm zone 54. # See http://spatialreference.org/ to find the epsg code for your projection ) do.write_data_file() # set elevations to zero as we need to ensure the stations are on the topography do.data_array['elev'] = 0. do.write_data_file(fill=False) # create model file mo = Model( station_locations=do.station_locations, cell_size_east=8000, cell_size_north=8000, pad_north= 7, # number of padding cells in each of the north and south directions pad_east=7, # number of east and west padding cells pad_z=6, # number of vertical padding cells pad_stretch_v=1.6, # factor to increase by in padding cells (vertical) pad_stretch_h=1.4, # factor to increase by in padding cells (horizontal) pad_num= 3, # number of constant-width cells to add to outside of model before padding cells start # this number is currently multiplied by 1.5 internally n_air_layers= 10, # number of air layers, set to 0 to incorporate bathymetry only res_model=100, # halfspace resistivity value for reference model n_layers=100, # total number of z layers, including air z1_layer=10, # first layer thickness pad_method='stretch', # method for calculating padding z_mesh_method='new', z_target_depth= 120000 # depth to bottom of core model (padding after this depth) ) mo.make_mesh() mo.write_model_file(save_path=workdir) # add topography to res model # if the number of air layers is zero - bathymetry only will be added. # if the number of air layers is nonzero - topography will be added, discretised into that number of cells # mo.add_topography_to_model2(r'C:\mtpywin\mtpy\examples\data\AussieContinent_etopo1.asc') mo.add_topography_to_model2( r'C:\Githubz\mtpy\examples\data\AussieContinent_etopo1.asc') mo.write_model_file(save_path=workdir) # update data elevations do.project_stations_on_topography(mo) # show the mesh mo.plot_sealevel_resistivity() co = Covariance() co.smoothing_east = 0.4 co.smoothing_north = 0.4 co.smoothing_z = 0.4 co.write_covariance_file(model_fn=mo.model_fn)
from mtpy.utils import gis_tools,convert_modem_data_to_geogrid from mtpy.utils.calculator import nearest_index from pyproj import Proj import numpy as np import os from scipy.interpolate import RegularGridInterpolator # wd = r'M:\AusLAMP\AusLAMP_NSW\Release\Model_release\MT075_DepthSlice_ArcGIS_ascii_grids' # wdmod = r'C:\Users\u64125\OneDrive - Geoscience Australia\AusLAMP_NSW\Modelling\ModEM\NSWinv141' wd = r'C:\Data\Alison_201910\MyOutput' wdmod = r'C:\Data\Alison_201910\Alison_ModEM_Grid\MT075_ModEM_files' filestem = 'Modular_MPI_NLCG_004' mObj = Model() mObj.read_model_file(os.path.join(wdmod,filestem+'.rho')) dObj = Data() dObj.read_data_file(os.path.join(wdmod,'ModEM_Data.dat')) gce,gcn,gcz = [np.mean([arr[:-1],arr[1:]],axis=0) for arr in [mObj.grid_east,mObj.grid_north,mObj.grid_z]] gce,gcn = gce[6:-6],gcn[6:-6] # padding big-sized edge cells # ge,gn = mObj.grid_east[6:-6],mObj.grid_north[6:-6] print(gce) print(gcn) print(gcz) print("Shapes E, N Z =", gce.shape, gcn.shape, gcz.shape)
datob.write_data_file(save_path=outputdir) # create mesh grid model object # model = Model(Data=datob, model = Model( station_object=datob.station_locations, epsg=epsg_code, # epsg # cell_size_east=500, cell_size_north=500, # concurry cell_size_east=10000, cell_size_north=10000, #GA_VIC # cell_size_east=1000, cell_size_north=1000, # Concurry cell_number_ew=120, cell_number_ns=100, # option to specify cell numbers pad_north= 8, # number of padding cells in each of the north and south directions pad_east=8, # number of east and west padding cells pad_z=8, # number of vertical padding cells pad_stretch_v=1.5, # factor to increase by in padding cells (vertical) pad_stretch_h=1.5, # factor to increase by in padding cells (horizontal) n_airlayers= 10, # number of air layers 0, 10, 20, depend on topo elev height res_model=100, # halfspace resistivity value for initial reference model n_layers=55, # total number of z layers, including air and pad_z z1_layer=50, # first layer thickness metres, depend z_target_depth=500000) model.make_mesh( ) # the data file will be re-write in this method. No topo elev file used yet model.plot_mesh()
model_epsg=28354 # model epsg, currently set to utm zone 54. # See http://spatialreference.org/ to find the epsg code for your projection ) do.write_data_file() do.data_array['elev'] = 0. do.write_data_file(fill=False) # create model file mo = Model(stations_object=do.stations_obj, cell_size_east=8000, cell_size_north=8000, pad_north=7, # number of padding cells in each of the north and south directions pad_east=7,# number of east and west padding cells pad_z=6, # number of vertical padding cells pad_stretch_v=1.6, # factor to increase by in padding cells (vertical) pad_stretch_h=1.4, # factor to increase by in padding cells (horizontal) n_air_layers = 10, #number of air layers res_model=100, # halfspace resistivity value for reference model n_layers=100, # total number of z layers, including air z1_layer=10, # first layer thickness pad_method='stretch', # method for calculating padding z_mesh_method='new', z_target_depth=120000 # depth to bottom of core model (padding after this depth) ) mo.make_mesh() mo.write_model_file(save_path=workdir) # add topography to res model mo.add_topography_to_model2(r'C:\mtpywin\mtpy\examples\data\AussieContinent_etopo1.asc') mo.write_model_file(save_path=workdir)
# -*- coding: utf-8 -*- """ Created on Wed Nov 10 14:31:28 2021 @author: jpeacock """ from pathlib import Path from mtpy.modeling.modem import Data, Model mfn_base = Path( r"c:\Users\jpeacock\OneDrive - DOI\Geysers\CEC\modem_inv\repeat_01\gz_base_sm.rho" ) mfn_repeat_01 = Path( r"c:\Users\jpeacock\OneDrive - DOI\Geysers\CEC\modem_inv\repeat_01\gz_z05_c03_061.rho" ) m_base = Model() m_base.read_model_file(mfn_base) m_repeat = Model() m_repeat.read_model_file(mfn_repeat_01) # m_base.res_model = m_base.res_model / m_repeat.res_model m_base.res_model = m_repeat.res_model - m_base.res_model m_base.write_vtk_file(vtk_fn_basename="cec_repeat_01_difference", label="resistivity")
@author: Alison Kirkby create modem input files """ import os.path as op import os os.chdir(r'C:/mtpywin/mtpy' ) # change to the directory where your mtpy is installed to # ensure you are using the correct mtpy from mtpy.modeling.modem import Model import numpy as np # path to save to wd = r'C:\mtpywin\mtpy\examples\model_files\ModEM_2' # provide centre position of model in real world coordinates (eastings/northings) centre = np.array([0., 0., 0.]) # modem .rho file iterfn = 'Modular_MPI_NLCG_004.rho' moo = Model(model_fn=op.join(wd, iterfn)) moo.read_model_file() moo.write_gocad_sgrid_file( origin=centre, fn=r'C:\test\ModEM\ModEM_output.sg' # filename to save to, optional # saves in model directory if not provided )
def run(self): # monkey patch plt.show() so the plot is not displayed in worker thread true_plt_show = plt.show plt.show = _fake_plt_show self._figures = [] try: if not os.path.exists(self.output_dir): os.mkdir(self.output_dir) # get period_list list self.status_updated.emit("Selecting Periods...") period_list = EdiCollection(self._edi_list).select_periods(**self._select_period_kwargs) # save period plot for reference figure = plt.gcf() figure.savefig(os.path.join(self.output_dir, self._period_image_name)) if self.show: self.figure_updated.emit('Period Distribution', figure) # data object self.status_updated.emit("Creating ModEM Data Object...") self._data_kwargs['period_list'] = period_list data = Data(edi_list=self._edi_list, **self._data_kwargs) # write data file self.status_updated.emit("Writing Initial ModEM Data File...") data.write_data_file() # create model self.status_updated.emit("Creating Mesh Model...") model = Model(data_object=data, **self._mesh_kwagrs) model.make_mesh() # plot mesh model.plot_mesh(fig_num=plt.gcf().number + 1) figure = plt.gcf() figure.savefig(os.path.join(self.output_dir, self._mesh_image_name)) if self.show: self.figure_updated.emit("Mesh", figure) # model.plot_mesh_xy() # self.figure_updated.emit("Mesh XY", plt.gcf()) # model.plot_mesh_xz() # self.figure_updated.emit("Mesh XZ", plt.gcf()) model.write_model_file() # add topography self.status_updated.emit("Adding Topography...") model.add_topography_to_mesh(**self._topo_args) if self.show: model.plot_topograph() # this is too slow so only plot and save image when asked figure = plt.gcf() figure.savefig(os.path.join(self.output_dir, self._topo_image_name)) self.figure_updated.emit("Topography", figure) self.status_updated.emit("Updating Mesh Model...") model.write_model_file() # covariance self.status_updated.emit("Creating Covariance File...") self._covariance_kwargs['mask_arr'] = model.covariance_mask cov = Covariance(**self._covariance_kwargs) self.status_updated.emit("Writing Covariance File...") cov.write_covariance_file(model_fn=model.model_fn, sea_water=self._topo_args['sea_resistivity'], air=self._topo_args['air_resistivity']) self.status_updated.emit("Creating README File...") self.write_readme(os.path.join(self.output_dir, self._readme_name)) # done self.status_updated.emit("Finishing...") except Exception as e: frm = inspect.trace()[-1] mod = inspect.getmodule(frm[0]) self.export_error.emit("{}: {}".format(mod.__name__, e.message)) # restore plt.show() plt.show = true_plt_show
def test_fun_rotate(self): # set the dir to the output from the previously correct run self._expected_output_dir = os.path.join(SAMPLE_DIR, 'ModEM_rotate40') edipath = EDI_DATA_DIR2 # example to specify a number of periods per decade start_period = 0.002 stop_period = 2000 periods_per_decade = 4 period_list = get_period_list(start_period, stop_period, periods_per_decade, include_outside_range=True) # list of edi files, search for all files ending with '.edi' edi_list = [ os.path.join(edipath, ff) for ff in os.listdir(edipath) if (ff.endswith('.edi')) ] do = Data( edi_list=edi_list, inv_mode='1', save_path=self._output_dir, period_list=period_list, period_buffer= 2, # factor to stretch interpolation by. For example: if period_buffer=2 # then interpolated data points will only be included if they are # within a factor of 2 of a true data point error_type_z= 'floor_egbert', # error type (egbert is % of sqrt(zxy*zyx)) # floor means apply it as an error floor error_value_z=5, # error floor (or value) in percent error_type_tipper='floor_abs', # type of error to set in tipper, # floor_abs is an absolute value set as a floor error_value_tipper=.03, rotation_angle=40, model_epsg=28354 # model epsg, currently set to utm zone 54. # See http://spatialreference.org/ to find the epsg code for your projection ) do.write_data_file() do.data_array['elev'] = 0. do.write_data_file(fill=False) # mesh rotation angle is the opposite direction to the rotation of the stations if do.rotation_angle == 0: mesh_rotation_angle = 0 else: mesh_rotation_angle = -do.rotation_angle # create model file mo = Model( stations_object=do.station_locations, cell_size_east=8000, cell_size_north=8000, pad_north= 7, # number of padding cells in each of the north and south directions pad_east=7, # number of east and west padding cells pad_z=6, # number of vertical padding cells pad_stretch_v= 1.6, # factor to increase by in padding cells (vertical) pad_stretch_h= 1.4, # factor to increase by in padding cells (horizontal) n_air_layers=10, #number of air layers res_model=100, # halfspace resistivity value for reference model n_layers=100, # total number of z layers, including air z1_layer=10, # first layer thickness pad_method='stretch', # method for calculating padding z_mesh_method='new', z_target_depth= 120000, # depth to bottom of core model (padding after this depth) mesh_rotation_angle=mesh_rotation_angle) mo.make_mesh() mo.write_model_file(save_path=self._output_dir) # add topography to res model mo.add_topography_to_model2(AUS_TOPO_FILE) mo.write_model_file(save_path=self._output_dir) co = Covariance() co.smoothing_east = 0.4 co.smoothing_north = 0.4 co.smoothing_z = 0.4 co.write_covariance_file(model_fn=mo.model_fn) for afile in ("ModEM_Data.dat", "covariance.cov", "ModEM_Model_File.rho"): output_data_file = os.path.normpath( os.path.join(self._output_dir, afile)) self.assertTrue(os.path.isfile(output_data_file), "output data file not found") expected_data_file = os.path.normpath( os.path.join(self._expected_output_dir, afile)) self.assertTrue( os.path.isfile(expected_data_file), "Ref output data file does not exist, nothing to compare with") # print ("Comparing", output_data_file, "and", expected_data_file) is_identical, msg = diff_files(output_data_file, expected_data_file) print(msg) self.assertTrue( is_identical, "The output file is not the same with the baseline file.")
def modem2geotiff(data_file, model_file, output_file, source_proj=None): """ Generate an output geotiff file from a modems.dat file and related modems.rho model file :param data_file: modem.dat :param model_file: modem.rho :param output_file: output.tif :param source_proj: None by defult. The UTM zone infered from the input non-uniform grid parameters :return: """ # Define Data and Model Paths data = Data() data.read_data_file(data_fn=data_file) # create a model object using the data object and read in model data model = Model(data_obj=data) model.read_model_file(model_fn=model_file) center = data.center_point if source_proj is None: zone_number, is_northern, utm_zone = gis_tools.get_utm_zone( center.lat.item(), center.lon.item()) #source_proj = Proj('+proj=utm +zone=%d +%s +datum=%s' % (zone_number, 'north' if is_northern else 'south', 'WGS84')) epsg_code = gis_tools.get_epsg(center.lat.item(), center.lon.item()) print("Input data epsg code is infered as ", epsg_code) else: epsg_code = source_proj # integer source_proj = Proj(init='epsg:' + str(epsg_code)) resistivity_data = { 'x': center.east.item() + (model.grid_east[1:] + model.grid_east[:-1]) / 2, 'y': center.north.item() + (model.grid_north[1:] + model.grid_north[:-1]) / 2, 'z': (model.grid_z[1:] + model.grid_z[:-1]) / 2, 'resistivity': np.transpose(model.res_model, axes=(2, 0, 1)) } grid_proj = Proj( init='epsg:4326') # output grid Coordinate systems: 4326, 4283, 3112 # grid_proj = Proj(init='epsg:4283') # output grid Coordinate system 4326, 4283, 3112 # grid_proj = Proj(init='epsg:3112') # output grid Coordinate system 4326, 4283, 3112 result = modem2nc.interpolate(resistivity_data, source_proj, grid_proj, center, modem2nc.median_spacing(model.grid_east), modem2nc.median_spacing(model.grid_north)) # nc.write_resistivity_grid(output_file, grid_proj, # result['latitude'], result['longitude'], result['depth'], # result['resistivity'], z_label='depth') print("result['latitude'] ==", result['latitude']) print("result['longitude'] ==", result['longitude']) print("result['depth'] ==", result['depth']) origin = (result['latitude'][0], result['longitude'][0]) pixel_width = result['longitude'][1] - result['longitude'][0] pixel_height = result['latitude'][1] - result['latitude'][0] # write the depth_index depth_index = 1 resis_data = result['resistivity'][depth_index, :, :] resis_data2 = resis_data[:: -1] # flipped upside down to get geotiff mapped correctly. array2geotiff_writer(output_file, origin, pixel_width, pixel_height, resis_data2) return output_file
data_fn = r'C:\mtpywin\mtpy\examples\model_files\ModEM\ModEM_Data.dat' dObj = Data() dObj.read_data_file(data_fn=data_fn) ### option 2 #### stationxyfile = r'C:\mtpywin\mtpy\examples\model_files\gocad\stationxy.txt' xy = np.loadtxt(stationxyfile, usecols=(1, 2)) station_names = np.loadtxt(stationxyfile, usecols=(0, ), dtype='S10') period_list = np.logspace(1, 4, 19) # change to your period list # create data file dObj = Data(epsg=epsg) dObj._initialise_empty_data_array(xy, period_list, location_type='LL', station_names=station_names) dObj.write_data_file(fill=False, save_path=workdir) # Create model file mObj = Model(Data=dObj, save_path=workdir) mObj.read_gocad_sgrid_file(gocad_sgrid_file) mObj.model_fn_basename = op.join(workdir, 'ModEM_Model_forward.ws') mObj.write_model_file() # create covariance file cov = Covariance(save_path=workdir, smoothing_east=0.3, smoothing_north=0.3, smoothing_z=0.3) cov.write_covariance_file(model_fn=mObj.model_fn)
######## inputs ############## wd = r'C:\mtpywin\mtpy\examples\model_files\ModEM_2' savepath = r'C:\test' model_fn = op.join(wd, 'Modular_MPI_NLCG_004.rho') data_fn = op.join(wd, 'ModEM_Data.dat') location_type = 'LL' # 'EN' to save eastings/northings, 'LL' to save longitude/latitude, need to provide model_epsg if using 'LL' model_epsg = 28355 # epsg number model was projected in. common epsg numbers: # 28351 (GDA94, mga zone 51), 28352 (mga zone 52), 28353 (mga zone 53), # 28354 (mga zone 54), 28355 (mga zone 55), 28356 (mga zone 56) # 3112 (Geoscience Australia Lambert) # go to http://spatialreference.org/ref/epsg/?search=&srtext=Search for more info model_utm_zone = '55S' # alternative to epsg, can provide utm zone depth_indices = [44, 45, 46] # indices that define depth ############################## # get the real-world origin from the data file dataObj = Data(data_fn=data_fn, model_epsg=model_epsg) dataObj.read_data_file() origin = [dataObj.center_point['east'][0], dataObj.center_point['north'][0]] modObj = Model() modObj.read_model_file(model_fn=op.join(wd, model_fn)) modObj.write_xyres(origin=origin, savepath=savepath, location_type=location_type, model_epsg=model_epsg, model_utm_zone=None, log_res=True, outfile_basename='GMTtest', depth_index=depth_indices)
error_value_tipper=.03, model_epsg=28354 # model epsg, currently set to utm zone 54 ) do.write_data_file() do.data_array['elev'] = 0. do.write_data_file(fill=False) # create model file mo = Model( station_locations=do.station_locations, cell_size_east=500, cell_size_north=500, pad_north= 7, # number of padding cells in each of the north and south directions pad_east=7, # number of east and west padding cells pad_z=6, # number of vertical padding cells pad_stretch_v=1.6, # factor to increase by in padding cells (vertical) pad_stretch_h=1.4, # factor to increase by in padding cells (horizontal) n_airlayers=10, #number of air layers res_model=100, # halfspace resistivity value for reference model n_layers=90, # total number of z layers, including air z1_layer=10, # first layer thickness pad_method='stretch', z_target_depth=120000) mo.make_mesh() mo.write_model_file(save_path=workdir) # add topography to res model mo.add_topography_to_model2( r'C:\Git\mtpy\examples\data\AussieContinent_etopo1.asc') mo.write_model_file(save_path=workdir)
from mtpy.modeling.modem import Data, Model if __name__ == "__main__": #workdir = r'C:\Git\mtpy\examples\data' workdir = r'E:\Githubz\mtpy\examples\data' modeldir = op.join(workdir, 'ModEM_files') # folder where *.rho files exist read_data = True iterfn = max([ff for ff in os.listdir(modeldir) if ff.endswith('.rho')]) if read_data: doo = Data() doo.read_data_file(op.join(modeldir, 'ModEM_Data.dat')) moo = Model(model_fn=op.join(modeldir, iterfn)) moo.read_model_file() snoew = 10 snons = 10 snoz = np.where(moo.grid_z > 80000)[0][0] gcz = np.mean([moo.grid_z[:-1], moo.grid_z[1:]], axis=0) plotdir = 'ew' if plotdir == 'ew': X, Y, res = moo.grid_east, moo.grid_z, np.log10( moo.res_model[snoew, :, :].T) xlim = (-25000, 25000) ylim = (1e4, 0) sliceinfo = '' elif plotdir == 'ns':
# ============================================================================= import numpy as np from mtpy.modeling.modem import Model # ============================================================================= res_levels = [ (0, 2, 10), (2, 5, 30), (5, 25, 300), (25, 60, 50), (60, 150, 100), (150, 1000, 10), ] m = Model() m.read_model_file( r"c:\Users\jpeacock\OneDrive - DOI\MountainPass\modem_inv\mnp_03\mnp_z03_t02_c02_098.rho" ) fwd = np.zeros_like(m.res_model) for r in res_levels: test = np.where((m.grid_z[:-1] >= r[0] * 1000) & (m.grid_z[:-1] < r[1] * 1000)) fwd[:, :, test] = r[2] # fwd[np.where(m.res_model <1)] = 0.3 m.write_model_file(model_fn_basename="mnp_fwd.rho", res_model=fwd)
def test_fun_edi_elevation(self): edipath = EDI_DATA_DIR # path where edi files are located # set the dir to the output from the previously correct run self._expected_output_dir = os.path.join(SAMPLE_DIR, 'ModEM') # period list (will not include periods outside of the range of the edi file) start_period = -2 stop_period = 3 n_periods = 17 period_list = np.logspace(start_period, stop_period, n_periods) # list of edi files, search for all files ending with '.edi' edi_list = [ os.path.join(edipath, ff) for ff in os.listdir(edipath) if (ff.endswith('.edi')) ] do = Data( edi_list=edi_list, inv_mode='1', save_path=self._output_dir, period_list=period_list, error_type_z='floor_egbert', error_value_z=5, error_type_tipper='floor_abs', error_value_tipper=.03, model_epsg=28354 # model epsg, currently set to utm zone 54 ) do.write_data_file() # create model file mo = Model( station_locations=do.station_locations, cell_size_east=500, cell_size_north=500, pad_north= 7, # number of padding cells in each of the north and south directions pad_east=7, # number of east and west padding cells pad_z=6, # number of vertical padding cells pad_stretch_v= 1.6, # factor to increase by in padding cells (vertical) pad_stretch_h= 1.4, # factor to increase by in padding cells (horizontal) n_air_layers=10, # number of air layers res_model=100, # halfspace resistivity value for reference model n_layers=90, # total number of z layers, including air z1_layer=10, # first layer thickness pad_method='stretch', z_target_depth=120000) mo.make_mesh() mo.write_model_file(save_path=self._output_dir) # Add topography from EDI data mo.add_topography_from_data(do) mo.write_model_file(save_path=self._output_dir) # BM: note this function makes a call to `write_data_file` and this is the datafile being # compared! do.project_stations_on_topography(mo) co = Covariance() co.write_covariance_file(model_fn=mo.model_fn) # BM: if this test is failing check that the correct filenames are being selected # for comparison for test_output, expected_output in ( ("ModEM_Data_topo.dat", "ModEM_Data_EDI_elev.dat"), ("covariance.cov", "covariance_EDI_elev.cov"), ("ModEM_Model_File.rho", "ModEM_Model_File_EDI_elev.rho")): output_data_file = os.path.normpath( os.path.join(self._output_dir, test_output)) self.assertTrue(os.path.isfile(output_data_file), "output data file not found") expected_data_file = os.path.normpath( os.path.join(self._expected_output_dir, expected_output)) self.assertTrue( os.path.isfile(expected_data_file), "Ref output data file '{}' does not exist, nothing to compare with" .format(expected_data_file)) is_identical, msg = diff_files(output_data_file, expected_data_file) print(msg) self.assertTrue( is_identical, "The output file '{}' is not the same with the baseline file '{}'." .format(output_data_file, expected_data_file))