Git Product home page Git Product logo

mttime's Introduction

MTtime

MTtime (Time Domain Moment Tensor Inversion in Python) is a python package developed for time domain inversion of complete seismic waveform data to obtain the seismic moment tensor. It supports deviatoric and full moment tensor inversions, and 1-D and 3-D basis Green's functions.

Requirements

The package was developed on python 3.7 and 3.8, and is running and tested on Mac OSX.

  • ObsPy and its dependencies
  • pandas
  • cartopy (for plotting maps)

Installation

  • Create a Python environment
  • Install ObsPy and pandas
  • Make sure you have cloned the repository
  • Install mttime

I recommend installing Python via Miniconda or Anaconda. Choose Miniconda for a lower footprint. Then follow the instructions on their sites to install ObsPy and pandas for your given platform.

Download mttime and install it from source. If you installed Python via conda make sure you activate the environment where ObsPy and pandas are installed.

# Activate environment
conda activate your_environment

# Build and install mttime
git clone https://github.com/LLNL/mttime
cd mttime
pip install .

Finally, if you want to run the tutorials you will need to install Jupyter Notebook.

Usage

Executing the package from command line will launch the inversion, save and plot the result to file:

mttime-run mtinv.in

The equivalent in the Python console:

import mttime
config = mttime.Configure(path_to_file="mtinv.in")
mt = mttime.Inversion(config=config)
mt.invert()
mt.write()

Resources

License

mttime is distributed under the terms of LGPL-3.0 license. All new contributions must be made under the LGPL-3.0 license.

SPDX-License-Identifier: LGPL-3.0

LLNL-CODE-814839

mttime's People

Contributors

ahchiang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

mttime's Issues

Trouble Matching Synthetics with Observed data

I want to make the green's functions for 1D local velocity model with these parameters:
freqmin = 0.025
freqmax = 1.0
npts = int(2048)
dt = 0.02
The synthetics have been generated. But it is difficult to match the waveforms. The output parameters looks like this.

Deviatoric Moment Tensor Inversion
Depth = 5.0000 km
Mw = -0.42
Percent DC/CLVD/ISO = 28/72/0
VR = 0.00%

Deviatoric Moment Tensor Inversion
Depth = 15.0000 km
Mw = -0.25
Percent DC/CLVD/ISO = 79/21/0
VR = 0.01%

Additionally, I have attached the waveform fits. Please inform me if any errors are present in my approach.
bbwaves d15 0000 00

ValueError: could not broadcast input array from shape (201,) into shape (256,)

# Import third-party libraries
import os
from pathlib import Path
import pandas as pd
from obspy.core import read, UTCDateTime, Stream

evid = "49462969" # event of interest
event_dir = evid
infile = "%s/datetime.csv"%event_dir # we need the event origin time
station_file = "%s/station.csv"%event_dir

sacdir = "%s/sac"%event_dir # location of processed data
outdir = "%s"%event_dir # location of filtered/cut/down-sampled data for inversion
    
# Check if data directory exist
P = Path(sacdir)
if P.exists():
    # Read event info and station info into Pandas table
    df = pd.read_csv(infile,parse_dates=True)
    station_df = pd.read_csv("%s"%(station_file),parse_dates=True,dtype={"location":str},na_filter=False)
    
    origin_time = UTCDateTime(df["origin"][0])
    print(origin_time)
    st = Stream()
    for _,row in station_df.iterrows():
        st += read("%s/%s.%s.%s.%s[%s]"%(
            sacdir,row.network,row.station,row.location,row.channel,row.component),format="SAC")
else:
    print("Directory %s does not exist. %s does not have instrument corrected data."%(sacdir,evid))
    

# Filter
freqmin = 0.025
freqmax = 0.0625
corners = 3

# Desired sampling interval
dt = 0.02

# Reduction velocity in km/sec, 0 sets the reference time to origin time
vred = 0

# time before and after reference time, data will be cut before and after the reference time
time_before = 50
time_after = 250

from obspy.core.event import Origin
if vred:
    p = 1/vred
else:
    p = 0
    
st.filter("bandpass",freqmin=freqmin,freqmax=freqmax,corners=corners,zerophase=True)
#st.taper(max_percentage=0.05)

