Version:

Changelog

Salvus version 0.12.14

Released: 2023-09-11
This is a minor release with small improvemente listed below. Additionally, the documentation of the Python API has been improved.
SalvusMesh
Add the ability to interpolate custom fields when performing mesh-to-mesh interpolation:
from salvus.mesh.tools.transforms import interpolate_mesh_to_mesh

int_mesh = interpolate_mesh_to_mesh(
    ...,
    fields_to_interpolate=["custom"],
)
SalvusProject
Add the option to plot the coordinates of an EventBlockData object in a custom axes frame.
SalvusProject
Ensure compatibility with pandas>=2.1.0.
SalvusProject
Fix a bug in parsing events from ASDF files, which caused a ValueError in some cases when adding events through p.actions.seismology.add_asdf_file().

Salvus version 0.12.13

Released: 2023-07-04
This is a minor release with a few bug fixes listed below.
SalvusMesh
When building meshes with exterior domains for modeling the gravitational potential, all material parameters will automatically be set to zero. Furthermore, the exterior is assigned a unique layer id, which increments the layer id at the surface by one.
SalvusProject
Fix a bug in the visualization widget of an inverse problem, which could cause a ZeroDivisionError if there were one or more events without windows in the data selection.
SalvusProject
Fix a bug in the window picking algorithm which caused a TypeError for constant traces.

Salvus version 0.12.12

Released: 2023-05-31
This release brings in a new backend of the Cartesian meshing algorithms. Those changes do not affect the API. In some scenarios, the resulting mesh can change slightly, because of the improved meshing algorithms. If you notice undesired changes, please reach out in the user forum or message [email protected]
This is also the first Salvus release that supports Python 3.9. You can choose the Python version from the interactive menu in the downloader. More information can be found here Note that Python 3.7 will reach its end-of-life at the end of June 2023.
SalvusFlow
The salvus-cli upgrade command now works in cases where the upgrade changes the initialization logic of Salvus.
SalvusMesh
API CHANGE
BM files parameterized using depth now explicitly need a model value specified at depth = 0. This is to avoid ambiguities that could otherwise occur in the vertical span of the mesh.
SalvusMesh
The backend Cartesian meshing algorithms have been improved, and this may result in changes to some meshes. If you notice significant undesired changes, or encounter and other problems, please contact us.
SalvusMesh
API CHANGE
The salvus.mesh.chunked_interface.create_mesh_chunkwise() function is now deprecated.

Salvus version 0.12.11

Released: 2023-05-09
Minor release with a few bug fixes and other small improvements listed below.
Highlights of new features include the ability to output volumes and surfaces on a subinterval of the simulation time axis, improved functionality to extrude meshes and an experimental feature to invert for the source wavelet.
SalvusCompute
Adds the ability to output surface and volume fields only between certain times. To access this functionality, the start_time_in_seconds and end_time_in_seconds can now be passed to the respective output groups in a simulation.Waveform(...) object. Times passed are always truncated (floored) to the preceding time step.
SalvusCompute
Fix a bug in computing gradients with respect to the C_ij components of the elastic tensor in fully anisotropic 3D media..
SalvusFlow
Fix a regression where sources and receivers could not longer be specified as dictionaries.
SalvusFlow
Enforce that each type of boundary condition can only be added once to a simulation object to ensure that the boundary conditions are treated properly in SalvusCompute.
w = sn.simple_config.simulation.Waveform(mesh=m)

# If all settings for the same type of boundary condition are the same,
# the side sets will be merged.
w.add_boundary_conditions([
  sn.simple_config.boundary.HomogeneousDirichlet(side_sets=["x0"]),
  sn.simple_config.boundary.HomogeneousDirichlet(side_sets=["x1"])
])

# However, using different settings for a boundary type will raise an error.
w.add_boundary_conditions([
  sn.simple_config.boundary.Absorbing(
    side_sets=["x0"], taper_amplitude=0.0, width_in_meters=0.0
  )
  sn.simple_config.boundary.Absorbing(
    side_sets=["x1"], taper_amplitude=1.0, width_in_meters=1.0
  )
])
This is now part of the validation of the simple config objects.
SalvusFlow
Fix a bug that could cause a failing license request when using tokens in adjoint simulations.
SalvusMesh
The mesh notebook widget will now initialize its camera to point at the center of spherical chunks.
SalvusMesh
Higher-order meshes can now be extruded from 2-D to 3-D.
SalvusMesh
Material parameters will now also be extruded when meshes are being extruded.
SalvusProject
Adding support for ipywidgets8.
SalvusProject
API CHANGE
The window picking algorithm for seismology now correctly handles cases where the event origin time is not the time of the first sample of the synthetics.
A consequence of this is that custom window picking functions must now also have a event_origin_time keyword argument. We believe this should not affect any users, if it does: the error message is very clear and fixing it is straight forward.
SalvusUtils
Add a new algorithm that groups elements by their number of occurrences before performing the wavefield output tensor contraction. This should be close to the most efficient approach in all cases, so it is also now the default when extracting a WavefieldOutput object to an xarray.

