This page here has been created for the latest stable release of Salvus. You have chosen to view the documentation for another Salvus version. Please be aware there might be some small differences you have to account for.
This release comes with two main features: (1) better support for spherical chunk domains formed by arbitrary polygons and (2) a new output format to compute the wavefield in frequency domain for a set of specified frequencies by applyling the Fourier transform on the fly during the simulation.
Additionally, there are several important bug fixes related to SmoothieSEM meshes, reading large hdf5 datasets, and writing xdmf files in SalvusCompute.
Enable on-the-fly Fourier transforms to output the volumetruc wavefield in frequency domain for a list of discrete frequencies.
It can be configured in the simple_config.simulation.Waveform
object using
output.frequency_domain
.
This feature is currently only enabled for simulations on CPUs.
Fix a bug in SalvusCompute that caused multiple ranks to write xdmf files.
It seems as though the large dataset mitigations introduced in HDF5 1.10.2 were only applied to dataset writes, and not reads. This introduces a temporary workaround to read models with large (> 2GB) amounts of data per rank.
Fixes an issue that caused broken meshes when smoothiesem was used with high number of elements in lateral direction.
Various bug fixes and quality-of-life improvements when using a
SphericalChunkDomain
together with a spherical polygon to further constrain
the spatial extent. Most importantly conversions between WGS84 and fully
spherical coordinates are now consistent with the rest of Salvus. The
in-notebook domain plot now also works and shows the original spherical chunk
together with the domain polygon.
Minor release which fixes a bug in certain GPU runs, and adds the capability to limit the number of simultaneously running jobs in a slurm job array.
Fix a bug that previously existed where, in the case of a multi-node GPU run with 1 rank per node, the GPU halo would not get initialized properly. This would then lead to a failure during site initialization (as expected).
Optionally limit the number of parallel jobs in a slurm job array.
This can be specified in the site configuration of a slurm site with
max_simultaneous_jobs_in_job_array = 4
which internally translates to, for example, the %4
in --array=0-15%4
.
Minor release including a few bug fixes listed below. Additionally, the
spectral-element order and output sampling rate for receivers is now
configurable through the WaveformSimulationConfiguration
.
The last part of running a simulation usually is to delete the remote run and temp directories Salvus needs to simulate waves. In most cases this just works but especially on network file systems the file system might be busy and refuse to actually delete anything. Previously this resulted in an exception but because everything else worked fine this was undesired. It now, by default, only raises a warning.
You can restore the old behaviour by setting raise_on_deletion_failure=True
when using the low-level SalvusFlow API calls:
sn.api.run(..., raise_on_deletion_failure=True) sn.api.run_many(..., raise_on_deletion_failure=True)
As before it will retry deleting a remote directory up to 5 times before actually raising the warning or exception with a now slightly increased timeout between retries.
It will also no longer raise in these cases in SalvusProject which should make it more stable on some file systems.
Add the sampling interval for point output to the WaveformSimulationConfiguration.
Fix a bug where side-sets involving fluid layers on UTM domains where incorrectly attached.
The polynomial degree of the spectral-element basis is now configurable
in the WaveformSimulationConfiguration
.
w = WaveformSimulationConfiguration(spectral_element_order=6)
If not specified, the default remains at 4
as in all previous releases.
The main feature in this release is a new method for the visualization /
analysis of 2- or 3-D models and gradients. The addition of the function
extract_model_to_regular_grid
to the salvus.mesh.unstructured_mesh_utils
module allows users to regularly sample a given mesh given locations
specified by an xarray
dataset. Additional improvements include a more
flexible API for surface topography in UTM domains, a memory use mitigation
when running many shots with the same mesh, and the automatic up-casting of
related types in certain schema (for example: "2 elements per wavelength" is
now upcast to "2.0 elements per wavelength").
Automatically cast integers to floats in many cases where objects expect floating point values to be set.
Copying simulation objects now, by default, only references a potentially attached mesh.
Many workflow have a large number of copied simulation objects which can result in a high memory usage if the meshes are copied as well.
The meshes can still be optionally copied with:
w_copy = w.copy(copy_mesh=True)
A new function named extract_model_to_regular_grid
has been added to the
unstructured_mesh_utils
module. This function performs an interpolation from a
general, unstructured mesh (spherical or cartesian) to a set of points defined
on a xarray
dataset. This can be useful, for instance, to create slices
through a model for efficient visualization and analysis. See the function's
docstring for additional examples, information, and tips.
A new parameter can optionally be passed to a cartesian SurfaceTopography
object that restricts the mesh deformation above a given z-value. This is
useful, for instance, when placing a layer (i.e. the atmosphere) above a free
surface with topography. Related constructors (such as
SurfaceTopography.from_gmrt_file()
optionally take this parameter as well.
This release focusses on quality of life improvements for solving the inverse problem. It includes a bunch of bug fixes as well as new features.
A new tab has been added to the inversion dashboard showing some details about model updates and the evolution of the trust-region algorithm. This grants insights into how an ongoing inversion is doing.
SalvusProject and SalvusFlow can now recover more gracefully from partially failed job arrays where only a few jobs did not finish.
Furthermore the window picking for seismological full waveform inversions is now a lot faster.
Note that plotly >= 4.12.0 is required to display the new widgets properly. To update the python environment, check the installation instructions or run
wget https://mondaic.com/environment.yml -O salvus-0.11.26.yml conda env update -n salvus -f salvus-0.11.26.yml
.
If a few jobs in a Salvus job array failed for some reason, the output for the successfully completed jobs can now be retrieved in a much simpler way:
SalvusJobArray.copy_output(..., copy_partial_results=True)
copy_partial_results
defaults to True
.
The same parameter is exposed to the salvus.flow.api.run_many()
command and
also defaults to True
there.
Expose more parameters to steer the adaptive adjustment of the trust-region radius.
Bug fix for the gradient widget of the inversion dashboard, where previously some event-dependent gradients were not displayed correctly.
Bug fix in the SimulationConfiguration to ensure the
extra_output_configuration
passed to launch
overwrites additional output
values defined in the WaveformSimulationConfiguration
. The output options
in the WaveformSimulationConfiguration
will be deprecated in a future
release.
Add a new tab to the inversion dashboard to visualize the progress of model updates and trust-region radius.
Add a toggle button to the misfit widget to switch between absolute and relative misfits - normalized per iteration or event, respectively.
Much faster seismological window picking for some cases. Additionally it is now a bit more conservative and will not pick some sketchy windows it did not pick before. All in all the picked windows should be very similar to results from the previous version of this algorithm but a few less windows will be picked.
The p.waveforms.has_data()
method now also works for synthetic data.
The partial copy of the Salvus job array results has been integrated into all parts of SalvusProject. If one or more jobs fail for a forward or an adjoint simulation, it will still raise an exception but copy all successfully completed jobs to the project folder. Any subsequent simulations launched will be aware of this and not submit the already run ones.
This makes it much easier to recover from sporadic cluster failures without having to directly modify the project directory.
This release comes with several improvements to make inversions run more efficiently. New options to manage checkpoints and to reduce the I/O overhead of smoothing have been added. Furthermore, the mapping function now offers more general parameterizations.
Additionally, some visualization tools have been improved, and a tuning parameter to mesh ocean layers was added.
Finally, Salvus now by default supports GLL orders of 1-7. Additional orders remain available upon request.
SEM orders 1-7 are now supported by default for simulation. Adjoint simulations on GPUs are currently limited to order 4.
It is sometimes convenient to visualize source and receiver locations in
Paraview. A new function, salvus.flow.utils.simulation_src_rec_to_vtk
, has
been added to facilitate this. As arguments it takes a simulation.Waveform
object, along with a string specifying what type of entity one wants to
generate a .vtk
file for (i.e. source or receiver). Check the function's
docstring for advice on how to open the resultant file in Paraview.
Adding a new parameter to better control the lateral element size in the ocean. This is particularly relevant for local domains with strong bathymetry, where Snel's law in 1D may break down.
Reduce the file access of the smoothing algorithms to construct the diffusion models and enable remote diffusion meshes.
Add support for flexible parameter mappings and inversion for relative or absolute perturbations:
sn.Mapping( scaling="relative_deviation_from_prior", inversion_parameters=["VSV", "VSH", "VP", "RHO"], map_to_physical_parameters={ "VPV": "VP", "VPH": "VP", } )
The example above assumes a prior model parameterized as
TTI medium. It inverts for four independent parameters that
encode relative perturbations from the prior model.
The deviations in VPV
and VPH
are tied to the same
inversion variable VP
..
Add memory_per_rank_in_MB
as optional parameter to SiteConfig
.
This allows to adjust the memory settings for different machines
during an inversion.
Improve memory management of checkpoints in SalvusProject.
This gives more flexibility to tune the strategy regarding checkpoints. By default, checkpoints will be stored for every forward run, and automatically removed after (a) gradients for the simulation configuration have been computed and/or (b) the model got rejected by the trust region algorithm.
This behavior can be modified using optional boolean flags store_checkpoints
and cleanup_checkpoints
in the job_submission
settings.
job_submission={ "forward": ..., "preconditioner": ..., "store_checkpoints": False, "cleanup_checkpoints": False, }
If the former is
False
checkpoints will only be stored when gradients are requested. If the latter
is False
checkpoints will never be deleted automatically.
The _plot
method of an EventData
object now takes an additional optional
parameter: _exclude_cbar
. If set to true, a colorbar won't be added to the
axis if a shotgather plot is requested. This makes it easier to produce
shotgathers for multi-component data (i.e. for strain output).
This release comes with a couple of generalizations and bug fixes related to preconditioners of the inverse problem as well as utilities to deal with cylindrical meshes.
Fix a bug in the auto time-step detection of the diffusion and the anisotropic acoustic wave equation that could previously result in a significant under-estimation of a stable time-step size.
New receiver collections to facilitate the creation of 3D apertures on Cartesian domains.
Add utilities to create cylindrical meshes including side sets and topography.
Enable space-dependent smoothing with arbitrary (an)-isotropic smoothing lengths as preconditioner of an InverseProblemConfiguration.
Fix a bug in plotting gradients in the inversion dashboard or using
p.viz.nb.gradients
.
This release adds several quality-of-life improvements for ongoing
inversions, as well as a more sophisticated scheme to handle sites where two
factor authentication is required. Support for volumetric models in 2-D
seismological domains was added, along with a relevant tutorial ("Teleseismic
2D"). Volumetric seismological mantle and crustal models will also now
automatically recognize the presence of oceans, and restrict the
interpolation of material parameters to the elastic regions. If more control
over this process is desired, one can still use the GenericModel
constructor.
The port number of remote sites in the ~/.ssh/config
file is now respected.
Salvus can now perform interactive SSH logins. This is necessary for example for interactive two factor authentication schemes.
Enable it like this in the site configuration:
[sites.site_name.ssh_settings] hostname = "host" username = "user" interactive_login = true
Adds functionality to refine, increase tensor order or build meshes in chunks to avoid memory bottlenecks. In particular, this adds two new functions:
Firstly, in salvus.mesh.tools.transforms
uniformly_refine_chunkwise()
wraps uniformly_refine()
working with a subset of elements at a time,
writing each of the readily processed chunks to a temporary file and finally
merging everything together. This can both be used to refine each element by
subdivision into an arbitrary number of elements in each dimension and/or to
increase the order of the shape mapping.
Secondly, salvus.mesh.chunked_interface.create_mesh_chunkwise()
can be used
instead of create_mesh()
of SphericalChunk3D
, Cartesian3D
and
Cartesian2D
using the same approach as described above to directly create
large meshes that would otherwise reach the memory limitations of the
machine.
Enable stopping criteria to limit the maximum number of iterations in an inverse problem. This is mainly useful for automated monolithic inversion workflows.
p.inversions.set_stopping_criteria( inverse_problem_configuration="...", criteria={ "max_iterations_global": 10, "max_iterations": 5, } )
The criteria can be overwritten anytime to continue with the inversion.
global
settings apply to the entire inversion tree, the other settings
apply to individual branches.
Remove some path dependencies which previously prevented renaming the project.
Various improvements to make 2-D seismological domains more useful.
The interpolation of volumetric models onto seismological meshes was
previously only available for 3-D domains. Support is now extended to 2-D
domains, with "longitude" and "radius" OR "depth" being required coordinate
axes in the parent xarray Dataset. A new tutorial (teleseismic_2d
) has been
added, fleshing out this feature.
Add the ability to ignore elements flagged with a certain value during volume
model interpolation for seismological models. This is useful, for instance,
if one wants to limit interpolation to a specific region (say, the elastic
subsurface, and not any water layers). See the description in the seismology
GenericModel
constructor for more details. Crustal and Mantle models will
now ignore fluid elements by default, to ensure that elastic models are not
interpolated into oceans. Is this behavior is undesirable, one has more
control with the GenericModel
interface.
This release contains several small improvements to streamline the workflow orchestration behind the scenes.
Salvus uses a job database to keep track of asynchronously launched jobs. Over time this database can become quite big to the point of negatively effecting the total performance.
With this change Salvus will now perform periodic maintenance of the database to optimize it and keep its size in check.
Additionally finished jobs are no longer moved into the "archived" group in the database but removed from the database upon job deletion. We don't expect this to have an effect on any user.
Provide a workaround for externally computed and incorrect adjoint sources.
It is strongly recommend to verify the implementation of custom misfits and
adjoint sources with a finite-difference test.
Using the optional parameter force_trust_region_scaling
badly scaled
adjont sources can be mitigated by enforcing to scale the proposed model
update to the trust region radius.
When re-launching simulations for which data already exist (e.g. to compute checkpoints), previously computed outputs are kept in the project file structure and only overwritten once the new jobs have finished. Additionally, a utility to manually clean the simulation store has been added.
This release contains several quality of life improvements and fixes for some minor issues.
The site configuration for local and SSH sites now has an extra
python_binary
key to choose which Python is used to execute the minimal
wrapper script used to launch and control SalvusCompute. This is only
important for sites which do not have a Python on their default paths.
Usage:
[sites.laptop] ... [sites.laptop.site_specific] python_executable = "/usr/local/bin/python"
Salvus now supports usernames in SSH proxy jump connections with settings like
ProxyJump [email protected]
in ~/.ssh/config
files.
A full disk previously raised an error that the internal SalvusFlow database was corrupt. It now gives a more descriptive error message.
salvus-flow init-site SITE_NAME
now always prints the disk usage of the
Salvus controlled run and temp directories. As init-site
is called each
time Salvus is upgraded this serves as a period reminder to monitor the size
of these directories.
The internal workflow for handling checkpoints and adjoint simulations has been improved to avoid duplicated simulations for missing checkpoints on remote sites. This changes the hash values of adjoint simulations, which do not depend on synthetic receiver files anymore.
The waveform plotting widget can now also plot windows without a reference time.
This release brings in local refinements for cylindrical meshes, a speed-up for surface data output, and several usability improvements in SalvusProject. See below for a detailed list of features and bugs that have been patched.
Fixed the applications of pressure-free boundaries for GPU simulations in certain situations where refinements were present along fluid/solid coupling interfaces.
Significant speedup to the detection of which facets to select for surface output.
Add cylindrical interpolation to local refinement schemes and adopt same interface as change_tensor_order() has for interpolation_type. This changes the api for spherical interpolation from
m.refine_locally(mask, spherical=True, r0_spherical=1.0, r1_spherical=2.0)
to
m.refine_locally( mask, interpolation_mode="spherical", interpolation_kwargs={"r0_spherical": 1.0, "r1_spherical": 2.0} )
The new cylindrical scheme can be used accordingly
m.refine_locally( mask, interpolation_mode="cylindrical", interpolation_kwargs={"r0_cylindrical": 1.0, "r1_cylindrical": 2.0} )
Below an example of how this can be used for improved representation of cylindrical structures (left new, right old).
Improve the inversion tree widget to visualize per-branch progress.
The p.simulations.launch()
method can now take extra output configurations.
These can be any setting that does not modify the receiver output which
currently are surface and volume data settings as well as the memory per rank
buffer settings.
p.simulations.launch( simulation_configuration="basic", events=p.events.list(), site_name="my_computer", ranks_per_job=12, extra_output_configuration={ "volume_data": { "sampling_interval_in_time_steps": 50, "fields": ["displacement"], }, "surface_data": { "sampling_interval_in_time_steps": 20, "fields": ["acceleration", "velocity"], "side_sets": ["x0", "x1"], }, "memory_per_rank_in_MB": 2000.0, }, )
The Project.from_domain()
constructor now takes an optional argument
load_if_exists
which defaults to False
. If this is set to True
, and if
the domains are identical, future runs of this constructor will simply load
the existing project from disk rather than raising a "project already exists"
error. This helps remove some boilerplate code which the user previously had
to write.
Add widget to query status of simulations and and improve the widgets of waveforms and inversions.
Minor bug fix in visualizing 2D domains using p.viz.nb.domain
that did not
display some source types correctly.
Minor update that enables license tokens for the diffusion equation. Furthermore, it adds some utilities to handle remote data in SalvusProject as well as small bug fixes listed below.
Fixing a bug where an anisotropic refinement is used in a single layer spherical model.
Previous to this change, the parameters governing the behavior of the linear
solids in viscous simulations would only be properly attached if they came in
via a background model. Now these parameters can be supplied to a
ModelConfiguration
via the LinearSolids
class (which can be found in
salvus.namespace
). Additional validations and checks have also been added
to help the user when viscous simulations are either requested or thought to
be desired.
Automatically clean-up checkpoint files after an adjoint simulation.
Add utilities to handle remote output data and to manually delete jobs in SalvusProject.
Chaining processing function in SalvusProject now works as expected.
Minor update with a couple of bug fixes listed below as well as
improved compatibility with xarray > 0.16.0
.
Fixed a bug where in some specific cases it might have requested windows and weights for components that do not have synthetic data and thus failed.
Fix the description in the caption of time-frequency phase shift plots.
Fix a bug in the horizontal spacing when generating 2D layered meshes from splines and extruding horizontally for absorbing boundaries.
This release contains improvements in a number of different areas.
Salvus can now compute consistent adjoint sources for measurements on the
time derivative fields, e.g. adjoint sources for receivers recording
velocity
and phi_t
. Additionally the (time frequency) phase misfits have
seen some significant improvements and added flexibility.
On the model building side there is a new function to derive a 1-D background model required for meshing from 2- or 3-D Cartesian volumen models.
Aside from that there are a few minor additions and bugfixes, please refer to the full changelog for details.
Add a new Cartesian receiver collection which creates a 2-D array of side set
receivers for use with 3-D models. The presence of a "z1"
side-set is
assumed, and the receivers will be buried exactly depth_in_meters
meters
below this side-set.
A minimal taper (the first and last 5 samples) will now be applied to every
waveform trace before the misfits and adjoint sources are computed in the
EventMisfit
object. This should not have any (or only a very minimal) effect
on existing inversions but is more stable in certain edge cases.
The EventMisfit
object can now compute fully consistent adjoint sources for
measurements on receivers recording velocity
or phi_t
with any misfit
functional. This functionality is also available from within SalvusProject.
Fix a bug where 1 layer of boundary elements would be added to a Cartesian mesh, even if an absorbing boundary width of 0 meters was requested.
The phase misfit now does a better selection of which frequencies to use. One can control which frequency to use and the minimum energy level of the frequencies to use for the phase difference measurement.
from salvus.opt.misfits import get_misfit_function misfit, adjoint_source = get_misfit_function("phase_misfit")( data_observed=data_observed, data_synthetic=data_synthetic, sampling_rate_in_hertz=sampling_rate_in_hertz, frequency_limits=(0.1, 0.5), # These two are optional. absolute_value_threshold=1e-3, taper_type="hanning", )
The old implementation is still valid (but not recommended) and can be accessed with
get_misfit_function("phase_misfit", version=1)
Existing projects that used the old phase misfit will keep using it until a
new MisfitConfiguration
has been created.
Fixed a bug in the adjoint source scaling of time-frequency adjoint sources that occurred for phase-shifted signals.
Additionally the time frequency phase misfit is now a lot more flexible with more options.
from salvus.opt.misfits import get_misfit_function misfit, adjoint_source = get_misfit_function("time_frequency_phase_misfit")( data_observed=data_observed, data_synthetic=data_synthetic, sampling_rate_in_hertz=sampling_rate_in_hertz, # These two are mandatory. segment_length_in_seconds=15.0, frequency_limits=(0.1, 0.5), # The others are optional. segment_overlap_fraction=0.75, absolute_value_threshold=1e-3, taper_type="hanning", stft_window="hann", )
Add a function derive_bm_file()
to derive a 1-D background model from a 2-
or 3-D Cartesian volume model. This is useful, for instance, when the 3-D
model has a significant increase in velocity with depth, and when no
appropriate 1-D model exists a-priori. If the velocity profile allows, using
the 1-D model output by this function may result in the insertion of doubling
layers when a simulation mesh is created, and as a consequence may allow for
a reduction of computational cost.
Minor modifications to create_events_from_segy_file
to handle 2-D events.
This release comes with several improvements regarding data selection and inverse modeling.
There are no breaking changes in the stable API. However, the window selection in SalvusProject has been completely rewritten, and is not compatible with previous versions.
The new DataSelectionConfiguration
allows window- and station-dependent
weights. Furthermore, there are several new options for visualization and
quality control of misfits. See the Seismological Gradient
tutorial in the
Experimental
section for several examples.
The mapping function has been extended to offer built-in support for a region of interest, and event-dependent masking of sources and receivers to mitigate singularities in the sensitivity kernels.
A new function for uniform mesh refinement and model interpolation has been
added to SalvusMesh
.
There are several more small changes documented below.
Added a new low level EventWindowAndWeightSet
class. It is a per-event data
structure that can be serialized to disc that is able to store interval
windows (e.g. windows that have a start as well as an end time). Additionally
it can store weights at the receiver, component, as well as the individual
window level.
In most cases this will be utilized through SalvusProject but it can be
used outside of it and it directly integrates with SalvusFlow's Event
and
EventMisfit
infrastructure.
Added ability to create SmoothieSEM meshes with surface as well as Moho topography, ellipticity and ocean loading. Includes several minor bugfixes to the SmoothieSEM meshes introduced in the previous release.
sm = sn.simple_mesh.SmoothieSEM() sm.basic.model = "prem_iso_one_crust" sm.basic.min_period_in_seconds = 200.0 sm.basic.elements_per_wavelength = 2.0 sm.basic.number_of_lateral_elements = 2 sm.advanced.tensor_order = 4 sm.source.latitude = 38.82 sm.source.longitude = 40.14 # Ellipticity. sm.spherical.ellipticity = 0.0033528106647474805 # Surface topography. sm.topography.topography_file = "topography_earth2014_egm2008_lmax_256.nc" sm.topography.topography_varname = ( "topography_earth2014_egm2008_lmax_256_lmax_16" ) # Moho topography. sm.topography.moho_topography_file = "moho_topography_crust_1_0_egm2008.nc" sm.topography.moho_topography_varname = ( "moho_topography_crust_1_0_egm2008_lmax_16" ) # Ocean loading. sm.ocean.bathymetry_file = "bathymetry_earth2014_lmax_256.nc" sm.ocean.bathymetry_varname = "bathymetry_earth2014_lmax_256_lmax_16"
Added a function to uniformly refine any mesh to double its element count along each dimension and thus doubles its resolved frequency. This should work for arbitrarily complicated meshes including discontinuities. Material parameters will be interpolated onto the new elements.
from salvus.mesh.tools.transforms import uniformly_refine new_mesh = uniformly_refine(mesh, tensor_order=2)
Include the reference frame in the HDF5 gradient output files.
Added features for defining a region of interest and for cutting around sources and receivers in the adjoint mapping function.
Implement p.viz.nb.domain()
method for 2D box domains.
Move job submission settings to the InverseProblemConfiguration and
enable different site configurations for simulations and the preconditioner.
The previous way of providing site_name
, ranks_per_job
and
wall_time_per_job_in_seconds
through the iterate
and resume
functions
still work, but will be deprecated in the future.
Add interactive misfit plots to the inverse problem Jupyter notebook widget.
Better workflow management for misfit and gradient computations. The newly added functionality ensures consistent settings for site name and the number of ranks and automatically resubmits simulations if the checkpoints are no longer available.
With very large models and / or meshes, interpolating volumetric models can
take some time. Here a 'verbose' argument is now accepted by
toolbox.interpolate_spherical
, which will print a progress bar if the
verbosity is 1 or greater. The verbose behavior is the default when
generating spherical meshes with project.
Better error handling and management of entities using
UnstructuredMeshSimulationConfiguration
objects.
Adding an already existing inverse problem configuration again with exactly the same parameters will no longer throw.
Projects created with an older Salvus version using the windows
component
cannot be imported anymore.
The windows
component has been removed in favor of a more generic
DataSelectionConfiguration
. This is for one more in line with the rest of
SalvusProject but also more powerful and flexible.
A direct consequence is that any function or object that took a
window_set_name
argument now takes a data_selection_configuration
argument.
A DataSelectionConfiguration
is either a function that is applied on the
fly to select pieces of data (think generalized windows and weights) or one
EventWindowAndWeightSet
set per event (or a combination of both).
Projects that used an on-the-fly temporal weighting/windowing function now have
to use it by creating a new DataSelectionConfiguration
with an attached
data_selection_function
. The function itself does not have to be changed.
p.add_to_project( sn.DataSelectionConfiguration( name="mute_with_direct_phase", receiver_field="phi", data_selection_function=mute_with_direct_phase, ) )
The pick_windows()
seismological action also requires changing
window_set_name
to data_selection_configuration
(if that configuration
does not yet exist, it will be created). In addition the
window_taper_width_in_seconds
argument is now exposed and required. It
controls the width of the taper for the windows.
p.actions.seismology.pick_windows( data_selection_configuration="custom_windows", ... window_taper_width_in_seconds=10.0, )
Salvus contains a lot of convenience functions to pick windows and weight individual receivers but it is also possible to directly operate on these data structures for full control.
# Get the data selection configuration. dsc = p.entities.get( entity_type="data_selection_configuration", entity_name="custom_windows" ) # If interval windows have been picked before an event, its # `EventWindowAndWeightSet` can be retrieved. ewws = dsc.get_event_window_and_weight_set(event=p.events.get("event_0000"))
This can than be used to exert detailed control on everything. Once this has
been done it will be applied in all subsequent steps that utilize that
particular DataSelectionConfiguration
.
In [1]: ewws.receivers Out [1]: {'XX.A0000.': {'receiver_weight': 1.5462720296177797, 'components': {'Z': {'component_weight': 1.0, 'windows': [{'window_start': 229.67554, 'window_end': 1389.219377, 'window_weight': 1.0}]}, ... In [2]: ewws.receivers["XX.A0000."]["receiver_weight"] = 0.7 In [3]: ewws.write(overwrite=True)
Can now add weights to individual receivers and components which will then be applied to each misfit and adjoint source computation. This could have been previously done with a custom windowing function with weights but this is more convenient and easier to control. It is detailed in other changelog items of this release.
It can either happen via window picking and receiver weighting or directly in the data selection function:
def data_selection_function(st, receiver, sources): # Receiver and component weights. weights = { # This is optional but allows to specify additional weights # important for the misfit and adjoint source computations. "receiver_and_component_weights": { # Pass the receiver weight here. "receiver_weight": 0.75, # It is also possible to give weights to individual # receivers. "component_weights": {"X": 1.0, "Y": 0.8", "Z": 0.5}, } } for tr in st: component = tr.stats.channel[-1] temporal_weights = compute_window(...) # Individual window weights. weights[component] = [ {"values": temporal_weights, "misfit_weight": 0.8}, ... ] return weights # Add to the project. p.add_to_project( sn.DataSelectionConfiguration( name="custom_data_selection", receiver_field="phi", data_selection_function=data_selection_function, ), overwrite=True, )
Added implementations for a few common seismological receiver weighting schemes with a general and easy to extend interface.
# Custom receiver weighting function. def my_favorite_station(event, receivers, receiver_name): weights = {} for name in receivers: if name == receiver_name: weight = 2.0 else: weight = 1.0 weights[name] = weight return weights p.actions.seismology.add_receiver_weights_to_windows( # Add the weights to existing windows in this data selection # configuration. data_selection_configuration="custom_windows", events=p.events.list(), # The weights for each item in the chain will be multiplied together. weighting_chain=[ { "weighting_scheme": "ruan_et_al_2019", "function_kwargs": {"ref_distance_condition_fraction": 1.0 / 3.0}, }, { "weighting_scheme": "mute_near_source_receivers", "function_kwargs": { # All receivers closer than this to the sources # will have zero weight. "minimum_receiver_distance_in_m": 200e3, # All receivers further away than this will not be muted. "maximum_receiver_mute_distance_in_m": 1000e3, # How to go from weight 0 to weight 1 for receivers in the # transition region. Currently only "hanning" is supported. "taper_type": "hanning", }, }, # Custom weighting function. { "weighting_scheme": my_favorite_station, "function_kwargs": {"receiver_name": "XX.A0044."}, }, ], # Normalize the sum of all receiver weights to the receiver count. normalize=True, )
New seismological receiver weight map plot.
p.viz.seismology.receiver_weights_map( data_selection_configuration="custom_windows" )
Various part of SalvusProject can serialize functions to disc. This is now more powerful and easier to use as the serialized functions can now access closure values as well as other variables in the global scope of the functions which will also be serialized alongside. Thus external variables and imports will now work with these functions.
Basically it means that it should now just work in more cases without any extra work or rewrites.
The p.viz.seismology.misfit_map()
method is now a widget and the event can
be selected interactively. Thus passing the event
argument is no longer
necessary.
New method to visualize and compare histograms of misfits.
p.viz.misfit_histogram( simulation_configuration_a="initial_model_70_120_seconds", simulation_configuration_b=p.inversions.get_simulation_name( inverse_problem_configuration="inversion", iteration_id=25 ), misfit_configuration="phase_misfit_70_120_seconds", events=p.events.list(), merge_all_components=False )
A few new utilities to analyze the statistics of interval windows.
One is the ability to get a pandas.DataFrame
object containing statistics
about all windows for a list of events. This is very useful to do some custom
analysis and figure out which events to use in the final inversion.
df = p.entities.get( entity_type="data_selection_configuration", entity_name="selection_a" ).get_interval_window_statistics_table(events=p.events.get_all())
A styled version of this table with all events in a project can be visualized with:
p.viz.interval_window_statistics("selection_a")
This release features a revamp of the mesh masking interface to be more flexible as well as easier to use. Additionally it contains a first version of global and continental scale wavefield adapted SmoothieSEM meshes.
Furthermore it includes a new receiver collection and the ability to retrieve
detailed misfit information from an EventMisfit
object. Last but not least
it includes a bugfix for gradients in meshes employing the region-of-interest
feature while using nontrivial checkpoints.
For the experimental SalvusProject packages it contains a number of quality-of-life to visualize and understand misfits in more detail as well as a number of bugfixes and some polish.
This update has no user facing breaking changes (aside the mesh masking) so we recommend this update to all users.
Bugfix for the region of interest in adjoint runs with nontrivial checkpoints.
New EventMisfit.misfit_per_receiver_and_component_and_weight_set
attribute
to yield a more detailed view of how the misfit for a single event is
computed.
In [1]: ed.misfit_per_receiver_and_component_and_weight_set Out [1]: {'XX.A0000.': {'Z': [0.00088682823102153761], 'N': [0.000256782248385296], 'E': [0.00012302960702887129, 0.0004303495400]}, 'XX.A0001.': {'Z': [0.0010641578304181843], 'N': [0.00025058292454050639], 'E': [0.00012369945631215902]}, ... }
New simple_config.receiver.seismology.collections.SideSetGridPoint3D
receiver collection.
lat_c, lon_c = 45.0, 10.0 lat_e, lon_e = 15.0, 18.0 receivers = sn.simple_config.receiver.seismology.collections.SideSetGridPoint3D( lat_center=lat_c, lat_extent=lat_e * 0.9, lon_center=lon_c, lon_extent=lon_e * 0.9, fields=["displacement"], n_lat=10, n_lon=10, )
New method UnstructuredMesh.get_side_set_nodes()
to get all nodes in a side
set.
New mask generators (SurfaceMaskGenerator
, RayMaskGenerator
) replacing
the existing JSON based masking interface.
They are now applied via the mesh_processing_callback
argument to the
central run_mesher()
function.
We expect this to only affect a small number of users.
Added the ability to generate wavefield adaptive spectral-element meshes
which we refer to as SmoothieSEM
.
sm = sn.simple_mesh.SmoothieSEM() sm.basic.model = "prem_iso_one_crust" sm.basic.min_period_in_seconds = 200.0 sm.basic.elements_per_wavelength = 2.0 sm.basic.number_of_lateral_elements = 4 sm.advanced.tensor_order = 2 sm.source.latitude = 35.0 sm.source.longitude = 12.0
Warn when receiver fields other than "displacement"
or "phi"
are used in
a MisfitConfiguration
object. Otherwise the adjoint sources are currently
not fully consistent.
New p.misfits.get_misfit_comparison_table()
method yielding a
pandas.DataFrame
containing detailed per-receiver misfit information that
can be used for further custom analysis.
In [1]: p.misfits.get_misfit_comparison_table( reference_data="initial_model", other_data=[ p.inversions.get_simulation_name( inverse_problem_configuration="inv", iteration_id=4 ) ], misfit_configuration="L2-misfit-to-target-model", event="event_0000", ) Out [1]: initial_model (ref) inv_it_3__trial Reduction inv_it_3__trial XX.A0000. 1.266640e-03 0.000224 0.001043 XX.A0001. 1.438440e-03 0.000361 0.001078 XX.A0002. 1.450685e-03 0.000369 0.001081 XX.A0003. 1.607995e-03 0.000430 0.001178 XX.A0004. 9.473526e-04 0.000238 0.000709 ... ... ... ... XX.A0095. 1.182061e-05 0.000065 -0.000053 XX.A0096. 1.360653e-06 0.000529 -0.000527 XX.A0097. 9.762485e-07 0.000102 -0.000101 XX.A0098. 4.663780e-06 0.000306 -0.000301 XX.A0099. 1.784453e-06 0.000165 -0.000163 [100 rows x 3 columns]
New p.viz.nb.misfit_comparison()
method to display the output from the
p.misfits.get_misfit_comparison_table()
method in a pretty table.
p.viz.nb.misfit_comparison( reference_data="initial_model", other_data=[ p.inversions.get_simulation_name( inverse_problem_configuration="inv", iteration_id=4 ) ], misfit_configuration="L2-misfit-to-target-model", event=p.events.list()[0], )
New p.viz.seismology.misfit_map()
method to display the output from the
p.misfits.get_misfit_comparison_table()
method on a geographical map.
p.viz.seismology.misfit_map( reference_data="initial_model", compare_data=p.inversions.get_simulation_name( inverse_problem_configuration="inv", iteration_id=5 ), misfit_configuration="L2-misfit-to-target-model", event=p.events.list()[0], )
Can now delete entities, even if they cannot be instantiated anymore. Useful for certain edge cases.
Fully consistent is_point_in_domain()
check for spherical chunk domains.
The map visualization for spherical chunks now also works for domains crossing the international date line.
sn.domain.dim3.SphericalChunkDomain( lat_center=52.0, lat_extent=16.0, lon_center=170.0, lon_extent=66.0, radius_in_meter=6371000.0, ).plot()
This release contains a few minor user facing improvements for the stable part of Salvus but it largely focusses on improvements for the experimental SalvusProject module.
The release is fully backwards compatible so we recommend all users to update.
All wavefield outputs now have a reference_time_in_seconds
attribute. Thus
also receiver output in the HDF5 block format can now be absolutely located
in time and not just ASDF files.
The EventData
object will now raise an exception if a temporal weight
function returns components that the data cannot have.
Fix the ABC element field for zero-width absorbing boundaries for proper visuzliations. This only affected visualizations and had no effect on the simulations.
Slider to change the min/max values of the colormap in the Jupyter notebook mesh visualization widget.
Generic mapping interface to transform inversion models between physical and simulation space.
A few quality-of-life improvements for inversions.
Uppercase variables names during model interpolation from xarray data sets and NetCDF files. Thus lowercase case variables now also work.
Several improvements and small bug fixes in a number of Jupyter notebook inversion widgets.
New inversion action to faciliate model smoothing.
p.actions.inversion.smooth_model( model=gradient, smoothing_configuration=sn.ConstantSmoothing( smoothing_lengths_in_meters={"VP": 0.01, "RHO": 0.01,}, ), ranks_per_job=4, site_name="local", )
Enable misfit configurations without observed data.
Prevent processing/misfit functions that cannot be deserialized again from being stored in a project in the first place.
New experimental 2-D circular domain.
Released: July 16th 2020
Changes:
SalvusMesh
: Fix side-sets for masked global domains.SalvusCompute
: Minor bug fix for safely writing the meta json.SalvusCompute
: Auto-time-step detection for the diffusion equation.SalvusFlow
: Removed the cpu_count
argument from all functions
performing receiver/source placement. It was not actually any faster and we
have to re-evaluate the chosen approach.SalvusFlow
: More control over the end time when using a
FilteredHeaviside
source time function.SalvusFlow
: The FilteredHeaviside
STFs now defaults to 3 lowpass filter
corners and additionally allows explicitly settings the sampling rate.
changed defaultsExperimental features:
SalvusOpt
: New implementation of time-frequency phase misfits.SalvusOpt
: Added new phase misfit.SalvusOpt
: Bug fix for scaling of cross-correlation adjoint sources.SalvusProject
: Correctly plot the time axis for seismological data.SalvusProject
: More stable and informative window picking process.SalvusProject
: Statistical window visualizations.SalvusProject
: The window picking action can now work with external
window picking functions. API changeSalvusProject
: Function serialization now works with imports as well as
closure variables making it a lot more flexible.SalvusProject
: The window picking action can now optionally also only act
on a subset of receivers and not store the results in the project. Useful
for debugging and tuning of the window picking process.SalvusProject
: All specialized processing configurations have been moved
to functions. The only remaining processing configurations are
ProcessingConfiguration
and SeismologyProcessingConfiguration
. The old
ones are deprecated but will stay around for the rest of the lifecylce of
Salvus 0.11.x. Please move to the new way of doings things. API changeSalvusProject
: The compute_window()
function has been moved to
salvus.project.tools.windows
. API changeSalvusProject
: Adding optional time_step_in_seconds
to the
WaveformSimulationConfiguration
constructor.Released: July 2th 2020
Changes:
SalvusMesh
: Still attach absorbing side sets if the number of wavelengths
is zero for Cartesian meshes.SalvusFlow
: Various optimizations to improve the speed of job arrays.SalvusFlow
: Various optimizations for simple config objects.SalvusProblem
: Tags in ASDF output will now always correspond to the
receiver field names. It is thus consistent with the input as well as the
HDF5 output. API changeSalvusCompute
: Compatibility with the ppc64le CPU architecture.Experimental features:
SalvusProject
: Make event names in EventCollections customizable.SalvusOpt
: Improve trust-region scaling.SalvusProject
: Consistent coordinate order for all models (volume,
topography, bathymetry).Released: June 22th 2020
Changes:
SalvusCompute
: Add a check for NaNs in the time loop of CUDA runs.SalvusMesh
: More control over mesh file size, improved documentation.SalvusCompute
: Speedup gradient postprocessing, especially for
anisotropic models.SalvusCompute
: Compliance with CWE/SANS Top 25.Experimental features:
SalvusOpt
: Auto-detect gradient parameterization from the model.
API changeSalvusProject
: Fix tmp file handling on foreign file systems.SalvusProject
: Fix bug in bathymetry dataset loading and improved test
coverage.SalvusProject
: Iteration widget for notebook visualization.SalvusOpt
: Simplified interfaces for diffusion-based preconditioning.Released: June 12th 2020
Changes:
SalvusCompute
: Fix allocation bug for adjoint absorbing boundaries on GPUs.SalvusFlow
: If files (e.g. meshes, source time functions, ...) are shared
between multiple jobs in a job array they will only be uploaded once to the
remote site and shared between jobs.SalvusFlow
: Optimized usage of SalvusFlow's internal job database.SalvusFlow
: Can now deal with ProxyJump
settings in SSH config files.Experimental features:
SalvusProject
: Fix domain vis. for sph. chunk domains, and improve it for
UTM domains.SalvusProject
: Add events from custom ASDF files.SalvusProject
: Inversion action component for misfit and gradient
computations.SalvusOpt
: Support for fully asynchronous inversions.Released: June 5th 2020
Changes:
SalvusMesh
: Fix ocean load for orders > 1SalvusFlow
: Improved validation of diffusion inputDocs
: Render doc strings for methods inherited from abstract methods.Experimental features:
SalvusProject
: Fix side set handling for masked spherical chunksSalvusOpt
: More robust trace interpolation for misfit computationsReleased: May 26th 2020
Changes:
SalvusFlow
: Increase default verbosity of simulations.launch()
to 2
SalvusCompute
: Small bug fixes in receiver handling.SalvusCompute
: Compile for additional CUDA device architectures.Meta
: Refined parameter validation in JSON schemaExperimental features:
SalvusProject
: Propagate NANs as a mask from spherical to cartesian
models.SalvusProject
: Make Courant number configurable in WaveformSimulationConfigurationReleased: May 19th 2020
Changes:
SalvusCompute
: Remove spurious device sync.SalvusCompute
: Adjoing simulations and gradients on GPUs.Released: May 8th 2020
Changes:
SalvusCompute
: Implement a MeshPartitioner
class to encapsulate
partitioning (including deterministic re-partitioning).Released: April 29th 2020
Changes:
SalvusCompute
: Temporarily disable multiple checkpoints.
SalvusCompute
: Fix some edge cases in handling checkpoints
SalvusCompute
: Ensure unique boundary conditions on side sets.
SalvusFlow
: Fix upgrading remote sites for incompatible versions.
SalvusFlow
: Validate side-sets for output and boundary conditions.
SalvusFlow
: Enable manual SSH password entry.
SalvusFlow
: Optionally use a login shell to execute commands at a site.
SalvusFlow
: More flexible in regards to any extra output added by a job
management system.
SalvusFlow
: New features for LSF sites:
{RANKS}
, {NODES}
, and {TASKS_PER_NODE}
variables in mpirun
replacement as well as all bsub arguments.SalvusMesh
: Ensure that additional ABC elements are strictly outside of the
domain.
SalvusToolbox
: dimensionless
is now an acceptable unit for parameters
that do not have units in the IRIS EMC model reader.
SalvusToolbox
: Read attenuation models with the IRIS EMC model reader.
Experimental features:
SalvusProject
: Better support for oceans and ocean loading.SalvusProject
: Notebook visualization of spherical domains.Released: April 17th 2020
Changes:
SalvusCompute
: Better estimate of the sampling interval required to
buffer fields during a checkpoint run. Relevant for simulations with
attenuation.SalvusFlow
: Increase wall-time of init-site
job.SalvusFlow
: Correctly distinguish and upload files if they have the same
name but different local folders.Released: April 16th 2020
Unfortunately the standard upgrading route of running:
salvus-flow upgrade
will not work for this particular release. We apologize for any caused inconvenience. Please re-run the Mondaic downloader instead:
bash -c "$(curl -sSL https://get.mondaic.com)"
and select version 0.11.3
or higher. Make sure to follow all the
installation steps, especially the one regarding pip install salvus*.whl
.
Once the installation process is complete, the acquisition issue should be
fixed. salvus-flow upgrade
should work for any future changes.
Changes:
Meta
: Adapted license check to server side changes.Meta
: New salvus
CLI command that is a strict alias to the existing
salvus-flow
CLI command. We plan on keeping both for the foreseeable
future.Meta
: New salvus --version
/salvus-flow --version
CLI command to
retrieve the current Salvus version number at a glance.Released: April 10th 2020
Changes:
SalvusFlow
: Enforce that the local Python Salvus version is identical to
the remote SalvusCompute version.SalvusFlow
: Automatically reinitialize all matching local sites upon
salvus-flow upgrade
.SalvusFlow
: Recommend a list of suitable remote sites to update after
salvus-flow upgrade
has finished.SalvusFlow
: Make sure the run and temp directories are not in the folder
managed by the Mondaic downloader.Released: April 3rd 2020
Changes:
SalvusCompute
: More robust estimation of wavefield buffer sizes for
checkpointing.