# Trim and decimate the data
for tr in st:
    #print(tr.stats)
    #tr.decimate(factor=int(tr.stats.sampling_rate*dt), strict_length=False, no_filter=True)
    df = pd.read_csv(infile,parse_dates=True)
    origin_time = UTCDateTime(df["origin"][0])
    print(origin_time)
    
    origin = Origin()
    tr.resample(1/dt)
    #tr.stats.sac.t1 = origin_time# + p*(tr.stats.sac.dist) # set reference time
    #print(tr.stats.sac.t1)
    origin.time = origin_time
    tr.trim(origin_time-time_before,origin_time+time_after,pad=True,fill_value=0)    
    #tr.data = 100*tr.data # m/s to cm/s
    #tr.stats.sac.b = -1*(origin_time - tr.stats.starttime)
    #tr.stats.sac.o = 0
    print(tr.stats)
    # Save final trace using tdmtpy file name format
    sacout = "%s/%s%s.dat"%(outdir,tr.id[:-4],tr.id[-1])
    tr.write(sacout,format="SAC")

model = "mahesh2013"
#depths = round(df["depth"][0]) # Only compute GFs at catalog depth
depths = sorted([5,round(df["depth"][0])]) # compute GF at 10, 20 km and at catalog depth
print(depths)
npts = int(1028) # number of points in the time series, must be a power of 2
t0 = int(0) # used to define the first sample point, t0 + distance_in_km/vred
#dt = 0.02
# Location of synthetic Green's functions
green_dir = "%s/%s"%(event_dir,model)

Path(green_dir).mkdir(parents=True,exist_ok=True)
print(Path(green_dir))
for depth in depths:
    # Create distance file
    dfile = ("{dist:.0f} {dt:.2f} {npts:d} {t0:d} {vred:.1f}\n")
    print(dfile)
    dfile_out = "%s/dfile"%event_dir
    print(dfile_out)
    with open(dfile_out,"w") as f:
        for _,row in station_df.iterrows():
            f.write(dfile.format(dist=row.distance,dt=dt,npts=npts,t0=t0,vred=vred))

    # Generate the synthetics
    print(os)
    os.system("/home/leo/PROGRAMS.330/bin/hprep96 -M %s.d -d %s -HS %.4f -HR 0 -EQEX"%(model,dfile_out,depth))
    os.system("/home/leo/PROGRAMS.330/bin/hspec96")
    os.system("/home/leo/PROGRAMS.330/bin/hpulse96 -D -i > file96")
    os.system("/home/leo/PROGRAMS.330/bin/f96tosac -B file96")

    # Filter and save the synthetic Green's functions
    greens = ("ZDD","RDD","ZDS","RDS","TDS","ZSS","RSS","TSS","ZEX","REX")

    for index,row in station_df.iterrows():      
        for j,grn in enumerate(greens):
            sacin = "B%03d%02d%s.sac"%(index+1,j+1,grn)
            sacout = "%s/%s.%s.%.4f"%(green_dir,row.network,row.station,depth)
            #sacout = "%s/%s.%s.%s.%.4f"%(green_dir,row.network,row.station,row.location,depth)
            tmp = read(sacin,format="SAC")
            tmp.filter('bandpass',freqmin=freqmin,freqmax=freqmax,corners=corners,zerophase=True)
            #tmp.data = 100000*tmp.data
            #print(temp.stats)
            tmp.write("%s.%s"%(sacout,grn),format="SAC") # overwrite

# Uncomment to remove unfiltered synthetic SAC files
os.system("rm B*.sac") # remove the unfiltered SAC files

# Create headers
headers = dict(datetime=df["origin"][0],
               longitude=df["lon"][0],
               latitude=df["lat"][0],
               depth=",".join([ "%.4f"%d for d in depths]),
               path_to_data=event_dir,
               path_to_green=green_dir,
               green="herrmann",
               components="ZRT",
               degree=5,
               weight="distance",
               plot=0,
               correlate=0,
              )

# Add station table
pd.options.display.float_format = "{:,.2f}".format
frame = {"station": station_df[["network","station"]].apply(lambda x: ".".join(x),axis=1)}
df_out = pd.DataFrame(frame)
df_out[["distance","azimuth"]] = station_df[["distance","azimuth"]]
df_out["ts"] = int(30)
df_out["npts"] = int(256)
df_out["dt"] = dt
df_out["used"] = 1
df_out[["longitude","latitude"]] = station_df[["longitude","latitude"]]
#print(df_out.to_string(index=False))