Changes to Experimental Features in 0.12.11

SalvusModules
Adds the ability to invert for source characteristics for single-component (acoustic) data. There are currently two interfaces for performing such a source inversion in the salvus.modules.source_inversion submodule by using one of the following functions:
  • invert_wavelet: Accepts the observed and synthetically generated data as NumPy arrays and returns the inverted wavelet as a NumPy array.
  • invert_wavelet_from_event_data: Performs the same inversion as within invert_wavelet, but accepts EventData objects instead of NumPy arrays. This is generally the more convenient approach when used together with SalvusProject.
Note that inverting for multi-component data is currently unsupported.

Salvus version 0.12.10

Released: 2023-03-15
First release of 2023 with several small improvements in various components of Salvus. Details are listed below.
SalvusCompute
Add support ASDF output for receivers that only differ by location code.
SalvusFlow
There is a a new custom_commands setting for Slurm sites to add custom bash commands to a job script.
SalvusMesh
Add function to compute the density model based on Gardner's relation, and support customizable Gardner's constants alpha and beta.
SalvusMesh
Adds a new function mesh.adjust_side_sets.adjust_site_set that allows for the re-interpolation of a mesh's vertical side set to a new digital elevation model, potentially at a higher order than originally used. This can be useful, for instance, when changing frequency bands and taking advantage of the smaller mesh size to better resolve topography, changing a mesh's model order, or re-interpolating after adding local refinements. This re-interpolation also now happens by default when using the layered meshing interface.
SalvusMesh
Both 2- and 3-d anisotropic acoustic models can now be specified in terms of velocities (rho, vph, and vpv). Note that this parameterization implies that epsilon = delta.
SalvusModules
Throw a descriptive error message when trying to use the waveform database with unsupported receiver types.
SalvusProject
Enable passing start and end time for computing the discrete Fourier transform as extra output configuration in SalvusProject.
Example:
p.simulations.launch(
    simulation_configuration="my_simulation",
    events=p.events.list(),
    ranks_per_job=2,
    site_name="local",
    extra_output_configuration={
        "frequency_domain": {
            "frequencies": [10.0],
            "fields": ["phi"],
            "start_time_in_seconds": 1.0,
            "end_time_in_seconds": 1.1,
        }
    }
)
SalvusProject
Fix a bug that would prevent launching simulations of events without receivers in SalvusProject. This can be useful, for instance, if only volumetric output is desired.
SalvusProject
Stability improvements in the receiver weighting algorithms in case a particular event has no or very little windows.
SalvusUtils
Add a new salvus.utils.logging.log_timing() context manager that logs the time the context takes to execute.
SalvusUtils
Adds the ability to properly handle surface output in the salvus.toolbox.helpers.wavefield_output module. To use this, one simply needs to pass "surface" as an output type when loading the wavefield output. Also added the ability to drop dimensions from outputs, so 3-D surface outputs can be visualized in 2-D planar plots (such as in matplotlib). This can be accessed by calling the .drop(...) function on a WavefieldOutput instance.

Salvus version 0.12.9

Released: 2022-12-22
This is a minor release that fixes a few bugs as well as adds some new features. Most notable of these new features are a) an improvement to SalvusCompute's time-step computation algorithm which now takes into account the influence of any absorbing boundary layers, which may improve the stability of some simulations, and b) a new set of functionality to interpolate time-dependent volumetric wavefield data onto a set of arbitrary points, including regular grids, for the purpose of simplyfing the analysis of such data.
SalvusCompute
Add a new heuristic for computing the time step inside the sponge layers of the absorbing boundaries. The previous logic required a more conservative choice of the Courant number to guarantee stability of the simulation.
SalvusMesh
Add a new free function name_free_side_set to unstructured_mesh_utils. This function finds all mesh surfaces not currently assigned to a side set and either a) creates a new side set with the name passed, assigning the found surfaces, or b) appends to an existing side set of the same name if it already exists in the mesh.
SalvusModules
Add safeguards to properly handle two edge cases in the point-to-linesource conversion utility.
SalvusUtils
Adds new functionality in salvus.toolbox.helpers.wavefield_output to help encapsulate and manipulate raw volumetric wavefield output from SalvusCompute. Additional functions allows for the extraction of time-dependent wavefield data from said files to regular grids in space and time.

Salvus version 0.12.8

