Source code for mtpy.modeling.ws3dinv.stations

# -*- coding: utf-8 -*-
"""
Created on Tue Nov  7 09:18:17 2023

@author: jpeacock
"""

# ==============================================================================

from pathlib import Path

import numpy as np
from loguru import logger
from pyevtk.hl import pointsToVTK

import mtpy.modeling.winglink as wl


# ==============================================================================
[docs] class WSStation: """Read and write a station file where the locations are relative to the 3D mesh. ==================== ====================================================== Attributes Description ==================== ====================================================== east array of relative locations in east direction elev array of elevations for each station names array of station names north array of relative locations in north direction station_fn full path to station file save_path path to save file to ==================== ====================================================== ==================== ====================================================== Methods Description ==================== ====================================================== read_station_file reads in a station file write_station_file writes a station file write_vtk_file writes a vtk points file for station locations ==================== ====================================================== """ def __init__(self, station_fn=None, **kwargs): self.logger = logger self.east = None self.north = None self.elev = None self.names = None self.save_path = Path() self.fn_basename = "WS_Station_Locations.txt" for key, value in kwargs.items(): setattr(self, key, value) @property def station_filename(self): """Station filename.""" return self.save_path.joinpath(self.fn_basename) @station_filename.setter def station_filename(self, value): """Station filename.""" if value is not None: value = Path(value) if value.parent == Path("."): self.fn_basename = value.name else: self.save_path = value.parent self.fn_basename = value.name
[docs] def write_station_file( self, east=None, north=None, station_list=None, save_path=None, elev=None, ): """Write a station file to go with the data file. the locations are on a relative grid where (0, 0, 0) is the center of the grid. Also, the stations are assumed to be in the center of the cell. Arguments:: **east** : np.ndarray(n_stations) relative station locations in east direction **north** : np.ndarray(n_stations) relative station locations in north direction **elev** : np.ndarray(n_stations) relative station locations in vertical direction **station_list** : list or np.ndarray(n_stations) name of stations **save_path** : string directory or full path to save station file to if a directory the file will be saved as save_path/WS_Station_Locations.txt if save_path is none the current working directory is used as save_path Outputs:: **station_fn** : full path to station file """ if east is not None: self.east = east if north is not None: self.north = north if station_list is not None: self.names = station_list if elev is not None: self.elev = elev else: if self.north is not None: self.elev = np.zeros_like(self.north) with open(self.station_filename, "w") as sfid: sfid.write(f"{'station':<14}{'east':^14}{'north':^14}{'elev':^14}\n") for ee, nn, zz, ss in zip(self.east, self.north, self.elev, self.names): ee = f"{ee:+.4e}" nn = f"{nn:+.4e}" zz = f"{zz:+.4e}" sfid.write(f"{ss:<14}{ee:^14}{nn:^14}{zz:^14}\n") self.logger.info(f"Wrote station locations to {self.station_filename}") return self.station_filename
[docs] def read_station_file(self, station_filename): """Read in station file written by write_station_file. Arguments:: **station_fn** : string full path to station file Outputs:: **east** : np.ndarray(n_stations) relative station locations in east direction **north** : np.ndarray(n_stations) relative station locations in north direction **elev** : np.ndarray(n_stations) relative station locations in vertical direction **station_list** : list or np.ndarray(n_stations) name of stations """ self.station_filename = station_filename self.station_locations = np.loadtxt( self.station_fn, skiprows=1, dtype=[ ("station", "|U10"), ("east_c", float), ("north_c", float), ("elev", float), ], ) self.east = self.station_locations["east_c"] self.north = self.station_locations["north_c"] self.names = self.station_locations["station"] self.elev = self.station_locations["elev"]
[docs] def write_vtk_file(self, save_path, vtk_basename="VTKStations"): """Write a vtk file to plot stations. Arguments:: **save_path** : string directory to save file to. Will save as save_path/vtk_basename **vtk_basename** : string base file name for vtk file, extension is automatically added. """ save_path = Path(save_path) if save_path.is_dir(): save_fn = save_path.joinpath(vtk_basename) if self.elev is None: self.elev = np.zeros_like(self.north) pointsToVTK( save_fn, self.north, self.east, self.elev, data={"value": np.ones_like(self.north)}, ) return save_fn
[docs] def from_wl_write_station_file(self, sites_file, out_file, ncol=5): """Write a ws station file from the outputs of winglink. Arguments:: **sites_fn** : string full path to sites file output from winglink **out_fn** : string full path to .out file output from winglink **ncol** : int number of columns the data is in *default* is 5 """ wl_east, wl_north, wl_station_list = wl.get_station_locations( sites_file, out_file, ncol=ncol ) self.write_station_file( east=wl_east, north=wl_north, station_list=wl_station_list )