# write
with open("mtinv.in","w") as f:
    for key, value in headers.items():
        f.write("{0:<15}{1}\n".format(key,value))
    f.write(df_out.to_string(index=False))
    
!cat mtinv.in

Error

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[9], line 4
      1 # Pass the parameters to the Inversion object and launch the inversion
      2 # The default is to plot all solutions
      3 tdmt = mttime.Inversion(config=config)
----> 4 tdmt.invert()
      5 tdmt.write()

File ~/anaconda3/envs/myenv/lib/python3.8/site-packages/mttime/core/inversion.py:113, in Inversion.invert(self, show)
    111 tensors = []
    112 for _depth in self.config.depth:
--> 113     self._single_inversion(_depth,tensors)
    115 # Get preferred moment tensor solution
    116 if len(tensors):

File ~/anaconda3/envs/myenv/lib/python3.8/site-packages/mttime/core/inversion.py:146, in Inversion._single_inversion(self, depth, tensors)
    144 if self.config.correlate:
    145     self._correlate()
--> 146 self._data_to_d()
    147 self._weights()
    149 ind = self.w != 0

File ~/anaconda3/envs/myenv/lib/python3.8/site-packages/mttime/core/inversion.py:412, in Inversion._data_to_d(self)
    410     e = self.config.index2[i]
    411     for d_b, d_e, component in zip(b, e, self.config.components):
--> 412         d[d_b:d_e] = self.streams[i].select(component=component)[0].data[obs_b[i]:obs_e[i]]
    414 self.d = d

ValueError: could not broadcast input array from shape (201,) into shape (256,)

Data file style

Can you share the corresponding file data style? Because there is no corresponding data, it is difficult to understand the logical relationship of the code. [email protected],THANKS

KeyError: 'components' and AttributeError: components when running Jupyter Notebook 03_Run_Inversion.

Hi. I was testing with the Jupyter Notebooks in the tdmtpy/examples/notebooks/ directory to check if the code works well. However, I got KeyError: 'components' and AttributeError: components errors when I executed the third cell of the notebook 03_Run_Inversion which looks like follows:

# Pass the parameters to the Inversion object and launch the inversion
# The default is to plot all solutions
tdmt = tdmtpy.Inversion(config=config)
tdmt.invert()

The printed errors look like follows:

Deviatoric Moment Tensor Inversion
Depth = 10.0000 km
Mw = 4.32
Percent DC/CLVD/ISO = 93/7/0
VR = 51.69%%

Deviatoric Moment Tensor Inversion
Depth = 12.0000 km
Mw = 4.27
Percent DC/CLVD/ISO = 88/12/0
VR = 53.74%%

Deviatoric Moment Tensor Inversion
Depth = 20.0000 km
Mw = 4.32
Percent DC/CLVD/ISO = 93/7/0
VR = 51.64%%

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/anaconda3/lib/python3.7/site-packages/obspy/core/util/attribdict.py in __getattr__(self, name, default)
    127         try:
--> 128             return self.__getitem__(name, default)
    129         except KeyError as e:

~/anaconda3/lib/python3.7/site-packages/obspy/core/util/attribdict.py in __getitem__(self, name, default)
     73         try:
---> 74             return self.__dict__[name]
     75         except KeyError:

KeyError: 'components'

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
<ipython-input-3-5302a250a3ce> in <module>
      2 # The default is to plot all solutions
      3 tdmt = tdmtpy.Inversion(config=config)
----> 4 tdmt.invert()

~/anaconda3/lib/python3.7/site-packages/tdmtpy-1.0.0-py3.7.egg/tdmtpy/inversion.py in invert(self)
    127 
    128         if self.config.plot:
--> 129             self.plot(view="normal")
    130             if len(self.config.depth) > 1:
    131                 self.plot(view="depth")

~/anaconda3/lib/python3.7/site-packages/tdmtpy-1.0.0-py3.7.egg/tdmtpy/inversion.py in plot(self, **kwargs)
    528             else:
    529                 for tensor in self.moment_tensors:
--> 530                     tensor._beach_waveforms_3c(*args)
    531         elif view == "depth":
    532             from .image import beach_mw_depth

~/anaconda3/lib/python3.7/site-packages/tdmtpy-1.0.0-py3.7.egg/tdmtpy/tensor.py in _beach_waveforms_3c(self, inv_type, components, df, show, format)
    457 
    458         for page, group in enumerate(pages):
--> 459             f, ax0, ax1 = new_page(len(group), nrows+1, ncols, annot=annot,title=self.inverted.components)
    460             # Plot beach balls
    461             for i in range(len(fm)):

~/anaconda3/lib/python3.7/site-packages/obspy/core/util/attribdict.py in __getattr__(self, name, default)
    128             return self.__getitem__(name, default)
    129         except KeyError as e:
--> 130             raise AttributeError(e.args[0])
    131 
    132     __setattr__ = __setitem__

AttributeError: components

I would like to know what might be the cause of these errors.

error when generate synthetic data

Hi, I was trying the example code and I bump into error when run the code 02_Prepare_Data_and_Synthetic_for_Inversion.
Here is the error, seems like it fails to generate the synthetic data, because the hprep96, hspec96, hpulse96, f96tosac is not recognize Thank you.

'hprep96' is not recognized as an internal or external command, operable program or batch file. 'hspec96' is not recognized as an internal or external command, operable program or batch file. 'hpulse96' is not recognized as an internal or external command, operable program or batch file. 'f96tosac' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last): File "C:/Users/User/Documents/PycharmProjects/SAMBOJA/mttime/examples/notebooks/02_Prepare_Data_and_Synthetics_For_Inversion.py", line 154, in <module> tmp = read(sacin,format="SAC") File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\decorator.py", line 232, in fun return caller(func, *(extras + args), **kw) File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\obspy\core\util\decorator.py", line 300, in _map_example_filename return func(*args, **kwargs) File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\obspy\core\stream.py", line 212, in read st = _generic_reader(pathname_or_url, _read, **kwargs) File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\obspy\core\util\base.py", line 700, in _generic_reader raise IOError(2, "No such file or directory", pathname) FileNotFoundError: [Errno 2] No such file or directory: 'B00101ZDD.sac'

mttime for microearthquake moment tensor

Greetings @ahchiang, hope you are doing well.

I've been trying the notebook and it's went well, except some error in plotting appeared but I'm trying to solving it.
I'm wondering that could we use mttime for solving microearthquake mt?
Let say the eq in depth of 2-5 km with freq signal in range of 20 - 50 Hz, the epi distance in range 1 - 10 km, the magnitude below 2 Mw. Thank you.

Best Regards,
Dicky

Question about inverting blasting signals in meter-scale mining environment

Dear sir, I have been trying to invert moment tensors of blasting signals with the mttime package, but I run into some problems when fitting the observed and synthesized waveforms (only contain Z component).
Since distances between blasting sources and receivers is around 60 meters, the high-frequency portion of the blast signal is relatively large, as shown below.
a544cbd24b0e4d87fc931fd15c0aee5

The corner frequency reaches 161.9048 Hz, and it poses challenges for selecting parameters of the bandpass filter.
When the parameters are set [30Hz, 160Hz] to contain low and high frequency of blasting signals, the differences between observed and synthesized waveforms are too large.
e3a71551a2df5fdefd61a105c863db0
When the parameters are set [120Hz,160Hz] containing only high frequency, the obtained results do not correspond to the characteristics of the blast signals.
Therefore, I would like to ask how to determine the filtering parameters applicable to the blast signal.
In addition, I found that the beach ball pattern of luna in the mttime package is inconsistent with the beach ball pattern in obspy.
1712411712946
Thank you for considering my question. I am eagerly anticipating your response.
Best regards,
Zhongwei Pei

Inversion with ZNE components

Dear @ahchiang, sometimes we need to use ZNE components instead of ZRT due to issues with some specific component. It would be nice if you could put an example regarding that (may also including "tensor" type green functions).

Question about the inversion with a pure isotropic source

Dear @ahchiang, I'm interested in the inversions for moment tensors of non-double-couple sources. In your paper(Moment tensor analysis for NKT events), you assume a pure isotropic source in the inversion. How can I modify the notebook files to achieve this result? It would be nice if you could put an example.
Thank you

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.