Released: 2022-11-21
This is a minor release featuring a few bug fixes and additions detailed below to improve usability and performance.
Additionally, several improvements to the internal meshing algorithms have been made.
SalvusCompute
Bug fix for reading in custom source time functions from hdf5 in SalvusCompute. This could cause an interpolation error when providing input on an oversampled time axis.
SalvusCompute
Enable new field frequency-domain for (time-dependent) volume and surface data. In combination with the static frequency-domain output, this enables storing the time-evolution of the discrete Fourier transform with the polynomial degree of the SEM shape functions.
SalvusFlow
There is a a new job_script_shebang setting for Slurm sites to allow overwriting the job script shebang.
SalvusMesh
Performance improvement in apply_element_mask, which can lead to significant speed-ups for meshes that neither have nodal parameters nor layered topography.
SalvusOpt
Enable optional additional outputs when computing the optimal transport misfit. If requested, the distance matrix and the optimal assignment will be returned, which is useful for visualizing the optimal transport map.
SalvusProject
Enable chunkwise job submission in task chains.
The optional parameter max_concurrent_chains can be passed to the TaskChainSiteConfig to limit the maximum number of concurrent chains. Note that when using more than one site, this parameter has to be consistent for all sites in the current implementation.
SalvusProject
Add ability to cancel ongoing or pending simulations in a project.
Example:
p.simulations.cancel(
  simulation_configuration="my_simulation",
  events=p.events.list()
)
Alternatively, p.simulations.cancel_all() will cancel all simulations from the simulations store.

Salvus version 0.12.7

Released: 2022-10-12
This is a minor bugfix / maintenance release that makes a few of the internal meshing algorithms more robust.

Salvus version 0.12.6

Released: 2022-09-29
New features introduced with this release include callback functions to implement event-dependent meshes and iteration-dependent event selections for mini-batch inversions. Furthermore, an initial implementation of a new workflow for computing forward simulations, misfits and gradients within a single chain of tasks is introduced.
Additionally, the release contains various minor bug fixes and small improvements listed below.
SalvusCompute
Allow for an axis-aligned shortcut for absorbing boundary attachment. Useful in cartesian domains, and specified via passing "side_sets_are_axis_aligned" to the simple config AbsorbingBoundary constructor.
SalvusFlow
Use shutil.copyfile() instead of shutil.copy() and shutil.copy2() to avoid problems copying between file systems with and without permission bits.
SalvusFlow
The data selection can now properly deselect data whose processing raises an exception for only a few receivers. This usually only happens with faulty receiver metadata.
SalvusOpt
Add new option use_event_dependent_gradients for the trust-region method. When set to True, only the accumulated gradient for all events is used, and tasks of type TaskMisfitsAndSummedGradient are issued instead of TaskMisfitsAndGradients.
SalvusOpt
Add a new option for discontinuous_model_blocks to the mapping function. When used in combination with a homogeneous scaling, this function allows for the parameterization of piecewise constant models.
SalvusProject
Upgrade to ipywidgets>=8.0.0. The changes are backward compatible with older versions of ipywidgets.
SalvusProject
Add functionality to check the trial model on subsets of events (including none). The list can be adjusted by using the optional argument control_group_events in the constructor of an iteration.
SalvusProject
New optional parameter max_events_per_job_submission for inversion action component to limit the maximum number of events that are simultaneously submitted per job to reduce the memory overhead.
SalvusProject
Add an optional callback function event_batch_selection to the InverseProblemConfiguration, which allows to define an iteration-dependent selection of events and/or control group to check the trial model only for a subset of events.
SalvusProject
Implement gradient mapping for event-dependent meshes to enable their use for inversions.
SalvusProject
Mitigate open nfs file handles when deleting simulation results.
SalvusProject
Integrate using event-dependent meshes with task chains. This also adds a faster way to compute misfits without gradients.

Changes to Experimental Features in 0.12.6

SalvusProject
Initial implementation of task chains for solving inverse problems. The job_submission settings can now optionally receive a TaskChainSiteConfig to compute misfits in parallel, and to chain forward and adjoint simulations.
This is an experimental feature which is currently restricted to remote sites which share the same file system and the DataBlockIO backend of events.

Salvus version 0.12.5

Released: 2022-08-25
Minor release containing several performance improvements in handling FWI workflows and a few bug fixes. Details are listed below.
From this version onward, Salvus drops support for Centos6 and older systems.
SalvusCompute
From this release onwards the oldest supported CentOS version is Centos7. Salvus will not run on Linux systems with an older libc anymore.
Centos6 reached End of Life (EOL) in November 2020. In case you still have a need for running Salvus on an old operating system, please get in touch with [email protected]
SalvusCompute
Fix a bug in the material parameterization of 3D anisotropic elastic material. When using the full tensor (Cij) it is no longer necessary to pass a symmetry axis with the mesh.
SalvusFlow
New event block data structure to more efficiently deal with large-scale acquisition geometries and a corresponding way to deal with them in SalvusProject.
SalvusFlow
New task chain controller and runner primitives to efficiently steer and parallelize a large collection of task chains across different machines.
SalvusMesh
Two small bug fixes in the mesh widget. The colorbar is now properly scaled for nearly constant parameter fields. Furthermore, it is possible to switch parameter fields while the side-sets toggle is active, which previously raised an error.
SalvusProject
Add new interal functionality to efficiently operate on structured receiver data. This includes resampling, tapering, and padding.
SalvusProject
Generalized external data proxies to read data from arbitrary external data sources without copying them into a Project.
SalvusProject
Assorted file format utilities, helpers, and converters.
SalvusProject
Automatically validate that all side-sets required for surface output or boundary conditions are contained in the mesh.
SalvusProject
Implement a masking function as an optional callback of the simulation configuration. This enables using event-dependent meshes for forward simulations. This feature is currently not supported for assembling gradients.
SalvusProject
Fix a bug which could cause simulation results ending up in the wrong directory when the event names were not padded with zeros.
SalvusProject
Performance improvements for misfit computation workflows in projects with a large number of events.

