├── settings_files ├── timelist_chino.csv ├── synth_two_arrays.csv ├── fig3_b.yml ├── fig3_a.yml ├── fig2_v3.4.yml ├── fig2_v3.6.yml ├── fig5_a.yml ├── fig6_GF.yml ├── fig6_v3.2.yml ├── fig2_v3.0.yml ├── fig2_v3.2.yml ├── fig4_b_c.yml ├── fig3_d.yml ├── fig2_GF.yml ├── fig3_c.yml ├── fig4_a.yml ├── fig5_c.yml └── fig5_b.yml ├── assets └── mfp.png ├── tutorial_notebook └── mfp.png ├── README.md ├── data_info └── fig5_chino_hills_data_info.txt └── figure_scripts ├── fig2.py ├── fig5.py └── fig4.py /settings_files/timelist_chino.csv: -------------------------------------------------------------------------------- 1 | time,lat,lon 2 | 2008-07-29T18:42:15.0Z,33.953,-117.761 -------------------------------------------------------------------------------- /assets/mfp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seismology-hamburg/schippkus_hadziioannou_2022/HEAD/assets/mfp.png -------------------------------------------------------------------------------- /settings_files/synth_two_arrays.csv: -------------------------------------------------------------------------------- 1 | x,y 2 | -20,-26.33 3 | -40,-26.33 4 | -30,-41.33 5 | 40,-26.33 6 | 20,-26.33 7 | 30,-41.33 -------------------------------------------------------------------------------- /tutorial_notebook/mfp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seismology-hamburg/schippkus_hadziioannou_2022/HEAD/tutorial_notebook/mfp.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Matched Field Processsing for complex Earth structure 2 | 3 | [![DOI](https://zenodo.org/badge/438557201.svg)](https://zenodo.org/badge/latestdoi/438557201) 4 | 5 | 6 | 7 | Repository to accompany the paper entitled "Matched Field Processsing for complex Earth structure" by Schippkus & Hadziioannou, published as pre-print on EarthArXiv ([doi.org/10.31223/X5492H](https://doi.org/10.31223/X5492H)) and submitted to Geophysical Journal International for peer review. 8 | 9 | Here, we provide all scripts and data necessary to reproduce all of our results. 10 | 11 | `/tutorial_notebook` contains a Python Jupyter notebook that introduces standard Matched Field Processing in a few easy steps. 12 | 13 | `/settings_files` contains yaml settings files used in the Matched Field Processing code developed for this paper (see [seismology-hamburg/matched_field_processing](https://github.com/seismology-hamburg/matched_field_processing)). These are the input files used to generate the synthetic tests and real-data results in the manuscript. Note that for all figures, multiple `.yml` files are provided. These correspond either directly to each subplots or the type of GF used. 14 | 15 | `/data_info` contains information on which stations and data exactly were used for the two real data examples in Figures 5 & 6 of our manuscript. For the Chino Hills earthquake, this includes data from 54 seismic stations of the CI network (estimated file size 40 MB). For the continous seismic data in February 2019, this includes data from 342 of the BE, BW, CH, CZ, DK, EI, FR, G, GB, GE, GR, GU, II, IM, IU, IV, LX, MN, NL, NO, OE, OX, PL, PM, RD, SX, TH, and WM networks (estimated file size 2.0 GB). For citations of these networks refer to our paper or [fdsn.org/networks](https://fdsn.org/networks). 16 | 17 | `/figure_scripts` contains Python scripts used to produce the figures in our manuscript from the output files of [seismology-hamburg/matched_field_processing](https://github.com/seismology-hamburg/matched_field_processing) using the settings files in `/settings_files`. Note that these scripts will require adapation to your file structure. They are provided as-is and are not well-documented. 18 | -------------------------------------------------------------------------------- /data_info/fig5_chino_hills_data_info.txt: -------------------------------------------------------------------------------- 1 | 54 Trace(s) in Stream: 2 | CI.ADO..LHZ | 2008-07-29T00:00:00.690800Z - 2008-07-29T23:59:59.690800Z | 1.0 Hz, 86400 samples 3 | CI.ARV..LHZ | 2008-07-29T00:00:00.069800Z - 2008-07-29T23:59:59.069800Z | 1.0 Hz, 86400 samples 4 | CI.BAK..LHZ | 2008-07-29T00:00:00.968800Z - 2008-07-29T23:59:59.968800Z | 1.0 Hz, 86400 samples 5 | CI.BAR..LHZ | 2008-07-29T00:00:00.560800Z - 2008-07-29T23:59:59.560800Z | 1.0 Hz, 86400 samples 6 | CI.BBR..LHZ | 2008-07-29T00:00:00.880600Z - 2008-07-29T23:59:59.880600Z | 1.0 Hz, 86400 samples 7 | CI.BC3..LHZ | 2008-07-29T00:00:00.084600Z - 2008-07-29T23:59:59.084600Z | 1.0 Hz, 86400 samples 8 | CI.BEL..LHZ | 2008-07-29T00:00:00.056600Z - 2008-07-29T23:59:59.056600Z | 1.0 Hz, 86400 samples 9 | CI.BFS..LHZ | 2008-07-29T00:00:00.366600Z - 2008-07-29T23:59:59.366600Z | 1.0 Hz, 86400 samples 10 | CI.CHF..LHZ | 2008-07-29T00:00:00.872600Z - 2008-07-29T23:59:59.872600Z | 1.0 Hz, 86400 samples 11 | CI.CIA..LHZ | 2008-07-29T00:00:00.932900Z - 2008-07-29T23:59:59.932900Z | 1.0 Hz, 86400 samples 12 | CI.CWC..LHZ | 2008-07-29T00:00:00.272800Z - 2008-07-29T23:59:59.272800Z | 1.0 Hz, 86400 samples 13 | CI.DAN..LHZ | 2008-07-29T00:00:00.026900Z - 2008-07-29T23:59:59.026900Z | 1.0 Hz, 86400 samples 14 | CI.DEC..LHZ | 2008-07-29T00:00:00.098600Z - 2008-07-29T23:59:59.098600Z | 1.0 Hz, 86400 samples 15 | CI.DGR..LHZ | 2008-07-29T00:00:00.698700Z - 2008-07-29T23:59:59.698700Z | 1.0 Hz, 86400 samples 16 | CI.DJJ..LHZ | 2008-07-29T00:00:00.902900Z - 2008-07-29T23:59:59.902900Z | 1.0 Hz, 86400 samples 17 | CI.DVT..LHZ | 2008-07-29T00:00:00.858600Z - 2008-07-29T23:59:59.858600Z | 1.0 Hz, 86400 samples 18 | CI.EDW2..LHZ | 2008-07-29T00:00:00.069600Z - 2008-07-29T23:59:59.069600Z | 1.0 Hz, 86400 samples 19 | CI.FMP..LHZ | 2008-07-29T00:00:00.842600Z - 2008-07-29T23:59:59.842600Z | 1.0 Hz, 86400 samples 20 | CI.FUR..LHZ | 2008-07-29T00:00:00.128900Z - 2008-07-29T23:59:59.128900Z | 1.0 Hz, 86400 samples 21 | CI.GLA..LHZ | 2008-07-29T00:00:00.035700Z - 2008-07-29T23:59:59.035700Z | 1.0 Hz, 86400 samples 22 | CI.GMR..LHZ | 2008-07-29T00:00:00.069500Z - 2008-07-29T23:59:59.069500Z | 1.0 Hz, 86400 samples 23 | CI.GRA..LHZ | 2008-07-29T00:00:00.582600Z - 2008-07-29T23:59:59.582600Z | 1.0 Hz, 86400 samples 24 | CI.GSC..LHZ | 2008-07-29T00:00:00.716900Z - 2008-07-29T23:59:59.716900Z | 1.0 Hz, 86400 samples 25 | CI.HEC..LHZ | 2008-07-29T00:00:00.930800Z - 2008-07-29T23:59:59.930800Z | 1.0 Hz, 86400 samples 26 | CI.IRM..LHZ | 2008-07-29T00:00:00.024900Z - 2008-07-29T23:59:59.024900Z | 1.0 Hz, 86400 samples 27 | CI.ISA..LHZ | 2008-07-29T00:00:00.936900Z - 2008-07-29T23:59:59.936900Z | 1.0 Hz, 86400 samples 28 | CI.LGU..LHZ | 2008-07-29T00:00:00.516900Z - 2008-07-29T23:59:59.516900Z | 1.0 Hz, 86400 samples 29 | CI.LRL..LHZ | 2008-07-29T00:00:00.690800Z - 2008-07-29T23:59:59.690800Z | 1.0 Hz, 86400 samples 30 | CI.MLAC..LHZ | 2008-07-29T00:00:00.248900Z - 2008-07-29T23:59:59.248900Z | 1.0 Hz, 86400 samples 31 | CI.MPM..LHZ | 2008-07-29T00:00:00.069500Z - 2008-07-29T23:59:59.069500Z | 1.0 Hz, 86400 samples 32 | CI.MUR..LHZ | 2008-07-29T00:00:00.098600Z - 2008-07-29T23:59:59.098600Z | 1.0 Hz, 86400 samples 33 | CI.MWC..LHZ | 2008-07-29T00:00:00.412800Z - 2008-07-29T23:59:59.412800Z | 1.0 Hz, 86400 samples 34 | CI.OSI..LHZ | 2008-07-29T00:00:00.648100Z - 2008-07-29T23:59:59.648100Z | 1.0 Hz, 86400 samples 35 | CI.PASC.00.LHZ | 2008-07-29T00:00:00.069500Z - 2008-07-29T23:59:59.069500Z | 1.0 Hz, 86400 samples 36 | CI.PDM..LHZ | 2008-07-29T00:00:00.066500Z - 2008-07-29T23:59:59.066500Z | 1.0 Hz, 86400 samples 37 | CI.PLM..LHZ | 2008-07-29T00:00:00.990900Z - 2008-07-29T23:59:59.990900Z | 1.0 Hz, 86400 samples 38 | CI.RCT..LHZ | 2008-07-29T00:00:00.482600Z - 2008-07-29T23:59:59.482600Z | 1.0 Hz, 86400 samples 39 | CI.RPV..LHZ | 2008-07-29T00:00:00.306900Z - 2008-07-29T23:59:59.306900Z | 1.0 Hz, 86400 samples 40 | CI.RRX..LHZ | 2008-07-29T00:00:00.368900Z - 2008-07-29T23:59:59.368900Z | 1.0 Hz, 86400 samples 41 | CI.SBC..LHZ | 2008-07-29T00:00:00.622900Z - 2008-07-29T23:59:59.622900Z | 1.0 Hz, 86400 samples 42 | CI.SCI2..LHZ | 2008-07-29T00:00:00.069500Z - 2008-07-29T23:59:59.069500Z | 1.0 Hz, 86400 samples 43 | CI.SCZ2..LHZ | 2008-07-29T00:00:00.069900Z - 2008-07-29T23:59:59.069900Z | 1.0 Hz, 86400 samples 44 | CI.SDD..LHZ | 2008-07-29T00:00:00.286900Z - 2008-07-29T23:59:59.286900Z | 1.0 Hz, 86400 samples 45 | CI.SHO..LHZ | 2008-07-29T00:00:00.294900Z - 2008-07-29T23:59:59.294900Z | 1.0 Hz, 86400 samples 46 | CI.SLA..LHZ | 2008-07-29T00:00:00.560600Z - 2008-07-29T23:59:59.560600Z | 1.0 Hz, 86400 samples 47 | CI.SMM..LHZ | 2008-07-29T00:00:00.488800Z - 2008-07-29T23:59:59.488800Z | 1.0 Hz, 86400 samples 48 | CI.SVD..LHZ | 2008-07-29T00:00:00.723600Z - 2008-07-29T23:59:59.723600Z | 1.0 Hz, 86400 samples 49 | CI.SWS..LHZ | 2008-07-29T00:00:00.896800Z - 2008-07-29T23:59:59.896800Z | 1.0 Hz, 86400 samples 50 | CI.TIN..LHZ | 2008-07-29T00:00:00.408900Z - 2008-07-29T23:59:59.408900Z | 1.0 Hz, 86400 samples 51 | CI.TUQ..LHZ | 2008-07-29T00:00:00.000900Z - 2008-07-29T23:59:59.000900Z | 1.0 Hz, 86400 samples 52 | CI.USC..LHZ | 2008-07-29T00:00:00.548100Z - 2008-07-29T23:59:59.548100Z | 1.0 Hz, 86400 samples 53 | CI.VCS..LHZ | 2008-07-29T00:00:00.498900Z - 2008-07-29T23:59:59.498900Z | 1.0 Hz, 86400 samples 54 | CI.VES..LHZ | 2008-07-29T00:00:00.730900Z - 2008-07-29T23:59:59.730900Z | 1.0 Hz, 86400 samples 55 | CI.VTV..LHZ | 2008-07-29T00:00:00.910500Z - 2008-07-29T23:59:59.910500Z | 1.0 Hz, 86400 samples -------------------------------------------------------------------------------- /settings_files/fig3_b.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig3_b" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "overlapping_windows" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "/path/to/timelists/timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: true 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "cartesian" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_x: [-100, 100] 51 | grid_limits_y: [-100, 100] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .25 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ["/path/to/data/fig6_atlantic.mseed"] 62 | 63 | # Location of station metadata files (stationXML) 64 | sta_xml_dir: "/data/stations/" 65 | 66 | # Sampling rate of the recorded data and synthetic green's functions. 67 | # Make sure this is correct for all data. 68 | # Green's functions database may only support up to 1Hz. 69 | sampling_rate: 1.0 70 | 71 | # 5 -- SYNTHETICS 72 | 73 | # the following settings determine the synthetics setup 74 | # toggle whether to do synthetics or real data processing 75 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 76 | do_synth: true 77 | 78 | # How should synthetic data be computed? 79 | # Options: 80 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 81 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 82 | synth_data_type: "database_GF" 83 | 84 | # Where are synthetic sources placed? 85 | # Coordinate units depend on geometry_type: 86 | # kilometers, if geometry_type is "cartesian" 87 | # degrees, if geometry_type is "geographic". 88 | synth_sources: [[0, 0]] 89 | 90 | # Add noise to synthetics 91 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 92 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 93 | # Percentage of max amplitude of noise level 94 | add_noise_to_synth: 0 95 | 96 | # Run multiple iterations with different random noise added. 97 | # Can help test/inform stability of results. 98 | add_noise_iterations: 1 99 | 100 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 101 | # - true: Define synthetic locations as below. 102 | # - false: Run synthetic tests using station locations from the stations in data_fn. 103 | use_synth_stations: true 104 | 105 | # Method of defining synthetic station locations. 106 | # Settings for each method are below. 107 | # Options: 108 | # - "file": Provide an external list of locations. See examples in synth/ 109 | # - "grid": Gridded distribution of evenly spaced stations 110 | # - "uniform": Uniform randomly distribution of stations 111 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 112 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 113 | synth_stations_mode: 'file' 114 | 115 | # if synth_stations_mode == 'file', which file to use 116 | synth_stations_file: "./synth_two_arrays.csv" 117 | 118 | # if synth_stations_mode == "partial_circle", how circle is defined 119 | # total potential station locations along circle 120 | synth_stations_circle_n: 20 121 | # number of total potential station locations that are actually used 122 | synth_stations_circle_max: 20 123 | # radius of circle in kilometers 124 | synth_stations_circle_radius: 1 125 | 126 | # if synth_stations_mode == 'grid' or 'uniform' 127 | # how many stations should be placed 128 | synth_stations_n: 400 129 | 130 | # alternatively, use locations of all open stations via 'ORFEUS' 131 | use_open_worldwide_stations: false 132 | 133 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 134 | 135 | # Green's functions extracted from the database may be used (depending on other settings) for 136 | # a) synthetic data if run is synthetic (defined above) 137 | # b) synthetic wavefield that data is matched against (defined below) 138 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 139 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 140 | 141 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 142 | 143 | # How is the synthetic wavefield / steering vector computed 144 | # Options: 145 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 146 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 147 | type_of_gf: "GF" 148 | 149 | # if type_of_gf is "GF", at what depth does the source lie. 150 | # given in kilometers 151 | source_depth: 0 152 | 153 | # How to handle correct for amplitudes of Green's functions from database. 154 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 155 | # We recommend "whitening_GF". 156 | # Options: 157 | # - "None": no treatment 158 | # - "whitening_GF": frequency-domain normalisation 159 | # - "time_domain_norm": time-domain normalisation 160 | # - "spreading": compute and apply spreading correction for surface waves 161 | amplitude_treatment: "spreading" 162 | 163 | # if type_of_gf is "v_const", specify the velocity used. 164 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 165 | # Δx is euclidean distance if geometry_type is cartesian 166 | # Δx is great-circle distance if geometry_type is geographic 167 | v_const: 3.0 168 | 169 | # 9 -- FREQUENCIES 170 | 171 | # A list of all frequencyt pairs to analyse. 172 | # Options: 173 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 174 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 175 | frequency_bands: [[0.13, 0.15]] 176 | 177 | # 10 -- SOURCE MECHANISM 178 | 179 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 180 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 181 | # Explosion 182 | MT: [1, 1, 1, 0, 0, 0] 183 | 184 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 185 | # For simplicity, this is a grid-search over strike/dip/rake. 186 | # moment tensors are computed from strike/dip/rake. 187 | strike_dip_rake_gridsearch: false 188 | 189 | # Strike/dip/rake are searched only in independent range. 190 | # Search strike in limits [180, 360] with given spacing 191 | strike_spacing: 10 192 | # Search dip in limits [0, 90] with given spacing 193 | dip_spacing: 10 194 | # Search rake in limits [-180, 180] with given spacing 195 | rake_spacing: 10 196 | 197 | # 6 -- COMPUTATIONAL EFFICIENCY 198 | 199 | # How many processes are spawned to increase computational speed. 200 | # !! WARNING: Using only 1 process is not supported at the moment. 201 | n_processes: 50 202 | 203 | # Distances are rounded to reduce number of Green's functions that need to be computed. 204 | # Unit is always kilometers (also if geometry_type is geographic). 205 | # Examples what accuray each ronding resuls in: 206 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 207 | decimal_round: 2 208 | 209 | # Grid-points that are on-land can be excluded for speed. 210 | # Only applies, if geometry_type is geographic. 211 | exclude_land: false 212 | 213 | # 11 -- MISC 214 | 215 | # Plot results for each run 216 | do_plot: true 217 | 218 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 219 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 220 | # list of all components to utilize 221 | components: ['Z'] 222 | wavetypes: ['Z'] 223 | 224 | # Initial implentation of singular-value decomposition 225 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 226 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 227 | # that contribute to signal vs those that contribute to noise. 228 | do_svd: false 229 | 230 | # How many eigenvectors should be kept. 231 | # Code will loop over all values given in the list. 232 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 233 | # and there are n_stations eigenvectors. 234 | n_svd_components: [0, 5, 10, 25, 50, 100] 235 | -------------------------------------------------------------------------------- /settings_files/fig3_a.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig3_a" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "overlapping_windows" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "/path/to/timelists/timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: true 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "cartesian" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_x: [-100, 100] 51 | grid_limits_y: [-100, 100] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .25 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ["/path/to/data/fig6_atlantic.mseed"] 62 | 63 | # Location of station metadata files (stationXML) 64 | sta_xml_dir: "/data/stations/" 65 | 66 | # Sampling rate of the recorded data and synthetic green's functions. 67 | # Make sure this is correct for all data. 68 | # Green's functions database may only support up to 1Hz. 69 | sampling_rate: 1.0 70 | 71 | # 5 -- SYNTHETICS 72 | 73 | # the following settings determine the synthetics setup 74 | # toggle whether to do synthetics or real data processing 75 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 76 | do_synth: true 77 | 78 | # How should synthetic data be computed? 79 | # Options: 80 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 81 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 82 | synth_data_type: "database_GF" 83 | 84 | # Where are synthetic sources placed? 85 | # Coordinate units depend on geometry_type: 86 | # kilometers, if geometry_type is "cartesian" 87 | # degrees, if geometry_type is "geographic". 88 | synth_sources: [[0, 0]] 89 | 90 | # Add noise to synthetics 91 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 92 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 93 | # Percentage of max amplitude of noise level 94 | add_noise_to_synth: 0 95 | 96 | # Run multiple iterations with different random noise added. 97 | # Can help test/inform stability of results. 98 | add_noise_iterations: 1 99 | 100 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 101 | # - true: Define synthetic locations as below. 102 | # - false: Run synthetic tests using station locations from the stations in data_fn. 103 | use_synth_stations: true 104 | 105 | # Method of defining synthetic station locations. 106 | # Settings for each method are below. 107 | # Options: 108 | # - "file": Provide an external list of locations. See examples in synth/ 109 | # - "grid": Gridded distribution of evenly spaced stations 110 | # - "uniform": Uniform randomly distribution of stations 111 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 112 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 113 | synth_stations_mode: 'file' 114 | 115 | # if synth_stations_mode == 'file', which file to use 116 | synth_stations_file: "./synth_two_arrays.csv" 117 | 118 | # if synth_stations_mode == "partial_circle", how circle is defined 119 | # total potential station locations along circle 120 | synth_stations_circle_n: 20 121 | # number of total potential station locations that are actually used 122 | synth_stations_circle_max: 20 123 | # radius of circle in kilometers 124 | synth_stations_circle_radius: 1 125 | 126 | # if synth_stations_mode == 'grid' or 'uniform' 127 | # how many stations should be placed 128 | synth_stations_n: 400 129 | 130 | # alternatively, use locations of all open stations via 'ORFEUS' 131 | use_open_worldwide_stations: false 132 | 133 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 134 | 135 | # Green's functions extracted from the database may be used (depending on other settings) for 136 | # a) synthetic data if run is synthetic (defined above) 137 | # b) synthetic wavefield that data is matched against (defined below) 138 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 139 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 140 | 141 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 142 | 143 | # How is the synthetic wavefield / steering vector computed 144 | # Options: 145 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 146 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 147 | type_of_gf: "GF" 148 | 149 | # if type_of_gf is "GF", at what depth does the source lie. 150 | # given in kilometers 151 | source_depth: 0 152 | 153 | # How to handle correct for amplitudes of Green's functions from database. 154 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 155 | # We recommend "whitening_GF". 156 | # Options: 157 | # - "None": no treatment 158 | # - "whitening_GF": frequency-domain normalisation 159 | # - "time_domain_norm": time-domain normalisation 160 | # - "spreading_attenuation": compute and apply spreading + attenuation terms for Rayleigh waves 161 | amplitude_treatment: "None" 162 | 163 | # if type_of_gf is "v_const", specify the velocity used. 164 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 165 | # Δx is euclidean distance if geometry_type is cartesian 166 | # Δx is great-circle distance if geometry_type is geographic 167 | v_const: 3.0 168 | 169 | # 9 -- FREQUENCIES 170 | 171 | # A list of all frequencyt pairs to analyse. 172 | # Options: 173 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 174 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 175 | frequency_bands: [[0.13, 0.15]] 176 | 177 | # 10 -- SOURCE MECHANISM 178 | 179 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 180 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 181 | # Explosion 182 | MT: [1, 1, 1, 0, 0, 0] 183 | 184 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 185 | # For simplicity, this is a grid-search over strike/dip/rake. 186 | # moment tensors are computed from strike/dip/rake. 187 | strike_dip_rake_gridsearch: false 188 | 189 | # Strike/dip/rake are searched only in independent range. 190 | # Search strike in limits [180, 360] with given spacing 191 | strike_spacing: 10 192 | # Search dip in limits [0, 90] with given spacing 193 | dip_spacing: 10 194 | # Search rake in limits [-180, 180] with given spacing 195 | rake_spacing: 10 196 | 197 | # 6 -- COMPUTATIONAL EFFICIENCY 198 | 199 | # How many processes are spawned to increase computational speed. 200 | # !! WARNING: Using only 1 process is not supported at the moment. 201 | n_processes: 50 202 | 203 | # Distances are rounded to reduce number of Green's functions that need to be computed. 204 | # Unit is always kilometers (also if geometry_type is geographic). 205 | # Examples what accuray each ronding resuls in: 206 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 207 | decimal_round: 2 208 | 209 | # Grid-points that are on-land can be excluded for speed. 210 | # Only applies, if geometry_type is geographic. 211 | exclude_land: false 212 | 213 | # 11 -- MISC 214 | 215 | # Plot results for each run 216 | do_plot: true 217 | 218 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 219 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 220 | # list of all components to utilize 221 | components: ['Z'] 222 | wavetypes: ['Z'] 223 | 224 | # Initial implentation of singular-value decomposition 225 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 226 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 227 | # that contribute to signal vs those that contribute to noise. 228 | do_svd: false 229 | 230 | # How many eigenvectors should be kept. 231 | # Code will loop over all values given in the list. 232 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 233 | # and there are n_stations eigenvectors. 234 | n_svd_components: [0, 5, 10, 25, 50, 100] 235 | -------------------------------------------------------------------------------- /settings_files/fig2_v3.4.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig2_v3.4" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "overlapping_windows" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "/path/to/timelists/timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: true 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "cartesian" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_x: [-100, 100] 51 | grid_limits_y: [-100, 100] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .25 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ["/path/to/data/fig6_atlantic.mseed"] 62 | 63 | # Location of station metadata files (stationXML) 64 | sta_xml_dir: "/data/stations/" 65 | 66 | # Sampling rate of the recorded data and synthetic green's functions. 67 | # Make sure this is correct for all data. 68 | # Green's functions database may only support up to 1Hz. 69 | sampling_rate: 1.0 70 | 71 | # 5 -- SYNTHETICS 72 | 73 | # the following settings determine the synthetics setup 74 | # toggle whether to do synthetics or real data processing 75 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 76 | do_synth: true 77 | 78 | # How should synthetic data be computed? 79 | # Options: 80 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 81 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 82 | synth_data_type: "database_GF" 83 | 84 | # Where are synthetic sources placed? 85 | # Coordinate units depend on geometry_type: 86 | # kilometers, if geometry_type is "cartesian" 87 | # degrees, if geometry_type is "geographic". 88 | synth_sources: [[0, 0]] 89 | 90 | # Add noise to synthetics 91 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 92 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 93 | # Percentage of max amplitude of noise level 94 | add_noise_to_synth: 0 95 | 96 | # Run multiple iterations with different random noise added. 97 | # Can help test/inform stability of results. 98 | add_noise_iterations: 1 99 | 100 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 101 | # - true: Define synthetic locations as below. 102 | # - false: Run synthetic tests using station locations from the stations in data_fn. 103 | use_synth_stations: true 104 | 105 | # Method of defining synthetic station locations. 106 | # Settings for each method are below. 107 | # Options: 108 | # - "file": Provide an external list of locations. See examples in synth/ 109 | # - "grid": Gridded distribution of evenly spaced stations 110 | # - "uniform": Uniform randomly distribution of stations 111 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 112 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 113 | synth_stations_mode: 'file' 114 | 115 | # if synth_stations_mode == 'file', which file to use 116 | synth_stations_file: "./synth_two_arrays.csv" 117 | 118 | # if synth_stations_mode == "partial_circle", how circle is defined 119 | # total potential station locations along circle 120 | synth_stations_circle_n: 20 121 | # number of total potential station locations that are actually used 122 | synth_stations_circle_max: 20 123 | # radius of circle in kilometers 124 | synth_stations_circle_radius: 1 125 | 126 | # if synth_stations_mode == 'grid' or 'uniform' 127 | # how many stations should be placed 128 | synth_stations_n: 400 129 | 130 | # alternatively, use locations of all open stations via 'ORFEUS' 131 | use_open_worldwide_stations: false 132 | 133 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 134 | 135 | # Green's functions extracted from the database may be used (depending on other settings) for 136 | # a) synthetic data if run is synthetic (defined above) 137 | # b) synthetic wavefield that data is matched against (defined below) 138 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 139 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 140 | 141 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 142 | 143 | # How is the synthetic wavefield / steering vector computed 144 | # Options: 145 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 146 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 147 | type_of_gf: "v_const" 148 | 149 | # if type_of_gf is "GF", at what depth does the source lie. 150 | # given in kilometers 151 | source_depth: 0 152 | 153 | # How to handle correct for amplitudes of Green's functions from database. 154 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 155 | # We recommend "whitening_GF". 156 | # Options: 157 | # - "whitening_GF": frequency-domain normalisation 158 | # - "time_domain_norm": time-domain normalisation 159 | # - "spreading_attenuation": compute and apply spreading + attenuation terms for Rayleigh waves 160 | amplitude_treatment: "whitening_GF" 161 | 162 | # if type_of_gf is "v_const", specify the velocity used. 163 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 164 | # Δx is euclidean distance if geometry_type is cartesian 165 | # Δx is great-circle distance if geometry_type is geographic 166 | v_const: 3.4 167 | 168 | # 9 -- FREQUENCIES 169 | 170 | # A list of all frequencyt pairs to analyse. 171 | # Options: 172 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 173 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 174 | frequency_bands: [[0.05, 0.2], [0.13, 0.15]] 175 | 176 | # 10 -- SOURCE MECHANISM 177 | 178 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 179 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 180 | # Explosion 181 | MT: [1, 1, 1, 0, 0, 0] 182 | 183 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 184 | # For simplicity, this is a grid-search over strike/dip/rake. 185 | # moment tensors are computed from strike/dip/rake. 186 | strike_dip_rake_gridsearch: false 187 | 188 | # Strike/dip/rake are searched only in independent range. 189 | # Search strike in limits [180, 360] with given spacing 190 | strike_spacing: 10 191 | # Search dip in limits [0, 90] with given spacing 192 | dip_spacing: 10 193 | # Search rake in limits [-180, 180] with given spacing 194 | rake_spacing: 10 195 | 196 | # 6 -- COMPUTATIONAL EFFICIENCY 197 | 198 | # How many processes are spawned to increase computational speed. 199 | # !! WARNING: Using only 1 process is not supported at the moment. 200 | n_processes: 50 201 | 202 | # Distances are rounded to reduce number of Green's functions that need to be computed. 203 | # Unit is always kilometers (also if geometry_type is geographic). 204 | # Examples what accuray each ronding resuls in: 205 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 206 | decimal_round: 2 207 | 208 | # Grid-points that are on-land can be excluded for speed. 209 | # Only applies, if geometry_type is geographic. 210 | exclude_land: false 211 | 212 | # 11 -- MISC 213 | 214 | # Plot results for each run 215 | do_plot: true 216 | 217 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 218 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 219 | # list of all components to utilize 220 | components: ['Z'] 221 | wavetypes: ['Z'] 222 | 223 | # Initial implentation of singular-value decomposition 224 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 225 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 226 | # that contribute to signal vs those that contribute to noise. 227 | do_svd: false 228 | 229 | # How many eigenvectors should be kept. 230 | # Code will loop over all values given in the list. 231 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 232 | # and there are n_stations eigenvectors. 233 | n_svd_components: [0, 5, 10, 25, 50, 100] 234 | -------------------------------------------------------------------------------- /settings_files/fig2_v3.6.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig2_v3.6" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "overlapping_windows" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "/path/to/timelists/timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: true 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "cartesian" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_x: [-100, 100] 51 | grid_limits_y: [-100, 100] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .25 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ["/path/to/data/fig6_atlantic.mseed"] 62 | 63 | # Location of station metadata files (stationXML) 64 | sta_xml_dir: "/data/stations/" 65 | 66 | # Sampling rate of the recorded data and synthetic green's functions. 67 | # Make sure this is correct for all data. 68 | # Green's functions database may only support up to 1Hz. 69 | sampling_rate: 1.0 70 | 71 | # 5 -- SYNTHETICS 72 | 73 | # the following settings determine the synthetics setup 74 | # toggle whether to do synthetics or real data processing 75 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 76 | do_synth: true 77 | 78 | # How should synthetic data be computed? 79 | # Options: 80 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 81 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 82 | synth_data_type: "database_GF" 83 | 84 | # Where are synthetic sources placed? 85 | # Coordinate units depend on geometry_type: 86 | # kilometers, if geometry_type is "cartesian" 87 | # degrees, if geometry_type is "geographic". 88 | synth_sources: [[0, 0]] 89 | 90 | # Add noise to synthetics 91 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 92 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 93 | # Percentage of max amplitude of noise level 94 | add_noise_to_synth: 0 95 | 96 | # Run multiple iterations with different random noise added. 97 | # Can help test/inform stability of results. 98 | add_noise_iterations: 1 99 | 100 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 101 | # - true: Define synthetic locations as below. 102 | # - false: Run synthetic tests using station locations from the stations in data_fn. 103 | use_synth_stations: true 104 | 105 | # Method of defining synthetic station locations. 106 | # Settings for each method are below. 107 | # Options: 108 | # - "file": Provide an external list of locations. See examples in synth/ 109 | # - "grid": Gridded distribution of evenly spaced stations 110 | # - "uniform": Uniform randomly distribution of stations 111 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 112 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 113 | synth_stations_mode: 'file' 114 | 115 | # if synth_stations_mode == 'file', which file to use 116 | synth_stations_file: "./synth_two_arrays.csv" 117 | 118 | # if synth_stations_mode == "partial_circle", how circle is defined 119 | # total potential station locations along circle 120 | synth_stations_circle_n: 20 121 | # number of total potential station locations that are actually used 122 | synth_stations_circle_max: 20 123 | # radius of circle in kilometers 124 | synth_stations_circle_radius: 1 125 | 126 | # if synth_stations_mode == 'grid' or 'uniform' 127 | # how many stations should be placed 128 | synth_stations_n: 400 129 | 130 | # alternatively, use locations of all open stations via 'ORFEUS' 131 | use_open_worldwide_stations: false 132 | 133 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 134 | 135 | # Green's functions extracted from the database may be used (depending on other settings) for 136 | # a) synthetic data if run is synthetic (defined above) 137 | # b) synthetic wavefield that data is matched against (defined below) 138 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 139 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 140 | 141 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 142 | 143 | # How is the synthetic wavefield / steering vector computed 144 | # Options: 145 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 146 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 147 | type_of_gf: "v_const" 148 | 149 | # if type_of_gf is "GF", at what depth does the source lie. 150 | # given in kilometers 151 | source_depth: 0 152 | 153 | # How to handle correct for amplitudes of Green's functions from database. 154 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 155 | # We recommend "whitening_GF". 156 | # Options: 157 | # - "whitening_GF": frequency-domain normalisation 158 | # - "time_domain_norm": time-domain normalisation 159 | # - "spreading_attenuation": compute and apply spreading + attenuation terms for Rayleigh waves 160 | amplitude_treatment: "whitening_GF" 161 | 162 | # if type_of_gf is "v_const", specify the velocity used. 163 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 164 | # Δx is euclidean distance if geometry_type is cartesian 165 | # Δx is great-circle distance if geometry_type is geographic 166 | v_const: 3.6 167 | 168 | # 9 -- FREQUENCIES 169 | 170 | # A list of all frequencyt pairs to analyse. 171 | # Options: 172 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 173 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 174 | frequency_bands: [[0.05, 0.2], [0.13, 0.15]] 175 | 176 | # 10 -- SOURCE MECHANISM 177 | 178 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 179 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 180 | # Explosion 181 | MT: [1, 1, 1, 0, 0, 0] 182 | 183 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 184 | # For simplicity, this is a grid-search over strike/dip/rake. 185 | # moment tensors are computed from strike/dip/rake. 186 | strike_dip_rake_gridsearch: false 187 | 188 | # Strike/dip/rake are searched only in independent range. 189 | # Search strike in limits [180, 360] with given spacing 190 | strike_spacing: 10 191 | # Search dip in limits [0, 90] with given spacing 192 | dip_spacing: 10 193 | # Search rake in limits [-180, 180] with given spacing 194 | rake_spacing: 10 195 | 196 | # 6 -- COMPUTATIONAL EFFICIENCY 197 | 198 | # How many processes are spawned to increase computational speed. 199 | # !! WARNING: Using only 1 process is not supported at the moment. 200 | n_processes: 50 201 | 202 | # Distances are rounded to reduce number of Green's functions that need to be computed. 203 | # Unit is always kilometers (also if geometry_type is geographic). 204 | # Examples what accuray each ronding resuls in: 205 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 206 | decimal_round: 2 207 | 208 | # Grid-points that are on-land can be excluded for speed. 209 | # Only applies, if geometry_type is geographic. 210 | exclude_land: false 211 | 212 | # 11 -- MISC 213 | 214 | # Plot results for each run 215 | do_plot: true 216 | 217 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 218 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 219 | # list of all components to utilize 220 | components: ['Z'] 221 | wavetypes: ['Z'] 222 | 223 | # Initial implentation of singular-value decomposition 224 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 225 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 226 | # that contribute to signal vs those that contribute to noise. 227 | do_svd: false 228 | 229 | # How many eigenvectors should be kept. 230 | # Code will loop over all values given in the list. 231 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 232 | # and there are n_stations eigenvectors. 233 | n_svd_components: [0, 5, 10, 25, 50, 100] 234 | -------------------------------------------------------------------------------- /settings_files/fig5_a.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig5_a" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "file" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "./timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: false 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "geographic" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_lon: [-121, -113] 51 | grid_limits_lat: [32, 37] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .1 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ['/path/to/data/fig5_chino_hills.mseed'] 62 | 63 | # Location of station metadata files (stationXML) 64 | sta_xml_dir: "/path/to/stationxml/" 65 | 66 | # Sampling rate of the recorded data and synthetic green's functions. 67 | # Make sure this is correct for all data. 68 | # Green's functions database may only support up to 1Hz. 69 | sampling_rate: 1.0 70 | 71 | # 5 -- SYNTHETICS 72 | 73 | # the following settings determine the synthetics setup 74 | # toggle whether to do synthetics or real data processing 75 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 76 | do_synth: false 77 | 78 | # How should synthetic data be computed? 79 | # Options: 80 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 81 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 82 | synth_data_type: "database_GF" 83 | 84 | # Where are synthetic sources placed? 85 | # Coordinate units depend on geometry_type: 86 | # kilometers, if geometry_type is "cartesian" 87 | # degrees, if geometry_type is "geographic". 88 | synth_sources: [[0, 0]] 89 | 90 | # Add noise to synthetics 91 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 92 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 93 | # Percentage of max amplitude of noise level 94 | add_noise_to_synth: 0 95 | 96 | # Run multiple iterations with different random noise added. 97 | # Can help test/inform stability of results. 98 | add_noise_iterations: 1 99 | 100 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 101 | # - true: Define synthetic locations as below. 102 | # - false: Run synthetic tests using station locations from the stations in data_fn. 103 | use_synth_stations: false 104 | 105 | # Method of defining synthetic station locations. 106 | # Settings for each method are below. 107 | # Options: 108 | # - "file": Provide an external list of locations. See examples in synth/ 109 | # - "grid": Gridded distribution of evenly spaced stations 110 | # - "uniform": Uniform randomly distribution of stations 111 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 112 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 113 | synth_stations_mode: 'file' 114 | 115 | # if synth_stations_mode == 'file', which file to use 116 | # synth_stations_file: './synth/synth_three_arrays_50km.csv' 117 | synth_stations_file: "./synth_two_arrays.csv" 118 | 119 | # if synth_stations_mode == "partial_circle", how circle is defined 120 | # total potential station locations along circle 121 | synth_stations_circle_n: 20 122 | # number of total potential station locations that are actually used 123 | synth_stations_circle_max: 20 124 | # radius of circle in kilometers 125 | synth_stations_circle_radius: 1 126 | 127 | # if synth_stations_mode == 'grid' or 'uniform' 128 | # how many stations should be placed 129 | synth_stations_n: 400 130 | 131 | # alternatively, use locations of all open stations via 'ORFEUS' 132 | use_open_worldwide_stations: false 133 | 134 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 135 | 136 | # Green's functions extracted from the database may be used (depending on other settings) for 137 | # a) synthetic data if run is synthetic (defined above) 138 | # b) synthetic wavefield that data is matched against (defined below) 139 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 140 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 141 | 142 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 143 | 144 | # How is the synthetic wavefield / steering vector computed 145 | # Options: 146 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 147 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 148 | type_of_gf: "v_const" 149 | 150 | # if type_of_gf is "GF", at what depth does the source lie. 151 | # given in kilometers 152 | source_depth: 15.5 153 | 154 | # How to handle correct for amplitudes of Green's functions from database. 155 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 156 | # We recommend "whitening_GF". 157 | # Options: 158 | # - "None": no treatment 159 | # - "whitening_GF": frequency-domain normalisation 160 | # - "time_domain_norm": time-domain normalisation 161 | # - "spreading": compute and apply spreading correction for surface waves 162 | amplitude_treatment: "whitening_GF" 163 | 164 | # if type_of_gf is "v_const", specify the velocity used. 165 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 166 | # Δx is euclidean distance if geometry_type is cartesian 167 | # Δx is great-circle distance if geometry_type is geographic 168 | v_const: 3.2 169 | 170 | # 9 -- FREQUENCIES 171 | 172 | # A list of all frequencyt pairs to analyse. 173 | # Options: 174 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 175 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 176 | frequency_bands: [[0.1, 0.2]] 177 | 178 | # 10 -- SOURCE MECHANISM 179 | 180 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 181 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 182 | # Explosion 183 | MT: [1, 1, 1, 0, 0, 0] 184 | 185 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 186 | # For simplicity, this is a grid-search over strike/dip/rake. 187 | # moment tensors are computed from strike/dip/rake. 188 | strike_dip_rake_gridsearch: false 189 | 190 | # Strike/dip/rake are searched only in independent range. 191 | # Search strike in limits [180, 360] with given spacing 192 | strike_spacing: 10 193 | # Search dip in limits [0, 90] with given spacing 194 | dip_spacing: 10 195 | # Search rake in limits [-180, 180] with given spacing 196 | rake_spacing: 10 197 | 198 | # 6 -- COMPUTATIONAL EFFICIENCY 199 | 200 | # How many processes are spawned to increase computational speed. 201 | # !! WARNING: Using only 1 process is not supported at the moment. 202 | n_processes: 50 203 | 204 | # Distances are rounded to reduce number of Green's functions that need to be computed. 205 | # Unit is always kilometers (also if geometry_type is geographic). 206 | # Examples what accuray each ronding resuls in: 207 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 208 | decimal_round: 2 209 | 210 | # Grid-points that are on-land can be excluded for speed. 211 | # Only applies, if geometry_type is geographic. 212 | exclude_land: false 213 | 214 | # 11 -- MISC 215 | 216 | # Plot results for each run 217 | do_plot: true 218 | 219 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 220 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 221 | # list of all components to utilize 222 | components: ['Z'] 223 | wavetypes: ['Z'] 224 | 225 | # Initial implentation of singular-value decomposition 226 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 227 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 228 | # that contribute to signal vs those that contribute to noise. 229 | do_svd: false 230 | 231 | # How many eigenvectors should be kept. 232 | # Code will loop over all values given in the list. 233 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 234 | # and there are n_stations eigenvectors. 235 | n_svd_components: [0, 5, 10, 25, 50, 100] 236 | -------------------------------------------------------------------------------- /settings_files/fig6_GF.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig6_GF" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "overlapping_windows" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "./timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: false 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "geographic" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_lon: [-18, 20] 51 | grid_limits_lat: [39, 66] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .1 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ["/path/to/data/fig6_atlantic.mseed"] 62 | # data_fn: ['/path/to/data/fig5_chino_hills.mseed'] 63 | 64 | # Location of station metadata files (stationXML) 65 | sta_xml_dir: "/path/to/stationxml/" 66 | 67 | # Sampling rate of the recorded data and synthetic green's functions. 68 | # Make sure this is correct for all data. 69 | # Green's functions database may only support up to 1Hz. 70 | sampling_rate: 1.0 71 | 72 | # 5 -- SYNTHETICS 73 | 74 | # the following settings determine the synthetics setup 75 | # toggle whether to do synthetics or real data processing 76 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 77 | do_synth: false 78 | 79 | # How should synthetic data be computed? 80 | # Options: 81 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 82 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 83 | synth_data_type: "database_GF" 84 | 85 | # Where are synthetic sources placed? 86 | # Coordinate units depend on geometry_type: 87 | # kilometers, if geometry_type is "cartesian" 88 | # degrees, if geometry_type is "geographic". 89 | synth_sources: [[0, 0]] 90 | 91 | # Add noise to synthetics 92 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 93 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 94 | # Percentage of max amplitude of noise level 95 | add_noise_to_synth: 0 96 | 97 | # Run multiple iterations with different random noise added. 98 | # Can help test/inform stability of results. 99 | add_noise_iterations: 1 100 | 101 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 102 | # - true: Define synthetic locations as below. 103 | # - false: Run synthetic tests using station locations from the stations in data_fn. 104 | use_synth_stations: false 105 | 106 | # Method of defining synthetic station locations. 107 | # Settings for each method are below. 108 | # Options: 109 | # - "file": Provide an external list of locations. See examples in synth/ 110 | # - "grid": Gridded distribution of evenly spaced stations 111 | # - "uniform": Uniform randomly distribution of stations 112 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 113 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 114 | synth_stations_mode: 'file' 115 | 116 | # if synth_stations_mode == 'file', which file to use 117 | synth_stations_file: "./synth_two_arrays.csv" 118 | 119 | # if synth_stations_mode == "partial_circle", how circle is defined 120 | # total potential station locations along circle 121 | synth_stations_circle_n: 20 122 | # number of total potential station locations that are actually used 123 | synth_stations_circle_max: 20 124 | # radius of circle in kilometers 125 | synth_stations_circle_radius: 1 126 | 127 | # if synth_stations_mode == 'grid' or 'uniform' 128 | # how many stations should be placed 129 | synth_stations_n: 400 130 | 131 | # alternatively, use locations of all open stations via 'ORFEUS' 132 | use_open_worldwide_stations: false 133 | 134 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 135 | 136 | # Green's functions extracted from the database may be used (depending on other settings) for 137 | # a) synthetic data if run is synthetic (defined above) 138 | # b) synthetic wavefield that data is matched against (defined below) 139 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 140 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 141 | 142 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 143 | 144 | # How is the synthetic wavefield / steering vector computed 145 | # Options: 146 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 147 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 148 | type_of_gf: "GF" 149 | 150 | # if type_of_gf is "GF", at what depth does the source lie. 151 | # given in kilometers 152 | source_depth: 0 153 | 154 | # How to handle correct for amplitudes of Green's functions from database. 155 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 156 | # We recommend "whitening_GF". 157 | # Options: 158 | # - "None": no treatment 159 | # - "whitening_GF": frequency-domain normalisation 160 | # - "time_domain_norm": time-domain normalisation 161 | # - "spreading": compute and apply spreading correction for surface waves 162 | amplitude_treatment: "whitening_GF" 163 | 164 | # if type_of_gf is "v_const", specify the velocity used. 165 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 166 | # Δx is euclidean distance if geometry_type is cartesian 167 | # Δx is great-circle distance if geometry_type is geographic 168 | v_const: 3.2 169 | 170 | # 9 -- FREQUENCIES 171 | 172 | # A list of all frequencyt pairs to analyse. 173 | # Options: 174 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 175 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 176 | frequency_bands: [[0.13, 0.15]] 177 | 178 | # 10 -- SOURCE MECHANISM 179 | 180 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 181 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 182 | # Explosion 183 | MT: [1, 1, 1, 0, 0, 0] 184 | 185 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 186 | # For simplicity, this is a grid-search over strike/dip/rake. 187 | # moment tensors are computed from strike/dip/rake. 188 | strike_dip_rake_gridsearch: false 189 | 190 | # Strike/dip/rake are searched only in independent range. 191 | # Search strike in limits [180, 360] with given spacing 192 | strike_spacing: 10 193 | # Search dip in limits [0, 90] with given spacing 194 | dip_spacing: 10 195 | # Search rake in limits [-180, 180] with given spacing 196 | rake_spacing: 10 197 | 198 | # 6 -- COMPUTATIONAL EFFICIENCY 199 | 200 | # How many processes are spawned to increase computational speed. 201 | # !! WARNING: Using only 1 process is not supported at the moment. 202 | n_processes: 50 203 | 204 | # Distances are rounded to reduce number of Green's functions that need to be computed. 205 | # Unit is always kilometers (also if geometry_type is geographic). 206 | # Examples what accuray each ronding resuls in: 207 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 208 | decimal_round: 2 209 | 210 | # Grid-points that are on-land can be excluded for speed. 211 | # Only applies, if geometry_type is geographic. 212 | exclude_land: false 213 | 214 | # 11 -- MISC 215 | 216 | # Plot results for each run 217 | do_plot: true 218 | 219 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 220 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 221 | # list of all components to utilize 222 | components: ['Z'] 223 | wavetypes: ['Z'] 224 | 225 | # Initial implentation of singular-value decomposition 226 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 227 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 228 | # that contribute to signal vs those that contribute to noise. 229 | do_svd: false 230 | 231 | # How many eigenvectors should be kept. 232 | # Code will loop over all values given in the list. 233 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 234 | # and there are n_stations eigenvectors. 235 | n_svd_components: [0, 5, 10, 25, 50, 100] 236 | -------------------------------------------------------------------------------- /settings_files/fig6_v3.2.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig6_v3.2" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "overlapping_windows" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "./timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: false 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "geographic" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_lon: [-18, 20] 51 | grid_limits_lat: [39, 66] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .1 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ["/path/to/data/fig6_atlantic.mseed"] 62 | 63 | # Location of station metadata files (stationXML) 64 | sta_xml_dir: "/path/to/stationxml/" 65 | 66 | # Sampling rate of the recorded data and synthetic green's functions. 67 | # Make sure this is correct for all data. 68 | # Green's functions database may only support up to 1Hz. 69 | sampling_rate: 1.0 70 | 71 | # 5 -- SYNTHETICS 72 | 73 | # the following settings determine the synthetics setup 74 | # toggle whether to do synthetics or real data processing 75 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 76 | do_synth: false 77 | 78 | # How should synthetic data be computed? 79 | # Options: 80 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 81 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 82 | synth_data_type: "database_GF" 83 | 84 | # Where are synthetic sources placed? 85 | # Coordinate units depend on geometry_type: 86 | # kilometers, if geometry_type is "cartesian" 87 | # degrees, if geometry_type is "geographic". 88 | synth_sources: [[0, 0]] 89 | 90 | # Add noise to synthetics 91 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 92 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 93 | # Percentage of max amplitude of noise level 94 | add_noise_to_synth: 0 95 | 96 | # Run multiple iterations with different random noise added. 97 | # Can help test/inform stability of results. 98 | add_noise_iterations: 1 99 | 100 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 101 | # - true: Define synthetic locations as below. 102 | # - false: Run synthetic tests using station locations from the stations in data_fn. 103 | use_synth_stations: false 104 | 105 | # Method of defining synthetic station locations. 106 | # Settings for each method are below. 107 | # Options: 108 | # - "file": Provide an external list of locations. See examples in synth/ 109 | # - "grid": Gridded distribution of evenly spaced stations 110 | # - "uniform": Uniform randomly distribution of stations 111 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 112 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 113 | synth_stations_mode: 'file' 114 | 115 | # if synth_stations_mode == 'file', which file to use 116 | # synth_stations_file: './synth/synth_three_arrays_50km.csv' 117 | synth_stations_file: "./synth_two_arrays.csv" 118 | 119 | # if synth_stations_mode == "partial_circle", how circle is defined 120 | # total potential station locations along circle 121 | synth_stations_circle_n: 20 122 | # number of total potential station locations that are actually used 123 | synth_stations_circle_max: 20 124 | # radius of circle in kilometers 125 | synth_stations_circle_radius: 1 126 | 127 | # if synth_stations_mode == 'grid' or 'uniform' 128 | # how many stations should be placed 129 | synth_stations_n: 400 130 | 131 | # alternatively, use locations of all open stations via 'ORFEUS' 132 | use_open_worldwide_stations: false 133 | 134 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 135 | 136 | # Green's functions extracted from the database may be used (depending on other settings) for 137 | # a) synthetic data if run is synthetic (defined above) 138 | # b) synthetic wavefield that data is matched against (defined below) 139 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 140 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 141 | 142 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 143 | 144 | # How is the synthetic wavefield / steering vector computed 145 | # Options: 146 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 147 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 148 | type_of_gf: "v_const" 149 | 150 | # if type_of_gf is "GF", at what depth does the source lie. 151 | # given in kilometers 152 | source_depth: 0 153 | 154 | # How to handle correct for amplitudes of Green's functions from database. 155 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 156 | # We recommend "whitening_GF". 157 | # Options: 158 | # - "None": no treatment 159 | # - "whitening_GF": frequency-domain normalisation 160 | # - "time_domain_norm": time-domain normalisation 161 | # - "spreading": compute and apply spreading correction for surface waves 162 | amplitude_treatment: "whitening_GF" 163 | 164 | # if type_of_gf is "v_const", specify the velocity used. 165 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 166 | # Δx is euclidean distance if geometry_type is cartesian 167 | # Δx is great-circle distance if geometry_type is geographic 168 | v_const: 3.2 169 | 170 | # 9 -- FREQUENCIES 171 | 172 | # A list of all frequencyt pairs to analyse. 173 | # Options: 174 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 175 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 176 | frequency_bands: [[0.13, 0.15]] 177 | 178 | # 10 -- SOURCE MECHANISM 179 | 180 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 181 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 182 | # Explosion 183 | MT: [1, 1, 1, 0, 0, 0] 184 | 185 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 186 | # For simplicity, this is a grid-search over strike/dip/rake. 187 | # moment tensors are computed from strike/dip/rake. 188 | strike_dip_rake_gridsearch: false 189 | 190 | # Strike/dip/rake are searched only in independent range. 191 | # Search strike in limits [180, 360] with given spacing 192 | strike_spacing: 10 193 | # Search dip in limits [0, 90] with given spacing 194 | dip_spacing: 10 195 | # Search rake in limits [-180, 180] with given spacing 196 | rake_spacing: 10 197 | 198 | # 6 -- COMPUTATIONAL EFFICIENCY 199 | 200 | # How many processes are spawned to increase computational speed. 201 | # !! WARNING: Using only 1 process is not supported at the moment. 202 | n_processes: 50 203 | 204 | # Distances are rounded to reduce number of Green's functions that need to be computed. 205 | # Unit is always kilometers (also if geometry_type is geographic). 206 | # Examples what accuray each ronding resuls in: 207 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 208 | decimal_round: 2 209 | 210 | # Grid-points that are on-land can be excluded for speed. 211 | # Only applies, if geometry_type is geographic. 212 | exclude_land: false 213 | 214 | # 11 -- MISC 215 | 216 | # Plot results for each run 217 | do_plot: true 218 | 219 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 220 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 221 | # list of all components to utilize 222 | components: ['Z'] 223 | wavetypes: ['Z'] 224 | 225 | # Initial implentation of singular-value decomposition 226 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 227 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 228 | # that contribute to signal vs those that contribute to noise. 229 | do_svd: false 230 | 231 | # How many eigenvectors should be kept. 232 | # Code will loop over all values given in the list. 233 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 234 | # and there are n_stations eigenvectors. 235 | n_svd_components: [0, 5, 10, 25, 50, 100] 236 | -------------------------------------------------------------------------------- /settings_files/fig2_v3.0.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig2_v3.0" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "overlapping_windows" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "/path/to/timelists/timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: true 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "cartesian" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_x: [-100, 100] 51 | grid_limits_y: [-100, 100] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .25 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ["/path/to/data/fig6_atlantic.mseed"] 62 | 63 | # Location of station metadata files (stationXML) 64 | sta_xml_dir: "/data/stations/" 65 | 66 | # Sampling rate of the recorded data and synthetic green's functions. 67 | # Make sure this is correct for all data. 68 | # Green's functions database may only support up to 1Hz. 69 | sampling_rate: 1.0 70 | 71 | # 5 -- SYNTHETICS 72 | 73 | # the following settings determine the synthetics setup 74 | # toggle whether to do synthetics or real data processing 75 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 76 | do_synth: true 77 | 78 | # How should synthetic data be computed? 79 | # Options: 80 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 81 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 82 | synth_data_type: "database_GF" 83 | 84 | # Where are synthetic sources placed? 85 | # Coordinate units depend on geometry_type: 86 | # kilometers, if geometry_type is "cartesian" 87 | # degrees, if geometry_type is "geographic". 88 | synth_sources: [[0, 0]] 89 | 90 | # Add noise to synthetics 91 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 92 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 93 | # Percentage of max amplitude of noise level 94 | add_noise_to_synth: 0 95 | 96 | # Run multiple iterations with different random noise added. 97 | # Can help test/inform stability of results. 98 | add_noise_iterations: 1 99 | 100 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 101 | # - true: Define synthetic locations as below. 102 | # - false: Run synthetic tests using station locations from the stations in data_fn. 103 | use_synth_stations: true 104 | 105 | # Method of defining synthetic station locations. 106 | # Settings for each method are below. 107 | # Options: 108 | # - "file": Provide an external list of locations. See examples in synth/ 109 | # - "grid": Gridded distribution of evenly spaced stations 110 | # - "uniform": Uniform randomly distribution of stations 111 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 112 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 113 | synth_stations_mode: 'file' 114 | 115 | # if synth_stations_mode == 'file', which file to use 116 | # synth_stations_file: './synth/synth_three_arrays_50km.csv' 117 | synth_stations_file: "./synth_two_arrays.csv" 118 | 119 | # if synth_stations_mode == "partial_circle", how circle is defined 120 | # total potential station locations along circle 121 | synth_stations_circle_n: 20 122 | # number of total potential station locations that are actually used 123 | synth_stations_circle_max: 20 124 | # radius of circle in kilometers 125 | synth_stations_circle_radius: 1 126 | 127 | # if synth_stations_mode == 'grid' or 'uniform' 128 | # how many stations should be placed 129 | synth_stations_n: 400 130 | 131 | # alternatively, use locations of all open stations via 'ORFEUS' 132 | use_open_worldwide_stations: false 133 | 134 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 135 | 136 | # Green's functions extracted from the database may be used (depending on other settings) for 137 | # a) synthetic data if run is synthetic (defined above) 138 | # b) synthetic wavefield that data is matched against (defined below) 139 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 140 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 141 | 142 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 143 | 144 | # How is the synthetic wavefield / steering vector computed 145 | # Options: 146 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 147 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 148 | type_of_gf: "v_const" 149 | 150 | # if type_of_gf is "GF", at what depth does the source lie. 151 | # given in kilometers 152 | source_depth: 0 153 | 154 | # How to handle correct for amplitudes of Green's functions from database. 155 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 156 | # We recommend "whitening_GF". 157 | # Options: 158 | # - "whitening_GF": frequency-domain normalisation 159 | # - "time_domain_norm": time-domain normalisation 160 | # - "spreading_attenuation": compute and apply spreading + attenuation terms for Rayleigh waves 161 | amplitude_treatment: "whitening_GF" 162 | 163 | # if type_of_gf is "v_const", specify the velocity used. 164 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 165 | # Δx is euclidean distance if geometry_type is cartesian 166 | # Δx is great-circle distance if geometry_type is geographic 167 | v_const: 3.0 168 | 169 | # 9 -- FREQUENCIES 170 | 171 | # A list of all frequencyt pairs to analyse. 172 | # Options: 173 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 174 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 175 | frequency_bands: [[0.05, 0.2], [0.13, 0.15]] 176 | 177 | # 10 -- SOURCE MECHANISM 178 | 179 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 180 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 181 | # Explosion 182 | MT: [1, 1, 1, 0, 0, 0] 183 | 184 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 185 | # For simplicity, this is a grid-search over strike/dip/rake. 186 | # moment tensors are computed from strike/dip/rake. 187 | strike_dip_rake_gridsearch: false 188 | 189 | # Strike/dip/rake are searched only in independent range. 190 | # Search strike in limits [180, 360] with given spacing 191 | strike_spacing: 10 192 | # Search dip in limits [0, 90] with given spacing 193 | dip_spacing: 10 194 | # Search rake in limits [-180, 180] with given spacing 195 | rake_spacing: 10 196 | 197 | # 6 -- COMPUTATIONAL EFFICIENCY 198 | 199 | # How many processes are spawned to increase computational speed. 200 | # !! WARNING: Using only 1 process is not supported at the moment. 201 | n_processes: 50 202 | 203 | # Distances are rounded to reduce number of Green's functions that need to be computed. 204 | # Unit is always kilometers (also if geometry_type is geographic). 205 | # Examples what accuray each ronding resuls in: 206 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 207 | decimal_round: 2 208 | 209 | # Grid-points that are on-land can be excluded for speed. 210 | # Only applies, if geometry_type is geographic. 211 | exclude_land: false 212 | 213 | # 11 -- MISC 214 | 215 | # Plot results for each run 216 | do_plot: true 217 | 218 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 219 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 220 | # list of all components to utilize 221 | components: ['Z'] 222 | wavetypes: ['Z'] 223 | 224 | # Initial implentation of singular-value decomposition 225 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 226 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 227 | # that contribute to signal vs those that contribute to noise. 228 | do_svd: false 229 | 230 | # How many eigenvectors should be kept. 231 | # Code will loop over all values given in the list. 232 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 233 | # and there are n_stations eigenvectors. 234 | n_svd_components: [0, 5, 10, 25, 50, 100] 235 | -------------------------------------------------------------------------------- /settings_files/fig2_v3.2.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig2_v3.2" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "overlapping_windows" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "/path/to/timelists/timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: true 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "cartesian" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_x: [-100, 100] 51 | grid_limits_y: [-100, 100] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .25 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ["/path/to/data/fig6_atlantic.mseed"] 62 | 63 | # Location of station metadata files (stationXML) 64 | sta_xml_dir: "/data/stations/" 65 | 66 | # Sampling rate of the recorded data and synthetic green's functions. 67 | # Make sure this is correct for all data. 68 | # Green's functions database may only support up to 1Hz. 69 | sampling_rate: 1.0 70 | 71 | # 5 -- SYNTHETICS 72 | 73 | # the following settings determine the synthetics setup 74 | # toggle whether to do synthetics or real data processing 75 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 76 | do_synth: true 77 | 78 | # How should synthetic data be computed? 79 | # Options: 80 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 81 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 82 | synth_data_type: "database_GF" 83 | 84 | # Where are synthetic sources placed? 85 | # Coordinate units depend on geometry_type: 86 | # kilometers, if geometry_type is "cartesian" 87 | # degrees, if geometry_type is "geographic". 88 | synth_sources: [[0, 0]] 89 | 90 | # Add noise to synthetics 91 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 92 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 93 | # Percentage of max amplitude of noise level 94 | add_noise_to_synth: 0 95 | 96 | # Run multiple iterations with different random noise added. 97 | # Can help test/inform stability of results. 98 | add_noise_iterations: 1 99 | 100 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 101 | # - true: Define synthetic locations as below. 102 | # - false: Run synthetic tests using station locations from the stations in data_fn. 103 | use_synth_stations: true 104 | 105 | # Method of defining synthetic station locations. 106 | # Settings for each method are below. 107 | # Options: 108 | # - "file": Provide an external list of locations. See examples in synth/ 109 | # - "grid": Gridded distribution of evenly spaced stations 110 | # - "uniform": Uniform randomly distribution of stations 111 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 112 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 113 | synth_stations_mode: 'file' 114 | 115 | # if synth_stations_mode == 'file', which file to use 116 | # synth_stations_file: './synth/synth_three_arrays_50km.csv' 117 | synth_stations_file: "./synth_two_arrays.csv" 118 | 119 | # if synth_stations_mode == "partial_circle", how circle is defined 120 | # total potential station locations along circle 121 | synth_stations_circle_n: 20 122 | # number of total potential station locations that are actually used 123 | synth_stations_circle_max: 20 124 | # radius of circle in kilometers 125 | synth_stations_circle_radius: 1 126 | 127 | # if synth_stations_mode == 'grid' or 'uniform' 128 | # how many stations should be placed 129 | synth_stations_n: 400 130 | 131 | # alternatively, use locations of all open stations via 'ORFEUS' 132 | use_open_worldwide_stations: false 133 | 134 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 135 | 136 | # Green's functions extracted from the database may be used (depending on other settings) for 137 | # a) synthetic data if run is synthetic (defined above) 138 | # b) synthetic wavefield that data is matched against (defined below) 139 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 140 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 141 | 142 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 143 | 144 | # How is the synthetic wavefield / steering vector computed 145 | # Options: 146 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 147 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 148 | type_of_gf: "v_const" 149 | 150 | # if type_of_gf is "GF", at what depth does the source lie. 151 | # given in kilometers 152 | source_depth: 0 153 | 154 | # How to handle correct for amplitudes of Green's functions from database. 155 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 156 | # We recommend "whitening_GF". 157 | # Options: 158 | # - "whitening_GF": frequency-domain normalisation 159 | # - "time_domain_norm": time-domain normalisation 160 | # - "spreading_attenuation": compute and apply spreading + attenuation terms for Rayleigh waves 161 | amplitude_treatment: "whitening_GF" 162 | 163 | # if type_of_gf is "v_const", specify the velocity used. 164 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 165 | # Δx is euclidean distance if geometry_type is cartesian 166 | # Δx is great-circle distance if geometry_type is geographic 167 | v_const: 3.2 168 | 169 | # 9 -- FREQUENCIES 170 | 171 | # A list of all frequencyt pairs to analyse. 172 | # Options: 173 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 174 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 175 | frequency_bands: [[0.05, 0.2], [0.13, 0.15]] 176 | 177 | # 10 -- SOURCE MECHANISM 178 | 179 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 180 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 181 | # Explosion 182 | MT: [1, 1, 1, 0, 0, 0] 183 | 184 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 185 | # For simplicity, this is a grid-search over strike/dip/rake. 186 | # moment tensors are computed from strike/dip/rake. 187 | strike_dip_rake_gridsearch: false 188 | 189 | # Strike/dip/rake are searched only in independent range. 190 | # Search strike in limits [180, 360] with given spacing 191 | strike_spacing: 10 192 | # Search dip in limits [0, 90] with given spacing 193 | dip_spacing: 10 194 | # Search rake in limits [-180, 180] with given spacing 195 | rake_spacing: 10 196 | 197 | # 6 -- COMPUTATIONAL EFFICIENCY 198 | 199 | # How many processes are spawned to increase computational speed. 200 | # !! WARNING: Using only 1 process is not supported at the moment. 201 | n_processes: 50 202 | 203 | # Distances are rounded to reduce number of Green's functions that need to be computed. 204 | # Unit is always kilometers (also if geometry_type is geographic). 205 | # Examples what accuray each ronding resuls in: 206 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 207 | decimal_round: 2 208 | 209 | # Grid-points that are on-land can be excluded for speed. 210 | # Only applies, if geometry_type is geographic. 211 | exclude_land: false 212 | 213 | # 11 -- MISC 214 | 215 | # Plot results for each run 216 | do_plot: true 217 | 218 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 219 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 220 | # list of all components to utilize 221 | components: ['Z'] 222 | wavetypes: ['Z'] 223 | 224 | # Initial implentation of singular-value decomposition 225 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 226 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 227 | # that contribute to signal vs those that contribute to noise. 228 | do_svd: false 229 | 230 | # How many eigenvectors should be kept. 231 | # Code will loop over all values given in the list. 232 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 233 | # and there are n_stations eigenvectors. 234 | n_svd_components: [0, 5, 10, 25, 50, 100] 235 | -------------------------------------------------------------------------------- /settings_files/fig4_b_c.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig4_b_c" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "overlapping_windows" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "/path/to/timelists/timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: true 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "cartesian" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_x: [-100, 100] 51 | grid_limits_y: [-100, 100] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .25 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ["/path/to/data/fig6_atlantic.mseed"] 62 | 63 | # Location of station metadata files (stationXML) 64 | sta_xml_dir: "/data/stations/" 65 | 66 | # Sampling rate of the recorded data and synthetic green's functions. 67 | # Make sure this is correct for all data. 68 | # Green's functions database may only support up to 1Hz. 69 | sampling_rate: 1.0 70 | 71 | # 5 -- SYNTHETICS 72 | 73 | # the following settings determine the synthetics setup 74 | # toggle whether to do synthetics or real data processing 75 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 76 | do_synth: true 77 | 78 | # How should synthetic data be computed? 79 | # Options: 80 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 81 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 82 | synth_data_type: "database_GF" 83 | 84 | # Where are synthetic sources placed? 85 | # Coordinate units depend on geometry_type: 86 | # kilometers, if geometry_type is "cartesian" 87 | # degrees, if geometry_type is "geographic". 88 | synth_sources: [[0, 0], [0, 40]] 89 | 90 | # Add noise to synthetics 91 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 92 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 93 | # Percentage of max amplitude of noise level 94 | add_noise_to_synth: 0 95 | 96 | # Run multiple iterations with different random noise added. 97 | # Can help test/inform stability of results. 98 | add_noise_iterations: 1 99 | 100 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 101 | # - true: Define synthetic locations as below. 102 | # - false: Run synthetic tests using station locations from the stations in data_fn. 103 | use_synth_stations: true 104 | 105 | # Method of defining synthetic station locations. 106 | # Settings for each method are below. 107 | # Options: 108 | # - "file": Provide an external list of locations. See examples in synth/ 109 | # - "grid": Gridded distribution of evenly spaced stations 110 | # - "uniform": Uniform randomly distribution of stations 111 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 112 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 113 | synth_stations_mode: 'file' 114 | 115 | # if synth_stations_mode == 'file', which file to use 116 | # synth_stations_file: './synth/synth_three_arrays_50km.csv' 117 | synth_stations_file: "./synth_two_arrays.csv" 118 | 119 | # if synth_stations_mode == "partial_circle", how circle is defined 120 | # total potential station locations along circle 121 | synth_stations_circle_n: 20 122 | # number of total potential station locations that are actually used 123 | synth_stations_circle_max: 20 124 | # radius of circle in kilometers 125 | synth_stations_circle_radius: 1 126 | 127 | # if synth_stations_mode == 'grid' or 'uniform' 128 | # how many stations should be placed 129 | synth_stations_n: 400 130 | 131 | # alternatively, use locations of all open stations via 'ORFEUS' 132 | use_open_worldwide_stations: false 133 | 134 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 135 | 136 | # Green's functions extracted from the database may be used (depending on other settings) for 137 | # a) synthetic data if run is synthetic (defined above) 138 | # b) synthetic wavefield that data is matched against (defined below) 139 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 140 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 141 | 142 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 143 | 144 | # How is the synthetic wavefield / steering vector computed 145 | # Options: 146 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 147 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 148 | type_of_gf: "GF" 149 | 150 | # if type_of_gf is "GF", at what depth does the source lie. 151 | # given in kilometers 152 | source_depth: 0 153 | 154 | # How to handle correct for amplitudes of Green's functions from database. 155 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 156 | # We recommend "whitening_GF". 157 | # Options: 158 | # - "None": no treatment 159 | # - "whitening_GF": frequency-domain normalisation 160 | # - "time_domain_norm": time-domain normalisation 161 | # - "spreading": compute and apply spreading correction for surface waves 162 | amplitude_treatment: "whitening_GF" 163 | 164 | # if type_of_gf is "v_const", specify the velocity used. 165 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 166 | # Δx is euclidean distance if geometry_type is cartesian 167 | # Δx is great-circle distance if geometry_type is geographic 168 | v_const: 3.0 169 | 170 | # 9 -- FREQUENCIES 171 | 172 | # A list of all frequencyt pairs to analyse. 173 | # Options: 174 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 175 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 176 | frequency_bands: [[0.05, 0.2], [0.13, 0.15]] 177 | 178 | # 10 -- SOURCE MECHANISM 179 | 180 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 181 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 182 | # Explosion 183 | MT: [1, 1, 1, 0, 0, 0] 184 | 185 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 186 | # For simplicity, this is a grid-search over strike/dip/rake. 187 | # moment tensors are computed from strike/dip/rake. 188 | strike_dip_rake_gridsearch: false 189 | 190 | # Strike/dip/rake are searched only in independent range. 191 | # Search strike in limits [180, 360] with given spacing 192 | strike_spacing: 10 193 | # Search dip in limits [0, 90] with given spacing 194 | dip_spacing: 10 195 | # Search rake in limits [-180, 180] with given spacing 196 | rake_spacing: 10 197 | 198 | # 6 -- COMPUTATIONAL EFFICIENCY 199 | 200 | # How many processes are spawned to increase computational speed. 201 | # !! WARNING: Using only 1 process is not supported at the moment. 202 | n_processes: 50 203 | 204 | # Distances are rounded to reduce number of Green's functions that need to be computed. 205 | # Unit is always kilometers (also if geometry_type is geographic). 206 | # Examples what accuray each ronding resuls in: 207 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 208 | decimal_round: 2 209 | 210 | # Grid-points that are on-land can be excluded for speed. 211 | # Only applies, if geometry_type is geographic. 212 | exclude_land: false 213 | 214 | # 11 -- MISC 215 | 216 | # Plot results for each run 217 | do_plot: true 218 | 219 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 220 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 221 | # list of all components to utilize 222 | components: ['Z'] 223 | wavetypes: ['Z'] 224 | 225 | # Initial implentation of singular-value decomposition 226 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 227 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 228 | # that contribute to signal vs those that contribute to noise. 229 | do_svd: false 230 | 231 | # How many eigenvectors should be kept. 232 | # Code will loop over all values given in the list. 233 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 234 | # and there are n_stations eigenvectors. 235 | n_svd_components: [0, 5, 10, 25, 50, 100] 236 | -------------------------------------------------------------------------------- /settings_files/fig3_d.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig3_d" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | # window_length: 17953 16 | 17 | # Mode of windows' start time determination: 18 | # - "file": extract start times from time external_timelist 19 | # - "overlapping_windows": define windows in given range (see below) 20 | time_window_mode: "overlapping_windows" 21 | 22 | # if time_window_mode == "overlapping_windows": 23 | 24 | # Start of first time window, given as obspy.UTCDateTime-readable string. 25 | start_time: "2019-02-01T01:00:00.0Z" 26 | 27 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 28 | end_time: "2019-02-07T23:59:59.0Z" 29 | 30 | # Overlap windows by how much in given time frame. 31 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 32 | overlap: 0.5 33 | 34 | # if time_window_mode == "file" (see above) use this file 35 | external_timelist: "/path/to/timelists/timelist_chino.csv" 36 | 37 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 38 | # TODO: handle this more elegantly in code, especially for synthetic tests. 39 | do_only_one_timewindow: true 40 | 41 | # 3 -- GEOMETRY 42 | 43 | # Type of coordinate system used: 44 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 45 | # - "geographic", when using georeferenced data and distances are in degrees 46 | geometry_type: "cartesian" 47 | 48 | # Longitude/X and Latitude/Y limits of the grid. 49 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 50 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 51 | grid_limits_x: [-100, 100] 52 | grid_limits_y: [-100, 100] 53 | 54 | # grid_spacing in units depending on geometry_type: 55 | # kilometers, if geometry_type is "cartesian" 56 | # degrees, if geometry_type is "geographic". 57 | grid_spacing: .25 58 | 59 | # 4 -- DATA 60 | 61 | # List of seismogram locations, obspy-readable strings 62 | data_fn: ["/path/to/data/fig6_atlantic.mseed"] 63 | 64 | # Location of station metadata files (stationXML) 65 | sta_xml_dir: "/data/stations/" 66 | 67 | # Sampling rate of the recorded data and synthetic green's functions. 68 | # Make sure this is correct for all data. 69 | # Green's functions database may only support up to 1Hz. 70 | sampling_rate: 1.0 71 | 72 | # 5 -- SYNTHETICS 73 | 74 | # the following settings determine the synthetics setup 75 | # toggle whether to do synthetics or real data processing 76 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 77 | do_synth: true 78 | 79 | # How should synthetic data be computed? 80 | # Options: 81 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 82 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 83 | synth_data_type: "database_GF" 84 | 85 | # Where are synthetic sources placed? 86 | # Coordinate units depend on geometry_type: 87 | # kilometers, if geometry_type is "cartesian" 88 | # degrees, if geometry_type is "geographic". 89 | synth_sources: [[0, 0]] 90 | 91 | # Add noise to synthetics 92 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 93 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 94 | # Percentage of max amplitude of noise level 95 | add_noise_to_synth: 0 96 | 97 | # Run multiple iterations with different random noise added. 98 | # Can help test/inform stability of results. 99 | add_noise_iterations: 1 100 | 101 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 102 | # - true: Define synthetic locations as below. 103 | # - false: Run synthetic tests using station locations from the stations in data_fn. 104 | use_synth_stations: true 105 | 106 | # Method of defining synthetic station locations. 107 | # Settings for each method are below. 108 | # Options: 109 | # - "file": Provide an external list of locations. See examples in synth/ 110 | # - "grid": Gridded distribution of evenly spaced stations 111 | # - "uniform": Uniform randomly distribution of stations 112 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 113 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 114 | synth_stations_mode: 'file' 115 | 116 | # if synth_stations_mode == 'file', which file to use 117 | # synth_stations_file: './synth/synth_three_arrays_50km.csv' 118 | synth_stations_file: "./synth_two_arrays.csv" 119 | 120 | # if synth_stations_mode == "partial_circle", how circle is defined 121 | # total potential station locations along circle 122 | synth_stations_circle_n: 20 123 | # number of total potential station locations that are actually used 124 | synth_stations_circle_max: 20 125 | # radius of circle in kilometers 126 | synth_stations_circle_radius: 1 127 | 128 | # if synth_stations_mode == 'grid' or 'uniform' 129 | # how many stations should be placed 130 | synth_stations_n: 400 131 | 132 | # alternatively, use locations of all open stations via 'ORFEUS' 133 | use_open_worldwide_stations: false 134 | 135 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 136 | 137 | # Green's functions extracted from the database may be used (depending on other settings) for 138 | # a) synthetic data if run is synthetic (defined above) 139 | # b) synthetic wavefield that data is matched against (defined below) 140 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 141 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 142 | 143 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 144 | 145 | # How is the synthetic wavefield / steering vector computed 146 | # Options: 147 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 148 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 149 | type_of_gf: "GF" 150 | 151 | # if type_of_gf is "GF", at what depth does the source lie. 152 | # given in kilometers 153 | source_depth: 0 154 | 155 | # How to handle correct for amplitudes of Green's functions from database. 156 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 157 | # We recommend "whitening_GF". 158 | # Options: 159 | # - "None": no treatment 160 | # - "whitening_GF": frequency-domain normalisation 161 | # - "time_domain_norm": time-domain normalisation 162 | # - "spreading": compute and apply spreading correction for surface waves 163 | amplitude_treatment: "whitening_GF" 164 | 165 | # if type_of_gf is "v_const", specify the velocity used. 166 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 167 | # Δx is euclidean distance if geometry_type is cartesian 168 | # Δx is great-circle distance if geometry_type is geographic 169 | v_const: 3.0 170 | 171 | # 9 -- FREQUENCIES 172 | 173 | # A list of all frequencyt pairs to analyse. 174 | # Options: 175 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 176 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 177 | frequency_bands: [[0.13, 0.15]] 178 | 179 | # 10 -- SOURCE MECHANISM 180 | 181 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 182 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 183 | # Explosion 184 | MT: [1, 1, 1, 0, 0, 0] 185 | 186 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 187 | # For simplicity, this is a grid-search over strike/dip/rake. 188 | # moment tensors are computed from strike/dip/rake. 189 | strike_dip_rake_gridsearch: false 190 | 191 | # Strike/dip/rake are searched only in independent range. 192 | # Search strike in limits [180, 360] with given spacing 193 | strike_spacing: 10 194 | # Search dip in limits [0, 90] with given spacing 195 | dip_spacing: 10 196 | # Search rake in limits [-180, 180] with given spacing 197 | rake_spacing: 10 198 | 199 | # 6 -- COMPUTATIONAL EFFICIENCY 200 | 201 | # How many processes are spawned to increase computational speed. 202 | # !! WARNING: Using only 1 process is not supported at the moment. 203 | n_processes: 50 204 | 205 | # Distances are rounded to reduce number of Green's functions that need to be computed. 206 | # Unit is always kilometers (also if geometry_type is geographic). 207 | # Examples what accuray each ronding resuls in: 208 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 209 | decimal_round: 2 210 | 211 | # Grid-points that are on-land can be excluded for speed. 212 | # Only applies, if geometry_type is geographic. 213 | exclude_land: false 214 | 215 | # 11 -- MISC 216 | 217 | # Plot results for each run 218 | do_plot: true 219 | 220 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 221 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 222 | # list of all components to utilize 223 | components: ['Z'] 224 | wavetypes: ['Z'] 225 | 226 | # Initial implentation of singular-value decomposition 227 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 228 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 229 | # that contribute to signal vs those that contribute to noise. 230 | do_svd: false 231 | 232 | # How many eigenvectors should be kept. 233 | # Code will loop over all values given in the list. 234 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 235 | # and there are n_stations eigenvectors. 236 | n_svd_components: [0, 5, 10, 25, 50, 100] 237 | -------------------------------------------------------------------------------- /settings_files/fig2_GF.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig2_GF" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "overlapping_windows" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "/path/to/timelists/timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: true 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "cartesian" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_x: [-100, 100] 51 | grid_limits_y: [-100, 100] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .25 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ["/path/to/data/fig6_atlantic.mseed"] 62 | 63 | # Location of station metadata files (stationXML) 64 | sta_xml_dir: "/data/stations/" 65 | 66 | # Sampling rate of the recorded data and synthetic green's functions. 67 | # Make sure this is correct for all data. 68 | # Green's functions database may only support up to 1Hz. 69 | sampling_rate: 1.0 70 | 71 | # 5 -- SYNTHETICS 72 | 73 | # the following settings determine the synthetics setup 74 | # toggle whether to do synthetics or real data processing 75 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 76 | do_synth: true 77 | 78 | # How should synthetic data be computed? 79 | # Options: 80 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 81 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 82 | synth_data_type: "database_GF" 83 | 84 | # Where are synthetic sources placed? 85 | # Coordinate units depend on geometry_type: 86 | # kilometers, if geometry_type is "cartesian" 87 | # degrees, if geometry_type is "geographic". 88 | synth_sources: [[0, 0]] 89 | 90 | # Add noise to synthetics 91 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 92 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 93 | # Percentage of max amplitude of noise level 94 | add_noise_to_synth: 0 95 | 96 | # Run multiple iterations with different random noise added. 97 | # Can help test/inform stability of results. 98 | add_noise_iterations: 1 99 | 100 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 101 | # - true: Define synthetic locations as below. 102 | # - false: Run synthetic tests using station locations from the stations in data_fn. 103 | use_synth_stations: true 104 | 105 | # Method of defining synthetic station locations. 106 | # Settings for each method are below. 107 | # Options: 108 | # - "file": Provide an external list of locations. See examples in synth/ 109 | # - "grid": Gridded distribution of evenly spaced stations 110 | # - "uniform": Uniform randomly distribution of stations 111 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 112 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 113 | synth_stations_mode: 'file' 114 | 115 | # if synth_stations_mode == 'file', which file to use 116 | # synth_stations_file: './synth/synth_three_arrays_50km.csv' 117 | synth_stations_file: "./synth_two_arrays.csv" 118 | 119 | # if synth_stations_mode == "partial_circle", how circle is defined 120 | # total potential station locations along circle 121 | synth_stations_circle_n: 20 122 | # number of total potential station locations that are actually used 123 | synth_stations_circle_max: 20 124 | # radius of circle in kilometers 125 | synth_stations_circle_radius: 1 126 | 127 | # if synth_stations_mode == 'grid' or 'uniform' 128 | # how many stations should be placed 129 | synth_stations_n: 400 130 | 131 | # alternatively, use locations of all open stations via 'ORFEUS' 132 | use_open_worldwide_stations: false 133 | 134 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 135 | 136 | # Green's functions extracted from the database may be used (depending on other settings) for 137 | # a) synthetic data if run is synthetic (defined above) 138 | # b) synthetic wavefield that data is matched against (defined below) 139 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 140 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 141 | 142 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 143 | 144 | # How is the synthetic wavefield / steering vector computed 145 | # Options: 146 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 147 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 148 | type_of_gf: "GF" 149 | 150 | # if type_of_gf is "GF", at what depth does the source lie. 151 | # given in kilometers 152 | source_depth: 0 153 | 154 | # How to handle correct for amplitudes of Green's functions from database. 155 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 156 | # We recommend "whitening_GF". 157 | # Options: 158 | # - "None": no treatment 159 | # - "whitening_GF": frequency-domain normalisation 160 | # - "time_domain_norm": time-domain normalisation 161 | # - "spreading_attenuation": compute and apply spreading + attenuation terms for Rayleigh waves 162 | amplitude_treatment: "whitening_GF" 163 | 164 | # if type_of_gf is "v_const", specify the velocity used. 165 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 166 | # Δx is euclidean distance if geometry_type is cartesian 167 | # Δx is great-circle distance if geometry_type is geographic 168 | v_const: 3.0 169 | 170 | # 9 -- FREQUENCIES 171 | 172 | # A list of all frequencyt pairs to analyse. 173 | # Options: 174 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 175 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 176 | frequency_bands: [[0.05, 0.2], [0.13, 0.15]] 177 | 178 | # 10 -- SOURCE MECHANISM 179 | 180 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 181 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 182 | # Explosion 183 | MT: [1, 1, 1, 0, 0, 0] 184 | 185 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 186 | # For simplicity, this is a grid-search over strike/dip/rake. 187 | # moment tensors are computed from strike/dip/rake. 188 | strike_dip_rake_gridsearch: false 189 | 190 | # Strike/dip/rake are searched only in independent range. 191 | # Search strike in limits [180, 360] with given spacing 192 | strike_spacing: 10 193 | # Search dip in limits [0, 90] with given spacing 194 | dip_spacing: 10 195 | # Search rake in limits [-180, 180] with given spacing 196 | rake_spacing: 10 197 | 198 | # 6 -- COMPUTATIONAL EFFICIENCY 199 | 200 | # How many processes are spawned to increase computational speed. 201 | # !! WARNING: Using only 1 process is not supported at the moment. 202 | n_processes: 50 203 | 204 | # Distances are rounded to reduce number of Green's functions that need to be computed. 205 | # Unit is always kilometers (also if geometry_type is geographic). 206 | # Examples what accuray each ronding resuls in: 207 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 208 | decimal_round: 2 209 | 210 | # Grid-points that are on-land can be excluded for speed. 211 | # Only applies, if geometry_type is geographic. 212 | exclude_land: false 213 | 214 | # 11 -- MISC 215 | 216 | # Plot results for each run 217 | do_plot: true 218 | 219 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 220 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 221 | # list of all components to utilize 222 | components: ['Z'] 223 | wavetypes: ['Z'] 224 | 225 | # Initial implentation of singular-value decomposition 226 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 227 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 228 | # that contribute to signal vs those that contribute to noise. 229 | do_svd: false 230 | 231 | # How many eigenvectors should be kept. 232 | # Code will loop over all values given in the list. 233 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 234 | # and there are n_stations eigenvectors. 235 | n_svd_components: [0, 5, 10, 25, 50, 100] 236 | -------------------------------------------------------------------------------- /settings_files/fig3_c.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig3_c" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "overlapping_windows" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "/path/to/timelists/timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: true 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "cartesian" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_x: [-100, 100] 51 | grid_limits_y: [-100, 100] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | # grid_spacing: .1 57 | grid_spacing: .25 # synthetic 58 | 59 | # 4 -- DATA 60 | 61 | # List of seismogram locations, obspy-readable strings 62 | data_fn: ["/path/to/data/fig6_atlantic.mseed"] 63 | 64 | # Location of station metadata files (stationXML) 65 | sta_xml_dir: "/data/stations/" 66 | 67 | # Sampling rate of the recorded data and synthetic green's functions. 68 | # Make sure this is correct for all data. 69 | # Green's functions database may only support up to 1Hz. 70 | sampling_rate: 1.0 71 | 72 | # 5 -- SYNTHETICS 73 | 74 | # the following settings determine the synthetics setup 75 | # toggle whether to do synthetics or real data processing 76 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 77 | do_synth: true 78 | 79 | # How should synthetic data be computed? 80 | # Options: 81 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 82 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 83 | synth_data_type: "database_GF" 84 | 85 | # Where are synthetic sources placed? 86 | # Coordinate units depend on geometry_type: 87 | # kilometers, if geometry_type is "cartesian" 88 | # degrees, if geometry_type is "geographic". 89 | synth_sources: [[0, 0]] 90 | 91 | # Add noise to synthetics 92 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 93 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 94 | # Percentage of max amplitude of noise level 95 | add_noise_to_synth: 0 96 | 97 | # Run multiple iterations with different random noise added. 98 | # Can help test/inform stability of results. 99 | add_noise_iterations: 1 100 | 101 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 102 | # - true: Define synthetic locations as below. 103 | # - false: Run synthetic tests using station locations from the stations in data_fn. 104 | use_synth_stations: true 105 | 106 | # Method of defining synthetic station locations. 107 | # Settings for each method are below. 108 | # Options: 109 | # - "file": Provide an external list of locations. See examples in synth/ 110 | # - "grid": Gridded distribution of evenly spaced stations 111 | # - "uniform": Uniform randomly distribution of stations 112 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 113 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 114 | synth_stations_mode: 'file' 115 | 116 | # if synth_stations_mode == 'file', which file to use 117 | # synth_stations_file: './synth/synth_three_arrays_50km.csv' 118 | synth_stations_file: "./synth_two_arrays.csv" 119 | 120 | # if synth_stations_mode == "partial_circle", how circle is defined 121 | # total potential station locations along circle 122 | synth_stations_circle_n: 20 123 | # number of total potential station locations that are actually used 124 | synth_stations_circle_max: 20 125 | # radius of circle in kilometers 126 | synth_stations_circle_radius: 1 127 | 128 | # if synth_stations_mode == 'grid' or 'uniform' 129 | # how many stations should be placed 130 | synth_stations_n: 400 131 | 132 | # alternatively, use locations of all open stations via 'ORFEUS' 133 | use_open_worldwide_stations: false 134 | 135 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 136 | 137 | # Green's functions extracted from the database may be used (depending on other settings) for 138 | # a) synthetic data if run is synthetic (defined above) 139 | # b) synthetic wavefield that data is matched against (defined below) 140 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 141 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 142 | 143 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 144 | 145 | # How is the synthetic wavefield / steering vector computed 146 | # Options: 147 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 148 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 149 | type_of_gf: "GF" 150 | 151 | # if type_of_gf is "GF", at what depth does the source lie. 152 | # given in kilometers 153 | source_depth: 0 154 | 155 | # How to handle correct for amplitudes of Green's functions from database. 156 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 157 | # We recommend "whitening_GF". 158 | # Options: 159 | # - "None": no treatment 160 | # - "whitening_GF": frequency-domain normalisation 161 | # - "time_domain_norm": time-domain normalisation 162 | # - "spreading": compute and apply spreading correction for surface waves 163 | amplitude_treatment: "time_domain_norm" 164 | 165 | # if type_of_gf is "v_const", specify the velocity used. 166 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 167 | # Δx is euclidean distance if geometry_type is cartesian 168 | # Δx is great-circle distance if geometry_type is geographic 169 | v_const: 3.0 170 | 171 | # 9 -- FREQUENCIES 172 | 173 | # A list of all frequencyt pairs to analyse. 174 | # Options: 175 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 176 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 177 | frequency_bands: [[0.13, 0.15]] 178 | 179 | # 10 -- SOURCE MECHANISM 180 | 181 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 182 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 183 | # Explosion 184 | MT: [1, 1, 1, 0, 0, 0] 185 | 186 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 187 | # For simplicity, this is a grid-search over strike/dip/rake. 188 | # moment tensors are computed from strike/dip/rake. 189 | strike_dip_rake_gridsearch: false 190 | 191 | # Strike/dip/rake are searched only in independent range. 192 | # Search strike in limits [180, 360] with given spacing 193 | strike_spacing: 10 194 | # Search dip in limits [0, 90] with given spacing 195 | dip_spacing: 10 196 | # Search rake in limits [-180, 180] with given spacing 197 | rake_spacing: 10 198 | 199 | # 6 -- COMPUTATIONAL EFFICIENCY 200 | 201 | # How many processes are spawned to increase computational speed. 202 | # !! WARNING: Using only 1 process is not supported at the moment. 203 | n_processes: 50 204 | 205 | # Distances are rounded to reduce number of Green's functions that need to be computed. 206 | # Unit is always kilometers (also if geometry_type is geographic). 207 | # Examples what accuray each ronding resuls in: 208 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 209 | decimal_round: 2 210 | 211 | # Grid-points that are on-land can be excluded for speed. 212 | # Only applies, if geometry_type is geographic. 213 | exclude_land: false 214 | 215 | # 11 -- MISC 216 | 217 | # Plot results for each run 218 | do_plot: true 219 | 220 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 221 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 222 | # list of all components to utilize 223 | components: ['Z'] 224 | wavetypes: ['Z'] 225 | 226 | # Initial implentation of singular-value decomposition 227 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 228 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 229 | # that contribute to signal vs those that contribute to noise. 230 | do_svd: false 231 | 232 | # How many eigenvectors should be kept. 233 | # Code will loop over all values given in the list. 234 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 235 | # and there are n_stations eigenvectors. 236 | n_svd_components: [0, 5, 10, 25, 50, 100] 237 | -------------------------------------------------------------------------------- /settings_files/fig4_a.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig4_a" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "overlapping_windows" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "/path/to/timelists/timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: true 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "cartesian" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_x: [-100, 100] 51 | grid_limits_y: [-100, 100] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .25 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ["/data/cen/u254/sven/global_mfp/data/for_publication/fig6_atlantic.mseed"] 62 | # data_fn: ['/data/cen/u254/sven/global_mfp/data/for_publication/fig5_chino_hills.mseed'] 63 | 64 | # Location of station metadata files (stationXML) 65 | sta_xml_dir: "/data/stations/" 66 | 67 | # Sampling rate of the recorded data and synthetic green's functions. 68 | # Make sure this is correct for all data. 69 | # Green's functions database may only support up to 1Hz. 70 | sampling_rate: 1.0 71 | 72 | # 5 -- SYNTHETICS 73 | 74 | # the following settings determine the synthetics setup 75 | # toggle whether to do synthetics or real data processing 76 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 77 | do_synth: true 78 | 79 | # How should synthetic data be computed? 80 | # Options: 81 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 82 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 83 | synth_data_type: "database_GF" 84 | 85 | # Where are synthetic sources placed? 86 | # Coordinate units depend on geometry_type: 87 | # kilometers, if geometry_type is "cartesian" 88 | # degrees, if geometry_type is "geographic". 89 | synth_sources: [[0, 0]] 90 | 91 | # Add noise to synthetics 92 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 93 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 94 | # Percentage of max amplitude of noise level 95 | add_noise_to_synth: 0 96 | 97 | # Run multiple iterations with different random noise added. 98 | # Can help test/inform stability of results. 99 | add_noise_iterations: 1 100 | 101 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 102 | # - true: Define synthetic locations as below. 103 | # - false: Run synthetic tests using station locations from the stations in data_fn. 104 | use_synth_stations: true 105 | 106 | # Method of defining synthetic station locations. 107 | # Settings for each method are below. 108 | # Options: 109 | # - "file": Provide an external list of locations. See examples in synth/ 110 | # - "grid": Gridded distribution of evenly spaced stations 111 | # - "uniform": Uniform randomly distribution of stations 112 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 113 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 114 | synth_stations_mode: 'file' 115 | 116 | # if synth_stations_mode == 'file', which file to use 117 | # synth_stations_file: './synth/synth_three_arrays_50km.csv' 118 | synth_stations_file: "./synth_two_arrays_50km_larger_quad.csv" 119 | 120 | # if synth_stations_mode == "partial_circle", how circle is defined 121 | # total potential station locations along circle 122 | synth_stations_circle_n: 20 123 | # number of total potential station locations that are actually used 124 | synth_stations_circle_max: 20 125 | # radius of circle in kilometers 126 | synth_stations_circle_radius: 1 127 | 128 | # if synth_stations_mode == 'grid' or 'uniform' 129 | # how many stations should be placed 130 | synth_stations_n: 400 131 | 132 | # alternatively, use locations of all open stations via 'ORFEUS' 133 | use_open_worldwide_stations: false 134 | 135 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 136 | 137 | # Green's functions extracted from the database may be used (depending on other settings) for 138 | # a) synthetic data if run is synthetic (defined above) 139 | # b) synthetic wavefield that data is matched against (defined below) 140 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 141 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 142 | 143 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 144 | 145 | # How is the synthetic wavefield / steering vector computed 146 | # Options: 147 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 148 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 149 | type_of_gf: "GF" 150 | 151 | # if type_of_gf is "GF", at what depth does the source lie. 152 | # given in kilometers 153 | source_depth: 0 154 | 155 | # How to handle correct for amplitudes of Green's functions from database. 156 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 157 | # We recommend "whitening_GF". 158 | # Options: 159 | # - "None": no treatment 160 | # - "whitening_GF": frequency-domain normalisation 161 | # - "time_domain_norm": time-domain normalisation 162 | # - "spreading": compute and apply spreading correction for surface waves 163 | amplitude_treatment: "whitening_GF" 164 | 165 | # if type_of_gf is "v_const", specify the velocity used. 166 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 167 | # Δx is euclidean distance if geometry_type is cartesian 168 | # Δx is great-circle distance if geometry_type is geographic 169 | v_const: 3.0 170 | 171 | # 9 -- FREQUENCIES 172 | 173 | # A list of all frequencyt pairs to analyse. 174 | # Options: 175 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 176 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 177 | frequency_bands: [[0.13, 0.15]] 178 | 179 | # 10 -- SOURCE MECHANISM 180 | 181 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 182 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 183 | # Explosion 184 | MT: [1, 1, 1, 0, 0, 0] 185 | 186 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 187 | # For simplicity, this is a grid-search over strike/dip/rake. 188 | # moment tensors are computed from strike/dip/rake. 189 | strike_dip_rake_gridsearch: false 190 | 191 | # Strike/dip/rake are searched only in independent range. 192 | # Search strike in limits [180, 360] with given spacing 193 | strike_spacing: 10 194 | # Search dip in limits [0, 90] with given spacing 195 | dip_spacing: 10 196 | # Search rake in limits [-180, 180] with given spacing 197 | rake_spacing: 10 198 | 199 | # 6 -- COMPUTATIONAL EFFICIENCY 200 | 201 | # How many processes are spawned to increase computational speed. 202 | # !! WARNING: Using only 1 process is not supported at the moment. 203 | n_processes: 50 204 | 205 | # Distances are rounded to reduce number of Green's functions that need to be computed. 206 | # Unit is always kilometers (also if geometry_type is geographic). 207 | # Examples what accuray each ronding resuls in: 208 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 209 | decimal_round: 2 210 | 211 | # Grid-points that are on-land can be excluded for speed. 212 | # Only applies, if geometry_type is geographic. 213 | exclude_land: false 214 | 215 | # 11 -- MISC 216 | 217 | # Plot results for each run 218 | do_plot: true 219 | 220 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 221 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 222 | # list of all components to utilize 223 | components: ['Z'] 224 | wavetypes: ['Z'] 225 | 226 | # Initial implentation of singular-value decomposition 227 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 228 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 229 | # that contribute to signal vs those that contribute to noise. 230 | do_svd: false 231 | 232 | # How many eigenvectors should be kept. 233 | # Code will loop over all values given in the list. 234 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 235 | # and there are n_stations eigenvectors. 236 | n_svd_components: [0, 5, 10, 25, 50, 100] 237 | -------------------------------------------------------------------------------- /settings_files/fig5_c.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig5_c" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "file" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "./timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: false 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "geographic" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_lon: [-121, -113] 51 | grid_limits_lat: [32, 37] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .1 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | data_fn: ['/path/to/data/fig5_chino_hills.mseed'] 62 | 63 | # Location of station metadata files (stationXML) 64 | sta_xml_dir: "/path/to/stationxml/" 65 | 66 | # Sampling rate of the recorded data and synthetic green's functions. 67 | # Make sure this is correct for all data. 68 | # Green's functions database may only support up to 1Hz. 69 | sampling_rate: 1.0 70 | 71 | # 5 -- SYNTHETICS 72 | 73 | # the following settings determine the synthetics setup 74 | # toggle whether to do synthetics or real data processing 75 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 76 | do_synth: false 77 | 78 | # How should synthetic data be computed? 79 | # Options: 80 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 81 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 82 | synth_data_type: "database_GF" 83 | 84 | # Where are synthetic sources placed? 85 | # Coordinate units depend on geometry_type: 86 | # kilometers, if geometry_type is "cartesian" 87 | # degrees, if geometry_type is "geographic". 88 | synth_sources: [[0, 0]] 89 | 90 | # Add noise to synthetics 91 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 92 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 93 | # Percentage of max amplitude of noise level 94 | add_noise_to_synth: 0 95 | 96 | # Run multiple iterations with different random noise added. 97 | # Can help test/inform stability of results. 98 | add_noise_iterations: 1 99 | 100 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 101 | # - true: Define synthetic locations as below. 102 | # - false: Run synthetic tests using station locations from the stations in data_fn. 103 | use_synth_stations: false 104 | 105 | # Method of defining synthetic station locations. 106 | # Settings for each method are below. 107 | # Options: 108 | # - "file": Provide an external list of locations. See examples in synth/ 109 | # - "grid": Gridded distribution of evenly spaced stations 110 | # - "uniform": Uniform randomly distribution of stations 111 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 112 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 113 | synth_stations_mode: 'file' 114 | 115 | # if synth_stations_mode == 'file', which file to use 116 | # synth_stations_file: './synth/synth_three_arrays_50km.csv' 117 | synth_stations_file: "./synth_two_arrays_50km_larger_quad.csv" 118 | 119 | # if synth_stations_mode == "partial_circle", how circle is defined 120 | # total potential station locations along circle 121 | synth_stations_circle_n: 20 122 | # number of total potential station locations that are actually used 123 | synth_stations_circle_max: 20 124 | # radius of circle in kilometers 125 | synth_stations_circle_radius: 1 126 | 127 | # if synth_stations_mode == 'grid' or 'uniform' 128 | # how many stations should be placed 129 | synth_stations_n: 400 130 | 131 | # alternatively, use locations of all open stations via 'ORFEUS' 132 | use_open_worldwide_stations: false 133 | 134 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 135 | 136 | # Green's functions extracted from the database may be used (depending on other settings) for 137 | # a) synthetic data if run is synthetic (defined above) 138 | # b) synthetic wavefield that data is matched against (defined below) 139 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 140 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 141 | 142 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 143 | 144 | # How is the synthetic wavefield / steering vector computed 145 | # Options: 146 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 147 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 148 | type_of_gf: "GF" 149 | 150 | # if type_of_gf is "GF", at what depth does the source lie. 151 | # given in kilometers 152 | source_depth: 15.5 153 | 154 | # How to handle correct for amplitudes of Green's functions from database. 155 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 156 | # We recommend "whitening_GF". 157 | # Options: 158 | # - "None": no treatment 159 | # - "whitening_GF": frequency-domain normalisation 160 | # - "time_domain_norm": time-domain normalisation 161 | # - "spreading": compute and apply spreading correction for surface waves 162 | amplitude_treatment: "whitening_GF" 163 | 164 | # if type_of_gf is "v_const", specify the velocity used. 165 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 166 | # Δx is euclidean distance if geometry_type is cartesian 167 | # Δx is great-circle distance if geometry_type is geographic 168 | v_const: 3.2 169 | 170 | # 9 -- FREQUENCIES 171 | 172 | # A list of all frequencyt pairs to analyse. 173 | # Options: 174 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 175 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 176 | frequency_bands: [[0.1, 0.2]] 177 | 178 | # 10 -- SOURCE MECHANISM 179 | 180 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 181 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 182 | # 2008-07-29 Mw5.4 Chino Hills earthquake moment tensor 183 | # from: https://web.archive.org/web/20090512092723/http://www.data.scec.org/mtarchive/solution.jsp?eventid=14383980 184 | MT: [-1450, 602, 844, 495, -198, -689] 185 | 186 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 187 | # For simplicity, this is a grid-search over strike/dip/rake. 188 | # moment tensors are computed from strike/dip/rake. 189 | strike_dip_rake_gridsearch: false 190 | 191 | # Strike/dip/rake are searched only in independent range. 192 | # Search strike in limits [180, 360] with given spacing 193 | strike_spacing: 10 194 | # Search dip in limits [0, 90] with given spacing 195 | dip_spacing: 10 196 | # Search rake in limits [-180, 180] with given spacing 197 | rake_spacing: 10 198 | 199 | # 6 -- COMPUTATIONAL EFFICIENCY 200 | 201 | # How many processes are spawned to increase computational speed. 202 | # !! WARNING: Using only 1 process is not supported at the moment. 203 | n_processes: 50 204 | 205 | # Distances are rounded to reduce number of Green's functions that need to be computed. 206 | # Unit is always kilometers (also if geometry_type is geographic). 207 | # Examples what accuray each ronding resuls in: 208 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 209 | decimal_round: 2 210 | 211 | # Grid-points that are on-land can be excluded for speed. 212 | # Only applies, if geometry_type is geographic. 213 | exclude_land: false 214 | 215 | # 11 -- MISC 216 | 217 | # Plot results for each run 218 | do_plot: true 219 | 220 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 221 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 222 | # list of all components to utilize 223 | components: ['Z'] 224 | wavetypes: ['Z'] 225 | 226 | # Initial implentation of singular-value decomposition 227 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 228 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 229 | # that contribute to signal vs those that contribute to noise. 230 | do_svd: false 231 | 232 | # How many eigenvectors should be kept. 233 | # Code will loop over all values given in the list. 234 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 235 | # and there are n_stations eigenvectors. 236 | n_svd_components: [0, 5, 10, 25, 50, 100] 237 | -------------------------------------------------------------------------------- /settings_files/fig5_b.yml: -------------------------------------------------------------------------------- 1 | # 1 -- GLOBAL SETTINGS 2 | 3 | # base directory to save results in 4 | project_basedir: "/path/to/your/projects_folder/" 5 | 6 | # a subfolder is created for project_id to differentiate runs with varying settings.yml 7 | project_id: "fig5_b" 8 | 9 | # 2 -- TIME 10 | 11 | # window length used in analysis in seconds 12 | # IMPORTANT: for now dictated by length of GFs in gf database 13 | # e.g., 3880s for aniso PREM 5s database from syngine 14 | window_length: 3880 15 | 16 | # Mode of windows' start time determination: 17 | # - "file": extract start times from time external_timelist 18 | # - "overlapping_windows": define windows in given range (see below) 19 | time_window_mode: "file" 20 | 21 | # if time_window_mode == "overlapping_windows": 22 | 23 | # Start of first time window, given as obspy.UTCDateTime-readable string. 24 | start_time: "2019-02-01T01:00:00.0Z" 25 | 26 | # Last time windows ends no later than, given as obspy.UTCDateTime-readable string. 27 | end_time: "2019-02-07T23:59:59.0Z" 28 | 29 | # Overlap windows by how much in given time frame. 30 | # Given as a ratio. allowed overlaps: 0 =< overlap < 1. 31 | overlap: 0.5 32 | 33 | # if time_window_mode == "file" (see above) use this file 34 | external_timelist: "./timelist_chino.csv" 35 | 36 | # for debugging purposes or synthetic runs, it can be useful to run only a single time window 37 | # TODO: handle this more elegantly in code, especially for synthetic tests. 38 | do_only_one_timewindow: false 39 | 40 | # 3 -- GEOMETRY 41 | 42 | # Type of coordinate system used: 43 | # - "cartesian", when using local coordinates (or UTM) and distances are in meters 44 | # - "geographic", when using georeferenced data and distances are in degrees 45 | geometry_type: "geographic" 46 | 47 | # Longitude/X and Latitude/Y limits of the grid. 48 | # if geometry_type is "cartesian", limits must be given as grid_limits_x, grid_limits_y 49 | # if geometry_type is "geographic", limits must be given as grid_limits_lon, grid_limits_lat 50 | grid_limits_lon: [-121, -113] 51 | grid_limits_lat: [32, 37] 52 | 53 | # grid_spacing in units depending on geometry_type: 54 | # kilometers, if geometry_type is "cartesian" 55 | # degrees, if geometry_type is "geographic". 56 | grid_spacing: .1 57 | 58 | # 4 -- DATA 59 | 60 | # List of seismogram locations, obspy-readable strings 61 | # data_fn: ["/data/cen/u254/sven/global_mfp/data/for_publication/fig6_atlantic.mseed"] 62 | data_fn: ['/path/to/data/fig5_chino_hills.mseed'] 63 | 64 | # Location of station metadata files (stationXML) 65 | sta_xml_dir: "/path/to/stationxml/" 66 | 67 | # Sampling rate of the recorded data and synthetic green's functions. 68 | # Make sure this is correct for all data. 69 | # Green's functions database may only support up to 1Hz. 70 | sampling_rate: 1.0 71 | 72 | # 5 -- SYNTHETICS 73 | 74 | # the following settings determine the synthetics setup 75 | # toggle whether to do synthetics or real data processing 76 | # If do_synth is set to false, remaining settings in "5 -- SYNTHETICS" can be skipped. 77 | do_synth: false 78 | 79 | # How should synthetic data be computed? 80 | # Options: 81 | # - "database_GF": Extract Green's functions from database (see below) and use as synthetic data. 82 | # - "ricker": Compute a ricker wavelet with velocity given in v_const (see below) 83 | synth_data_type: "database_GF" 84 | 85 | # Where are synthetic sources placed? 86 | # Coordinate units depend on geometry_type: 87 | # kilometers, if geometry_type is "cartesian" 88 | # degrees, if geometry_type is "geographic". 89 | synth_sources: [[0, 0]] 90 | 91 | # Add noise to synthetics 92 | # For no noise set add_noise_to_synth: 0 and add_noise_iterations: 1 93 | # Noise is random uniformly distributed with limits [-add_noise_to_synth, add_noise_to_synth] 94 | # Percentage of max amplitude of noise level 95 | add_noise_to_synth: 0 96 | 97 | # Run multiple iterations with different random noise added. 98 | # Can help test/inform stability of results. 99 | add_noise_iterations: 1 100 | 101 | # Whether to place stations synthetically (more below) or use real locations (from metadata) 102 | # - true: Define synthetic locations as below. 103 | # - false: Run synthetic tests using station locations from the stations in data_fn. 104 | use_synth_stations: false 105 | 106 | # Method of defining synthetic station locations. 107 | # Settings for each method are below. 108 | # Options: 109 | # - "file": Provide an external list of locations. See examples in synth/ 110 | # - "grid": Gridded distribution of evenly spaced stations 111 | # - "uniform": Uniform randomly distribution of stations 112 | # - "partial_circle": Define a circle around the [0, 0] and put stations along it. 113 | # - "real_locations_worldwide": Use ORFEUS webservice to get a list of all worldwide broadband stations 114 | synth_stations_mode: 'file' 115 | 116 | # if synth_stations_mode == 'file', which file to use 117 | # synth_stations_file: './synth/synth_three_arrays_50km.csv' 118 | synth_stations_file: "./synth_two_arrays_50km_larger_quad.csv" 119 | 120 | # if synth_stations_mode == "partial_circle", how circle is defined 121 | # total potential station locations along circle 122 | synth_stations_circle_n: 20 123 | # number of total potential station locations that are actually used 124 | synth_stations_circle_max: 20 125 | # radius of circle in kilometers 126 | synth_stations_circle_radius: 1 127 | 128 | # if synth_stations_mode == 'grid' or 'uniform' 129 | # how many stations should be placed 130 | synth_stations_n: 400 131 | 132 | # alternatively, use locations of all open stations via 'ORFEUS' 133 | use_open_worldwide_stations: false 134 | 135 | # 6 -- GREEN's FUNCTION DATABASE (instaseis) 136 | 137 | # Green's functions extracted from the database may be used (depending on other settings) for 138 | # a) synthetic data if run is synthetic (defined above) 139 | # b) synthetic wavefield that data is matched against (defined below) 140 | # download prem_a_5s from https://ds.iris.edu/ds/products/syngine/ 141 | gf_db_dir: "/path/to/gf_database/prem_a_5s" 142 | 143 | # 8 -- SYNTHETIC WAVEFIELD TO MATCH AGAINST 144 | 145 | # How is the synthetic wavefield / steering vector computed 146 | # Options: 147 | # - "GF": extract synthetic wavefield from the Green's function database (see above) 148 | # - "v_const": Use spectra e^(-iωt), where t is estimated from v_const 149 | type_of_gf: "GF" 150 | 151 | # if type_of_gf is "GF", at what depth does the source lie. 152 | # given in kilometers 153 | source_depth: 15.5 154 | 155 | # How to handle correct for amplitudes of Green's functions from database. 156 | # For more details on the why and how, see Schippkus & Hadziioannou 2021. 157 | # We recommend "whitening_GF". 158 | # Options: 159 | # - "None": no treatment 160 | # - "whitening_GF": frequency-domain normalisation 161 | # - "time_domain_norm": time-domain normalisation 162 | # - "spreading": compute and apply spreading correction for surface waves 163 | amplitude_treatment: "whitening_GF" 164 | 165 | # if type_of_gf is "v_const", specify the velocity used. 166 | # spectra are computed as e^(-iωt), with traveltime t=Δx/v_const. 167 | # Δx is euclidean distance if geometry_type is cartesian 168 | # Δx is great-circle distance if geometry_type is geographic 169 | v_const: 3.2 170 | 171 | # 9 -- FREQUENCIES 172 | 173 | # A list of all frequencyt pairs to analyse. 174 | # Options: 175 | # - "None": Full spectra are used. May need to be careful w/ frequency content of signals. 176 | # - [fmin, fmax]: Spectra are sliced to given frequency band. 177 | frequency_bands: [[0.1, 0.2]] 178 | 179 | # 10 -- SOURCE MECHANISM 180 | 181 | # Moment tensor (MT) used to compute synthetic seismograms from Green's function database. 182 | # MT contains the 6 independent MT-components in this order: [Mxx, Myy, Mzz, Mxy, Mxz, Myz] 183 | # Explosion 184 | MT: [1, 1, 1, 0, 0, 0] 185 | # 2008 Mw5.4 Chino Hills earthquake moment tensor 186 | # from: https://web.archive.org/web/20090512092723/http://www.data.scec.org/mtarchive/solution.jsp?eventid=14383980 187 | # MT: [-1450, 602, 844, 495, -198, -689] 188 | 189 | # Instead of given a single source mechanism, the source mechanism may be grid-searched. 190 | # For simplicity, this is a grid-search over strike/dip/rake. 191 | # moment tensors are computed from strike/dip/rake. 192 | strike_dip_rake_gridsearch: false 193 | 194 | # Strike/dip/rake are searched only in independent range. 195 | # Search strike in limits [180, 360] with given spacing 196 | strike_spacing: 10 197 | # Search dip in limits [0, 90] with given spacing 198 | dip_spacing: 10 199 | # Search rake in limits [-180, 180] with given spacing 200 | rake_spacing: 10 201 | 202 | # 6 -- COMPUTATIONAL EFFICIENCY 203 | 204 | # How many processes are spawned to increase computational speed. 205 | # !! WARNING: Using only 1 process is not supported at the moment. 206 | n_processes: 50 207 | 208 | # Distances are rounded to reduce number of Green's functions that need to be computed. 209 | # Unit is always kilometers (also if geometry_type is geographic). 210 | # Examples what accuray each ronding resuls in: 211 | # 1 -> 0.1km; 0 -> 1km; -1 -> 10km, -2 -> 100km 212 | decimal_round: 2 213 | 214 | # Grid-points that are on-land can be excluded for speed. 215 | # Only applies, if geometry_type is geographic. 216 | exclude_land: false 217 | 218 | # 11 -- MISC 219 | 220 | # Plot results for each run 221 | do_plot: true 222 | 223 | # !! WARNING: Multiple components not yet supported. Only some basic groundwork layed out in the code. 224 | # !! Use ['Z'] for both at the moment. The code will fail otherwise. 225 | # list of all components to utilize 226 | components: ['Z'] 227 | wavetypes: ['Z'] 228 | 229 | # Initial implentation of singular-value decomposition 230 | # !! WARNING: NOT CONFIRMED TO BE WORKING. NEEDS FURTHER WORK. 231 | # In principle, SVD may be used to extract the eigenvectors of the cross-spectral density matrix 232 | # that contribute to signal vs those that contribute to noise. 233 | do_svd: false 234 | 235 | # How many eigenvectors should be kept. 236 | # Code will loop over all values given in the list. 237 | # Must be smaller than number of stations (CSDM is of shape (n_stations, n_stations, ω)), 238 | # and there are n_stations eigenvectors. 239 | n_svd_components: [0, 5, 10, 25, 50, 100] 240 | -------------------------------------------------------------------------------- /figure_scripts/fig2.py: -------------------------------------------------------------------------------- 1 | from itertools import product 2 | 3 | import cartopy.crs as ccrs 4 | import numpy as np 5 | import pandas as pd 6 | import pylab as plt 7 | import yaml 8 | from cmcrameri import cm 9 | 10 | 11 | def get_plotting_info_for_project(settings): 12 | def get_synth_stations(settings, wiggle=0.5): 13 | 14 | mode = settings["synth_stations_mode"] 15 | n = settings["synth_stations_n"] 16 | 17 | if mode == "grid": 18 | lons = np.linspace(-180, 180 - (360 / int(np.sqrt(n))), int(np.sqrt(n))) 19 | lats = np.linspace(-50, 50, int(np.sqrt(n))) 20 | station_locations = list(product(lons, lats)) 21 | 22 | elif mode == "uniform": 23 | lons = np.random.uniform(low=0, high=180, size=n) 24 | lats = np.random.uniform(low=-50, high=50, size=n) 25 | station_locations = list(zip(lons, lats)) 26 | 27 | elif mode == "partial_circle": 28 | n_total = settings["synth_stations_circle_max"] 29 | radius = settings["synth_stations_circle_radius"] 30 | n_used = settings["synth_stations_circle_n"] 31 | 32 | azimuths = np.linspace(0, 2 * np.pi, n_total) 33 | azimuths_used = azimuths[:n_used] 34 | 35 | lons = radius * np.cos(azimuths_used) 36 | lats = radius * np.sin(azimuths_used) 37 | station_locations = list(zip(lons, lats)) 38 | 39 | elif mode == "file": 40 | 41 | df = pd.read_csv( 42 | "/data/cen/u254/sven/global_mfp/code/" + settings["synth_stations_file"] 43 | ) 44 | lons = df["x"].values 45 | lats = df["y"].values 46 | station_locations = list(zip(lons, lats)) 47 | 48 | station_locations = np.array(station_locations) 49 | 50 | return station_locations 51 | 52 | def generate_global_grid(settings): 53 | """ 54 | Generate the grid geometry 55 | Returns coordinates of n grid_points as [[x0,y0,z0], [x1,y1,z1], ..., [xn,yn,zn]| 56 | """ 57 | 58 | if settings["geometry_type"] == "cartesian": 59 | grid_limits_lon = settings["grid_limits_x"] 60 | grid_limits_lat = settings["grid_limits_y"] 61 | else: 62 | grid_limits_lon = settings["grid_limits_lon"] 63 | grid_limits_lat = settings["grid_limits_lat"] 64 | 65 | grid_spacing_in_deg = settings["grid_spacing"] 66 | 67 | n_gridpoints_lon = int( 68 | (grid_limits_lon[1] - grid_limits_lon[0]) / grid_spacing_in_deg 69 | ) 70 | n_gridpoints_lat = int( 71 | (grid_limits_lat[1] - grid_limits_lat[0]) / grid_spacing_in_deg 72 | ) 73 | 74 | # grid geometry 75 | grid_lon_coords = np.linspace( 76 | grid_limits_lon[0], grid_limits_lon[1], n_gridpoints_lon 77 | ) 78 | grid_lat_coords = np.linspace( 79 | grid_limits_lat[0], grid_limits_lat[1], n_gridpoints_lat 80 | ) 81 | grid_points = np.asarray(list(product(grid_lon_coords, grid_lat_coords))) 82 | 83 | return grid_points, grid_lon_coords, grid_lat_coords 84 | 85 | station_locations = get_synth_stations(settings) 86 | grid_points, grid_lon_coords, grid_lat_coords = generate_global_grid( 87 | settings=settings 88 | ) 89 | source_loc = np.array(settings["synth_sources"]).T 90 | return grid_lon_coords, grid_lat_coords, station_locations, source_loc 91 | 92 | 93 | def plot_beampowers_on_map( 94 | lons, 95 | lats, 96 | beampowers, 97 | settings, 98 | station_locations=None, 99 | outfile=None, 100 | source_loc=None, 101 | title=None, 102 | fig=None, 103 | ax=None, 104 | vmin=None, 105 | vmax=None, 106 | plot_station_locations=False, 107 | ax_id=None, 108 | LHS=False, 109 | eiwt_vel=None, 110 | ): 111 | 112 | xx, yy = np.meshgrid(lons, lats) 113 | trans = ccrs.PlateCarree() 114 | 115 | if settings["geometry_type"] == "geographic": 116 | ax.coastlines(resolution="10m", linewidth=0.5, color="#AAAAAA") 117 | 118 | if plot_station_locations: 119 | if settings["geometry_type"] == "geographic": 120 | ax.scatter( 121 | station_locations[:, 0], 122 | station_locations[:, 1], 123 | c="k", 124 | s=4, 125 | marker="^", 126 | lw=0, 127 | transform=trans, 128 | zorder=5, 129 | ) 130 | else: 131 | ax.scatter( 132 | station_locations[:, 0], 133 | station_locations[:, 1], 134 | c="k", 135 | s=25, 136 | marker="^", 137 | lw=0, 138 | zorder=5, 139 | label="Station", 140 | ) 141 | 142 | if settings["geometry_type"] == "geographic": 143 | if vmin is None and vmax is None: 144 | bp_absmax = np.abs(np.nanmax(beampowers)) 145 | vmin = -bp_absmax 146 | vmax = bp_absmax 147 | pcm = ax.pcolormesh( 148 | xx, 149 | yy, 150 | beampowers.T, 151 | edgecolors="face", 152 | vmin=vmin, 153 | vmax=vmax, 154 | transform=trans, 155 | # cmap=cm.batlowW_r, 156 | cmap=cm.vik_r, 157 | ) 158 | else: 159 | # force symmetric colorscale 160 | if vmin is None and vmax is None: 161 | bp_absmax = np.abs(np.nanmax(beampowers)) 162 | vmin = -bp_absmax 163 | vmin = 0 164 | vmax = bp_absmax 165 | 166 | # compute max 167 | max_indices = np.unravel_index( 168 | np.argmax(beampowers, axis=None), beampowers.shape 169 | ) 170 | lon_max = lons[max_indices[0]] 171 | lat_max = lats[max_indices[1]] 172 | # vmin = -.005 173 | # vmax = .005 174 | pcm = ax.pcolormesh( 175 | xx, 176 | yy, 177 | beampowers.T, 178 | edgecolors="face", 179 | vmin=vmin, 180 | vmax=vmax, 181 | # cmap=cm.batlowW_r, 182 | cmap=cm.vik_r, 183 | shading="nearest", 184 | ) 185 | # pcm = ax.contourf(xx, yy, beampowers.T, levels=np.linspace(-1, 1, 50), vmin=vmin, vmax=vmax, cmap=roma_map) # , norm=LogNorm()) 186 | ax.set_xticks([-50, 0, 50]) 187 | ax.set_xticklabels([-50, 0, 50], fontsize=6) 188 | ax.set_yticks([-50, 0, 50]) 189 | ax.set_yticklabels([-50, 0, 50], fontsize=6) 190 | if ax_id == 0: 191 | if LHS: 192 | ax.set_ylabel("Distance [km]", fontsize=6) 193 | ax.set_xticklabels([]) 194 | ax.set_yticklabels(["-50\n50", 0, 50], fontsize=6) 195 | else: 196 | ax.set_xticklabels([]) 197 | ax.set_yticklabels(["-50\n50", 0, 50], fontsize=6) 198 | elif ax_id == 1: 199 | ax.set_xticklabels([]) 200 | ax.set_yticklabels([]) 201 | elif ax_id == 2: 202 | if LHS: 203 | ax.set_ylabel("Distance [km]", fontsize=6) 204 | ax.set_yticklabels([-50, 0, ""], fontsize=6) 205 | ax.set_xticklabels([-50, 0, "50/-50"], fontsize=6) 206 | # ax.set_xlabel("Distance [km]", fontsize=6) 207 | else: 208 | ax.set_yticklabels([-50, 0, ""], fontsize=6) 209 | ax.set_xticklabels([-50, 0, "50/-50"], fontsize=6) 210 | # ax.set_xlabel("Distance [km]", fontsize=6) 211 | elif ax_id == 3: 212 | ax.set_yticklabels([]) 213 | # ax.set_xlabel("Distance [km]", fontsize=6) 214 | ax.set_xticklabels(["", 0, 50], fontsize=6) 215 | 216 | ax.set_xlim(-50, 50) 217 | ax.set_ylim(-50, 50) 218 | 219 | if ax_id is None: 220 | ax.set_xlabel("Distance [km]", fontsize=6) 221 | if LHS: 222 | ax.set_ylabel("Distance [km]", fontsize=6) 223 | dist_to_true_src = np.linalg.norm( 224 | [lon_max - source_loc[0], lat_max - source_loc[1]] 225 | ) 226 | if eiwt_vel: 227 | t = ax.text( 228 | 0.07, 229 | 0.93, 230 | f"v={eiwt_vel}km/s\n" 231 | + r"$\Delta \vec{x}$ = " 232 | + f"{dist_to_true_src:.1f}km", 233 | ha="left", 234 | va="top", 235 | fontsize=6, 236 | # fontweight="bold", 237 | transform=ax.transAxes, 238 | ) 239 | t.set_bbox(dict(facecolor="w", alpha=0.50, edgecolor="None")) 240 | else: 241 | t = ax.text( 242 | 0.05, 243 | 0.95, 244 | f"Our approach\n" 245 | + r"$\Delta \vec{x}$ = " 246 | + f"{dist_to_true_src:.1f}km", 247 | ha="left", 248 | va="top", 249 | fontsize=6, 250 | # fontweight="bold", 251 | transform=ax.transAxes, 252 | ) 253 | t.set_bbox(dict(facecolor="w", alpha=0.50, edgecolor="None")) 254 | 255 | if LHS and ax_id == 0: 256 | ax.text( 257 | 0, 1.05, "a)", ha="center", va="bottom", transform=ax.transAxes, 258 | ) 259 | ax.text( 260 | 1, 1.05, "broadband", ha="center", va="bottom", transform=ax.transAxes, 261 | ) 262 | if ax_id == 0 and not LHS: 263 | ax.text( 264 | 0, 1.05, "c)", ha="center", va="bottom", transform=ax.transAxes, 265 | ) 266 | ax.text( 267 | 1, 268 | 1.05, 269 | "narrowband (0.13-0.15Hz)", 270 | ha="center", 271 | va="bottom", 272 | transform=ax.transAxes, 273 | ) 274 | if ax_id is None and LHS: 275 | ax.text( 276 | 0, 1.025, "b)", ha="center", va="bottom", transform=ax.transAxes, 277 | ) 278 | if ax_id is None and not LHS: 279 | ax.text( 280 | 0, 1.025, "d)", ha="center", va="bottom", transform=ax.transAxes, 281 | ) 282 | # pcm = ax.pcolormesh(xx, yy, beampowers.T, edgecolors='face', vmin=-bp_absmax, vmax=bp_absmax, norm=SymLogNorm(linthresh=1E-3), cmap=roma_map) 283 | # ax.stock_img() 284 | 285 | # x0, y0, w, h = ax.get_position().bounds 286 | # cb_ax = fig.add_axes([x0 + w + 0.025 * w, y0, 0.025 * w, h]) 287 | # plt.colorbar(pcm, cax=cb_ax) 288 | 289 | # plot max 290 | if settings["do_synth"]: 291 | 292 | # tdist = ax.text( 293 | # source_loc[0] + 5, 294 | # source_loc[1] + 5, 295 | # r"$\Delta \vec{x}$ = " + f"{dist_to_true_src:.2f}km", 296 | # fontsize=6, 297 | # va="bottom", 298 | # ha="left", 299 | # ) 300 | if settings["geometry_type"] == "geographic": 301 | ax.scatter( 302 | lon_max, 303 | lat_max, 304 | facecolors="#E2001A", 305 | edgecolors="w", 306 | linewidth=0.5, 307 | s=20, 308 | marker="o", 309 | label="Beampower Peak", 310 | transform=trans, 311 | ) 312 | elif settings["geometry_type"] == "cartesian": 313 | ax.scatter( 314 | lon_max, 315 | lat_max, 316 | facecolors="#E2001A", 317 | edgecolors="w", 318 | linewidth=0.5, 319 | s=20, 320 | marker="o", 321 | label="Beampower Peak", 322 | zorder=20, 323 | ) 324 | 325 | if source_loc is not None: 326 | if settings["geometry_type"] == "geographic": 327 | ax.scatter( 328 | source_loc[0], 329 | source_loc[1], 330 | edgecolors="k", 331 | c="magenta", 332 | linewidth=0.5, 333 | s=50, 334 | marker="*", 335 | transform=trans, 336 | ) 337 | else: 338 | ax.scatter( 339 | source_loc[0, :], 340 | source_loc[1, :], 341 | edgecolors="k", 342 | # c="#e2001a", 343 | c="w", 344 | linewidth=0.5, 345 | s=100, 346 | marker="*", 347 | label="Synth. Source", 348 | ) 349 | 350 | if title and settings["geometry_type"] == "geographic": 351 | ax.set_title(title) 352 | 353 | # ax.legend() 354 | 355 | # from cartopy.io import shapereader 356 | # ax.add_geometries(list(shapereader.Reader('/home/zmaw/u254070/.local/share/cartopy/shapefiles/natural_earth/physical/ne_10m_coastline.shp').geometries()), crs_use) 357 | 358 | # import cartopy.feature as cfeat 359 | # ax.add_feature(cfeat.GSHHSFeature) 360 | 361 | # ax.gridlines(crs=crs_use) 362 | 363 | # custom lim to check results 364 | # chile lat -35.47, lon -72.91 365 | # ax.set_extent([-76, -72, -40, -25], crs=trans) 366 | # ax.set_ylim(-40, -30) 367 | 368 | if ax_id is None and LHS: 369 | lgnd = ax.legend(loc="upper right", fontsize=6) 370 | 371 | if outfile: 372 | fig.savefig(outfile, dpi=300, transparent=False) 373 | else: 374 | plt.show() 375 | plt.close(fig) 376 | 377 | return pcm 378 | 379 | 380 | plt.rcParams.update({"font.size": 8}) 381 | 382 | with open( 383 | "/data/cen/u254/sven/global_mfp/projects/173_redevelop_synth_test_larger_array_GF/1635927790_settings.yml", 384 | "r", 385 | ) as stream: 386 | settings = yaml.safe_load(stream) 387 | 388 | # fig, axs = plt.subplots(2, 2) 389 | fig = plt.figure(figsize=(5, 5)) 390 | fig.subplots_adjust(left=0.09, right=0.915, top=0.95) 391 | outer_grid = fig.add_gridspec(2, 2) 392 | # left plots (broadband) 393 | # e-iwt - subplots for vconst=2.5, 2.6, 2.7, 2.8 394 | inner_grid_left = outer_grid[0, 0].subgridspec(2, 2, wspace=0, hspace=0) 395 | axs_eiwt_broadband = inner_grid_left.subplots() 396 | # eiwt_vels = [2.5, 2.6, 2.7, 2.8] 397 | eiwt_vels = [3.0, 3.2, 3.4, 3.6] 398 | for ax_id, (ax, eiwt_vel) in enumerate(zip(axs_eiwt_broadband.flatten(), eiwt_vels)): 399 | bp_fn = f"/data/cen/u254/sven/global_mfp/projects/173_redevelop_synth_test_larger_array_v{eiwt_vel}/out/out_1548982800.0_3880_None_0_0_False.npy" 400 | # bp_fn = f"/data/cen/u254/sven/global_mfp/projects/172_redo_synth_fig2_vconst{eiwt_vel}/out/out_1217356935.0_3880_None_0_0_False.npy" 401 | beampowers = np.load(bp_fn) 402 | beampowers /= np.max(np.abs(beampowers)) 403 | print(ax) 404 | ( 405 | grid_lon_coords, 406 | grid_lat_coords, 407 | station_locations, 408 | source_loc, 409 | ) = get_plotting_info_for_project(settings) 410 | pcm = plot_beampowers_on_map( 411 | lons=grid_lon_coords, 412 | lats=grid_lat_coords, 413 | beampowers=beampowers, 414 | settings=settings, 415 | station_locations=station_locations, 416 | source_loc=source_loc, 417 | ax=ax, 418 | vmin=-1, 419 | vmax=1, 420 | plot_station_locations=True, 421 | ax_id=ax_id, 422 | LHS=True, 423 | eiwt_vel=eiwt_vel, 424 | ) 425 | # GF 426 | # bp_fn = "/data/cen/u254/sven/global_mfp/projects/159_synth_test_GF/out/out_1548982800.0_3880_None_0_0.npy" 427 | with open( 428 | "/data/cen/u254/sven/global_mfp/projects/173_redevelop_synth_test_larger_array_GF_densergrid/1635941547_settings.yml", 429 | "r", 430 | ) as stream: 431 | settings = yaml.safe_load(stream) 432 | bp_fn = f"/data/cen/u254/sven/global_mfp/projects/173_redevelop_synth_test_larger_array_GF_densergrid/out/out_1548982800.0_3880_[0.01, 0.5]_0_0_False.npy" 433 | beampowers = np.load(bp_fn) 434 | beampowers /= np.max(np.abs(beampowers)) 435 | ax_GF_broadband = fig.add_subplot(outer_grid[1, 0]) 436 | ( 437 | grid_lon_coords, 438 | grid_lat_coords, 439 | station_locations, 440 | source_loc, 441 | ) = get_plotting_info_for_project(settings) 442 | pcm = plot_beampowers_on_map( 443 | lons=grid_lon_coords, 444 | lats=grid_lat_coords, 445 | beampowers=beampowers, 446 | settings=settings, 447 | station_locations=station_locations, 448 | source_loc=source_loc, 449 | ax=ax_GF_broadband, 450 | vmin=-1, 451 | vmax=1, 452 | plot_station_locations=True, 453 | LHS=True, 454 | ) 455 | 456 | # right plots (narrowband) 457 | # e-iwt 458 | with open( 459 | "/data/cen/u254/sven/global_mfp/projects/173_redevelop_synth_test_larger_array_GF/1635927790_settings.yml", 460 | "r", 461 | ) as stream: 462 | settings = yaml.safe_load(stream) 463 | inner_grid_left = outer_grid[0, 1].subgridspec(2, 2, wspace=0, hspace=0) 464 | axs_eiwt_narrowband = inner_grid_left.subplots() 465 | for ax_id, (ax, eiwt_vel) in enumerate(zip(axs_eiwt_narrowband.flatten(), eiwt_vels)): 466 | # bp_fn = f"/data/cen/u254/sven/global_mfp/projects/159_synth_test_vconst{eiwt_vel}/out/out_1548982800.0_3880_[0.13, 0.15]_0_0.npy" 467 | # bp_fn = f"/data/cen/u254/sven/global_mfp/projects/172_redo_synth_fig2_vconst{eiwt_vel}/out/out_1217356935.0_3880_[0.13, 0.15]_0_0_False.npy" 468 | bp_fn = f"/data/cen/u254/sven/global_mfp/projects/173_redevelop_synth_test_larger_array_v{eiwt_vel}/out/out_1548982800.0_3880_[0.13, 0.15]_0_0_False.npy" 469 | beampowers = np.load(bp_fn) 470 | beampowers /= np.max(np.abs(beampowers)) 471 | ( 472 | grid_lon_coords, 473 | grid_lat_coords, 474 | station_locations, 475 | source_loc, 476 | ) = get_plotting_info_for_project(settings) 477 | pcm = plot_beampowers_on_map( 478 | lons=grid_lon_coords, 479 | lats=grid_lat_coords, 480 | beampowers=beampowers, 481 | settings=settings, 482 | station_locations=station_locations, 483 | source_loc=source_loc, 484 | ax=ax, 485 | vmin=-1, 486 | vmax=1, 487 | plot_station_locations=True, 488 | ax_id=ax_id, 489 | LHS=False, 490 | eiwt_vel=eiwt_vel, 491 | ) 492 | # GF 493 | with open( 494 | "/data/cen/u254/sven/global_mfp/projects/173_redevelop_synth_test_larger_array_GF_densergrid/1635941547_settings.yml", 495 | "r", 496 | ) as stream: 497 | settings = yaml.safe_load(stream) 498 | bp_fn = f"/data/cen/u254/sven/global_mfp/projects/173_redevelop_synth_test_larger_array_GF_densergrid/out/out_1548982800.0_3880_[0.13, 0.15]_0_0_False.npy" 499 | beampowers = np.load(bp_fn) 500 | beampowers /= np.max(np.abs(beampowers)) 501 | ax_GF_narrowband = fig.add_subplot(outer_grid[1, 1]) 502 | ( 503 | grid_lon_coords, 504 | grid_lat_coords, 505 | station_locations, 506 | source_loc, 507 | ) = get_plotting_info_for_project(settings) 508 | pcm = plot_beampowers_on_map( 509 | lons=grid_lon_coords, 510 | lats=grid_lat_coords, 511 | beampowers=beampowers, 512 | settings=settings, 513 | station_locations=station_locations, 514 | source_loc=source_loc, 515 | ax=ax_GF_narrowband, 516 | vmin=-1, 517 | vmax=1, 518 | plot_station_locations=True, 519 | LHS=False, 520 | ) 521 | 522 | cb_ax = fig.add_axes([0.915 + 0.015, 0.3, 0.015, 0.4]) 523 | cbar = plt.colorbar(pcm, cax=cb_ax) # , extend="min") 524 | cbar.set_ticks([-1, 0, 1]) 525 | cbar.set_label(label="Normalised Beampower", fontsize=6, labelpad=-3) 526 | cbar.ax.tick_params(labelsize=6) 527 | 528 | fig.savefig("/data/cen/u254/sven/global_mfp/figure_scripts/png/fig2.png", dpi=300) 529 | -------------------------------------------------------------------------------- /figure_scripts/fig5.py: -------------------------------------------------------------------------------- 1 | # plot earthquake real data example 2 | 3 | # only plot stack, if something to stack 4 | # from sven_utils import suColors 5 | # my_cmap = suColors.get_custom_cmap(name='devon', inverted=True) 6 | # if len(beampowers_per_start_time) > 1: 7 | 8 | import cartopy.crs as ccrs 9 | import cartopy.feature 10 | import obspy 11 | from cmcrameri import cm 12 | from matplotlib.pyplot import axis 13 | 14 | 15 | def get_plotting_info_for_project(settings): 16 | import obspy 17 | 18 | def get_station_locs_from_staxml(st, settings): 19 | import obspy 20 | 21 | station_locations = [] 22 | for tr in st: 23 | inv = obspy.read_inventory( 24 | f"./data/stations/{tr.stats.network}.{tr.stats.station}.xml", 25 | format="STATIONXML", 26 | ) 27 | lat, lon = inv[0][0][0].latitude, inv[0][0][0].longitude 28 | station_locations.append([lon, lat]) 29 | return np.array(station_locations) 30 | 31 | def generate_global_grid(settings): 32 | """ 33 | Generate the grid geometry 34 | Returns coordinates of n grid_points as [[x0,y0,z0], [x1,y1,z1], ..., [xn,yn,zn]| 35 | """ 36 | from itertools import product 37 | 38 | if settings["geometry_type"] == "cartesian": 39 | grid_limits_lon = settings["grid_limits_x"] 40 | grid_limits_lat = settings["grid_limits_y"] 41 | else: 42 | grid_limits_lon = settings["grid_limits_lon"] 43 | grid_limits_lat = settings["grid_limits_lat"] 44 | 45 | grid_spacing_in_deg = settings["grid_spacing"] 46 | 47 | n_gridpoints_lon = int( 48 | (grid_limits_lon[1] - grid_limits_lon[0]) / grid_spacing_in_deg 49 | ) 50 | n_gridpoints_lat = int( 51 | (grid_limits_lat[1] - grid_limits_lat[0]) / grid_spacing_in_deg 52 | ) 53 | 54 | # grid geometry 55 | grid_lon_coords = np.linspace( 56 | grid_limits_lon[0], grid_limits_lon[1], n_gridpoints_lon 57 | ) 58 | grid_lat_coords = np.linspace( 59 | grid_limits_lat[0], grid_limits_lat[1], n_gridpoints_lat 60 | ) 61 | grid_points = np.asarray(list(product(grid_lon_coords, grid_lat_coords))) 62 | 63 | # exclude grid points on land? 64 | # from global_land_mask import globe 65 | # for gp in grid_points: 66 | # if globe.is_land(gp[1], gp[0]) 67 | 68 | return grid_points, grid_lon_coords, grid_lat_coords 69 | 70 | # 71 | st = obspy.read("./data/deconv/CI/LHZ_chino.mseed") 72 | st.merge(fill_value=0) 73 | station_locations = get_station_locs_from_staxml(st, settings) 74 | # print(station_locations) 75 | grid_points, grid_lon_coords, grid_lat_coords = generate_global_grid( 76 | settings=settings 77 | ) 78 | # source_loc = np.array(settings["synth_sources"]).T 79 | source_loc = [-117.766, 33.949] 80 | return grid_lon_coords, grid_lat_coords, station_locations, source_loc 81 | 82 | 83 | def plot_beampowers_on_map( 84 | lons, 85 | lats, 86 | beampowers, 87 | settings, 88 | station_locations=None, 89 | outfile=None, 90 | source_loc=None, 91 | title=None, 92 | fig=None, 93 | ax=None, 94 | vmin=None, 95 | vmax=None, 96 | plot_station_locations=False, 97 | ax_id=None, 98 | LHS=False, 99 | eiwt_vel=None, 100 | ): 101 | import cartopy.crs as ccrs 102 | import numpy as np 103 | import pylab as plt 104 | 105 | # plt.style.use("dracula") 106 | # crs_use = ccrs.Robinson() 107 | # convert lons, lats to corresponding CRS 108 | 109 | xx, yy = np.meshgrid(lons, lats) 110 | 111 | max_indices = np.unravel_index(np.argmax(beampowers, axis=None), beampowers.shape) 112 | lon_max = lons[max_indices[0]] 113 | lat_max = lats[max_indices[1]] 114 | dist = ( 115 | obspy.geodetics.gps2dist_azimuth( 116 | lat1=source_loc[1], lon1=source_loc[0], lat2=lat_max, lon2=lon_max 117 | )[0] 118 | / 1000 119 | ) 120 | 121 | # ax = plt.axes(projection=ccrs.Orthographic(central_longitude=source_loc[0], central_latitude=source_loc[1])) 122 | # _map = Basemap(projection='eck4',lon_0=0,resolution='c', ax=ax) 123 | # _map.drawcoastlines(linewidth=.5, color='k') 124 | # _map.drawparallels(np.arange(-90.,120.,30.)) 125 | # _map.drawmeridians(np.arange(0.,420.,60.)) 126 | trans = ccrs.PlateCarree() 127 | 128 | if settings["geometry_type"] == "geographic": 129 | ax.coastlines(resolution="10m", linewidth=0.5, color="k") 130 | 131 | if plot_station_locations: 132 | if settings["geometry_type"] == "geographic": 133 | ax.scatter( 134 | station_locations[:, 0], 135 | station_locations[:, 1], 136 | c="k", 137 | s=4, 138 | marker="^", 139 | lw=0, 140 | transform=trans, 141 | zorder=5, 142 | ) 143 | else: 144 | ax.scatter( 145 | station_locations[:, 0], 146 | station_locations[:, 1], 147 | c="k", 148 | s=25, 149 | marker="^", 150 | lw=0, 151 | zorder=5, 152 | label="Station", 153 | ) 154 | 155 | # xx, yy = _map(xx_mg, yy_mg) 156 | from matplotlib.colors import LogNorm, SymLogNorm 157 | 158 | if settings["geometry_type"] == "geographic": 159 | # bp_absmax = np.abs(np.nanmax(beampowers)) 160 | # bp_absmin = np.abs(np.nanmin(beampowers)) 161 | if vmin is None and vmax is None: 162 | bp_absmax = np.abs(np.nanmax(beampowers)) 163 | vmin = -bp_absmax 164 | vmax = bp_absmax 165 | # pcm = ax.pcolormesh(xx, yy, beampowers.T, edgecolors='face', vmin=-bp_absmax, vmax=bp_absmax, transform=trans, norm=SymLogNorm(linthresh=1E-3), cmap='RdBu') 166 | # pcm = ax.pcolormesh(xx, yy, beampowers.T, edgecolors='face', vmin=bp_absmin, vmax=bp_absmax, transform=trans, norm=LogNorm(), cmap='magma') 167 | pcm = ax.pcolormesh( 168 | xx, 169 | yy, 170 | beampowers.T, 171 | edgecolors="face", 172 | vmin=vmin, 173 | vmax=vmax, 174 | transform=trans, 175 | # cmap=cm.batlowW_r, 176 | cmap=cm.vik_r, 177 | ) 178 | # cnt = ax.contour( 179 | # xx, 180 | # yy, 181 | # beampowers.T, 182 | # levels=[0.95], 183 | # transform=trans, 184 | # colors="#E2001A", 185 | # linewidths=1, 186 | # ) 187 | # ax.set_xlim( 188 | # settings["grid_limits_lon"][0] + 0.75, settings["grid_limits_lon"][1] - 1 189 | # ) 190 | # ax.set_ylim(settings["grid_limits_lat"][0], settings["grid_limits_lat"][1]) 191 | # plot_lims = ( 192 | # np.round(source_loc[0] - 2, 0), 193 | # np.round(source_loc[0] + 2, 0), 194 | # np.round(source_loc[1] - 1.5, 0), 195 | # np.round(source_loc[1] + 1.5, 0), 196 | # ) 197 | plot_lims = (-119, -116.5, 33, 35) 198 | ax.set_xlim(*plot_lims[:2]) 199 | ax.set_ylim(*plot_lims[2:]) 200 | 201 | if ax_id == 0: 202 | ax.set_xticks([-119, -118, -117]) 203 | ax.set_yticks([33, 34, 35]) 204 | ax.set_xticklabels( 205 | [ 206 | r"119$^\circ$W", 207 | r"118$^\circ$W", 208 | r"117$^\circ$W", 209 | # r"116$^\circ$W/119$^\circ$W", 210 | ], 211 | fontsize=6, 212 | ) 213 | ax.set_yticklabels( 214 | [r"33$^\circ$N", r"34$^\circ$N", r"35$^\circ$N"], fontsize=6 215 | ) 216 | 217 | # overview_ax 218 | x0, y0, w, h = ax.get_position().bounds 219 | overview_ax = fig.add_axes( 220 | [x0 + 0.65 * w, y0 + 0.63 * h, 0.35 * w, 0.35 * h], 221 | projection=ccrs.NearsidePerspective( 222 | central_latitude=33.949, 223 | central_longitude=-117.766, 224 | satellite_height=500_000, 225 | ), 226 | ) 227 | # overview_ax.set_frame_on(False) 228 | 229 | overview_ax.plot( 230 | [plot_lims[0], plot_lims[0], plot_lims[1], plot_lims[1], plot_lims[0]], 231 | [plot_lims[2], plot_lims[3], plot_lims[3], plot_lims[2], plot_lims[2]], 232 | c="k", 233 | lw=0.75, 234 | transform=trans, 235 | ) 236 | 237 | overview_ax.add_feature(cartopy.feature.LAND, color="w") 238 | overview_ax.add_feature(cartopy.feature.OCEAN, color="w") 239 | overview_ax.add_feature(cartopy.feature.STATES, lw=0.1, edgecolor="#CCCCCC") 240 | overview_ax.add_feature(cartopy.feature.BORDERS, lw=0.25, color="#AAAAAA") 241 | overview_ax.set_global() 242 | 243 | overview_ax.coastlines(lw=0.25) 244 | # overview_ax.scatter( 245 | # 33.949, 246 | # -117.766, 247 | # edgecolors="k", 248 | # c="w", 249 | # linewidth=0.5, 250 | # s=25, 251 | # marker="*", 252 | # transform=trans, 253 | # zorder=5, 254 | # ) 255 | 256 | label_text = ( 257 | "Standard approach\n" + r"$\Delta \vec{x}$ = " + f"{dist:0.1f}km" 258 | ) 259 | 260 | # ax.add_feature(cartopy.feature.STATES, lw=0.1, edgecolor="#CCCCCC") 261 | ax.add_feature(cartopy.feature.BORDERS, lw=0.5, color="k") 262 | 263 | if ax_id == 1: 264 | label_text = ( 265 | "Our approach - Explosion source\n" 266 | + r"$\Delta \vec{x} = $" 267 | + f"{dist:0.1f}km" 268 | ) 269 | ax.set_xticks([-119, -118, -117]) 270 | ax.set_xticklabels( 271 | [r"119$^\circ$W", r"118$^\circ$W", r"117$^\circ$W"], fontsize=6, 272 | ) 273 | 274 | if ax_id == 2: 275 | label_text = ( 276 | "Our approach - CI moment tensor\n" 277 | + r"$\Delta \vec{x} = $" 278 | + f"{dist:0.1f}km" 279 | ) 280 | ax.set_xticks([-119, -118, -117]) 281 | ax.set_xticklabels( 282 | [r"119$^\circ$W", r"118$^\circ$W", r"117$^\circ$W"], fontsize=6, 283 | ) 284 | # cb_ax = fig.add_axes([0.915 + 0.015, 0.3, 0.015, 0.4]) 285 | x0, y0, w, h = ax.get_position().bounds 286 | cb_ax = fig.add_axes([x0 + w + 0.05 * w, y0, 0.05 * w, h]) 287 | cbar = plt.colorbar(pcm, cax=cb_ax) # , extend="min") 288 | # cbar.add_lines(cnt) 289 | cbar.set_ticks([-1, 0, 1]) 290 | cbar.set_label(label="Normalised Beampower", fontsize=6) 291 | cbar.ax.tick_params(labelsize=6) 292 | 293 | t = ax.text( 294 | 0.05, 295 | 0.95, 296 | label_text, 297 | ha="left", 298 | va="top", 299 | fontsize=6, 300 | # fontweight="bold", 301 | transform=ax.transAxes, 302 | zorder=100, 303 | ) 304 | t.set_bbox(dict(facecolor="w", alpha=0.75, edgecolor="None")) 305 | 306 | lblbls = ["a)", "b)", "c)"] 307 | ax.text( 308 | 0.00, 309 | 1.01, 310 | lblbls[ax_id], 311 | ha="left", 312 | va="bottom", 313 | fontsize=10, 314 | # fontweight="bold", 315 | transform=ax.transAxes, 316 | zorder=100, 317 | ) 318 | 319 | else: 320 | # force symmetric colorscale 321 | if vmin is None and vmax is None: 322 | bp_absmax = np.abs(np.nanmax(beampowers)) 323 | vmin = -bp_absmax 324 | vmin = 0 325 | vmax = bp_absmax 326 | # vmin = -.005 327 | # vmax = .005 328 | pcm = ax.pcolormesh( 329 | xx, 330 | yy, 331 | beampowers.T, 332 | edgecolors="face", 333 | vmin=vmin, 334 | vmax=vmax, 335 | # cmap=cm.batlowW_r, 336 | cmap=cm.vik_r, 337 | shading="nearest", 338 | ) # , norm=LogNorm()) 339 | # pcm = ax.contourf(xx, yy, beampowers.T, levels=np.linspace(-1, 1, 75), vmin=vmin, vmax=vmax, cmap=roma_map) # , norm=LogNorm()) 340 | ax.set_xticks([-75, 0, 75]) 341 | ax.set_xticklabels([-75, 0, 75], fontsize=6) 342 | ax.set_yticks([-75, 0, 75]) 343 | ax.set_yticklabels([-75, 0, 75], fontsize=6) 344 | if ax_id == 0: 345 | if LHS: 346 | ax.set_ylabel("Distance [km]", fontsize=6) 347 | ax.set_xticklabels([]) 348 | ax.set_yticklabels([-75, 0, 75], fontsize=6) 349 | else: 350 | ax.set_xticklabels([]) 351 | ax.set_yticklabels([-75, 0, 75], fontsize=6) 352 | elif ax_id == 1: 353 | ax.set_xticklabels([]) 354 | ax.set_yticklabels([]) 355 | elif ax_id == 2: 356 | if LHS: 357 | ax.set_yticklabels([-75, 0, 75], fontsize=6) 358 | ax.set_ylabel("Distance [km]", fontsize=6) 359 | ax.set_xticklabels([-75, 0, 75], fontsize=6) 360 | # ax.set_xlabel("Distance [km]", fontsize=6) 361 | else: 362 | ax.set_yticklabels([-75, 0, 75], fontsize=6) 363 | ax.set_xticklabels([-75, 0, 75], fontsize=6) 364 | # ax.set_xlabel("Distance [km]", fontsize=6) 365 | elif ax_id == 3: 366 | ax.set_yticklabels([]) 367 | # ax.set_xlabel("Distance [km]", fontsize=6) 368 | ax.set_xticklabels([-75, 0, 75], fontsize=6) 369 | if ax_id is None: 370 | ax.set_xlabel("Distance [km]", fontsize=6) 371 | if LHS: 372 | ax.set_ylabel("Distance [km]", fontsize=6) 373 | if eiwt_vel: 374 | ax.text( 375 | 0.05, 376 | 0.95, 377 | f"analytical GF, v={eiwt_vel}km/s", 378 | ha="left", 379 | va="top", 380 | fontsize=6, 381 | fontweight="bold", 382 | transform=ax.transAxes, 383 | ) 384 | else: 385 | ax.text( 386 | 0.05, 387 | 0.95, 388 | f"Numerical GF", 389 | ha="left", 390 | va="top", 391 | fontsize=6, 392 | fontweight="bold", 393 | transform=ax.transAxes, 394 | ) 395 | if LHS and ax_id == 0: 396 | ax.text( 397 | 0, 1.05, "a)", ha="center", va="bottom", transform=ax.transAxes, 398 | ) 399 | ax.text( 400 | 1, 1.05, "broadband", ha="center", va="bottom", transform=ax.transAxes, 401 | ) 402 | if ax_id == 0 and not LHS: 403 | ax.text( 404 | 0, 1.05, "c)", ha="center", va="bottom", transform=ax.transAxes, 405 | ) 406 | ax.text( 407 | 1, 408 | 1.05, 409 | "narrowband (0.13-0.15Hz)", 410 | ha="center", 411 | va="bottom", 412 | transform=ax.transAxes, 413 | ) 414 | if ax_id is None and LHS: 415 | ax.text( 416 | 0, 1.025, "b)", ha="center", va="bottom", transform=ax.transAxes, 417 | ) 418 | if ax_id is None and not LHS: 419 | ax.text( 420 | 0, 1.025, "d)", ha="center", va="bottom", transform=ax.transAxes, 421 | ) 422 | # pcm = ax.pcolormesh(xx, yy, beampowers.T, edgecolors='face', vmin=-bp_absmax, vmax=bp_absmax, norm=SymLogNorm(linthresh=1E-3), cmap=roma_map) 423 | # ax.stock_img() 424 | 425 | # x0, y0, w, h = ax.get_position().bounds 426 | # cb_ax = fig.add_axes([x0 + w + 0.025 * w, y0, 0.025 * w, h]) 427 | # plt.colorbar(pcm, cax=cb_ax) 428 | 429 | # plot max 430 | # if settings["do_synth"]: 431 | 432 | if settings["geometry_type"] == "geographic": 433 | ax.scatter( 434 | lon_max, 435 | lat_max, 436 | facecolors="#E2001A", 437 | edgecolors="w", 438 | linewidth=0.5, 439 | s=20, 440 | marker="o", 441 | label="Beampower Peak", 442 | transform=trans, 443 | zorder=10, 444 | ) 445 | elif settings["geometry_type"] == "cartesian": 446 | ax.scatter( 447 | lon_max, 448 | lat_max, 449 | facecolors="k", 450 | edgecolors="w", 451 | linewidth=0.5, 452 | s=50, 453 | marker="o", 454 | label="Beampower Peak", 455 | ) 456 | 457 | if source_loc is not None: 458 | if settings["geometry_type"] == "geographic": 459 | ax.scatter( 460 | source_loc[0], 461 | source_loc[1], 462 | edgecolors="k", 463 | c="w", 464 | linewidth=0.5, 465 | s=50, 466 | marker="*", 467 | transform=trans, 468 | ) 469 | else: 470 | ax.scatter( 471 | source_loc[0, :], 472 | source_loc[1, :], 473 | edgecolors="k", 474 | # c="#e2001a", 475 | c="w", 476 | linewidth=0.5, 477 | s=100, 478 | marker="*", 479 | label="Synth. Source", 480 | ) 481 | 482 | if title and settings["geometry_type"] == "geographic": 483 | ax.set_title(title) 484 | 485 | # ax.legend() 486 | 487 | # from cartopy.io import shapereader 488 | # ax.add_geometries(list(shapereader.Reader('/home/zmaw/u254070/.local/share/cartopy/shapefiles/natural_earth/physical/ne_10m_coastline.shp').geometries()), crs_use) 489 | 490 | # import cartopy.feature as cfeat 491 | # ax.add_feature(cfeat.GSHHSFeature) 492 | 493 | # ax.gridlines(crs=crs_use) 494 | 495 | # custom lim to check results 496 | # chile lat -35.47, lon -72.91 497 | # ax.set_extent([-76, -72, -40, -25], crs=trans) 498 | # ax.set_ylim(-40, -30) 499 | 500 | if outfile: 501 | fig.savefig(outfile, dpi=300, transparent=False) 502 | else: 503 | plt.show() 504 | plt.close(fig) 505 | 506 | return pcm 507 | 508 | 509 | import numpy as np 510 | import pylab as plt 511 | import yaml 512 | 513 | plt.rcParams.update({"font.size": 8}) 514 | 515 | with open( 516 | "/data/cen/u254/sven/global_mfp/projects/173_redo_chino_hills_denser/1636106117_settings.yml", 517 | "r", 518 | ) as stream: 519 | settings = yaml.safe_load(stream) 520 | # fig, axs = plt.subplots(2, 2) 521 | fig, axs = plt.subplots( 522 | 1, 3, subplot_kw={"projection": ccrs.PlateCarree()}, figsize=(6, 1.875) 523 | ) 524 | fig.subplots_adjust(left=0.06, right=0.9, top=0.95, wspace=0) 525 | 526 | bp_fn = "/data/cen/u254/sven/global_mfp/projects/173_redo_chino_hills_denser_GF_15.5km/out/out_1217356935.0_3880_[0.1, 0.2]_0_0_False.npy" 527 | # bp_fn = "/data/cen/u254/sven/global_mfp/projects/166_chino_GF_expl_MT_depth18km/out/out_1217356935.0_3880_[0.1, 0.5]_0_0_False.npy" 528 | beampowers = np.load(bp_fn) 529 | beampowers /= np.max(np.abs(beampowers)) 530 | ( 531 | grid_lon_coords, 532 | grid_lat_coords, 533 | station_locations, 534 | source_loc, 535 | ) = get_plotting_info_for_project(settings) 536 | pcm = plot_beampowers_on_map( 537 | lons=grid_lon_coords, 538 | lats=grid_lat_coords, 539 | beampowers=beampowers, 540 | settings=settings, 541 | station_locations=station_locations, 542 | source_loc=source_loc, 543 | ax=axs[1], 544 | vmin=-1, 545 | vmax=1, 546 | plot_station_locations=True, 547 | ax_id=1, 548 | LHS=True, 549 | fig=fig, 550 | # title="GF explosion", 551 | ) 552 | 553 | # GF 554 | bp_fn = "/data/cen/u254/sven/global_mfp/projects/173_redo_chino_hills_denser_GF_15.5km_trueGF/out/out_1217356935.0_3880_[0.1, 0.2]_0_0_False.npy" 555 | # bp_fn = "/data/cen/u254/sven/global_mfp/projects/166_chino_GF_correct_MT_depth18km/out/out_1217356935.0_3880_[0.1, 0.5]_0_0_False.npy" 556 | beampowers = np.load(bp_fn) 557 | beampowers /= np.max(np.abs(beampowers)) 558 | ( 559 | grid_lon_coords, 560 | grid_lat_coords, 561 | station_locations, 562 | source_loc, 563 | ) = get_plotting_info_for_project(settings) 564 | pcm = plot_beampowers_on_map( 565 | lons=grid_lon_coords, 566 | lats=grid_lat_coords, 567 | beampowers=beampowers, 568 | settings=settings, 569 | station_locations=station_locations, 570 | source_loc=source_loc, 571 | ax=axs[2], 572 | ax_id=2, 573 | vmin=-1, 574 | vmax=1, 575 | plot_station_locations=True, 576 | LHS=True, 577 | fig=fig, 578 | # title="GF correct MT", 579 | ) 580 | 581 | # vconst 582 | bp_fn = "/data/cen/u254/sven/global_mfp/projects/173_redo_chino_hills_denser/out/out_1217356935.0_3880_[0.1, 0.2]_0_0_False.npy" 583 | # bp_fn = "/data/cen/u254/sven/global_mfp/projects/166_chino_vconst3.0_depth18km/out/out_1217356935.0_3880_[0.1, 0.5]_0_0_False.npy" 584 | beampowers = np.load(bp_fn) 585 | beampowers /= np.max(np.abs(beampowers)) 586 | ( 587 | grid_lon_coords, 588 | grid_lat_coords, 589 | station_locations, 590 | source_loc, 591 | ) = get_plotting_info_for_project(settings) 592 | pcm = plot_beampowers_on_map( 593 | lons=grid_lon_coords, 594 | lats=grid_lat_coords, 595 | beampowers=beampowers, 596 | settings=settings, 597 | station_locations=station_locations, 598 | source_loc=source_loc, 599 | ax=axs[0], 600 | ax_id=0, 601 | vmin=-1, 602 | vmax=1, 603 | plot_station_locations=True, 604 | LHS=True, 605 | fig=fig, 606 | # title="v=3 km/s", 607 | ) 608 | 609 | fig.savefig("/data/cen/u254/sven/global_mfp/figure_scripts/png/fig5.png", dpi=300) 610 | -------------------------------------------------------------------------------- /figure_scripts/fig4.py: -------------------------------------------------------------------------------- 1 | # only plot stack, if something to stack 2 | # from sven_utils import suColors 3 | # my_cmap = suColors.get_custom_cmap(name='devon', inverted=True) 4 | # if len(beampowers_per_start_time) > 1: 5 | 6 | from cmcrameri import cm 7 | 8 | 9 | def get_plotting_info_for_project(settings): 10 | def get_synth_stations(settings, wiggle=0.5): 11 | from itertools import product 12 | 13 | import numpy as np 14 | 15 | mode = settings["synth_stations_mode"] 16 | n = settings["synth_stations_n"] 17 | 18 | if mode == "grid": 19 | lons = np.linspace(-180, 180 - (360 / int(np.sqrt(n))), int(np.sqrt(n))) 20 | lats = np.linspace(-75, 50, int(np.sqrt(n))) 21 | station_locations = list(product(lons, lats)) 22 | 23 | elif mode == "uniform": 24 | lons = np.random.uniform(low=0, high=180, size=n) 25 | lats = np.random.uniform(low=-75, high=75, size=n) 26 | station_locations = list(zip(lons, lats)) 27 | 28 | elif mode == "partial_circle": 29 | n_total = settings["synth_stations_circle_max"] 30 | radius = settings["synth_stations_circle_radius"] 31 | n_used = settings["synth_stations_circle_n"] 32 | 33 | azimuths = np.linspace(0, 2 * np.pi, n_total) 34 | azimuths_used = azimuths[:n_used] 35 | 36 | lons = radius * np.cos(azimuths_used) 37 | lats = radius * np.sin(azimuths_used) 38 | station_locations = list(zip(lons, lats)) 39 | 40 | elif mode == "file": 41 | import pandas as pd 42 | 43 | df = pd.read_csv( 44 | "/data/cen/u254/sven/global_mfp/code/" + settings["synth_stations_file"] 45 | ) 46 | lons = df["x"].values 47 | lats = df["y"].values 48 | station_locations = list(zip(lons, lats)) 49 | 50 | # if wiggle != 0: 51 | # station_locations = [[sta_lon+np.random.uniform(-wiggle, wiggle), sta_lat+np.random.uniform(-wiggle, wiggle)] for sta_lon, sta_lat in product(lons, lats)] 52 | 53 | station_locations = np.array(station_locations) 54 | 55 | return station_locations 56 | 57 | def generate_global_grid(settings): 58 | """ 59 | Generate the grid geometry 60 | Returns coordinates of n grid_points as [[x0,y0,z0], [x1,y1,z1], ..., [xn,yn,zn]| 61 | """ 62 | from itertools import product 63 | 64 | if settings["geometry_type"] == "cartesian": 65 | grid_limits_lon = settings["grid_limits_x"] 66 | grid_limits_lat = settings["grid_limits_y"] 67 | else: 68 | grid_limits_lon = settings["grid_limits_lon"] 69 | grid_limits_lat = settings["grid_limits_lat"] 70 | 71 | grid_spacing_in_deg = settings["grid_spacing"] 72 | 73 | n_gridpoints_lon = int( 74 | (grid_limits_lon[1] - grid_limits_lon[0]) / grid_spacing_in_deg 75 | ) 76 | n_gridpoints_lat = int( 77 | (grid_limits_lat[1] - grid_limits_lat[0]) / grid_spacing_in_deg 78 | ) 79 | 80 | # grid geometry 81 | grid_lon_coords = np.linspace( 82 | grid_limits_lon[0], grid_limits_lon[1], n_gridpoints_lon 83 | ) 84 | grid_lat_coords = np.linspace( 85 | grid_limits_lat[0], grid_limits_lat[1], n_gridpoints_lat 86 | ) 87 | grid_points = np.asarray(list(product(grid_lon_coords, grid_lat_coords))) 88 | 89 | # exclude grid points on land? 90 | # from global_land_mask import globe 91 | # for gp in grid_points: 92 | # if globe.is_land(gp[1], gp[0]) 93 | 94 | return grid_points, grid_lon_coords, grid_lat_coords 95 | 96 | station_locations = get_synth_stations(settings) 97 | grid_points, grid_lon_coords, grid_lat_coords = generate_global_grid( 98 | settings=settings 99 | ) 100 | source_loc = np.array(settings["synth_sources"]).T 101 | return grid_lon_coords, grid_lat_coords, station_locations, source_loc 102 | 103 | 104 | def plot_beampowers_on_map( 105 | lons, 106 | lats, 107 | beampowers, 108 | settings, 109 | station_locations=None, 110 | outfile=None, 111 | source_loc=None, 112 | title=None, 113 | fig=None, 114 | ax=None, 115 | vmin=None, 116 | vmax=None, 117 | plot_station_locations=False, 118 | ax_id=None, 119 | LHS=False, 120 | eiwt_vel=None, 121 | nonorm=False, 122 | ): 123 | import cartopy.crs as ccrs 124 | import numpy as np 125 | import pylab as plt 126 | 127 | # plt.style.use("dracula") 128 | # crs_use = ccrs.Robinson() 129 | # convert lons, lats to corresponding CRS 130 | 131 | xx, yy = np.meshgrid(lons, lats) 132 | 133 | # ax = plt.axes(projection=ccrs.Orthographic(central_longitude=source_loc[0], central_latitude=source_loc[1])) 134 | # _map = Basemap(projection='eck4',lon_0=0,resolution='c', ax=ax) 135 | # _map.drawcoastlines(linewidth=.5, color='k') 136 | # _map.drawparallels(np.arange(-90.,120.,30.)) 137 | # _map.drawmeridians(np.arange(0.,420.,60.)) 138 | trans = ccrs.PlateCarree() 139 | 140 | if settings["geometry_type"] == "geographic": 141 | ax.coastlines(resolution="10m", linewidth=0.5, color="#AAAAAA") 142 | 143 | if plot_station_locations: 144 | if settings["geometry_type"] == "geographic": 145 | ax.scatter( 146 | station_locations[:, 0], 147 | station_locations[:, 1], 148 | c="k", 149 | s=4, 150 | marker="^", 151 | lw=0, 152 | transform=trans, 153 | zorder=5, 154 | ) 155 | else: 156 | ax.scatter( 157 | station_locations[:, 0], 158 | station_locations[:, 1], 159 | c="k", 160 | ec="w", 161 | s=20, 162 | marker="^", 163 | lw=0.5, 164 | zorder=5, 165 | label="Station", 166 | ) 167 | 168 | # xx, yy = _map(xx_mg, yy_mg) 169 | from matplotlib.colors import LogNorm, SymLogNorm 170 | 171 | if settings["geometry_type"] == "geographic": 172 | # bp_absmax = np.abs(np.nanmax(beampowers)) 173 | # bp_absmin = np.abs(np.nanmin(beampowers)) 174 | if vmin is None and vmax is None: 175 | bp_absmax = np.abs(np.nanmax(beampowers)) 176 | vmin = -bp_absmax 177 | vmax = bp_absmax 178 | # pcm = ax.pcolormesh(xx, yy, beampowers.T, edgecolors='face', vmin=-bp_absmax, vmax=bp_absmax, transform=trans, norm=SymLogNorm(linthresh=1E-3), cmap='RdBu') 179 | # pcm = ax.pcolormesh(xx, yy, beampowers.T, edgecolors='face', vmin=bp_absmin, vmax=bp_absmax, transform=trans, norm=LogNorm(), cmap='magma') 180 | pcm = ax.pcolormesh( 181 | xx, 182 | yy, 183 | beampowers.T, 184 | edgecolors="face", 185 | vmin=vmin, 186 | vmax=vmax, 187 | transform=trans, 188 | # cmap=cm.batlowW_r, 189 | cmap=cm.vik_r, 190 | ) 191 | else: 192 | # force symmetric colorscale 193 | if vmin is None and vmax is None: 194 | bp_absmax = np.abs(np.nanmax(beampowers)) 195 | vmin = -bp_absmax 196 | vmin = 0 197 | vmax = bp_absmax 198 | # vmin = -.005 199 | # vmax = .005 200 | if nonorm: 201 | pcm = ax.pcolormesh( 202 | xx, 203 | yy, 204 | beampowers.T, 205 | edgecolors="face", 206 | vmin=1e-4, 207 | vmax=vmax, 208 | # cmap=cm.batlowW_r, 209 | cmap=cm.vik_r, 210 | shading="nearest", 211 | norm=LogNorm(), 212 | ) 213 | x0, y0, w, h = ax.get_position().bounds 214 | cb_ax = fig.add_axes([x0 + 0.9 * w, y0 + 0.2 * h, w * 0.05, h * 0.6]) 215 | cbar = plt.colorbar(pcm, cax=cb_ax) 216 | cbar.set_ticks([-1, 0, 1]) 217 | cbar.set_label(label="Normalised Beampower", fontsize=6) 218 | cbar.ax.tick_params(labelsize=6) 219 | else: 220 | pcm = ax.pcolormesh( 221 | xx, 222 | yy, 223 | beampowers.T, 224 | edgecolors="face", 225 | vmin=vmin, 226 | vmax=vmax, 227 | # cmap=cm.batlowW_r, 228 | cmap=cm.vik_r, 229 | shading="nearest", 230 | ) # , norm=LogNorm()) 231 | # pcm = ax.contourf(xx, yy, beampowers.T, levels=np.linspace(-1, 1, 50), vmin=vmin, vmax=vmax, cmap=roma_map) # , norm=LogNorm()) 232 | ax.set_xticks([-50, 0, 50]) 233 | ax.set_xticklabels([-50, 0, 50], fontsize=6) 234 | ax.set_yticks([-50, 0, 50]) 235 | ax.set_yticklabels([-50, 0, 50], fontsize=6) 236 | figlbl = "" 237 | if ax_id == 0: 238 | figlbl = "a)" 239 | labeltext = "Station density\n(x4 on right side)" 240 | ax.set_xlabel("Distance [km]", fontsize=6) 241 | ax.set_ylabel("Distance [km]", fontsize=6) 242 | ax.scatter( 243 | station_locations[3:, 0], 244 | station_locations[3:, 1], 245 | c="k", 246 | ec="w", 247 | s=60, 248 | marker="^", 249 | lw=0.75, 250 | zorder=5, 251 | ) 252 | # if LHS: 253 | # ax.set_ylabel("Distance [km]", fontsize=6) 254 | # ax.set_xticklabels([]) 255 | # ax.set_yticklabels([-50, 0, 50], fontsize=6) 256 | # else: 257 | # ax.set_xticklabels([]) 258 | # ax.set_yticklabels([-50, 0, 50], fontsize=6) 259 | elif ax_id == 1: 260 | figlbl = "a)" 261 | labeltext = "Right: quadruple station density" 262 | ax.set_xticklabels([]) 263 | ax.set_yticklabels([]) 264 | elif ax_id == 2: 265 | figlbl = "b)" 266 | labeltext = "Two sources (narrowband)" 267 | ax.set_yticklabels([]) 268 | # ax.set_yticks([]) 269 | ax.set_xlabel("Distance [km]", fontsize=6) 270 | ax.set_xticklabels([-50, 0, 50], fontsize=6) 271 | # ax.set_xlabel("Distance [km]", fontsize=6) 272 | 273 | elif ax_id == 3: 274 | figlbl = "c)" 275 | labeltext = "Two sources (broadband)" 276 | ax.set_yticklabels([]) 277 | # ax.set_yticks([]) 278 | ax.set_xlabel("Distance [km]", fontsize=6) 279 | ax.set_xticklabels([-50, 0, 50], fontsize=6) 280 | from scipy.ndimage import maximum_filter 281 | 282 | maxima = beampowers == maximum_filter(beampowers, size=50, mode="constant") 283 | localmaxlons = lons[np.where(maxima)[0]] 284 | localmaxlats = lats[np.where(maxima)[1]] 285 | maxima_values = beampowers[maxima] 286 | localmaxlons[maxima_values <= 0.5] = np.nan 287 | localmaxlats[maxima_values <= 0.5] = np.nan 288 | # localmaxlons[localmaxlats <= -80] = np.nan 289 | # localmaxlats[localmaxlats <= -80] = np.nan 290 | # localmaxlats[localmaxlons <= -5] = np.nan 291 | # localmaxlons[localmaxlons <= -5] = np.nan 292 | # localmaxlats[localmaxlons >= 5] = np.nan 293 | # localmaxlons[localmaxlons >= 5] = np.nan 294 | ax.scatter( 295 | localmaxlons, 296 | localmaxlats, 297 | facecolors="#E2001A", 298 | edgecolors="#E2001A", 299 | linewidth=0.5, 300 | s=5, 301 | marker="o", 302 | label="Beampower Peak", 303 | alpha=1, 304 | zorder=10, 305 | ) 306 | ax.set_xlim(-50, 50) 307 | ax.set_ylim(-50, 50) 308 | ltextx, ltexty = 0.05, 0.95 309 | if ax_id is None: 310 | ax.set_xlabel("Distance [km]", fontsize=6) 311 | if LHS: 312 | ax.set_ylabel("Distance [km]", fontsize=6) 313 | if ax_id == 100: 314 | labeltext = "zoom-in" 315 | ltextx += 0.02 316 | ltexty -= 0.02 317 | t = ax.text( 318 | ltextx, 319 | ltexty, 320 | labeltext, 321 | ha="left", 322 | va="top", 323 | fontsize=6, 324 | # fontweight="bold", 325 | transform=ax.transAxes, 326 | ) 327 | t.set_bbox(dict(facecolor="w", alpha=0.75, edgecolor="None")) 328 | ax.text( 329 | 0.00, 330 | 1.01, 331 | figlbl, 332 | ha="left", 333 | va="bottom", 334 | fontsize=10, 335 | # fontweight="bold", 336 | transform=ax.transAxes, 337 | zorder=100, 338 | ) 339 | # if LHS and ax_id == 0: 340 | # ax.text( 341 | # 0, 1.05, "a)", ha="center", va="bottom", transform=ax.transAxes, 342 | # ) 343 | # # ax.text( 344 | # # 1, 1.05, "broadband", ha="center", va="bottom", transform=ax.transAxes, 345 | # # ) 346 | 347 | if ax_id is None and LHS: 348 | ax.text( 349 | 0, 1.025, "b)", ha="center", va="bottom", transform=ax.transAxes, 350 | ) 351 | if ax_id is None and not LHS: 352 | ax.text( 353 | 0, 1.025, "d)", ha="center", va="bottom", transform=ax.transAxes, 354 | ) 355 | # pcm = ax.pcolormesh(xx, yy, beampowers.T, edgecolors='face', vmin=-bp_absmax, vmax=bp_absmax, norm=SymLogNorm(linthresh=1E-3), cmap=roma_map) 356 | # ax.stock_img() 357 | 358 | # x0, y0, w, h = ax.get_position().bounds 359 | # cb_ax = fig.add_axes([x0 + w + 0.025 * w, y0, 0.025 * w, h]) 360 | # plt.colorbar(pcm, cax=cb_ax) 361 | 362 | # plot max 363 | if settings["do_synth"]: 364 | max_indices = np.unravel_index( 365 | np.argmax(beampowers, axis=None), beampowers.shape 366 | ) 367 | lon_max = lons[max_indices[0]] 368 | lat_max = lats[max_indices[1]] 369 | if settings["geometry_type"] == "geographic": 370 | ax.scatter( 371 | lon_max, 372 | lat_max, 373 | facecolors="#E2001A", 374 | edgecolors="w", 375 | linewidth=0.5, 376 | s=50, 377 | marker="o", 378 | label="Beampower Peak", 379 | transform=trans, 380 | ) 381 | elif settings["geometry_type"] == "cartesian": 382 | ax.scatter( 383 | lon_max, 384 | lat_max, 385 | facecolors="#E2001A", 386 | edgecolors="w", 387 | linewidth=0.5, 388 | s=20, 389 | marker="o", 390 | label="Beampower Peak", 391 | zorder=10, 392 | ) 393 | 394 | if source_loc is not None: 395 | if settings["geometry_type"] == "geographic": 396 | ax.scatter( 397 | source_loc[0], 398 | source_loc[1], 399 | edgecolors="k", 400 | c="magenta", 401 | linewidth=0.75, 402 | s=50, 403 | marker="*", 404 | transform=trans, 405 | ) 406 | else: 407 | ax.scatter( 408 | source_loc[0, :], 409 | source_loc[1, :], 410 | edgecolors="k", 411 | # c="#e2001a", 412 | c="w", 413 | linewidth=0.5, 414 | s=100, 415 | marker="*", 416 | label="Synth. Source", 417 | ) 418 | 419 | if title and settings["geometry_type"] == "geographic": 420 | ax.set_title(title) 421 | 422 | # ax.legend() 423 | 424 | # from cartopy.io import shapereader 425 | # ax.add_geometries(list(shapereader.Reader('/home/zmaw/u254070/.local/share/cartopy/shapefiles/natural_earth/physical/ne_10m_coastline.shp').geometries()), crs_use) 426 | 427 | # import cartopy.feature as cfeat 428 | # ax.add_feature(cfeat.GSHHSFeature) 429 | 430 | # ax.gridlines(crs=crs_use) 431 | 432 | # custom lim to check results 433 | # chile lat -35.47, lon -72.91 434 | # ax.set_extent([-76, -72, -40, -25], crs=trans) 435 | # ax.set_ylim(-40, -30) 436 | 437 | if ax_id == 100: 438 | # 65,-66.33 439 | ax.set_xlim(65 - 2.5, 65 + 2.5) 440 | ax.set_ylim(-66.33 - 2.5, -66.33 + 2.5) 441 | ax.set_xticks([64, 66]) 442 | ax.set_yticks([-64, -66, -68]) 443 | ax.set_xticklabels([64, 66], fontsize=6) 444 | ax.set_yticklabels([-64, -66, -68], fontsize=6) 445 | # 65 - 2.5, 65 + 2.5 446 | # -66.33 - 2.5, -66.33 + 2.5 447 | # 65,-66.33 448 | 449 | if ax_id == 0: 450 | # lgnd = ax.legend(loc="upper right", fontsize=6) 451 | pass 452 | 453 | if outfile: 454 | fig.savefig(outfile, dpi=300, transparent=False) 455 | else: 456 | plt.show() 457 | plt.close(fig) 458 | 459 | return pcm 460 | 461 | 462 | import numpy as np 463 | import pylab as plt 464 | import yaml 465 | 466 | plt.rcParams.update({"font.size": 8}) 467 | 468 | with open( 469 | "/data/cen/u254/sven/global_mfp/projects/173_redo_quad/1636027988_settings.yml", 470 | "r", 471 | ) as stream: 472 | settings = yaml.safe_load(stream) 473 | 474 | # fig, axs = plt.subplots(2, 2) 475 | fig = plt.figure(figsize=(6, 2.25)) 476 | fig.subplots_adjust(left=0.075, bottom=0.075, right=0.915, top=0.95) 477 | outer_grid = fig.add_gridspec(1, 3, wspace=0.1, hspace=0.1) 478 | # left plots (broadband) 479 | # e-iwt - subplots for vconst=2.5, 2.6, 2.7, 2.8 480 | # inner_grid_left = outer_grid[0, 0].subgridspec(2, 2, wspace=0, hspace=0) 481 | # axs_eiwt_broadband = inner_grid_left.subplots() 482 | # ax_notreatment = fig.add_subplot(outer_grid[0]) 483 | # # bp_fn = f"/data/cen/u254/sven/global_mfp/projects/160_ampl_treatment_none/out/out_1548982800.0_3880_[0.13, 0.15]_0_0.npy" 484 | # # bp_fn = f"/data/cen/u254/sven/global_mfp/projects/167_synth/out/out_1548982800.0_3880_[0.13, 0.15]_0_0_False.npy" 485 | # bp_fn = f"/data/cen/u254/sven/global_mfp/projects/170_redo_synths_fig1_broadband_GF/out/out_1548982800.0_3880_[0.13, 0.15]_0_0_False.npy" 486 | # # bp_fn = f"/data/cen/u254/sven/global_mfp/projects/160_ampl_treatment_spreading_attenuation_7_corciulo/out/out_1548982800.0_3880_[0.13, 0.15]_0_0.npy" 487 | # beampowers = np.load(bp_fn) 488 | # beampowers /= np.max(np.abs(beampowers)) 489 | # ( 490 | # grid_lon_coords, 491 | # grid_lat_coords, 492 | # station_locations, 493 | # source_loc, 494 | # ) = get_plotting_info_for_project(settings) 495 | # pcm = plot_beampowers_on_map( 496 | # lons=grid_lon_coords, 497 | # lats=grid_lat_coords, 498 | # beampowers=beampowers, 499 | # settings=settings, 500 | # station_locations=station_locations, 501 | # source_loc=source_loc, 502 | # ax=ax_notreatment, 503 | # vmin=-1, 504 | # vmax=1, 505 | # plot_station_locations=True, 506 | # ax_id=0, 507 | # LHS=True, 508 | # # nonorm=True, 509 | # # fig=fig, 510 | # ) 511 | 512 | # ax_notreatment.plot( 513 | # [0.335, 0.335 + 0.09], [0.675, 0.61], transform=fig.transFigure, c="k", lw=0.5, 514 | # ) 515 | 516 | # 65 - 2.5, 65 + 2.5 517 | # -66.33 - 2.5, -66.33 + 2.5 518 | # ax_notreatment.plot( 519 | # [65 - 2.5, 65 - 2.5, 65 + 2.5, 65 + 2.5, 65 - 2.5], 520 | # [-66.33 - 2.5, -66.33 + 2.5, -66.33 + 2.5, -66.33 - 2.5, -66.33 - 2.5], 521 | # c="#E2001A", 522 | # lw=1, 523 | # zorder=100, 524 | # ) 525 | 526 | # ax_notreatment_zoom.set_xlim() 527 | 528 | # time-domain top-right 529 | ax_timedomain = fig.add_subplot(outer_grid[0]) 530 | ax_timedomain.set_aspect("equal") 531 | bp_fn = f"/data/cen/u254/sven/global_mfp/projects/173_redo_quad/out/out_1548982800.0_3880_[0.13, 0.15]_0_0_False.npy" 532 | beampowers = np.load(bp_fn) 533 | beampowers /= np.max(np.abs(beampowers)) 534 | ( 535 | grid_lon_coords, 536 | grid_lat_coords, 537 | station_locations, 538 | source_loc, 539 | ) = get_plotting_info_for_project(settings) 540 | pcm = plot_beampowers_on_map( 541 | lons=grid_lon_coords, 542 | lats=grid_lat_coords, 543 | beampowers=beampowers, 544 | settings=settings, 545 | station_locations=station_locations, 546 | source_loc=source_loc, 547 | ax=ax_timedomain, 548 | vmin=-1, 549 | vmax=1, 550 | plot_station_locations=True, 551 | ax_id=0, 552 | LHS=False, 553 | ) 554 | 555 | 556 | with open( 557 | "/data/cen/u254/sven/global_mfp/projects/173_redo_two_source_12/1636104599_settings.yml", 558 | "r", 559 | ) as stream: 560 | settings = yaml.safe_load(stream) 561 | 562 | ( 563 | grid_lon_coords, 564 | grid_lat_coords, 565 | station_locations, 566 | source_loc, 567 | ) = get_plotting_info_for_project(settings) 568 | 569 | # phase-corr bottom-left 570 | ax_phasecorr = fig.add_subplot(outer_grid[1]) 571 | ax_phasecorr.set_aspect("equal") 572 | bp_fn = f"/data/cen/u254/sven/global_mfp/projects/173_redo_two_source_12/out/out_1548982800.0_3880_[0.13, 0.15]_0_0_False.npy" 573 | beampowers = np.load(bp_fn) 574 | beampowers /= np.max(np.abs(beampowers)) 575 | ( 576 | grid_lon_coords, 577 | grid_lat_coords, 578 | station_locations, 579 | source_loc, 580 | ) = get_plotting_info_for_project(settings) 581 | pcm = plot_beampowers_on_map( 582 | lons=grid_lon_coords, 583 | lats=grid_lat_coords, 584 | beampowers=beampowers, 585 | settings=settings, 586 | station_locations=station_locations, 587 | source_loc=source_loc, 588 | ax=ax_phasecorr, 589 | vmin=-1, 590 | vmax=1, 591 | plot_station_locations=True, 592 | ax_id=2, 593 | LHS=True, 594 | ) 595 | 596 | # whitening bottom-right 597 | ax_whitening = fig.add_subplot(outer_grid[2]) 598 | ax_whitening.set_aspect("equal") 599 | bp_fn = f"/data/cen/u254/sven/global_mfp/projects/173_redo_two_source_12/out/out_1548982800.0_3880_[0.01, 0.5]_0_0_False.npy" 600 | beampowers = np.load(bp_fn) 601 | beampowers /= np.max(np.abs(beampowers)) 602 | ( 603 | grid_lon_coords, 604 | grid_lat_coords, 605 | station_locations, 606 | source_loc, 607 | ) = get_plotting_info_for_project(settings) 608 | pcm = plot_beampowers_on_map( 609 | lons=grid_lon_coords, 610 | lats=grid_lat_coords, 611 | beampowers=beampowers, 612 | settings=settings, 613 | station_locations=station_locations, 614 | source_loc=source_loc, 615 | ax=ax_whitening, 616 | vmin=-1, 617 | vmax=1, 618 | plot_station_locations=True, 619 | ax_id=3, 620 | LHS=False, 621 | ) 622 | 623 | 624 | x0, y0, w, h = ax_whitening.get_position().bounds 625 | # cb_ax = fig.add_axes([0.915 + 0.015, 0.3, 0.015, 0.4]) 626 | cb_ax = fig.add_axes([x0 + w + 0.05 * w, y0, 0.05 * w, h]) 627 | cbar = plt.colorbar(pcm, cax=cb_ax) # , extend="min") 628 | cbar.set_ticks([-1, 0, 1]) 629 | cbar.set_label(label="Normalised Beampower", fontsize=6) 630 | cbar.ax.tick_params(labelsize=6) 631 | 632 | fig.savefig("/data/cen/u254/sven/global_mfp/figure_scripts/png/fig4.png", dpi=300) 633 | --------------------------------------------------------------------------------