Salvus version 0.12.4

Released: 2022-07-28
Minor release that brings in support for using strain and gradient measurements in full-waveform inversion. Furthermore, the ability to read (adjoint) sources in chunks was added to alleviate the memory requirements for simulations with many sources or time steps.
There are a few more small improvements and bug fixes listed below.
SalvusCompute
Support the partial loading of sources into memory. Can be important for simulations with lots of sources and / or a long duration.
SalvusFlow
New omit_tasks_per_node setting for Slurm sites.
This will cause the ntasks-per-node to be omitted for both the #SBATCH command as well as the call to srun for the rare site where this is necessary.
SalvusProject
Fix a bug in the bandpass processing fragment, which did not recognize frequency inputs in scientific number format.
Here is an example of a data name:
"EXTERNAL_DATA:raw_data | bandpass(1.0e3, 2.0e3) | normalize"
SalvusProject
Enable the use of misfits and adjoint sources based on first spatial derivatives of the wavefield, i.e., strains and gradients.
It is now possible to also pass strain, gradient-of-displacement and gradient-of-phi as valid receiver fields in the misfit configuration and related event data and event misfit objects.
Remember that strain data are not rotated and output is in Cartesian coordinates.
SalvusProject
API CHANGE
Rename datasets (and derived channel names) in ASDF output for gradients of the displacement field to comply with the SEED convention.
This is a (small) breaking change that only affects the combination of ASDF files with outputting the gradient of the displacement field.
The names of datasets and channels need to be adjusted as follows:
2D (old): XXX, XXY, XYX, XYY
2D (new): XG0, XG1, XG2, XG3
3D (old): XXX, XXY, XXZ, XYX, XYY, XYZ, XZX, XZY, XZZ
3D (new): XG0, XG1, XG2, XG3, XG4, XG5, XG6, XG7, XG8
Apologies for the inconvenience caused.
SalvusProject
Fix a bug in p.viz.waveforms(), which caused to function to fail with a cryptic error message when data was passed as a string.

Salvus version 0.12.3

Released: 2022-07-03
This release introduces new modules or improved support for several physics in the simulation engine. This includes anisotropic acoustic media, native support for visco-acoustic simulations, and a new solver model for static problems to solve the Poisson equation. Some of the new features are currently only supported on CPU hardware.
Additionally, the release enables custom MPI commands, for instance to use machine files on remote machines and contains several small bug fixes.
SalvusCompute
Support waveform simulations and gradients w.r.t. medium properties in VTI acoustic media.
SalvusCompute
Support visco-acoustic modeling in the scalar wave equation. The implementation and API are very similar to visco-elastic modeling, and require the specification of linear solids and QKAPPA as a material parameter.
Previously, attenuation in a fluid could only be modeled as a degenerate case of elastic physics.
This feature is currently only supported on CPUs and SalvusCompute will throw an error when attempting to run a visco-acoustic simulation on a CUDA-enabled site.
SalvusFlow
API CHANGE
Extend functionality of handling segy files for adding external data to a project.
Instead of just passing the source mechanism, users can now define simple callback functions for sources and receivers to create Salvus objects from the information stored in segy files. This breaks the previous syntax of the implementation of SegyEvent, but it should be straightforward to upgrade.
SalvusFlow
Minor improvement in the SSH connection error handling. It should now report a better error message.
SalvusFlow
Extra keyword arguments can now be passed to paramiko.SSHClient.connect() to allow more fine tuning for some SSH connections.
Usage in the site config file:
[sites.my_site.ssh_settings]
    hostname = "some_host"
    username = "some_user"
    [sites.my_site.ssh_settings.extra_paramiko_connect_arguments.disabled_algorithms]
        pubkeys = ["rsa-sha2-512", "rsa2-sha2-256"]
Furthermore the init-site command now has a --verbose flag to facilitate debugging tricky connections:
salvus-cli init-site my_site --verbose
SalvusFlow
A new mpirun_template parameter for ssh and local site types that allows full customization of the actual call to mpirun in case it is necessary.
Usage in the site config file:
[sites.my_site.site_specific]
    mpirun_template = "/custom/mpirun -machinefile ~/mf -n {RANKS}"
This example will thus use a custom mpirun executable with a non-standard argument for all Salvus runs on that site. The {RANKS} argument will be filled in by Salvus with the number of ranks for each simulation.
SalvusProject
Changes to the event configuration in UnstructuredMeshSimulationConfiguration objects are now properly recognized when trying to overwrite an existing configuration of the same name.

Changes to Experimental Features in 0.12.3

SalvusCompute
Add a new physics module to solve the Poisson equation.
This is the first elliptic PDE that can be solved with Salvus. The Poisson equation is useful for simulatingthe gravitational potential of a planetary object as well as computing correct inner products and regularization terms in the Sobolev space H1H^1.
This feature is currently only supported on CPUs and is considered experimental.

Salvus version 0.12.2

Released: 2022-05-31
Minor update with a new model class based on xarray to invert for structured data in SalvusOpt. Furthermore, we extended the options for passing callback functions to SalvusProject.
SalvusOpt
Add new model class StructuredModel to SalvusOpt to invert models parameterized on a regular grid using xarray.Datasets.
SalvusProject
The function serialization can now also deal with functions passed in closures.

Salvus version 0.12.1

Released: 2022-05-16
This release provides several small improvements for making inversion workflows more resilient and more robust.
Furthermore, we added easier support for arbitrary boundary conditions through the WaveformSimulationConfiguration.
SalvusFlow
Add an normalization option for the misfit and adjoint source computation.
The adjoint source is aware of this operation and Salvus will make sure it is correct.
SalvusOpt
Add basic timing statistics for the tasks of an iteration. A summary is printed in the Stats tab of the iteration widget.
SalvusOpt
Reduce the memory overhead of dealing with many event-dependent gradients.
SalvusProject
Add support for specifying boundary conditions in the WaveformSimulationConfiguration. This is useful for Dirichlet-type boundaries or absorbing boundaries of a UnstructuredMeshSimulationConfiguration. Boundaries specified here will be applied in addition to ocean load and/or absorbing boundaries specified as AbsorbingBoundaryParameters in the SimulationConfiguration. A ValueError is raised for duplicated conditions on a side set.
SalvusProject
Add ability to recover from failed preconditioner tasks and provide error logs of failed smoothing jobs.
SalvusProject
Add ability to recover from failed misfit computations. If a misfit computation fails for one more events during compute_misfits, the simulation results are considered corrupted and will be automatically deleted. This means that those simulations will be resubmitted when calling compute_misfits again.
This helps, for instance, to recover from corrupted ASDF files in case they have not have been written or downloaded correctly.

Salvus version 0.12.0

Released: 2022-04-30
This is a new major release which comes with a big portion of internal changes.
Fortunately, there are only a few breaking changes on the user-facing API, which are mostly related to custom meshing functionality.
We've also used the opportunity to remove some deprecated functionality of the inversion component, and added several improvements related to resilience and performance.
SalvusFlow
Will now reinitialize the SSH site in case a socket has been closed.
SalvusFlow
Better sharing of existing SSH connections. Should reduce the number of necessary SSH connection reinitializations.
SalvusFlow
Added timings to the individual tasks of a TaskChain.
SalvusMesh
API CHANGE
Removed the StructuredGrid2D, StructuredGrid3D and Skeleton classes and replaced them with new MeshBlock and MeshBlockCollection classes.
This should have a minimal influence on most users - please contact us if you experience any issues.
SalvusOpt
Performance improvement of the adjoint mapping function when using cutouts around source or receiver locations.
SalvusProject
Remove job submission settings from the inversion routines iterate() and resume(). Specifying site_name, ranks_per_job and wall_time_in_seconds_per_job is no longer supported. Instead, the job_submission_settings either need to be passed to the constructor of the InverseProblemConfiguration or by using p.inversions.set_job_submission_configuration().
SalvusProject
Add option to query simulations for specific compression settings.
Example:
p.simulations.query(
    simulation_configuration="my_simulation",
    misfit_configuration="my_misfit",
    wavefield_compression=sn.WavefieldCompression(
        forward_wavefield_sampling_interval=15
    ),
    events=p.events.list(),
)
SalvusProject
Add the option to pass an element mask to Cartesian volume models. Useful, for instance, when you only want to interpolate parameters onto a specific subdomain of the mesh (i.e. only onto elastic elements).
SalvusProject
Fix a bug that could occur in very specific circumstances when overwriting an existing bathymetry model.

Salvus version 0.11.48

Released: 2022-03-30
This release contains a long-sought feature for reducing the memory footprint of checkpoints for adjoint simulations by sampling the forward wavefield on a coarser grid during the adjoint run. This includes breaking changes for some of the inversion routines, which may require updating the syntax of some notebooks. Details are listed below. If you are concerned about upgrading, please get in touch with us in the user forum.
The release also contains bug fixes concerning the use of custom bm files in SalvusProject and attaching receivers on SmoothieSEM meshes, as well as the option to provide a custom scaling for the mapping function of the inversion.
Also, don't forget to keep your python environment up-to-date! We recommend to always run
wget https://mondaic.com/environment.yml -O ~/environment.yml
conda env update -n salvus -f ~/environment.yml
before upgrading.
SalvusFlow
New TaskChain workflow primitive that can be used to run multiple Salvus jobs and/or Python scripts in a linear chain within a single local/ssh/HPC job.
This is a first implementation so expect some rough edges:
# Construct a forward simulation object.
w_forward = sn.simple_config.simulation.Waveform(
    ..., store_adjoint_checkpoints=True
)

# Construct an adjoint simulation object.
w_adjoint = sn.simple_config.simulation.Waveform(...)
...
# There is a new `PROMISE_FILE:` prefix to tell SalvusFlow that a file does
# not exist yet but it will exist when the simulation is run.
w_adjoint.adjoint.point_source_block = {
    "filename": "PROMISE_FILE:task_2_of_2/input/adjoint_source.h5",
    "groups": ["adjoint_sources"],
}

# Define a Python function that is run between forward and adjoint simulations
# to generate the adjoint sources.
def compute_adjoint_source(
    task_index: int, task_index_folder_map: typing.Dict[int, pathlib.Path]
):
    folder_forward = task_index_folder_map[task_index - 1]
    folder_adjoint = task_index_folder_map[task_index + 1]

    output_folder = folder_forward / "output"

    event = sn.EventData.from_output_folder(output_folder=output_folder)

    event_misfit = sn.EventMisfit(
        synthetic_event=event,
        misfit_function="L2_energy_no_observed_data",
        receiver_field="displacement",
    )

    input_folder_adjoint = folder_adjoint / "input"
    event_misfit.write(input_folder_adjoint / "adjoint_source.h5")


# Launch the task chain. It will serialize the Python function and launches
# everything either locally or in Slurm/other supported systems.
tc = sn.api.run_task_chain_async(
    site_name="local",
    tasks=[w_forward, compute_adjoint_source, w_adjoint],
    ranks=4,
)
# Wait until it finishes.
tc.wait()
SalvusFlow
More stable implementation of the rewritten receiver placement and it should now also work for highly distored meshes.
SalvusOpt
Add option for custom scaling in mapping function. The custom scaling parameters need to be defined on the same mesh as the simulation and provided as elemental fields for all parameters.
Example
mesh = p.simulations.get_mesh("sim")

# Modify scaling parameters for all fields
mesh.elemental_fields["VP"] = ...
mesh.elemental_fields["RHO"] = ...

m = Mapping(
  scaling=mesh,
  inversion_parameters=["M"],
  map_to_physical_parameters={"VP": "M", "RHO": "M"},
)
SalvusProject
API CHANGE
Add proper serialization of bm files in SalvusProject. Previously, custom bm files were not added to the project and relied on external paths which prevented copying projects to other machines.
Adding custom background models as string will now throw a deprecation warning. It is strongly recommended to add custom bm files using the class model.background.one_dimensional.FromBm.
SalvusProject
API CHANGE
Add option for wavefield compression during adjoint runs to reduce the memory overhead. In order to allocate the correct number of checkpoints, this setting needs to be available at the time of computing the forward wavefield. This setting can now be used in several locations listed below by adding
sn.WavefieldCompression(
      forward_wavefield_sampling_interval=N
  )
if checkpoints should be stored for a resampling interval of N during the adjoint run. forward_wavefield_sampling_interval=1 corresponds to no compression and is equivalent to what was done prior to this release.
This is a (small) breaking change that requires updating the syntax of inversion-related functionality!
new optional arguments:
The wavefield compression settings enter now as optional argument into some objects and functions. If not given, it will default to forward_wavefield_sampling_interval=1, which is consistent with Salvus <= 0.11.47.
Examples:
# Inversion actions:
p.action.inversion.compute_misfits(
  ...,
  derived_job_config=sn.WavefieldCompression(
      forward_wavefield_sampling_interval=5
  ),
  ...
)

p.action.inversion.compute_gradients(
  ...,
  wavefield_compression=sn.WavefieldCompression(
      forward_wavefield_sampling_interval=5
  ),
  ...
)

p.action.inversion.sum_gradients(
  ...,
  wavefield_compression=sn.WavefieldCompression(
      forward_wavefield_sampling_interval=5
  ),
  ...
)

# InverseProblemConfiguration
sn.InverseProblemConfiguration(
  ...
  wavefield_compression=sn.WavefieldCompression(
      forward_wavefield_sampling_interval=5
  ),
  ...
)
deprecated parameters:
The parameters store_adjoint_checkpoints in p.simulations.launch(...) and store_checkpoints in p.actions.inversion.compute_misfits(...) are deprecated. Instead, use
derived_job_config=WavefieldCompression(
      forward_wavefield_sampling_interval=N
  ),
derived_job_config=None is the new default, which corresponds to the deprecated store_adjoint_checkpoints=False or store_checkpoints=False, respectively.
breaking changes:
compute_misfits and compute_gradients in p.action.inversion are now keyword-only functions. Additionally, we made the wavefield compression settings mandatory arguments of a few lower-level functions, such as:
p.misfits.get_gradient_filenames()
p.simulations.get_adjoint_input_files()
p.action.validation.validate_model_gradients()
In case you are using one of these directly, you will notice an error like
TypeError: compute_gradients() needs keyword-only argument
wavefield_compression
which can be fixed by just adding the wavefield_compression object shown above.

Salvus version 0.11.47

Released: 2022-03-23
Minor update to patch a bug introduced with 0.11.46.
SalvusProject
Fix a bug introduced with 0.11.46, which broke backward compatibility of a project when deserializing an UnstructuredMeshSimulationConfiguration.

Salvus version 0.11.46

Released: 2022-03-18
This release comes with a fairly long list of small improvements and bug fixes listed below. Notable new features include (full) gradient sources for elastic simulations, GPU support for acoustic gradient sources, better memory management of inversions, several tweaks regarding window selection and weighting, and a more robust and faster algorithm to attach receivers.
Thanks again to all users who reported bugs and requested features!
SalvusCompute
Added vector gradient sources for elastic media.
SalvusCompute
Scalar gradient sources now also work on GPUs.
SalvusFlow
Initializing a site with SalvusFlow now runs a test job using the default number of ranks for that site instead of 2.
SalvusFlow
The site configuration for the GridEngine and PBS site types now allows simplistic expressions:
[[sites.site_name.site_specific.additional_qsub_arguments]]
      name = "pe"
      value = "mpi {NODES * TASKS_PER_NODE}"

  [[sites.site_name.site_specific.additional_qsub_arguments]]
      name = "l"
      value = "ngpus={int(ceil(RANKS / 12))}"
SalvusFlow
Add a new lat_lng_to_utm_crs() helper routine to directly get a pyproj UTM CRS object from a point given in latitude and longitude.
SalvusFlow
The relative source and receiver placement code is much faster now due to algorithmic changes and code optimizations. Additionally, a few previously uncaught edge cases now work as expected.
SalvusFlow
Added local version of all HPC sites that directly interact with the job queuing and file systems without using SSH.
SalvusFlow
New salvus-cli alias for the salvus-flow command line call. This will become the default at one point.
SalvusProject
Safely remove adjoint sources after the adjoint simulation. This happens automatically after retrieving the results from the adjoint simulation. Adjoint source files will be recomputed on-the-fly if required. This can also be done explicitly using
p.misfits.compute_adjoint_source()
SalvusProject
Fix a bug in the hash computation for adjoint simulations that could result in non-unique hashes in special cases.
SalvusProject
New default basemap for the seismology receiver weights and misfit maps. Furthermore they are now configurable.
SalvusProject
The error log output of the seismological window picking routine is now more descriptive.
SalvusProject
SalvusProject will no longer create an empty EventWindowAndWeightSet in case the window selection routine did not pick a single window for a chosen event.
An appropriate warning message and log file entry will be created in that case.
SalvusProject
New function to get all events with windows for a chosen data selection configuration:
p.actions.seismology.get_events_with_windows("DSC_NAME")
SalvusProject
Added some more receiver weight validation steps and Salvus now properly deals with a few more edge cases, for example when the total receiver weight sum of an event is zero.
SalvusProject
UTMDomain objects no longer require the ellipsoid to be passed.

Salvus version 0.11.45

Released: 2022-01-27
First release of 2022 with several small bug fixes listed below. As a new feature, SalvusProject supports multiple source time functions for different point sources, which facilitates simulating finite faults or encoded sources.
SalvusCompute
Bugfix for the Clayton-Enquist absorbing boundaries in 2-D anisotropic physics.
SalvusCompute
Fixes a performance bug for adjoint GPU runs in purely elastic media. In this case, an unnecessary serial step is now skipped when loading checkpoints.
SalvusFlow
Enable salvus-flow upgrade and salvus-flow upgrade-site for double precision versions using the salvus_f64 binary.
SalvusFlow
The init-site script will wait a bit longer for the stderr in case it is not yet available due to some synchronization delays on shared and parallel file systems.
SalvusMesh
The UnstructuredMesh.extrude_side_set_2D() method now also works as expected for higher order meshes. Additionally fixed an issue with inverted elements in certain scenarios.
SalvusOpt
Fix a bug in the gradient view of the iteration widget. Now the mapped gradient accumulated from all events is correctly displayed in the widget.
SalvusProject
Fix a bug that prevented loading an InverseProblemConfiguration after the project has been transferred to another python environment with a different site configuration.
SalvusProject
Enable different source time functions for event with multiple point sources.
Example:
Event(
  event_name="event",
  sources=[point_src1, point_src2],
  receivers=receivers,
)

...

EventConfiguration(
  waveform_simulation_configuration=...,
  wavelet=[
      simple_config.stf.Ricker(center_frequency=1.0),
      simple_config.stf.Ricker(center_frequency=2.0),
  ],
)

Salvus version 0.11.44

Released: 2021-12-06
Minor release with a few bug fixes listed below.
Shoutout to the user community for identifying these bugs and helping us to fix them.
SalvusCompute
Fix a bug for CPU sites where surface output with multiple side sets per element could cause an issue in the surface wavefield output ordering.
SalvusFlow
Fix a bug in (de)-serialization of receiver objects when accidentially passing int instead of float types.
SalvusFlow
Fixing a bug when plotting adjoint sources.
SalvusProject
Fix a bug in plotting shotgathers for single data series.
Example:
p.viz.shotgather(
    data="simulation",
    event="event",
    receiver_field="phi",
    component="A"
)

Salvus version 0.11.43

Released: 2021-10-21
Minor update with a bug fix for serializing cythonized functions.
SalvusProject
The function serialization can now serialize cythonized functions imported from other modules.

Salvus version 0.11.42

Released: 2021-10-19
Minor update with some internal changes and support for frequency domain output in Salvus project.
SalvusProject
Add support for frequency-domain output to Salvus project.
Optional output of the Fourier transform for a discrete set of frequencies can now be passed as extra_output_configuration to the launch function.
p.simulations.launch(
    ranks_per_job=4,
    site_name="local",
    events=p.events.list(),
    simulation_configuration="simulation",
    extra_output_configuration={
        "frequency_domain": {
            "fields": ["displacement"],
            "frequencies": [1.0, 2.0, 3.0],
        }
    },
)

Salvus version 0.11.41

Released: 2021-10-08
This is a large release that adds many features useful for the inversion of seismic data, particularly for land and near-surface applications.
SalvusFlow
The observed and synthetic data can now optionally be downsampled before the misfit and adjoint source are computed. The adjoint source is later upsampled again and scaled correctly. Useful for expensive misfit functionals.
It can be used either at the event misfit level:
event_misfit = EventMisfit(
    ...,
    # Optionally downsample to the given number of npts.
    max_samples_for_misfit_computation=max_samples_for_misfit_computation
)
Or at the misfit configuration level within SalvusProject:
mc = MisfitConfiguration(
    ...,
    # Optionally downsample to the given number of npts.
    max_samples_for_misfit_computation=max_samples_for_misfit_computation
SalvusMesh
Fix a bug that caused the mesh widget to crash for fields with only negative values.
SalvusModules
Added comprehensive support for converting data from a point source to an equivalent line source which is necessary for example when using 3-D observed data in 2-D inversions.
We added a variety of different transform, each applicable in different use cases. Please have a look at the documentation for details.
from salvus.modules.near_surface.processing import convert_point_to_line_source

new_st = convert_point_to_line_source(
    st=st,
    source_coordinates=[22.0, 1.0],
    receiver_coordinates=[132.0, 0.0],
    transform_type="single_velocity_exact",
    velocity_m_s=550.0
)
SalvusModules
Added utility functions to compute, remove, and plot geophone responses.
import numpy as np
from salvus.modules.near_surface.processing import geophone_response

frequencies = np.logspace(0.1, 2, 2000)
response = geophone_response.compute_geophone_response(
    frequencies=frequencies,
    geophone_frequency=4.5,
    damping_ratio=0.4,
    calibration_factor=11.2,
)
geophone_response.plot_response(frequencies=frequencies, response=response)
SalvusOpt
Added an implementation of a graph space optimal transport misfit measure as introduced in this paper:
L. Métivier, R. Brossier, Q. Mérigot, and E. Oudet. 2019.
"A graph space optimal transport distance as a generalization of Lp  distances: application to a seismic imaging inverse problem"
Inverse Problems, Volume 35, Number 8, https://doi.org/10.1088/1361-6420/ab206f
You can use it by choosing "graph_space_optimal_tranport" everywhere Salvus accepts misfit functionals. The one tuning parameters is the "max_expected_time_shift" which, as the name implies, should be set to the maximum expected time shift in seconds for individual wiggles between observed and synthetic data.
For many problems this can get completely avoid the cycle skipping problem. This, admittedly manufactured, synthetic inversion example demonstrates the potential gains:
SalvusProject
The function serialization can now serialize numpy arrays and dictionaries as closure values.
SalvusProject
Added the ability to use processing fragments to more easily perform some simple and common processing techniques.
To for example bandpass and normalize some data use "EXTERNAL_DATA:raw_data | bandpass(1.0, 2.0) | normalize" as the data name.
Available processing fragments:
  • time_shift({SHIFT})
  • normalize
  • scale({FACTOR})
  • flip
  • bandpass({FREQ_MIN}, {FREQ_MAX}[, zerophase][, corners={CORNERS}])
SalvusProject
Added an automatic domain preview visualization for 3-D box domains.
SalvusProject
Added an improved shotgather visualization. Amongst other things, it can now plot interleaved data from multiple traces and sort the receivers with a lambda function:
p.viz.shotgather(
    data=[
        "PROCESSED_DATA:corrected_data_10_15_hz | normalize",
        "SYNTHETIC_DATA:starting_model_10_15_hz | normalize",
    ],
    event="shot_049",
    receiver_field="velocity",
    component="Y",
    sort_by=lambda r: r.location[0]
)