Giter VIP home page Giter VIP logo

judi.jl's Introduction

The Julia Devito Inversion framework (JUDI)

Documentation Build Status

Overview

JUDI is a framework for large-scale seismic modeling and inversion and is designed to enable rapid translations of algorithms to fast and efficient code that scales to industry-size 3D problems. The focus of the package lies on seismic modeling as well as PDE-constrained optimization such as full-waveform inversion (FWI) and imaging (LS-RTM). Wave equations in JUDI are solved with Devito, a Python domain-specific language for automated finite-difference (FD) computations. JUDI's modeling operators can also be used as layers in (convolutional) neural networks to implement physics-augmented deep learning algorithms thanks to its implementation of ChainRules's rrule for the linear operators representing the discre wave equation.

Interact and contribute

We gladly welcome and encourage contributions from the community to improve our software and its usability. Feel free to:

  • Open issues for bugs
  • Start discussions to interact with the developer and ask any questions
  • Open PR for bug fixes and improvements

FAQ

You can find an FAQ with answers to issues at FAQ

Installation and prerequisites

You can find installation instructions in our Wiki at Installation

GPU

JUDI supports the computation of the wave equation on GPU via Devito's GPU offloading support.

NOTE: Only the wave equation part will be computed on GPU, the Julia arrays will still be CPU arrays and CUDA.jl is not supported.

Installation

To enable gpu support in JUDI, you will need to install one of Devito's supported offloading compilers. We strongly recommend checking the Wiki for installation steps and to reach out to the Devito community for GPU compiler related issues.

  • nvc/pgcc. This is recommended and the simplest installation. You can install the compiler following Nvidia's installation instruction at HPC-sdk
  • aompcc. This is the AMD compiler that is necessary for running on AMD GPUs. This installation is not tested with JUDI and we recommend to reach out to Devito's team for installation guidelines.
  • openmp5/clang. This installation requires the compilation from source openmp, clang and llvm to install the latest version of openmp5 enabling gpu offloading. You can find instructions on this installation in Devito's Wiki

Setup

The only required setup for GPU support are the environment variables for Devito. For the currently supported nvc+openacc setup these are:

export DEVITO_LANGUAGE=openacc
export DEVITO_ARCH=nvc
export DEVITO_PLATFORM=nvidiaX

Running with Docker

If you do not want to install JUDI, you can run JUDI as a docker image. The first possibility is to run the docker container as a Jupyter notebook. JUDI provides two docker images for the latest JUDI release for Julia versions 1.6 (LTS) and 1.7 (latest stable version). The images names are mloubout/judi:JVER-latest where JVER is the Julia version. This docker images contain pre-installed compilers for CPUs (gcc-10) and Nvidia GPUs (nvc) via the nvidia HPC sdk. The environment is automatically set for Devito based on the hardware available.

Note: If you wish to use your gpu, you will need to install nvidia-docker and run docker run --gpus all in order to make the GPUs available at runtime from within the image.

To run JUDI via docker execute the following command in your terminal:

docker run -p 8888:8888 mloubout/judi:1.7-latest

This command downloads the image and launches a container. You will see a link that you can copy-paste to your browser to access the notebooks. Alternatively, you can run a bash session, in which you can start a regular interactive Julia session and run the example scripts. Download/start the container as a bash session with:

docker run -it mloubout/judi:1.7-latest /bin/bash

Inside the container, all examples are located in the directory /app/judi/examples/scripts.

Previous versions: As of version v2.6.7 of JUDI, we also ship version-tagged images as mloubout/judi:JVER-ver where ver is the version of JUDI wanted, for example the current JUDI version with Julia 1.7 is mloubout/judi:1.7-v2.6.7

Development version: Additionally, we provide two images corresponding to the latest development version of JUDI (latest state of the master branch). These images are called mloubout/judi:JVER-dev and can be used in a similar way.

Testing

A complete test suite is included with JUDI and is tested via GitHub Actions. You can also run the test locally via:

    Julia --project -e 'using Pkg;Pkg.test(coverage=false)'

By default, only the JUDI base API will be tested. However, the testing suite supports other modes controlled via the environment variable GROUP such as:

	GROUP=JUDI Julia --project -e 'using Pkg;Pkg.test(coverage=false)'

The supported modes are:

  • JUDI : Only the base API (linear operators, vectors, ...)
  • BASICS: Generic modeling and inversion tests such as out of core behavior
  • ISO_OP : Isotropic acoustic operators
  • ISO_OP_FS : Isotropic acoustic operators with free surface
  • TTI_OP : Transverse tilted isotropic operators
  • TTI_OP_FS : Transverse tilted isotropic operators with free surface
  • filename : you can also provide just a filename (i.e GROUP=test_judiVector.jl) and only this one test file will be run. Single files with TTI or free surface are not currently supported as it relies on Base.ARGS for the setup.

Configure compiler and OpenMP

Devito uses just-in-time compilation for the underlying wave equation solves. The default compiler is intel, but can be changed to any other specified compiler such as gnu. Either run the following command from the command line or add it to your ~/.bashrc file:

export DEVITO_ARCH=gnu

Devito uses shared memory OpenMP parallelism for solving PDEs. OpenMP is disabled by default, but you can enable OpenMP and define the number of threads (per PDE solve) as follows:

export DEVITO_LANGUAGE=openmp  # Enable OpenMP. 
export OMP_NUM_THREADS=4    # Number of OpenMP threads

Full-waveform inversion

JUDI is designed to let you set up objective functions that can be passed to standard packages for (gradient-based) optimization. The following example demonstrates how to perform FWI on the 2D Overthrust model using a spectral projected gradient algorithm from the minConf library, which is included in the software. A small test dataset (62 MB) and the model can be downloaded from this FTP server:

run(`wget ftp://slim.gatech.edu/data/SoftwareRelease/WaveformInversion.jl/2DFWI/overthrust_2D.segy`)
run(`wget ftp://slim.gatech.edu/data/SoftwareRelease/WaveformInversion.jl/2DFWI/overthrust_2D_initial_model.h5`)

The first step is to load the velocity model and the observed data into Julia, as well as setting up bound constraints for the inversion, which prevent too high or low velocities in the final result. Furthermore, we define an 8 Hertz Ricker wavelet as the source function:

using PyPlot, HDF5, SegyIO, JUDI, SlimOptim, Statistics, Random

# Load starting model
n, d, o, m0 = read(h5open("overthrust_2D_initial_model.h5", "r"), "n", "d", "o", "m0")
model0 = Model((n[1], n[2]), (d[1], d[2]), (o[1], o[2]), m0)	# need n, d, o as tuples and m0 as array

# Bound constraints
vmin = ones(Float32, model0.n) .+ 0.3f0
vmax = ones(Float32, model0.n) .+ 5.5f0
mmin = vec((1f0 ./ vmax).^2)	# convert to slowness squared [s^2/km^2]
mmax = vec((1f0 ./ vmin).^2)

# Load segy data
block = segy_read("overthrust_2D.segy")
dobs = judiVector(block)

# Set up wavelet
src_geometry = Geometry(block; key="source", segy_depth_key="SourceDepth")	# read source position geometry
wavelet = ricker_wavelet(src_geometry.t[1], src_geometry.dt[1], 0.008f0)	# 8 Hz wavelet
q = judiVector(src_geometry, wavelet)

For this FWI example, we define an objective function that can be passed to the minConf optimization library, which is included in the Julia Devito software package. We allow a maximum of 20 function evaluations using a spectral-projected gradient (SPG) algorithm. To save computational cost, each function evaluation uses a randomized subset of 20 shot records, instead of all 97 shots:

# Optimization parameters
fevals = 20	# number of function evaluations
batchsize = 20	# number of sources per iteration
fvals = zeros(21)
opt = Options(optimal_checkpointing = false)    # set to true to enable checkpointing

# Objective function for minConf library
count = 0
function objective_function(x)
	model0.m = reshape(x, model0.n);

	# fwi function value and gradient
	i = randperm(dobs.nsrc)[1:batchsize]
	fval, grad = fwi_objective(model0, q[i], dobs[i]; options=opt)
	grad = reshape(grad, model0.n); grad[:, 1:21] .= 0f0	# reset gradient in water column to 0.
	grad = .1f0*grad/maximum(abs.(grad))	# scale gradient for line search

	global count; count += 1; fvals[count] = fval
    return fval, vec(grad.data)
end

# FWI with SPG
ProjBound(x) = median([mmin x mmax], dims=2)	# Bound projection
options = spg_options(verbose=3, maxIter=fevals, memory=3)
x, fsave, funEvals= minConf_SPG(objective_function, vec(m0), ProjBound, options)

This example script can be run in parallel and requires roughly 220 MB of memory per source location. Execute the following code to generate figures of the initial model and the result, as well as the function values:

figure(); imshow(sqrt.(1./adjoint(m0))); title("Initial model")
figure(); imshow(sqrt.(1./adjoint(reshape(x, model0.n)))); title("FWI")
figure(); plot(fvals); title("Function value")

fwi

Least squares reverse-time migration

JUDI includes matrix-free linear operators for modeling and linearized (Born) modeling, that let you write algorithms for migration that follow the mathematical notation of standard least squares problems. This example demonstrates how to use Julia Devito to perform least-squares reverse-time migration on the 2D Marmousi model. Start by downloading the test data set (1.1 GB) and the model:

run(`wget ftp://slim.gatech.edu/data/SoftwareRelease/Imaging.jl/2DLSRTM/marmousi_2D.segy`)
run(`wget ftp://slim.gatech.edu/data/SoftwareRelease/Imaging.jl/2DLSRTM/marmousi_migration_velocity.h5`)

Once again, load the starting model and the data and set up the source wavelet. For this example, we use a Ricker wavelet with 30 Hertz peak frequency. For setting up matrix-free linear operators, an info structure with the dimensions of the problem is required:

using PyPlot, HDF5, JUDI, SegyIO, Random

# Load smooth migration velocity model
n,d,o,m0 = read(h5open("marmousi_migration_velocity.h5","r"), "n", "d", "o", "m0")
model0 = Model((n[1],n[2]), (d[1],d[2]), (o[1],o[2]), m0)

# Load data
block = segy_read("marmousi_2D.segy")
dD = judiVector(block)

# Set up wavelet
src_geometry = Geometry(block; key="source", segy_depth_key="SourceDepth")
wavelet = ricker_wavelet(src_geometry.t[1],src_geometry.dt[1],0.03)	# 30 Hz wavelet
q = judiVector(src_geometry,wavelet)

# Set up info structure
ntComp = get_computational_nt(q.geometry,dD.geometry,model0)	# no. of computational time steps
info = Info(prod(model0.n),dD.nsrc,ntComp)

To speed up the convergence of our imaging example, we set up a basic preconditioner for each the model- and the data space, consisting of mutes to suppress the ocean-bottom reflection in the data and the source/receiver imprint in the image. The operator J represents the linearized modeling operator and its adjoint J' corresponds to the migration (RTM) operator. The forward and adjoint pair can be used for a basic LS-RTM example with (stochastic) gradient descent:

# Set up matrix-free linear operators
opt = Options(optimal_checkpointing = true)    # set to false to disable optimal checkpointing
F = judiModeling(model0, q.geometry, dD.geometry; options=opt)
J = judiJacobian(F, q)

# Right-hand preconditioners (model topmute)
Mr = judiTopmute(model0.n, 52, 10)	# mute up to grid point 52, with 10 point taper

# Left-hand preconditioners
Ml = judiDataMute(q.geometry, dD.geometry; t0=.120)	# data topmute starting at 120ms (30 samples)

# Stochastic gradient
x = zeros(Float32, info.n)	# zero initial guess
batchsize = 10	# use subset of 10 shots per iteration
niter = 32
fval = zeros(Float32, niter)

for j=1:niter
	println("Iteration: ", j)

	# Select batch and set up left-hand preconditioner
	i = randperm(dD.nsrc)[1:batchsize]

	# Compute residual and gradient
	r = Ml[i]*J[i]*Mr*x - Ml[i]*dD[i]
	g = adjoint(Mr)*adjoint(J[i])*adjoint(Ml[i])*r

	# Step size and update variable
	fval[j] = .5f0*norm(r)^2
	t = norm(r)^2/norm(g)^2
	global x -= t*g
end

lsrtm

Machine Learning

JUDI implements ChainRulesCore reverse rules to integrate the modeling operators into convolutional neural networks for deep learning. For example, the following code snippet shows how to create a shallow CNN consisting of two convolutional layers with a nonlinear forward modeling layer in-between them. JUDI enables backpropagation through Flux' automatic differentiation tools, but calls the corresponding adjoint JUDI operators under the hood.

# Jacobian
W1 = judiJacobian(F0, q)
b1 = randn(Float32, num_samples)

# Fully connected layer
W2 = randn(Float32, n_out, num_samples)
b2 = randn(Float32, n_out)

# Network and loss
network(x) = W2*(W1*x .+ b1) .+ b2
loss(x, y) = Flux.mse(network(x), y)

# Compute gradient w/ Flux
p = params(x, y, W1, b1, b2)
gs = Tracker.gradient(() -> loss(x, y), p)
gs[x]	# gradient w.r.t. to x

JUDI allows implementing physics-augmented neural networks for seismic inversion, such as loop-unrolled seismic imaging algorithms. For example, the following results are a conventional RTM image, an LS-RTM image and a loop-unrolled LS-RTM image for a single simultaneous shot record.

flux

Authors

This package was written by Philipp Witte and Mathias Louboutin from the Seismic Laboratory for Imaging and Modeling (SLIM) at the Georgia Institute of Technology.

If you use our software for your research, please cite our Geophysics paper:

@article{witteJUDI2019,
author = {Philipp A. Witte and Mathias Louboutin and Navjot Kukreja and Fabio Luporini and Michael Lange and Gerard J. Gorman and Felix J. Herrmann},
title = {A large-scale framework for symbolic implementations of seismic inversion algorithms in Julia},
journal = {GEOPHYSICS},
volume = {84},
number = {3},
pages = {F57-F71},
year = {2019},
doi = {10.1190/geo2018-0174.1},
URL = {https://doi.org/10.1190/geo2018-0174.1},
eprint = {https://doi.org/10.1190/geo2018-0174.1}
}

Also visit the Devito homepage at https://www.devitoproject.org/publications for more information and references.

Contact authors via: [email protected].

judi.jl's People

Contributors

cako avatar gbruer15 avatar henryk-modzelewski avatar kerim371 avatar mloubout avatar nogueirapeterson avatar philippwitte avatar ziyiyin97 avatar

Stargazers

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

Watchers

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

judi.jl's Issues

parallel problem when running on multi node

Hi, I am new to parallel computing and I guess my situation is interesting for others, at least in terms of education. I try to run "[JUDI.jl](/examples/compressive_splsrtm/Sigsbee2A/rtm_sigsbee.jl" example on the cluster using 6 nodes,each contains 16 cores. I use PBS to submit my commands, but seem like parallel computing is not happening. Only one node (node16) is assigned to the task of parallel computing.
16

While other nodes are not assigned to the task.
1

Is there anything else I lose? Thank you very much.(^▽^)

UNHANDLED TASK ERROR

MFE is below

using JUDI, JLD2

# Set up model structure
n = (600, 600)   # (x,y,z) or (x,z)
d = (10., 10.)
o = (0., 0.)

# Velocity [km/s]
v = ones(Float32,n) .+ 0.5f0
v0 = ones(Float32,n) .+ 0.5f0
v[:,Int(round(end/2)):end] .= 3.5f0
rho = (v0 .+ .5f0) ./ 2

# Slowness squared [s^2/km^2]
m = (1f0 ./ v).^2
m0 = (1f0 ./ v0).^2
dm = vec(m - m0)

# Setup info and model structure
nsrc = 4	# number of sources
model = Model(n, d, o, m)
model0 = Model(n, d, o, m0)

# Set up receiver geometry
nxrec = 120
xrec = range(50f0, stop=1150f0, length=nxrec)
yrec = 0f0
zrec = range(50f0, stop=50f0, length=nxrec)

# receiver sampling and recording time
timeR = 1000f0   # receiver recording time [ms]
dtR = 2f0    # receiver sampling interval [ms]

# Set up receiver structure
recGeometry = Geometry(xrec, yrec, zrec; dt=dtR, t=timeR, nsrc=nsrc)

# Set up source geometry (cell array with source locations for each shot)
xsrc = convertToCell(range(400f0, stop=800f0, length=nsrc))
ysrc = convertToCell(range(0f0, stop=0f0, length=nsrc))
zsrc = convertToCell(range(200f0, stop=200f0, length=nsrc))

# source sampling and number of time steps
timeS = 1000f0  # ms
dtS = 2f0   # ms

# Set up source structure
srcGeometry = Geometry(xsrc, ysrc, zsrc; dt=dtS, t=timeS)

# setup wavelet
f0 = 0.01f0     # kHz
wavelet = ricker_wavelet(timeS, dtS, f0)
q = judiVector(srcGeometry, wavelet)

# Set up info structure for linear operators
ntComp = get_computational_nt(srcGeometry, recGeometry, model)
info = Info(prod(n), nsrc, ntComp)

###################################################################################################

# Write shots as segy files to disk
opt = Options(isic=true)

# Setup operators
Pr = judiProjection(info, recGeometry)
F = judiModeling(info, model; options=opt)
F0 = judiModeling(info, model0; options=opt)
Ps = judiProjection(info, srcGeometry)
J = judiJacobian(Pr*F0*adjoint(Ps), q)

# Nonlinear modeling
# dobs = Pr*F*adjoint(Ps)*q
JLD2.@load "dobs.jld2" dobs

# evaluate LSRTM objective function
fj, gj = lsrtm_objective(model0, [q, q], [dobs, dobs], [dm, dm]; nlind=false, options=opt)

I did julia -p 2 -L ~/startup.jl with the startup file as

# Sytem informations

nthreads = parse(Int, ENV["OMP_NUM_THREADS"])
if nthreads*nworkers() > 8
    println("WARNING: allocating more ressources than available, ($(nthreads) threads and $(nworkers()) workers with only 8 cpus)")
end

threadlist=[0, 4, 1, 5, 2, 6, 3, 7]

k = myid()%nworkers()
ft = k*nthreads+1
lt = ft+nthreads-1
threads = threadlist[ft:lt]

ENV["OMP_DISPLAY_AFFINITY"]="true"
ENV["GOMP_CPU_AFFINITY"]=join(threads, " ")
println("using threads $(threads)")

terminal log is

[zyin62@eas-coda-fherr08 scripts]$ julia -p 2 -L ~/startup.jl 
using threads [2, 6, 3, 7]
      From worker 2:    using threads [0, 4, 1, 5]
      From worker 3:    using threads [2, 6, 3, 7]
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.7.1 (2021-12-22)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

(@v1.7) pkg> status JUDI
      Status `~/.julia/environments/v1.7/Project.toml`
  [f3b833dc] JUDI v2.6.8 `~/.julia/dev/JUDI`

julia> include("MFE.jl")
      From worker 2:    ┌ Warning: `vendor()` is deprecated, use `BLAS.get_config()` and inspect the output instead
      From worker 2:    │   caller = npyinitialize() at numpy.jl:67
      From worker 2:    └ @ PyCall ~/.julia/packages/PyCall/L0fLP/src/numpy.jl:67
      From worker 3:    ┌ Warning: `vendor()` is deprecated, use `BLAS.get_config()` and inspect the output instead
      From worker 3:    │   caller = npyinitialize() at numpy.jl:67
      From worker 3:    └ @ PyCall ~/.julia/packages/PyCall/L0fLP/src/numpy.jl:67
      From worker 2:    level 1 thread 0x7fbf3975e740 affinity 0,4
      From worker 2:    level 1 thread 0x7fbeeb9ce700 affinity 1,5
      From worker 2:    level 1 thread 0x7fbef41cf700 affinity 2,6
      From worker 2:    level 1 thread 0x7fbef49d0700 affinity 3,7
      From worker 3:    level 1 thread 0x7f65a8946740 affinity 0,4
      From worker 3:    level 1 thread 0x7f656c98d700 affinity 1,5
      From worker 3:    level 1 thread 0x7f656d18e700 affinity 2,6
      From worker 3:    level 1 thread 0x7f656d98f700 affinity 3,7
      From worker 2:    Operator `born` ran in 0.64 s
      From worker 3:    Operator `born` ran in 0.63 s
      From worker 2:    Operator `gradient` ran in 0.31 s
      From worker 3:    Operator `gradient` ran in 0.31 s
      From worker 2:    Operator `born` ran in 0.70 s
      From worker 3:    Operator `born` ran in 0.70 s
      From worker 2:    Operator `gradient` ran in 0.39 s
      From worker 3:    Operator `gradient` ran in 0.40 s
      From worker 2:    Operator `born` ran in 0.37 s
      From worker 2:    Operator `gradient` ran in 0.31 s
      From worker 3:    Operator `born` ran in 0.49 s
      From worker 3:    Operator `gradient` ran in 0.26 s
      From worker 2:    Operator `born` ran in 0.37 s
      From worker 2:    Operator `gradient` ran in 0.53 s
      From worker 3:    Operator `born` ran in 0.65 s
      From worker 3:    Operator `gradient` ran in 0.23 s
      From worker 2:    UNHANDLED TASK ERROR: On worker 1:
      From worker 2:    On worker 3:
      From worker 2:    peer 2 has not connected to 3
      From worker 2:    Stacktrace:
      From worker 2:     [1] error
      From worker 2:       @ ./error.jl:33
      From worker 2:     [2] wait_for_conn
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:192
      From worker 2:     [3] #23
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:180
      From worker 2:     [4] exec_conn_func
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:181
      From worker 2:     [5] exec_conn_func
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:175
      From worker 2:     [6] #106
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:278
      From worker 2:     [7] run_work_thunk
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:63
      From worker 2:     [8] macro expansion
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:278 [inlined]
      From worker 2:     [9] #105
      From worker 2:       @ ./task.jl:423
      From worker 2:    Stacktrace:
      From worker 2:     [1] #remotecall_fetch#155
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:469
      From worker 2:     [2] remotecall_fetch
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:461 [inlined]
      From worker 2:     [3] #remotecall_fetch#158
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:496 [inlined]
      From worker 2:     [4] remotecall_fetch
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:496 [inlined]
      From worker 2:     [5] #19
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:167
      From worker 2:     [6] #106
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:278
      From worker 2:     [7] run_work_thunk
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:63
      From worker 2:     [8] macro expansion
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:278 [inlined]
      From worker 2:     [9] #105
      From worker 2:       @ ./task.jl:423
      From worker 2:    Stacktrace:
      From worker 2:     [1] remotecall_fetch(::Function, ::Distributed.Worker, ::Int64, ::Vararg{Int64}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
      From worker 2:       @ Distributed ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:469
      From worker 2:     [2] remotecall_fetch
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:461 [inlined]
      From worker 2:     [3] #remotecall_fetch#158
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:496 [inlined]
      From worker 2:     [4] remotecall_fetch
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:496 [inlined]
      From worker 2:     [5] (::Distributed.var"#18#21"{Distributed.Worker})()
      From worker 2:       @ Distributed ./task.jl:423
      From worker 2:    UNHANDLED TASK ERROR: On worker 1:
      From worker 2:    On worker 3:
      From worker 2:    peer 2 has not connected to 3
      From worker 2:    Stacktrace:
      From worker 2:     [1] #24
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:183
      From worker 2:     [2] exec_conn_func
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:181
      From worker 2:     [3] exec_conn_func
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:175
      From worker 2:     [4] #106
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:278
      From worker 2:     [5] run_work_thunk
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:63
      From worker 2:     [6] macro expansion
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:278 [inlined]
      From worker 2:     [7] #105
      From worker 2:       @ ./task.jl:423
      From worker 2:    Stacktrace:
      From worker 2:     [1] #remotecall_fetch#155
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:469
      From worker 2:     [2] remotecall_fetch
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:461 [inlined]
      From worker 2:     [3] #remotecall_fetch#158
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:496 [inlined]
      From worker 2:     [4] remotecall_fetch
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:496 [inlined]
      From worker 2:     [5] #19
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:167
      From worker 2:     [6] #106
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:278
      From worker 2:     [7] run_work_thunk
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:63
      From worker 2:     [8] macro expansion
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:278 [inlined]
      From worker 2:     [9] #105
      From worker 2:       @ ./task.jl:423
      From worker 2:    Stacktrace:
      From worker 2:     [1] remotecall_fetch(::Function, ::Distributed.Worker, ::Int64, ::Vararg{Int64}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
      From worker 2:       @ Distributed ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:469
      From worker 2:     [2] remotecall_fetch
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:461 [inlined]
      From worker 2:     [3] #remotecall_fetch#158
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:496 [inlined]
      From worker 2:     [4] remotecall_fetch
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:496 [inlined]
      From worker 2:     [5] (::Distributed.var"#18#21"{Distributed.Worker})()
      From worker 2:       @ Distributed ./task.jl:423
      From worker 2:    UNHANDLED TASK ERROR: On worker 1:
      From worker 2:    On worker 3:
      From worker 2:    peer 2 has not connected to 3
      From worker 2:    Stacktrace:
      From worker 2:     [1] #24
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:183
      From worker 2:     [2] exec_conn_func
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:181
      From worker 2:     [3] exec_conn_func
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:175
      From worker 2:     [4] #106
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:278
      From worker 2:     [5] run_work_thunk
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:63
      From worker 2:     [6] macro expansion
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:278 [inlined]
      From worker 2:     [7] #105
      From worker 2:       @ ./task.jl:423
      From worker 2:    Stacktrace:
      From worker 2:     [1] #remotecall_fetch#155
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:469
      From worker 2:     [2] remotecall_fetch
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:461 [inlined]
      From worker 2:     [3] #remotecall_fetch#158
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:496 [inlined]
      From worker 2:     [4] remotecall_fetch
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:496 [inlined]
      From worker 2:     [5] #19
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/cluster.jl:167
      From worker 2:     [6] #106
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:278
      From worker 2:     [7] run_work_thunk
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:63
      From worker 2:     [8] macro expansion
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/process_messages.jl:278 [inlined]
      From worker 2:     [9] #105
      From worker 2:       @ ./task.jl:423
      From worker 2:    Stacktrace:
      From worker 2:     [1] remotecall_fetch(::Function, ::Distributed.Worker, ::Int64, ::Vararg{Int64}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
      From worker 2:       @ Distributed ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:469
      From worker 2:     [2] remotecall_fetch
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:461 [inlined]
      From worker 2:     [3] #remotecall_fetch#158
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:496 [inlined]
      From worker 2:     [4] remotecall_fetch
      From worker 2:       @ ~/GATechBundle/Julia/julia-1.7.1/share/julia/stdlib/v1.7/Distributed/src/remotecall.jl:496 [inlined]
      From worker 2:     [5] (::Distributed.var"#18#21"{Distributed.Worker})()
      From worker 2:       @ Distributed ./task.jl:423
(576634.4f0, PhysicalParameter{Float32}[[-14.895155, -34.88797, -52.451332, -54.490524, -35.469727, -1.2343807, 37.44786, 72.84346, 102.36653, 126.52875  …  0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [-14.895113, -34.887924, -52.451294, -54.490498, -35.46977, -1.2344112, 37.447815, 72.8434, 102.36653, 126.528915  …  0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])

Note that the error doesn't occur when model size n is small, nor first generate dobs by forward modelling and then do lsrtm_objective.

Any idea what causes the error?

MFE: JUDI's boundary function fails in test_adjoint_J from Devito

This MFE is related with PR #95 .
I could notice that the boundary from JUDI fails in test_adjoint_J in Devito.
I only brought the initialize_damp from JUDI to Devito and ran the test.
We create a MFE mfe.txt to show that issue.
You can run the MFE as:
python mfe.py -d devito
to run the test_adjoint_J with initialize_damp from Devito.
And
python mfe.py -d judi
to run the test_adjoint_J with initialize_damp from JUDI.

So considering this fact, could we create a damp_kernel so that we could keep the two functions? I suggest this because I would like to have the viscoacoustic operators pass the tests like in Devito.

LoadError: MethodError: no method matching Array{Float32,1}(::Float32)

Hi, when I run the the following example,

/examples/compressive_splsrtm/Sigsbee2A/generate_data_sigsbee.jl

the error persists.

ERROR: LoadError: MethodError: no method matching Array{Float32,1}(::Float32)
Closest candidates are:
Array{Float32,1}() where T at boot.jl:424
Array{Float32,1}(!Matched::UndefInitializer, !Matched::Int64) where T at boot.jl:405
Array{Float32,1}(!Matched::UndefInitializer, !Matched::Int64...) where {T, N} at boot.jl:411
...
Stacktrace:
[1] (::JUDI.var"#26#29"{Array{Float32,1},Float32})(::Int64) at ./none:0
[2] iterate at ./generator.jl:47 [inlined]
[3] collect at ./array.jl:665 [inlined]
[4] Geometry(::Array{Array{Array{Float32,1},1},1}, ::Array{Float32,1}, ::Array{Array{Array{Float32,1},1},1}; dt::Float32, t::Float32) at /public/home/dongshiqi/.julia/packages/JUDI/BG8kx/src/TimeModeling/Types/GeometryStructure.jl:139
[5] Geometry(::Array{Any,1}, ::Array{Any,1}, ::Array{Any,1}; dt::Float32, t::Float32, nsrc::Nothing) at /public/home/dongshiqi/.julia/packages/JUDI/BG8kx/src/TimeModeling/Types/GeometryStructure.jl:127
[6] top-level scope at /public/home/dongshiqi/.julia/environments/v1.4/generate_data_sigsbee.jl:72
[7] include(::Module, ::String) at ./Base.jl:377
[8] exec_options(::Base.JLOptions) at ./client.jl:288
[9] _start() at ./client.jl:484
in expression starting at /public/home/dongshiqi/.julia/environments/v1.4/generate_data_sigsbee.jl:72

Do you have any suggestion for this please? I guess it may be caused by a version update.Thank you very much.

Output size of rrule is not the same as the size of the variable

MFE is here

using JUDI
using ArgParse, Test, Printf, Aqua
using SegyIO, LinearAlgebra, Distributed, JOLI
using TimerOutputs: TimerOutputs, @timeit
using Flux

# JUDI seismic utils
include(joinpath(JUDIPATH,"../test/seismic_utils.jl"))

### Model
nsrc = 1
dt = 1f0

model, model0, dm = setup_model(false, false, 4)
m, m0 = model.m.data, model0.m.data
q, srcGeometry, recGeometry, f0 = setup_geom(model; nsrc=nsrc, dt=dt)

# Common op
F = judiModeling(model, srcGeometry, recGeometry)
d_obs = F*q

g = gradient(Flux.params(m0)) do
    ϕ = .5f0*norm(F(m0, q) - d_obs)^2
    return ϕ
end

## problem
println(size(m0)) # (301, 151)
println(size(g.grads[m0])) # (45451, 1)

### MFE starts now
v0 = sqrt.(1f0./m0)

gv = gradient(Flux.params(v0)) do
    ϕ = .5f0*norm(F((1f0./v0).^2f0, q) - d_obs)^2
    return ϕ
end

As you can see in the first example, these two got different sizes

println(size(m0)) # (301, 151)
println(size(g.grads[m0])) # (45451, 1)

thus when working with v0 = sqrt.(1f0./m0), there is a shape mismatch error

ERROR: LoadError: DimensionMismatch("variable with size(x) == (301, 151) cannot have a gradient with size(dx) == (45451,)")
Stacktrace:
  [1] (::ChainRulesCore.ProjectTo{AbstractArray, NamedTuple{(:element, :axes), Tuple{ChainRulesCore.ProjectTo{Float32, NamedTuple{(), Tuple{}}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}}})(dx::Vector{Float32})
    @ ChainRulesCore ~/.julia/packages/ChainRulesCore/RbX5a/src/projection.jl:227
  [2] _project
    @ ~/.julia/packages/Zygote/ytjqm/src/compiler/chainrules.jl:183 [inlined]
  [3] unbroadcast(x::Matrix{Float32}, x̄::Vector{Float32})
    @ Zygote ~/.julia/packages/Zygote/ytjqm/src/lib/broadcast.jl:51
  [4] map
    @ ./tuple.jl:247 [inlined]
  [5] (::Zygote.var"#∇broadcasted#1106"{Tuple{Matrix{Float32}, Float32}, Matrix{Tuple{Float32, Zygote.ZBack{ChainRules.var"#power_pullback#1212"{Float32, Float32, ChainRulesCore.ProjectTo{Float32, NamedTuple{(), Tuple{}}}, ChainRulesCore.ProjectTo{Float32, NamedTuple{(), Tuple{}}}, Float32}}}}, Val{3}})(ȳ::PhysicalParameter{Float32})
    @ Zygote ~/.julia/packages/Zygote/ytjqm/src/lib/broadcast.jl:198
  [6] #4012#back
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:67 [inlined]
  [7] #212
    @ ~/.julia/packages/Zygote/ytjqm/src/lib/lib.jl:203 [inlined]
  [8] #1750#back
    @ ~/.julia/packages/ZygoteRules/AIbCs/src/adjoint.jl:67 [inlined]
  [9] Pullback
    @ ./broadcast.jl:1303 [inlined]
 [10] (::typeof((broadcasted)))(Δ::PhysicalParameter{Float32})
    @ Zygote ~/.julia/packages/Zygote/ytjqm/src/compiler/interface2.jl:0
 [11] Pullback
    @ ~/Desktop/FNO4CO2/scripts/MFE.jl:35 [inlined]
 [12] (::typeof((#8)))(Δ::Float32)
    @ Zygote ~/.julia/packages/Zygote/ytjqm/src/compiler/interface2.jl:0
 [13] (::Zygote.var"#93#94"{Zygote.Params{Zygote.Buffer{Any, Vector{Any}}}, typeof((#8)), Zygote.Context})(Δ::Float32)
    @ Zygote ~/.julia/packages/Zygote/ytjqm/src/compiler/interface.jl:357
 [14] gradient(f::Function, args::Zygote.Params{Zygote.Buffer{Any, Vector{Any}}})
    @ Zygote ~/.julia/packages/Zygote/ytjqm/src/compiler/interface.jl:76
 [15] top-level scope
    @ ~/Desktop/FNO4CO2/scripts/MFE.jl:34
 [16] include(fname::String)
    @ Base.MainInclude ./client.jl:451
 [17] top-level scope
    @ REPL[1]:1
in expression starting at /Users/francisyin/Desktop/FNO4CO2/scripts/MFE.jl:34

overload DepthScaling and Topmute operators for PhysicalParameter?

Would it make sense to overload depth scaling and top mute operators? Now the default operation of depth scaling on physical parameter is given in https://github.com/slimgroup/JUDI.jl/blob/f22170d3709bf9f4320190b6915d063570c7e003/src/TimeModeling/ModelStructure.jl#L216 where it directly outputs Julia array. So I guess we can define the operation of depth scaling directly on physical parameters, then follow what we've done for judiWeights https://github.com/slimgroup/JUDI.jl/blob/f22170d3709bf9f4320190b6915d063570c7e003/src/TimeModeling/judiWeights.jl#L203 so that it remains the data structure instead of outputting Julia arrays.

lsrtm_objective does not produce the same gradient as is produced by Jacobians

I compared ways to get gradients in LS-RTM

  1. Use lsrtm_objective.
  2. Do linear algebras by judiJacobian operator.

and they produce different results. However, there is no problem when x is all 0. The script is shown below.

Also a small thing: J[1] works by J[[1]] produces error at

function subsample(geometry::GeometryIC,srcnum)
because of unsupported keyword arguments.

using PyPlot
using Random, Images, JLD2, LinearAlgebra
using JOLI, Statistics
using JUDI
Random.seed!(1234)

n = (101,101)
d = (12.5f0,12.5f0)
o = (0f0, 0f0)
v = 1.5*ones(Float32,n)
v[:,19:end] .= 2.5f0
v[:,40:end] .= 3f0
v[:,60:end] .= 3.5f0
m = 1f0./v.^2f0
m0 = convert(Array{Float32,2},imfilter(m, Kernel.gaussian(4)))

model0 = Model(n,d,o,m0;nb=80)

nsrc = 1
nrec = n[1]

dtS = dtR = 1f0
timeS = timeR = 2000f0

xsrc = convertToCell(range((n[1]-1)*d[1]/2,stop=(n[1]-1)*d[1]/2,length=nsrc))
ysrc = convertToCell(range(0f0,stop=0f0,length=nsrc))
zsrc = convertToCell(range(17*d[2]-2f0,stop=17*d[2]-2f0,length=nsrc))

srcGeometry = Geometry(xsrc, ysrc, zsrc; dt=dtS, t=timeS)
wavelet = ricker_wavelet(timeS,dtS,0.012f0)

q = judiVector(srcGeometry, wavelet)

xrec = range(d[1],stop=(n[1]-1)*d[1],length=nrec)
yrec = 0f0
zrec = range(10f0,stop=10f0,length=nrec)

recGeometry = Geometry(xrec,yrec,zrec; dt=dtR, t=timeR, nsrc=nsrc)

ntComp = get_computational_nt(srcGeometry, recGeometry, model0)
info = Info(prod(n), nsrc, ntComp)

opt = Options(isic=true)

F0 = judiProjection(info, recGeometry)*judiModeling(info, model0; options=opt)*adjoint(judiProjection(info, srcGeometry))
J = judiJacobian(F0,q)
dlin = J*vec(m-m0)

x = J'*dlin

phi1, g1 = lsrtm_objective(model0, q, dlin, x; nlind=false,options=opt)
g1 = vec(g1)
d_res = J*x-dlin
g = J'*d_res
g = vec(g.data)
phi = 0.5f0 * norm(d_res)^2
 
println("misfit in g = ", norm(g1-g)/norm(g1+g)) ## problem here
println("misfit in phi = ", norm(phi1-phi)/norm(phi1+phi)) ## problem here
 
x1 = zeros(Float32, prod(n))

phi1, g1 = lsrtm_objective(model0, q, dlin, x1; nlind=false,options=opt)
g1 = vec(g1)
d_res = J*x1-dlin
g = J'*d_res
g = vec(g.data)
phi = 0.5f0 * norm(d_res)^2
 
println("misfit in g = ", norm(g1-g)/norm(g1+g))    ## no problem here
println("misfit in phi = ", norm(phi1-phi)/norm(phi1+phi))  ## no problem here

JUDI DepthScaling is in-place now

JUDI Depth Scaling operator is in-place right now, which should not be the case! A minimal failing example is here

using JUDI.TimeModeling, LinearAlgebra, JOLI, Test, Printf
# Set up model structure
n = (401, 401)   # (x,y,z) or (x,z)
d = (2.5f0, 2.5f0)
o = (0f0, 0f0)

# Velocity [km/s]
v0 = 2f0*ones(Float32,n)
v = deepcopy(v0);
v[201,201] = 3f0;

# Slowness squared [s^2/km^2]
m = (1f0 ./ v).^2
m0 = (1f0 ./ v0).^2
dm = vec(m0-m)

# Setup info and model structure	# number of sources
model0 = Model(n, d, o, m0; nb = 200)

dm1 = deepcopy(dm)

S = judiDepthScaling(model0)

dm2 = S*dm

@test isapprox(dm1,dm)

The problem is at

, it should be

m = copy(reshape(m,model.n))

I am going to fix this with a PR and add a test case to it.

Forward modeling error

MFE is

using JUDI
using LinearAlgebra

n = (50, 50)
d = (10f0, 10f0)
o = (0f0, 0f0)
v = 1.5f0 * ones(Float32, n)
m = 1f0./v.^2f0

model = Model(n,d,o,m; nb=80)

nsrc = 3
nrec = 50

dtS = dtR = 4f0
timeS = timeR = 1000f0

xsrc = convertToCell([100f0, 200f0, 300f0])
ysrc = convertToCell(range(0f0,stop=0f0,length=nsrc))
zsrc = convertToCell(range(10f0,stop=10f0,length=nrec))

srcGeometry = Geometry(xsrc, ysrc, zsrc; dt=dtS, t=timeS)
wavelet = ricker_wavelet(timeS,dtS,0.015f0)

q = judiVector(srcGeometry, wavelet)

xrec = range(d[1],stop=(n[1]-1)*d[1],length=nrec)
yrec = 0f0
zrec = range(10f0, stop=10f0, length=nrec)

recGeometry = Geometry(xrec,yrec,zrec; dt=dtR, t=timeR, nsrc=nsrc)

ntComp = get_computational_nt(srcGeometry, recGeometry, model)
info = Info(prod(n), nsrc, ntComp)

opt = Options()

F = judiProjection(info, recGeometry)*judiModeling(info, model; options=opt)*adjoint(judiProjection(info, srcGeometry))

dobs = F*q

println(norm(dobs.data[2]-dobs.data[3])) # this is 0

It works fine with 2 sources but when it goes to 3 sources, the 2nd and 3rd shot records are exactly the same. I'll look into how the new parallel strategy affected this (possibly the error comes from #71 )

marmousi_2D

Could you offer marmousi_2D model to me?
run(wget ftp://slim.eos.ubc.ca/data/SoftwareRelease/Imaging.jl/2DLSRTM/marmousi_2D.segy)
run(wgetftp://slim.eos.ubc.ca/data/SoftwareRelease/Imaging.jl/2DLSRTM/marmousi_migration_velocity.h5)
these address I can't open them, my email:[email protected]

jo_convert does not accept judiVector -- only work with AbstractArray

Hi, the following example shows that there is a problem with
scalar * joLinearFunction * judiVector
mainly because of this line
https://github.com/slimgroup/JOLI.jl/blob/102f99538cced8072818859e14f6b22fb52c02e6/src/joAbstractLinearOperator/base_functions.jl#L215
where jo_convert function cannot take judiVector as an input. It only accepts AbstractArray. So I am thinking of if it is reasonable to simply change this line

mutable struct judiVector{vDT<:Number} <: joAbstractLinearOperator{vDT,vDT}
to

mutable struct judiVector{vDT<:Number} <: AbstractArray{vDT}

so that then judiVector could fit with JOLI (or any other AbstractArray based package). But I don't know if it is a good idea to do so and how much work we have to do.

Right now I just do scalar * (joLinearFunction * judiVector) in my code so that it does not raise an error, but this still hides the problem and is not friendly to future users.

using Random, JUDI.TimeModeling, JOLI

n = (201, 201)   # (x,y,z) or (x,z)
d = (5f0, 5f0)
o = (0f0, 0f0)
v = 2f0*ones(Float32,n)
m = convert(Array{Float32,2},(1f0 ./ v).^2)	# true model

model = Model(n, d, o, m)

nsrc = 2
nrec = n[1]

xrec = range(0f0, stop=Float32((n[1]-1)*d[1]), length=nrec)
yrec = 0f0
zrec = range(14f0, stop=14f0, length=nrec)

timeR = 4000f0
dtR   = 4f0
ntR = 1001

recGeometry = Geometry(xrec, yrec, zrec; dt=dtR, t=timeR, nsrc=nsrc)

M = judiMarineTopmute2D(10,recGeometry)

data = Array{Array}(undef, nsrc)
for j=1:nsrc
    data[j] = randn(Float32, ntR, nrec)
end

d_obs = judiVector(recGeometry,data)

result = 2*M*d_obs
julia> include("mfe.jl")
ERROR: LoadError: MethodError: no method matching jo_convert(::Type{Float32}, ::judiVector{Float32}, ::Bool)
Closest candidates are:
  jo_convert(::DataType, ::AbstractArray{VT,N} where N, ::Bool) where VT<:Integer at /Users/francisyin/.julia/dev/JOLI/src/joUtils.jl:368
  jo_convert(::DataType, ::AbstractArray{VT,N} where N, ::Bool) where VT<:AbstractFloat at /Users/francisyin/.julia/dev/JOLI/src/joUtils.jl:382
  jo_convert(::DataType, ::AbstractArray{VT,N} where N, ::Bool) where VT<:Complex at /Users/francisyin/.julia/dev/JOLI/src/joUtils.jl:392
  ...
Stacktrace:
 [1] (::JOLI.var"#181#185"{Float32,Int64,joLinearFunction{Float32,Float32}})(::judiVector{Float32}) at /Users/francisyin/.julia/dev/JOLI/src/joAbstractLinearOperator/base_functions.jl:215
 [2] *(::joLinearOperator{Float32,Float32}, ::judiVector{Float32}) at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/judiVector.jl:394
 [3] *(::Int64, ::joLinearFunction{Float32,Float32}, ::judiVector{Float32}) at ./operators.jl:538
 [4] top-level scope at /Users/francisyin/Desktop/mfe.jl:33
 [5] include(::String) at ./client.jl:457
 [6] top-level scope at REPL[1]:1
in expression starting at /Users/francisyin/Desktop/mfe.jl:33

miniConf Library

I was trying to implement the example with the Overthrust model and everything is working well until the last line of code, where I need to use the miniConf_SPG library. This gives me an error, it seems like it can't find this library. How can I fix this? Am I missing something?

Thank you for your help!

ERROR: LoadError: MethodError: no method matching SlimOptim.BregmanParams

Hello,

I've tried denoising example from:
https://slimgroup.github.io/SlimOptim.jl/dev/tutorials/01_denoising/

With BergmanParams specified, it produces the following error:

ERROR: LoadError: MethodError: no method matching SlimOptim.BregmanParams(::Int64, ::Float64, ::Int64, ::Bool, ::Bool, ::Float64)
Closest candidates are:
SlimOptim.BregmanParams(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any) at ~/.julia/packages/SlimOptim/rFROp/src/bregman.jl:5

I've tried opt = SlimOptim.BregmanParams(1, 1e-6, 1e-8, 20, false, .5, .25, false) as well,
but the same error is produced.

Without specifying the parameter option though, it works.

I was wondering if you could advise me how to solve this issue.

Thank you,

All examples fail to run the function `setup_3D_grid`

Hi,

When I try to run any example that uses setup_3D_grid I get error. For example if I run modeling_basic_3D.jl:

# Set up 3D receiver geometry by defining one receiver vector in each x and y direction
nxrec = 120
nyrec = 100
xrec = range(50f0, stop=1150f0, length=nxrec)
yrec = range(100f0, stop=900f0, length=nyrec)
zrec = 50f0

# Construct 3D grid from basis vectors
(xrec, yrec, zrec) = setup_3D_grid(xrec, yrec, zrec)

and the error:

ERROR: LoadError: BoundsError: attempt to access 1-element Vector{Float32} at index [2]
Stacktrace:
 [1] getindex
   @ ./array.jl:805 [inlined]
 [2] setup_3D_grid(xrec::Vector{Vector{Float32}}, yrec::Vector{Vector{Float32}}, zrec::Vector{Float32})
   @ JUDI ~/.julia/packages/JUDI/fPPVi/src/TimeModeling/Utils/auxiliaryFunctions.jl:448
 [3] setup_3D_grid(xrec::StepRangeLen{Float32, Float64, Float64}, yrec::StepRangeLen{Float32, Float64, Float64}, zrec::Float32)
   @ JUDI ~/.julia/packages/JUDI/fPPVi/src/TimeModeling/Utils/auxiliaryFunctions.jl:487
 [4] top-level scope
   @ ~/Documents/mytest.jl:43
in expression starting at ~/Documents/mytest.jl:43

I think that something is wrong with the overloaded function setup_3D_grid.

It is possible to pass the rec positions if they were are arrays:

xrec = Array{Float32, 1}(range(50f0, stop=1150f0, length=nxrec))
yrec = Array{Float32, 1}(range(100f0, stop=900f0, length=nyrec))
zrec = 50f0

(xrec, yrec, zrec) = setup_3D_grid(xrec, yrec, zrec)

This way it works

JUDI version: 2.6.1

Failed to run `modeling_basic_2D` example (JUDI 3.1.4)

Hi,

When simply trying to run modeling_basic_2D example an error is arised:

ERROR: PyError ($(Expr(:escape, :(ccall(#= /home/kerim/Documents/Colada/d/julia-1.6/.julia/packages/PyCall/7a7w0/src/pyfncall.jl:43 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'TypeError'>
TypeError('object.__new__() takes exactly one argument (the type to instantiate)')
  File "/home/kerim/Documents/Colada/d/julia-1.6/.julia/packages/JUDI/jk3ff/src/pysource/models.py", line 172, in __init__
    initialize_damp(self.damp, self.padsizes, abc_type=abc_type, fs=fs)
  File "/home/kerim/Documents/Colada/d/python-install/lib/python3.9/site-packages/devito/parameters.py", line 249, in wrapper
    result = func(*args, **kwargs)
  File "/home/kerim/Documents/Colada/d/julia-1.6/.julia/packages/JUDI/jk3ff/src/pysource/models.py", line 106, in initialize_damp
    op = damp_op(damp.grid.dim, padsizes, abc_type, fs)
  File "/home/kerim/Documents/Colada/d/python-install/lib/python3.9/site-packages/devito/tools/memoization.py", line 33, in __call__
    value = self.func(*args)
  File "/home/kerim/Documents/Colada/d/julia-1.6/.julia/packages/JUDI/jk3ff/src/pysource/models.py", line 83, in damp_op
    return Operator(eqs, name='initdamp')
  File "/home/kerim/Documents/Colada/d/python-install/lib/python3.9/site-packages/devito/operator/operator.py", line 146, in __new__
    kwargs = parse_kwargs(**kwargs)
  File "/home/kerim/Documents/Colada/d/python-install/lib/python3.9/site-packages/devito/operator/operator.py", line 977, in parse_kwargs
    kwargs['compiler'] = configuration['compiler'].__new_with__()
  File "/home/kerim/Documents/Colada/d/python-install/lib/python3.9/site-packages/devito/arch/compiler.py", line 190, in __new_with__
    return self.__class__(suffix=kwargs.pop('suffix', self.suffix),
  File "/home/kerim/Documents/Colada/d/python-install/lib/python3.9/site-packages/devito/arch/compiler.py", line 615, in __new__
    obj = super().__new__(cls, *args, **kwargs)

Stacktrace:
  [1] pyerr_check
    @ ~/Documents/Colada/d/julia-1.6/.julia/packages/PyCall/7a7w0/src/exception.jl:62 [inlined]
  [2] pyerr_check
    @ ~/Documents/Colada/d/julia-1.6/.julia/packages/PyCall/7a7w0/src/exception.jl:66 [inlined]
  [3] _handle_error(msg::String)
    @ PyCall ~/Documents/Colada/d/julia-1.6/.julia/packages/PyCall/7a7w0/src/exception.jl:83
  [4] macro expansion
    @ ~/Documents/Colada/d/julia-1.6/.julia/packages/PyCall/7a7w0/src/exception.jl:97 [inlined]
  [5] #107
    @ ~/Documents/Colada/d/julia-1.6/.julia/packages/PyCall/7a7w0/src/pyfncall.jl:43 [inlined]
  [6] disable_sigint
    @ ./c.jl:458 [inlined]
  [7] __pycall!
    @ ~/Documents/Colada/d/julia-1.6/.julia/packages/PyCall/7a7w0/src/pyfncall.jl:42 [inlined]
  [8] _pycall!(ret::PyCall.PyObject, o::PyCall.PyObject, args::Tuple{Tuple{Float64, Float64}, Tuple{Float64, Float64}, Tuple{Int64, Int64}, PyCall.PyObject}, nargs::Int64, kw::PyCall.PyObject)
    @ PyCall ~/Documents/Colada/d/julia-1.6/.julia/packages/PyCall/7a7w0/src/pyfncall.jl:29
  [9] _pycall!(ret::PyCall.PyObject, o::PyCall.PyObject, args::Tuple{Tuple{Float64, Float64}, Tuple{Float64, Float64}, Tuple{Int64, Int64}, PyCall.PyObject}, kwargs::Base.Iterators.Pairs{Symbol, Union{Nothing, Real}, NTuple{5, Symbol}, NamedTuple{(:fs, :nbl, :space_order, :dt, :dm), Tuple{Bool, Int64, Int64, Float64, Nothing}}})
    @ PyCall ~/Documents/Colada/d/julia-1.6/.julia/packages/PyCall/7a7w0/src/pyfncall.jl:11
 [10] (::PyCall.PyObject)(::Tuple{Float64, Float64}, ::Vararg{Any, N} where N; kwargs::Base.Iterators.Pairs{Symbol, Union{Nothing, Real}, NTuple{5, Symbol}, NamedTuple{(:fs, :nbl, :space_order, :dt, :dm), Tuple{Bool, Int64, Int64, Float64, Nothing}}})
    @ PyCall ~/Documents/Colada/d/julia-1.6/.julia/packages/PyCall/7a7w0/src/pyfncall.jl:86
 [11] devito_model(model::Model, options::JUDIOptions, dm::Nothing)
    @ JUDI ~/Documents/Colada/d/julia-1.6/.julia/packages/JUDI/jk3ff/src/TimeModeling/Utils/auxiliaryFunctions.jl:31
 [12] time_modeling(model_full::Model, srcGeometry::GeometryIC{Float32}, srcData::Matrix{Float32}, recGeometry::GeometryIC{Float32}, recData::Nothing, dm::Nothing, op::Symbol, options::JUDIOptions)
    @ JUDI ~/Documents/Colada/d/julia-1.6/.julia/packages/JUDI/jk3ff/src/TimeModeling/Modeling/time_modeling_serial.jl:33
 [13] propagate(F::judiDataSourceModeling{Float32, :forward}, q::judiVector{Float32, Matrix{Float32}})
    @ JUDI ~/Documents/Colada/d/julia-1.6/.julia/packages/JUDI/jk3ff/src/TimeModeling/Modeling/propagation.jl:9
 [14] run_and_reduce(func::Function, #unused#::Nothing, nsrc::Int64, arg_func::JUDI.var"#196#197"{judiDataSourceModeling{Float32, :forward}, judiVector{Float32, Matrix{Float32}}})
    @ JUDI ~/Documents/Colada/d/julia-1.6/.julia/packages/JUDI/jk3ff/src/TimeModeling/Modeling/propagation.jl:37
 [15] multi_src_propagate(F::judiDataSourceModeling{Float32, :forward}, q::judiVector{Float32, Matrix{Float32}})
    @ JUDI ~/Documents/Colada/d/julia-1.6/.julia/packages/JUDI/jk3ff/src/TimeModeling/Modeling/propagation.jl:66
 [16] *
    @ ~/Documents/Colada/d/julia-1.6/.julia/packages/JUDI/jk3ff/src/TimeModeling/LinearOperators/operators.jl:172 [inlined]
 [17] afoldl
    @ ./operators.jl:533 [inlined]
 [18] *(a::judiProjection{Float32}, b::judiModeling{Float32, :forward}, c::JUDI.jAdjoint{judiProjection{Float32}}, xs::judiVector{Float32, Matrix{Float32}})
    @ Base ./operators.jl:560
 [19] top-level scope
    @ ~/Documents/Colada/d/julia-1.6/.julia/dev/JUDI/examples/scripts/modeling_basic_2D.jl:123

I believe this happen on the line dobs = PrFadjoint(Ps)*q

JUDI 3.1.4
PyCall 1.93.1
Ubuntu 20.04

Simultaneous source experiment?

Hi,

I am following the tutorial at https://slimgroup.github.io/JUDI.jl/tutorials/#simultaneous-sources to make simultaneous shot experiment -- firing 4 sources. However, I met some error. Could anyone take a look? Thanks

My code is

using JUDI.TimeModeling

n=(301, 151)
d=(10., 10.)
o = (0., 0.)	
    
v = ones(Float32,n) .* 1.5f0	
v[:,100:end] .= 2f0

m = (1f0 ./ v).^2

model = Model(n, d, o, m)

nsrc = 1    # single simultaneous source
xsrc = Array{Any}(undef, nsrc)
ysrc = Array{Any}(undef, nsrc)
zsrc = Array{Any}(undef, nsrc)

# Set up source geometry
xsrc[1] = [250f0, 500f0, 750f0, 1000f0]     # four simultaneous sources
ysrc[1] = 0f0
zsrc[1] = [50f0, 50f0, 50f0, 50f0]  

# Source sampling and number of time steps
time = 2000f0
dt = 4f0

# Set up source structure
src_geometry = Geometry(xsrc, ysrc, zsrc; dt=dt, t=time)

# Create wavelet
f0 = 0.01   # source peak frequencies
q = ricker_wavelet(500f0, dt, f0)  # 500 ms wavelet

# Create array with different time shifts of the wavelet
wavelet = zeros(Float32, 4, src_geometry.nt[1])
wavelet[1, 1:1+length(q)-1] = q
wavelet[2, 41:41+length(q)-1] = q
wavelet[3, 121:121+length(q)-1] = q
wavelet[4, 201:201+length(q)-1] = q

# Source wavelet
q = judiVector(src_geometry, wavelet)

ntComp = get_computational_nt(src_geometry, model; dt=dt)
info = Info(prod(model.n), nsrc, ntComp)

Ps = judiProjection(info, src_geometry)
F = judiModeling(info, model)

temp = F*Ps'*q

The error is

julia> include("MFE.jl")
`DEVITO_OPENMP` is deprecated. DEVITO_LANGUAGE=openmp should be used instead
Both `DEVITO_OPENMP` and `DEVITO_LANGUAGE` set. Ignoring `DEVITO_OPENMP`
ERROR: LoadError: DimensionMismatch("A has dimensions (1059,501) but B has dimensions (4,501)")
Stacktrace:
 [1] gemm_wrapper!(::Array{Float64,2}, ::Char, ::Char, ::Array{Float64,2}, ::Array{Float64,2}, ::LinearAlgebra.MulAddMul{true,true,Bool,Bool}) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/LinearAlgebra/src/matmul.jl:569
 [2] mul! at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/LinearAlgebra/src/matmul.jl:169 [inlined]
 [3] mul! at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/LinearAlgebra/src/matmul.jl:208 [inlined]
 [4] * at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.5/LinearAlgebra/src/matmul.jl:160 [inlined]
 [5] SincInterpolation(::Array{Float32,2}, ::StepRangeLen{Float32,Float64,Float64}, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}) at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/auxiliaryFunctions.jl:373
 [6] time_resample(::Array{Float32,2}, ::GeometryIC, ::Float64) at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/auxiliaryFunctions.jl:383
 [7] devito_interface(::PyCall.PyObject, ::Model, ::GeometryIC, ::Array{Array,1}, ::Nothing, ::Nothing, ::Nothing, ::Options) at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/python_interface.jl:66
 [8] time_modeling(::Model, ::GeometryIC, ::Array{Array,1}, ::Nothing, ::Nothing, ::Nothing, ::Int64, ::Char, ::Int64, ::Options) at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/time_modeling_serial.jl:51
 [9] (::JUDI.var"#144#146"{Options,Model})(::Tuple{GeometryIC,Array{Array,1},Nothing,Nothing,Nothing}) at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/judiModeling.jl:80
 [10] *(::judiModeling{Float32,Float32}, ::judiRHS{Float32}) at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/judiModeling.jl:157
 [11] (::JOLI.var"#173#177"{judiModeling{Float32,Float32},judiProjection{Float32,Float32}})(::judiVector{Float32}) at /Users/francisyin/.julia/packages/JOLI/UMvG4/src/joAbstractLinearOperator/base_functions.jl:139
 [12] *(::JOLI.joLinearOperator{Float32,Float32}, ::judiVector{Float32}) at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/judiVector.jl:416
 [13] *(::judiModeling{Float32,Float32}, ::judiProjection{Float32,Float32}, ::judiVector{Float32}) at ./operators.jl:538
 [14] top-level scope at /Users/francisyin/Desktop/PermeabilityToConcentrationNN/MFE.jl:51
 [15] include(::String) at ./client.jl:457
 [16] top-level scope at REPL[1]:1
in expression starting at /Users/francisyin/Desktop/PermeabilityToConcentrationNN/MFE.jl:51

Having trouble modeling with density for some variances.

Varying Density values that trigger rho parameterization give an error. for example this density setup:

using JUDI

n = (120, 100)   # (x,y,z) or (x,z)
d = (10., 10.)
o = (0., 0.)

v = ones(Float32,n) .+ 0.5f0
v[:,Int(round(end/2)):end] .= 3.5f0
rho = ones(Float32,n) ;
rho[1,1] = .09;# error but .1 makes rho go to b and then it is happy

m = (1f0 ./ v).^2

nsrc = 2	# number of sources
model = Model(n, d, o, m;rho=rho)

nxrec = 120
xrec = range(0f0, stop=(n[1]-1)*d[1], length=nxrec)
yrec = 0f0 # WE have to set the y coordiante to zero (or any number) for 2D modeling
zrec = range(d[1], stop=d[1], length=nxrec)
timeD = 1250f0   # receiver recording time [ms]
dtD = 2f0    # receiver sampling interval [ms]
recGeometry = Geometry(xrec, yrec, zrec; dt=dtD, t=timeD, nsrc=nsrc)

xsrc = convertToCell(range(0f0, stop=(n[1]-1)*d[1], length=nsrc))
ysrc = convertToCell(range(0f0, stop=0f0, length=nsrc))
zsrc = convertToCell(range(d[1], stop=d[1], length=nsrc))
srcGeometry = Geometry(xsrc, ysrc, zsrc; dt=dtD, t=timeD)

f0 = 0.01f0     # kHz
wavelet = ricker_wavelet(timeD, dtD, f0)
q = judiVector(srcGeometry, wavelet)

opt = Options(subsampling_factor=2, dt_comp=1.0)

Pr = judiProjection(recGeometry)
F = judiModeling(model; options=opt)
Ps = judiProjection(srcGeometry)

dobs = Pr*F*adjoint(Ps)*q

errors out with this message.

julia> dobs = Pr*F*adjoint(Ps)*q
ERROR: PyError ($(Expr(:escape, :(ccall(#= /home/rorozcom3/.julia/packages/PyCall/7a7w0/src/pyfncall.jl:43 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'ValueError'>
ValueError('Unrecognized argument rho=rho(x, y)')
  File "/home/rorozcom3/.julia/packages/JUDI/XZMNj/src/pysource/interface.py", line 40, in forward_rec
    rec, _, _ = forward(model, src_coords, rec_coords, wavelet, save=False,
  File "/home/rorozcom3/.julia/packages/JUDI/XZMNj/src/pysource/propagators.py", line 57, in forward
    summary = op(**kw)
  File "/home/rorozcom3/.local/lib/python3.8/site-packages/devito/operator/operator.py", line 609, in __call__
    return self.apply(**kwargs)
  File "/home/rorozcom3/.local/lib/python3.8/site-packages/devito/operator/operator.py", line 675, in apply
    args = self.arguments(**kwargs)
  File "/home/rorozcom3/.local/lib/python3.8/site-packages/devito/operator/operator.py", line 557, in arguments
    args = self._prepare_arguments(**kwargs)
  File "/home/rorozcom3/.local/lib/python3.8/site-packages/devito/operator/operator.py", line 442, in _prepare_arguments
    raise ValueError("Unrecognized argument %s=%s" % (k, v))

If this check is true and it gets parameterized by b then the error does not show up.

Unsatisfiable requirements detected for package SegyIO

ERROR: Unsatisfiable requirements detected for package SegyIO [157a0f19]:
SegyIO [157a0f19] log:
├─SegyIO [157a0f19] has no known versions!
└─restricted to versions * by JUDI [f3b833dc] — no versions left
└─JUDI [f3b833dc] log:
├─possible versions are: 1.2.3 or uninstalled
└─JUDI [f3b833dc] is fixed to version 1.2.3

Example from repository main page doesn't work

Hi,

I'm trying to run the example from main repository page and I get the error:

MethodError: no method matching minConf_SPG(::typeof(objective_function), ::PhysicalParameter{Float32}, ::typeof(ProjBound), ::JUDI.SLIM_optim.SPG_params)
Closest candidates are:
  minConf_SPG(::Any, !Matched::Array{vDt,N} where N, ::Any, ::Any) where vDt at /root/.julia/dev/JUDI/src/Optimization/SPGSlim.jl:78

Stacktrace:
 [1] top-level scope at In[6]:25
 [2] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091

at the very last line:

x, fsave, funEvals= minConf_SPG(objective_function, vec(model0.m), ProjBound, options)

I don't have GPU computing on my computer that is why I created Colab notebook with that example and it allows me to launch the code on the cloud. It uses Julia 1.5.0

JudiJacobian

Is it possible to visualize the Jacobian operator in its matrix form? I can only see the data, which is a JudiVector but i cannot see the Jacobian or Forward operator.

Thank you!

Shot record contains low frequency artifacts

Hi,

I am running some codes to generate shot record in a homogenous medium with a band-pass wavelet. However, the shot record contains some strong low frequency artifacts in the middle which look weird to me. I didn't find what is wrong in my code. However, the shot record looks fine if wavelet is Ricker. Could anyone please help explain the shot record? Thanks! Below is my code and some plots of wavelet and shot record. I pulled the latest master branch.

Thanks for helping me out!

using PyPlot, JUDI.TimeModeling, LinearAlgebra, DSP, FFTW

n = (201, 201)   # (x,y,z) or (x,z)
d = (2.5f0, 2.5f0)
o = (0f0, 0f0)

extentx = (n[1]-1)*d[1]
extentz = (n[2]-1)*d[2]

v0 = 1.5f0*ones(Float32,n)

# Slowness squared [s^2/km^2]
m0 = convert(Array{Float32,2},(1f0 ./ v0).^2)

model0 = Model(n, d, o, m0; nb = 80)

# Model structure

dtS = 1f0
timeS = 1000f0
nt = Int64(timeS/dtS)+1

wavelet = zeros(Float32,nt)
wavelet[50] = 1
myfilter = digitalfilter(Bandpass(0.08,0.15),Butterworth(4));
wavelet = filtfilt(myfilter,wavelet)

# Set up receiver geometry

nrec = n[1]

xrec = range(0f0, stop=Float32((n[1]-1)*d[1]), length=nrec)
yrec = 0f0
zrec = range(14f0, stop=14f0, length=nrec)

# receiver sampling and recording time
timeR = timeS   # receiver recording time [ms]
dtR   = dtS 

nsrc = 1

xsrc = convertToCell(range((n[1]-1)*d[1]/2f0, stop=(n[1]-1)*d[1]/2f0, length=nsrc))
ysrc = convertToCell(range(0f0, stop=0f0, length=nsrc))
zsrc = convertToCell(range(9f0, stop=9f0, length=nsrc))

recGeometry = Geometry(xrec, yrec, zrec; dt=dtR, t=timeR, nsrc=nsrc)
srcGeometry = Geometry(xsrc, ysrc, zsrc; dt=dtS, t=timeS)

q = judiVector(srcGeometry, wavelet)

# Set up info structure for linear operators
ntComp = get_computational_nt(srcGeometry, recGeometry, model0)
info = Info(prod(n), nsrc, ntComp)
F0 = judiModeling(info, model0, srcGeometry, recGeometry)

d_obs = F0*q

figure();imshow(d_obs.data[1],aspect="auto");title("shot record")

figure();plot(wavelet);title("wavelet in time domian")
figure();plot(abs.(fftshift(fft(wavelet))));title("wavelet in frequency domain")

shot
wavelet_freq
wavelet_time

RTM in frequency domain result in error

Hi,

I tried to perform RTM in frequency domain but I got an error:

container = segy_scan(prestk_dir, prestk_file, ["SourceX", "SourceY", "GroupX", "GroupY", "RecGroupElevation", "SourceSurfaceElevation", "dt"])
d_obs = judiVector(container; segy_depth_key = "RecGroupElevation")

# Set up wavelet and source vector
src_geometry = Geometry(container; key = "source", segy_depth_key = "SourceSurfaceElevation")
q = judiVector(src_geometry, wavelet)

t_sub = 2

# JUDI options
jopt = JUDI.Options(
    space_order=16,
    limit_m = true,
    buffer_size = buffer_size,
    optimal_checkpointing=false,
    IC = "isic")

# Setup operators
Pr = judiProjection(d_obs.geometry)
F = judiModeling(model0; options=jopt)
Ps = judiProjection(q.geometry)
J = judiJacobian(Pr*F*adjoint(Ps), q)

q_dist = generate_distribution(q)
# Set up random frequencies
nfreq = 20
J.options.frequencies = Array{Any}(undef, d_obs.nsrc)
J.options.dft_subsampling_factor = 8
for k=1:d_obs.nsrc
    J.options.frequencies[k] = select_frequencies(q_dist; fmin=0.003, fmax=0.07, nf=nfreq)
end

# Add random noise
d_lin = get_data(d_obs)
for j=1:d_lin.nsrc
    noise = randn(Float32, size(d_lin.data[j]))
    d_lin.data[j] += (noise/norm(vec(noise), Inf)*0.02f0)
end

# Topmute
d_lin = Ml_ref*d_lin

# RTM
rtm = adjoint(J)*d_lin

and the error:

/tmp/devito-jitcache-uid1000/86c2567d795373c88a9e10272fe3adb595c1c133.c: In function ‘gradient’:
/tmp/devito-jitcache-uid1000/86c2567d795373c88a9e10272fe3adb595c1c133.c:164:28: error: ‘r4’ undeclared (first use in this function); did you mean ‘r14’?
  164 |               float r14 = -r4*ufru[freq_dim][x + 1][y + 1];
      |                            ^~
      |                            r14
/tmp/devito-jitcache-uid1000/86c2567d795373c88a9e10272fe3adb595c1c133.c:164:28: note: each undeclared identifier is reported only once for each function it appears in
/tmp/devito-jitcache-uid1000/86c2567d795373c88a9e10272fe3adb595c1c133.c:165:27: error: ‘r5’ undeclared (first use in this function); did you mean ‘r15’?
  165 |               float r13 = r5*ufiu[freq_dim][x + 1][y + 1];
      |                           ^~
      |                           r15
FAILED compiler invocation:gcc-11 -O3 -g -fPIC -Wall -std=c99 -march=native -Wno-unused-result -Wno-unused-variable -Wno-unused-but-set-variable -ffast-math -shared -fopenmp /tmp/devito-jitcache-uid1000/86c2567d795373c88a9e10272fe3adb595c1c133.c -lm -o /tmp/devito-jitcache-uid1000/86c2567d795373c88a9e10272fe3adb595c1c133.so
/tmp/devito-jitcache-uid1000/3fc5d91317078abb08f733303d1646cbd30c2698.c: In function ‘gradient’:
/tmp/devito-jitcache-uid1000/3fc5d91317078abb08f733303d1646cbd30c2698.c:143:26: error: ‘r4’ undeclared (first use in this function); did you mean ‘r14’?
  143 |             float r14 = -r4*ufru[freq_dim][x + 1][y + 1];
      |                          ^~
      |                          r14
/tmp/devito-jitcache-uid1000/3fc5d91317078abb08f733303d1646cbd30c2698.c:143:26: note: each undeclared identifier is reported only once for each function it appears in
/tmp/devito-jitcache-uid1000/3fc5d91317078abb08f733303d1646cbd30c2698.c:144:25: error: ‘r5’ undeclared (first use in this function); did you mean ‘r15’?
  144 |             float r13 = r5*ufiu[freq_dim][x + 1][y + 1];
      |                         ^~
      |                         r15
FAILED compiler invocation:gcc-11 -O3 -g -fPIC -Wall -std=c99 -march=native -Wno-unused-result -Wno-unused-variable -Wno-unused-but-set-variable -ffast-math -shared -fopenmp /tmp/devito-jitcache-uid1000/3fc5d91317078abb08f733303d1646cbd30c2698.c -lm -o /tmp/devito-jitcache-uid1000/3fc5d91317078abb08f733303d1646cbd30c2698.so
ERROR: /PyErrorH ($(Expr(:escape, :(ccall(#= /home/kerim/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/pyfncall.jl:43 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw)))))D D<class 'codepy.CompileError'>_
2CompileError('module compilation failed')T
B  File "/home/kerim/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/pysource/interface.py", line 353, in J_adjoint
    return J_adjoint_freq(model, src_coords, wavelet, rec_coords, recin, ws=ws,
/  File "/home/kerim/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/pysource/interface.py", line 424, in J_adjoint_freq
    g, Iv, _ = gradient(model, residual, rec_coords, u, space_order=space_order, ic=ic,
V  File "/home/kerim/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/pysource/propagators.py", line 127, in gradient
    summary = op(**kw)
i  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/devito/operator/operator.py", line 686, in __call__
    return self.apply(**kwargs)
k  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/devito/operator/operator.py", line 757, in apply
    cfunction = self.cfunction
i  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/devito/operator/operator.py", line 639, in cfunction
    self._jit_compile()
n  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/devito/operator/operator.py", line 624, in _jit_compile
    recompiled, src_file = self._compiler.jit_compile(self._soname,
g  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/devito/arch/compiler.py", line 319, in jit_compile
    _, _, _, recompiled = compile_from_string(self, target, code, src_file,
G  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/codepy/jit.py", line 433, in compile_from_string
    toolchain.build_extension(ext_file, source_paths, debug=debug)
r  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/codepy/toolchain.py", line 210, in build_extension
    raise CompileError("module compilation failed")
a
Stacktrace:b
e n [1]/ lpyerr_checki
n    @ e~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/12exception.jl/:v62en [inlined]v
/ b [2]i npyerr_check/
julia> urce /mnt/HDD_2TB/VikingGraben/line12/venv/bin/activate

  [3] _handle_error(msg::String)
    @ PyCall ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/exception.jl:83
  [4] macro expansion
    @ ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/exception.jl:97 [inlined]
  [5] #107
    @ ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/pyfncall.jl:43 [inlined]
  [6] disable_sigint
    @ ./c.jl:458 [inlined]
  [7] __pycall!
    @ ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/pyfncall.jl:42 [inlined]
  [8] _pycall!(ret::PyCall.PyObject, o::PyCall.PyObject, args::Tuple{PyCall.PyObject, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}}, nargs::Int64, kw::PyCall.PyObject)
    @ PyCall ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/pyfncall.jl:29
  [9] _pycall!(ret::PyCall.PyObject, o::PyCall.PyObject, args::Tuple{PyCall.PyObject, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}}, kwargs::Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Vector{Float32}, String, Bool, Int64, Float32, Bool}}})
    @ PyCall ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/pyfncall.jl:11
 [10] pycall(::PyCall.PyObject, ::Type{Tuple{PyCall.PyArray, PyCall.PyObject, PyCall.PyObject}}, ::PyCall.PyObject, ::Vararg{Any, N} where N; kwargs::Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Vector{Float32}, String, Bool, Int64, Float32, Bool}}})
    @ PyCall ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/pyfncall.jl:80
 [11] (::JUDI.var"#198#199"{Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Vector{Float32}, String, Bool, Int64, Float32, Bool}}}, PyCall.PyObject, Tuple{PyCall.PyObject, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}}, DataType})()
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/python_interface.jl:52
 [12] (::JUDI.var"#1#2"{JUDI.var"#198#199"{Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Vector{Float32}, String, Bool, Int64, Float32, Bool}}}, PyCall.PyObject, Tuple{PyCall.PyObject, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}}, DataType}})()
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/JUDI.jl:68
 [13] lock(f::JUDI.var"#1#2"{JUDI.var"#198#199"{Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Vector{Float32}, String, Bool, Int64, Float32, Bool}}}, PyCall.PyObject, Tuple{PyCall.PyObject, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}}, DataType}}, l::ReentrantLock)
    @ Base ./lock.jl:187
 [14] pylock(f::JUDI.var"#198#199"{Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Vector{Float32}, String, Bool, Int64, Float32, Bool}}}, PyCall.PyObject, Tuple{PyCall.PyObject, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}}, DataType})
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/JUDI.jl:65
 [15] wrapcall_grad(::PyCall.PyObject, ::PyCall.PyObject, ::Vararg{Any, N} where N; kw::Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Vector{Float32}, String, Bool, Int64, Float32, Bool}}})
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/python_interface.jl:51
 [16] devito_interface(modelPy::PyCall.PyObject, srcGeometry::GeometryIC{Float32}, srcData::Matrix{Float32}, recGeometry::GeometryIC{Float32}, recData::Matrix{Float32}, dm::Nothing, options::JUDIOptions, illum::Bool, fw::Bool)
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/python_interface.jl:143
 [17] time_modeling(model_full::Model, srcGeometry::GeometryOOC{Float32}, srcData::Matrix{Float32}, recGeometry::GeometryOOC{Float32}, recData::Matrix{Float32}, dm::Nothing, op::Symbol, options::JUDIOptions, fw::Bool)
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/time_modeling_serial.jl:39
 [18] propagate(F::judiJacobian{Float32, :adjoint_born, judiDataSourceModeling{Float32, :forward}}, q::judiVector{Float32, Matrix{Float32}})
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/propagation.jl:9
 [19] run_and_reduce(func::Function, #unused#::Nothing, nsrc::Int64, arg_func::JUDI.var"#228#229"{judiJacobian{Float32, :adjoint_born, judiDataSourceModeling{Float32, :forward}}, judiVector{Float32, Matrix{Float32}}})
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/propagation.jl:32
 [20] multi_src_propagate(F::judiJacobian{Float32, :adjoint_born, judiDataSourceModeling{Float32, :forward}}, q::judiVector{Float32, Matrix{Float32}})
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/propagation.jl:67
 [21] *(F::judiJacobian{Float32, :adjoint_born, judiDataSourceModeling{Float32, :forward}}, q::judiVector{Float32, Matrix{Float32}})
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/LinearOperators/operators.jl:173
 [22] top-level scope
    @ /mnt/HDD_2TB/VikingGraben/line12/inversion/scripts/rtm.jl:192

Incorrect seismograms from JudiModeling

Hello I am getting a strange result when trying to compute a shot gather with traces that are 10s long. Looks like there is an issue with padding somewhere, but being brand new to JUDI (and devito) I am really not sure what is going on. With Devito only I can compute the seismograms without an issue, so I am wondering what is it that I am doing wrong here. A minimal example follows:

using PyPlot, HDF5, SegyIO, JUDI.TimeModeling, JUDI.SLIM_optim, Statistics, Random, LinearAlgebra

# Load smooth migration velocity model
n,d,o,m0 = read(h5open("marmousi_migration_velocity.h5","r"), "n", "d", "o", "m0")
model0 = Model((n[1],n[2]), (d[1],d[2]), (o[1],o[2]), m0)

#Set up source geometry
nsrc = 1  # no. of sources
xsrc = convertToCell(range(800*5f0, stop=800*5f0, length=nsrc))
ysrc = convertToCell(range(0f0, stop=0f0, length=nsrc))
zsrc = convertToCell(range(20f0, stop=20f0, length=nsrc))

# Modeling time and sampling interval
time = 10000f0  # ms
dt = 4f0   # ms

# Set up source structure
src_geometry = Geometry(xsrc, ysrc, zsrc; dt=dt, t=time)

# Source wavelet
f0 = 0.010f0     # kHz
wavelet = ricker_wavelet(time, dt, f0)
q = judiVector(src_geometry, wavelet);

# Set up receiver geometry (for 2D, set yrec to zero)
nxrec = 101
xrec = range(0f0, stop=1599*5f0, length=nxrec)
yrec = 0f0
zrec = range(50f0, stop=50f0, length=nxrec)

# Set up receiver structure
rec_geometry = Geometry(xrec, yrec, zrec; dt=dt, t=time, nsrc=nsrc);

# Set up info structure for linear operators
ntComp = get_computational_nt(src_geometry, rec_geometry, model0)
info = Info(prod(n), nsrc, ntComp)

#Setup operators
Pr = judiProjection(info, rec_geometry)
A_inv = judiModeling(info, model0)
Ps = judiProjection(info, src_geometry);

F = judiModeling(info, model0, src_geometry, rec_geometry);
F = Pr*A_inv*Ps';
d_obs = F*q

The shot gather, however, has this really strange low freq signal at the bottom of the traces

pcolormesh(d_obs.data[1], vmin=-1, vmax=1, cmap="seismic")
gca().invert_yaxis()

shotgather_juliatest

plot(d_obs.data[1][1:4:end,51], "r.-")

shotgather_juliatest_trace

Mpi problem when running on cluster?

Hi,

I try to run "examples/scripts/modeling_basic_3D.jl" example on the cluster using 8 cores, but I got some warnings, shown in the following picture:
image

On the cluster, I allocate the resource using: salloc --nodes 2 --ntasks-per-node 4 -t 1:00:00 --mem-per-cpu 25G and then run julia interactively. There is no warning or error when I run this script on my local workstation using 8 cores.

And I've got some errors when running 3D modeling and inversion using my own examples. The model is quite simple:
image
In this example, I use 64 cores on cluster: salloc --nodes 16 --ntasks-per-node 4 -t 1:00:00 --mem-per-cpu 25G.
image

But I got no errors when I ran the scripts using 8 cores in both modeling and inversion: salloc --nodes 2 --ntasks-per-node 4 -t 1:00:00 --mem-per-cpu 25G. And I also can run on my local workstation using 8 cores.

I've tried to solve this problem online for several days, but not find a solution. Could you tell me where might be wrong? Thanks!

Run JUDI with the newest version Devito-3.4

Hi, I have updated the Devito recently from version 3.2 to the most recent version 3.4. But then I cannot run JUDI any more. It used to work well. When I tried to run using JUDI.TimeModeling, it shows the ERROR: LoadError: PyError (PyImport_ImportModule). I wonder that is it caused by the Devito version upgrade? May I have any suggestions on what should I do? Thanks a lot!
judi_runerror

RTM with `subsampling_factor` with `space_order` cause error

Hi,

The following code snippet lead to an error during RTM. The error only appears when both space_order=16 and subsampling_factor=2 are set. If space_order=8 then it works fine.
But I have tried JUDI's example modeling_basic_2D.jl with the same space_order and subsampling_factor parameters and there was no such error. So maybe the fact that I also use OOC geometry and segy_scan have some sense...

container = segy_scan(prestk_dir, prestk_file, ["SourceX", "SourceY", "GroupX", "GroupY", "RecGroupElevation", "SourceSurfaceElevation", "dt"])
d_obs = judiVector(container; segy_depth_key = "RecGroupElevation")

# Set up wavelet and source vector
src_geometry = Geometry(container; key = "source", segy_depth_key = "SourceSurfaceElevation")
q = judiVector(src_geometry, wavelet)

t_sub = 2

# JUDI options
jopt = JUDI.Options(
    space_order=16,
    limit_m = true,
    buffer_size = buffer_size,
    optimal_checkpointing=false,
    IC = "isic",
    subsampling_factor=t_sub)

# Setup operators
Pr = judiProjection(d_obs.geometry)
F = judiModeling(model0; options=jopt)
Ps = judiProjection(q.geometry)
J = judiJacobian(Pr*F*adjoint(Ps), q)

# RTM
rtm = adjoint(J)*d_obs

The error:

┌ Info: JOLI method error for combination:
│   left_name = "(judiJacobian{Float32, :adjoint_born, judiDataSourceModeling{Float32, :forward}}*DataMute{Float32, :reflection})"
│   left_type = JOLI.joLinearOperator{Float32, Float32}
│   right_name = "non-JOLI"
└   right_type = Vector{SegyIO.IBMFloat32} (alias for Array{SegyIO.IBMFloat32, 1})
ERROR: JOLI.joUtilsException("*(jo,vec) not implemented or type mismatch")
Stacktrace:
 [1] jo_method_error(L::JOLI.joLinearOperator{Float32, Float32}, R::Vector{SegyIO.IBMFloat32}, s::String)
   @ JOLI ~/Documents/Colada/r/julia-1.6/.julia/packages/JOLI/SZxFH/src/joUtils.jl:53
 [2] *(A::JOLI.joLinearOperator{Float32, Float32}, v::Vector{SegyIO.IBMFloat32})
   @ JOLI ~/Documents/Colada/r/julia-1.6/.julia/packages/JOLI/SZxFH/src/joAbstractOperator/base_functions.jl:80
 [3] *(J::JOLI.joLinearOperator{Float32, Float32}, x::judiVector{Float32, SeisCon})
   @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Types/abstract.jl:84
 [4] *(::judiJacobian{Float32, :adjoint_born, judiDataSourceModeling{Float32, :forward}}, ::DataMute{Float32, :reflection}, ::judiVector{Float32, SeisCon})
   @ Base ./operators.jl:560
 [5] top-level scope
   @ /mnt/HDD_2TB/VikingGraben/line12/inversion/scripts/rtm.jl:164

caused by: PyError ($(Expr(:escape, :(ccall(#= /home/kerim/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/pyfncall.jl:43 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'devito.exceptions.InvalidArgument'>
InvalidArgument('OOB detected due to x_M=597')
  File "/home/kerim/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/pysource/interface.py", line 359, in J_adjoint
    return J_adjoint_standard(model, src_coords, wavelet, rec_coords, recin,
  File "/home/kerim/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/pysource/interface.py", line 486, in J_adjoint_standard
    g, Iv, _ = gradient(model, residual, rec_coords, u, space_order=space_order, ic=ic,
  File "/home/kerim/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/pysource/propagators.py", line 127, in gradient
    summary = op(**kw)
  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/devito/operator/operator.py", line 686, in __call__
    return self.apply(**kwargs)
  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/devito/operator/operator.py", line 752, in apply
    args = self.arguments(**kwargs)
  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/devito/operator/operator.py", line 601, in arguments
    args = self._prepare_arguments(**kwargs)
  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/devito/operator/operator.py", line 552, in _prepare_arguments
    p._arg_check(args, self._dspace[p])
  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/devito/types/dense.py", line 1424, in _arg_check
    super(TimeFunction, self)._arg_check(args, intervals)
  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/devito/types/dense.py", line 874, in _arg_check
    i._arg_check(args, s, intervals[i])
  File "/home/kerim/Documents/Colada/r/python-install/lib/python3.9/site-packages/devito/types/dimension.py", line 293, in _arg_check
    raise InvalidArgument("OOB detected due to %s=%d" % (self.max_name,

Stacktrace:
  [1] pyerr_check
    @ ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/exception.jl:62 [inlined]
  [2] pyerr_check
    @ ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/exception.jl:66 [inlined]
  [3] _handle_error(msg::String)
    @ PyCall ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/exception.jl:83
  [4] macro expansion
    @ ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/exception.jl:97 [inlined]
  [5] #107
    @ ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/pyfncall.jl:43 [inlined]
  [6] disable_sigint
    @ ./c.jl:458 [inlined]
  [7] __pycall!
    @ ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/pyfncall.jl:42 [inlined]
  [8] _pycall!(ret::PyCall.PyObject, o::PyCall.PyObject, args::Tuple{PyCall.PyObject, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}}, nargs::Int64, kw::PyCall.PyObject)
    @ PyCall ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/pyfncall.jl:29
  [9] _pycall!(ret::PyCall.PyObject, o::PyCall.PyObject, args::Tuple{PyCall.PyObject, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}}, kwargs::Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Nothing, String, Bool, Int64, Float32, Bool}}})
    @ PyCall ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/pyfncall.jl:11
 [10] pycall(::PyCall.PyObject, ::Type{Tuple{PyCall.PyArray, PyCall.PyObject, PyCall.PyObject}}, ::PyCall.PyObject, ::Vararg{Any, N} where N; kwargs::Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Nothing, String, Bool, Int64, Float32, Bool}}})
    @ PyCall ~/Documents/Colada/r/julia-1.6/.julia/packages/PyCall/ygXW2/src/pyfncall.jl:80
 [11] (::JUDI.var"#198#199"{Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Nothing, String, Bool, Int64, Float32, Bool}}}, PyCall.PyObject, Tuple{PyCall.PyObject, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}}, DataType})()
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/python_interface.jl:52
 [12] (::JUDI.var"#1#2"{JUDI.var"#198#199"{Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Nothing, String, Bool, Int64, Float32, Bool}}}, PyCall.PyObject, Tuple{PyCall.PyObject, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}}, DataType}})()
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/JUDI.jl:68
 [13] lock(f::JUDI.var"#1#2"{JUDI.var"#198#199"{Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Nothing, String, Bool, Int64, Float32, Bool}}}, PyCall.PyObject, Tuple{PyCall.PyObject, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}}, DataType}}, l::ReentrantLock)
    @ Base ./lock.jl:187
 [14] pylock(f::JUDI.var"#198#199"{Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Nothing, String, Bool, Int64, Float32, Bool}}}, PyCall.PyObject, Tuple{PyCall.PyObject, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}, Matrix{Float32}}, DataType})
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/JUDI.jl:65
 [15] wrapcall_grad(::PyCall.PyObject, ::PyCall.PyObject, ::Vararg{Any, N} where N; kw::Base.Iterators.Pairs{Symbol, Any, NTuple{10, Symbol}, NamedTuple{(:fw, :t_sub, :space_order, :checkpointing, :freq_list, :ic, :is_residual, :dft_sub, :f0, :illum), Tuple{Bool, Int64, Int64, Bool, Nothing, String, Bool, Int64, Float32, Bool}}})
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/python_interface.jl:51
 [16] devito_interface(modelPy::PyCall.PyObject, srcGeometry::GeometryIC{Float32}, srcData::Matrix{Float32}, recGeometry::GeometryIC{Float32}, recData::Matrix{Float32}, dm::Nothing, options::JUDIOptions, illum::Bool, fw::Bool)
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/python_interface.jl:143
 [17] time_modeling(model_full::Model, srcGeometry::GeometryOOC{Float32}, srcData::Matrix{Float32}, recGeometry::GeometryOOC{Float32}, recData::Matrix{Float32}, dm::Nothing, op::Symbol, options::JUDIOptions, fw::Bool)
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/time_modeling_serial.jl:39
 [18] propagate(F::judiJacobian{Float32, :adjoint_born, judiDataSourceModeling{Float32, :forward}}, q::judiVector{Float32, Matrix{Float32}})
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/propagation.jl:9
 [19] run_and_reduce(func::Function, #unused#::Nothing, nsrc::Int64, arg_func::JUDI.var"#228#229"{judiJacobian{Float32, :adjoint_born, judiDataSourceModeling{Float32, :forward}}, judiVector{Float32, Matrix{Float32}}})
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/propagation.jl:32
 [20] multi_src_propagate(F::judiJacobian{Float32, :adjoint_born, judiDataSourceModeling{Float32, :forward}}, q::judiVector{Float32, Matrix{Float32}})
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/propagation.jl:67
 [21] *
    @ ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/LinearOperators/operators.jl:173 [inlined]
 [22] (::JOLI.var"#173#177"{judiJacobian{Float32, :adjoint_born, judiDataSourceModeling{Float32, :forward}}, DataMute{Float32, :reflection}})(v1::judiVector{Float32, SeisCon})
    @ JOLI ~/Documents/Colada/r/julia-1.6/.julia/packages/JOLI/SZxFH/src/joAbstractLinearOperator/base_functions.jl:139
 [23] *(J::JOLI.joLinearOperator{Float32, Float32}, x::judiVector{Float32, SeisCon})
    @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Types/abstract.jl:84
 [24] *(::judiJacobian{Float32, :adjoint_born, judiDataSourceModeling{Float32, :forward}}, ::DataMute{Float32, :reflection}, ::judiVector{Float32, SeisCon})
    @ Base ./operators.jl:560
 [25] top-level scope
    @ /mnt/HDD_2TB/VikingGraben/line12/inversion/scripts/rtm.jl:164

Info about upcoming removal of packages in the General registry

As described in https://discourse.julialang.org/t/ann-plans-for-removing-packages-that-do-not-yet-support-1-0-from-the-general-registry/ we are planning on removing packages that do not support 1.0 from the General registry. This package has been detected to not support 1.0 and is thus slated to be removed. The removal of packages from the registry will happen approximately a month after this issue is open.

To transition to the new Pkg system using Project.toml, see https://github.com/JuliaRegistries/Registrator.jl#transitioning-from-require-to-projecttoml.
To then tag a new version of the package, see https://github.com/JuliaRegistries/Registrator.jl#via-the-github-app.

If you believe this package has erroneously been detected as not supporting 1.0 or have any other questions, don't hesitate to discuss it here or in the thread linked at the top of this post.

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Assembler Message

Hi,

I was running an LS-RTM (101 sources, 401 receivers, BG model, batchsize 8) and the code is here https://github.gatech.edu/zyin62/multiples/blob/master/BG_multiple.jl. I got a warning in the 2nd iteration (but no warning afterwards). The warning is in assembly level which I am not good at interpreting. Could you please help me check if this is OK?

Thanks

From worker 2:	/tmp/ccNEhkjv.s: Assembler messages:
From worker 2:	/tmp/ccNEhkjv.s:2262: Warning: index and destination registers should be distinct
From worker 2:	/tmp/ccNEhkjv.s:2794: Warning: index and destination registers should be distinct

Out of bounds receiver lead to incorrect size output

WHile remove_out_of_bounds_reciever works correctly, the resulting data has missing traces instead of zero out traces leading to incorrect sized output with regard to the linear operator size.

Some post-process step is needed to put back the skipped traces with zeros.

JUDI.SLIM_optim

I have installed JUDI, unfortunately,terminal shows that "UnderVarError: SLIM_optim not defined" after running, I don't known what happen? please help me,,thank you !

judiVector_to_seisblock error

This MFE includes a verbatim copy of https://github.com/slimgroup/JUDI.jl/blob/master/examples/scripts/modeling_basic_2D.jl to generate data. It errors when turning judiVector to SeisBlock

# Example for basic 2D modeling:
# The receiver positions and the source wavelets are the same for each of the four experiments.
# Author: Philipp Witte, [email protected]
# Date: January 2017
#

using JUDI, SegyIO, LinearAlgebra

# Set up model structure
n = (120, 100)   # (x,y,z) or (x,z)
d = (10., 10.)
o = (0., 0.)

# Velocity [km/s]
v = ones(Float32,n) .+ 0.5f0
v0 = ones(Float32,n) .+ 0.5f0
v[:,Int(round(end/2)):end] .= 3.5f0
rho = (v0 .+ .5f0) ./ 2

# Slowness squared [s^2/km^2]
m = (1f0 ./ v).^2
m0 = (1f0 ./ v0).^2
dm = vec(m - m0)

# Setup info and model structure
nsrc = 2	# number of sources
model = Model(n, d, o, m)
model0 = Model(n, d, o, m0)

# Set up receiver geometry
nxrec = 120
xrec = range(50f0, stop=1150f0, length=nxrec)
yrec = 0f0
zrec = range(50f0, stop=50f0, length=nxrec)

# receiver sampling and recording time
timeR = 1000f0   # receiver recording time [ms]
dtR = 2f0    # receiver sampling interval [ms]

# Set up receiver structure
recGeometry = Geometry(xrec, yrec, zrec; dt=dtR, t=timeR, nsrc=nsrc)

# Set up source geometry (cell array with source locations for each shot)
xsrc = convertToCell(range(400f0, stop=800f0, length=nsrc))
ysrc = convertToCell(range(0f0, stop=0f0, length=nsrc))
zsrc = convertToCell(range(200f0, stop=200f0, length=nsrc))

# source sampling and number of time steps
timeS = 1000f0  # ms
dtS = 2f0   # ms

# Set up source structure
srcGeometry = Geometry(xsrc, ysrc, zsrc; dt=dtS, t=timeS)

# setup wavelet
f0 = 0.01f0     # kHz
wavelet = ricker_wavelet(timeS, dtS, f0)
q = judiVector(srcGeometry, wavelet)

# Set up info structure for linear operators
ntComp = get_computational_nt(srcGeometry, recGeometry, model)
info = Info(prod(n), nsrc, ntComp)

###################################################################################################

# Write shots as segy files to disk
opt = Options(optimal_checkpointing=false, isic=false, subsampling_factor=2, dt_comp=1.0)

# Setup operators
Pr = judiProjection(info, recGeometry)
F = judiModeling(info, model; options=opt)
F0 = judiModeling(info, model0; options=opt)
Ps = judiProjection(info, srcGeometry)
J = judiJacobian(Pr*F0*adjoint(Ps), q)

# Nonlinear modeling
dobs = Pr*F*adjoint(Ps)*q

block = judiVector_to_SeisBlock(dobs, q; source_depth_key="SourceDepth")

the error is

ERROR: LoadError: MethodError: no method matching round(::Vector{Float32})
Closest candidates are:
  round(::Union{Dates.Day, Dates.Week, Dates.TimePeriod}, ::Union{Dates.Day, Dates.Week, Dates.TimePeriod}, ::RoundingMode{:NearestTiesUp}) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Dates/src/rounding.jl:267
  round(::Union{Dates.Day, Dates.Week, Dates.TimePeriod, Dates.TimeType}, ::Dates.Period) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Dates/src/rounding.jl:282
  round(::Union{Dates.Day, Dates.Week, Dates.TimePeriod, Dates.TimeType}, ::Dates.Period, ::RoundingMode{:Down}) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Dates/src/rounding.jl:273
  ...
Stacktrace:
 [1] judiVector_to_SeisBlock(d::judiVector{Float32, Matrix{Float32}}, q::judiVector{Float32, Matrix{Float32}}; source_depth_key::String, receiver_depth_key::String)
   @ JUDI ~/.julia/dev/JUDI/src/TimeModeling/Types/judiVector.jl:435
 [2] top-level scope
   @ ~/.julia/dev/JUDI/MFE.jl:79
 [3] include(fname::String)
   @ Base.MainInclude ./client.jl:444
 [4] top-level scope
   @ REPL[1]:1
in expression starting at /Users/francisyin/.julia/dev/JUDI/MFE.jl:79

and the problem really is yrec=0f0. If we turn it to yrec=range(0f0, stop=0f0, length=nxrec) then it works.

This in the end leads to further concern: should 2D seismic data has a yloc as [[0],[0]] (for 2 sources), or [[0,0,....0],[0,0,...,0]]? It's either the first one or the second one, and turning from judiVector to SeisBlock then back to judiVector must be an "identity" operation which remains the geometry.

Plan to fix this by #69

Example at https://github.com/slimgroup/JUDI.jl/blob/master/examples/scripts/extended_source_lsqr.jl fails to work

Currently on latest master branch. The example at https://github.com/slimgroup/JUDI.jl/blob/master/examples/scripts/extended_source_lsqr.jl fails to run with the error below. Possibly due to something new because I remember it worked before.

ERROR: LoadError: JOLI.joUtilsException("type mismatch: expected Float32 instead of Any in RDT from *(joLinearFunction,judiWeights): / joStack(2) / joCoreBlock{Float32,Float32} / Any") Stacktrace: [1] jo_check_type_match(::DataType, ::DataType, ::String) at /Users/francisyin/.julia/dev/JOLI/src/joUtils.jl:329 [2] *(::joCoreBlock{Float32,Float32}, ::judiWeights{Float32}) at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/judiWeights.jl:205 [3] lsqr_method!(::ConvergenceHistory{false,Nothing}, ::judiWeights{Float32}, ::joCoreBlock{Float32,Float32}, ::JUDI.TimeModeling.judiVStack{Float32}; damp::Float64, atol::Float32, btol::Float32, conlim::Float32, maxiter::Int64, verbose::Bool) at /Users/francisyin/.julia/packages/IterativeSolvers/3g7hG/src/lsqr.jl:122 [4] lsqr!(::judiWeights{Float32}, ::joCoreBlock{Float32,Float32}, ::JUDI.TimeModeling.judiVStack{Float32}; maxiter::Int64, log::Bool, kwargs::Base.Iterators.Pairs{Symbol,Real,Tuple{Symbol,Symbol},NamedTuple{(:verbose, :damp),Tuple{Bool,Float64}}}) at /Users/francisyin/.julia/packages/IterativeSolvers/3g7hG/src/lsqr.jl:74 [5] top-level scope at /Users/francisyin/Desktop/JUDI.jl/examples/scripts/extended_source_lsqr.jl:76 [6] include(::String) at ./client.jl:457 [7] top-level scope at REPL[1]:1 in expression starting at /Users/francisyin/Desktop/JUDI.jl/examples/scripts/extended_source_lsqr.jl:76

lsrtm_objective produces wrong results w/ selected frequencies or optimal checkpointing

Script is here https://github.com/slimgroup/JUDI.jl/blob/c9bda1244f0cd4863cea47f475ce1769faf14cb6/test/MFE.jl

  1. When inputting selected frequencies in the options, lsrtm_objective always outputs all zeros as the gradient.
  2. When doing optimal checkpointing, lsrtm_objective does not do what it is supposed to do, i.e. outputing 0.5*||Jx-d+d0||_2^2 and J^T(Jx-d+d0).
  3. lsrtm_objective w/ optimal checkpointing and linear data produces error
ERROR: LoadError: PyError ($(Expr(:escape, :(ccall(#= /Users/francisyin/.julia/packages/PyCall/BD546/src/pyfncall.jl:43 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'ValueError'>
ValueError('Unrecognized argument rcvu=rcvul(time, p_rcvul)')
  File "/Users/francisyin/.julia/dev/JUDI/src/pysource/interface.py", line 665, in J_adjoint_checkpointing
    wrap_fw = CheckpointOperator(op_f, m=model.m, **uk)
  File "/Users/francisyin/.julia/dev/JUDI/src/pysource/checkpoint.py", line 29, in __init__
    op_default_args = self.op._prepare_arguments(**kwargs)
  File "/Users/francisyin/.local/lib/python3.7/site-packages/devito/operator/operator.py", line 500, in _prepare_arguments
    raise ValueError("Unrecognized argument %s=%s" % (k, v))

Stacktrace:
 [1] pyerr_check at /Users/francisyin/.julia/packages/PyCall/BD546/src/exception.jl:62 [inlined]
 [2] pyerr_check at /Users/francisyin/.julia/packages/PyCall/BD546/src/exception.jl:66 [inlined]
 [3] _handle_error(::String) at /Users/francisyin/.julia/packages/PyCall/BD546/src/exception.jl:83
 [4] macro expansion at /Users/francisyin/.julia/packages/PyCall/BD546/src/exception.jl:97 [inlined]
 [5] #107 at /Users/francisyin/.julia/packages/PyCall/BD546/src/pyfncall.jl:43 [inlined]
 [6] disable_sigint at ./c.jl:446 [inlined]
 [7] __pycall! at /Users/francisyin/.julia/packages/PyCall/BD546/src/pyfncall.jl:42 [inlined]
 [8] _pycall!(::PyCall.PyObject, ::PyCall.PyObject, ::Tuple{PyCall.PyObject,Array{Float32,2},Array{Float32,2},Array{Float32,2},Array{Float32,2}}, ::Int64, ::PyCall.PyObject) at /Users/francisyin/.julia/packages/PyCall/BD546/src/pyfncall.jl:29
 [9] _pycall!(::PyCall.PyObject, ::PyCall.PyObject, ::Tuple{PyCall.PyObject,Array{Float32,2},Array{Float32,2},Array{Float32,2},Array{Float32,2}}, ::Base.Iterators.Pairs{Symbol,Integer,NTuple{7,Symbol},NamedTuple{(:is_residual, :return_obj, :t_sub, :space_order, :born_fwd, :nlind, :isic),Tuple{Bool,Bool,Int64,Int64,Bool,Bool,Bool}}}) at /Users/francisyin/.julia/packages/PyCall/BD546/src/pyfncall.jl:11
 [10] pycall(::PyCall.PyObject, ::Type{Tuple{Float32,Array{Float32,2}}}, ::PyCall.PyObject, ::Vararg{Any,N} where N; kwargs::Base.Iterators.Pairs{Symbol,Integer,NTuple{7,Symbol},NamedTuple{(:is_residual, :return_obj, :t_sub, :space_order, :born_fwd, :nlind, :isic),Tuple{Bool,Bool,Int64,Int64,Bool,Bool,Bool}}}) at /Users/francisyin/.julia/packages/PyCall/BD546/src/pyfncall.jl:80
 [11] lsrtm_objective(::Model, ::judiVector{Float32,Array{Float32,2}}, ::judiVector{Float32,Array{Float32,2}}, ::PhysicalParameter{Float32}, ::Options; nlind::Bool) at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/Modeling/lsrtm_objective_serial.jl:31
 [12] #165 at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/Modeling/lsrtm_objective_parallel.jl:22 [inlined]
 [13] judipmap(::JUDI.var"#165#167"{Options,Bool,Model,judiVector{Float32,Array{Float32,2}},judiVector{Float32,Array{Float32,2}},PhysicalParameter{Float32}}, ::UnitRange{Int64}) at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/Modeling/utils.jl:5
 [14] lsrtm_objective(::Model, ::judiVector{Float32,Array{Float32,2}}, ::judiVector{Float32,Array{Float32,2}}, ::PhysicalParameter{Float32}; options::Options, nlind::Bool) at /Users/francisyin/.julia/dev/JUDI/src/TimeModeling/Modeling/lsrtm_objective_parallel.jl:22
 [15] top-level scope at /Users/francisyin/.julia/dev/JUDI/test/MFE.jl:48
 [16] include(::String) at ./client.jl:457
 [17] top-level scope at REPL[1]:1
in expression starting at /Users/francisyin/.julia/dev/JUDI/test/MFE.jl:48

ERROR: MethodError: Cannot `convert` an object of type Float32 to an object of type Vector{Float32}

Hello,
I’ve got a syntax error when I was running the documentation example (from: https://slimgroup.github.io/JUDI.jl/dev/tutorials/03_constrained_fwi/#pos). Here is the error:

src_geom = Geometry(xsrc, ysrc, zsrc; dt=dt, t=tn);
ERROR: MethodError: Cannot convert an object of type Float32 to an object of type Vector{Float32}
Closest candidates are:
convert(::Type{Array{T, N}}, ::StaticArrays.SizedArray{S, T, N, N, Array{T, N}}) where {S, T, N} at ~/.julia/packages/StaticArrays/58yy1/src/SizedArray.jl:218
convert(::Type{Array{T, N}}, ::StaticArrays.SizedArray{S, T, N, M, TData} where {M, TData<:AbstractArray{T, M}}) where {T, S, N} at ~/.julia/packages/StaticArrays/58yy1/src/SizedArray.jl:212
convert(::Type{T}, ::Factorization) where T<:AbstractArray at ~/local/julia-1.7.3/share/julia/stdlib/v1.7/LinearAlgebra/src/factorization.jl:58
...
Stacktrace:
[1] GeometryIC{Float32}(xloc::Vector{Vector{Float32}}, yloc::Vector{Vector{Float32}}, zloc::Vector{Vector{Float32}}, dt::Float32, nt::Int64, t::Float32)
@ JUDI ~/.julia/packages/JUDI/Xrqx6/src/TimeModeling/Types/GeometryStructure.jl:15
[2] Geometry(xloc::Vector{Vector{Float32}}, yloc::Vector{Vector{Float32}}, zloc::Vector{Vector{Float32}}; dt::Float32, t::Int64)
@ JUDI ~/.julia/packages/JUDI/Xrqx6/src/TimeModeling/Types/GeometryStructure.jl:258
[3] Geometry(xloc::Vector{Vector{Float64}}, yloc::Vector{Vector{Float32}}, zloc::Vector{Vector{Float32}}; dt::Float32, t::Int64, nsrc::Nothing)
@ JUDI ~/.julia/packages/JUDI/Xrqx6/src/TimeModeling/Types/GeometryStructure.jl:240
[4] top-level scope
@ REPL[91]:1
[5] top-level scope
@ ~/.julia/packages/CUDA/GGwVa/src/initialization.jl:52

julia>

I’d be grateful if you could help. It might be worth mentioning that some lines in the documentation need to be updated. As I got errors when running those as well. Functions from Distributed (e.g. workers) need to be imported explicitly.
Thank you
Afsaneh

FWI: Dimension mismatch when `limit_m=true`

Hi,

Starting from v3.1.9 I'm no longer able to run FWI with limit_m=true with my field data while fwi_example_2D.jl works fine even if model is limited.

The error I get:

ERROR: DimensionMismatch("new dimensions (477450,) must be consistent with array size 117000")
Stacktrace:
 [1] (::Base.var"#throw_dmrsa#234")(dims::Tuple{Int64}, len::Int64)
   @ Base ./reshapedarray.jl:41
 [2] reshape(a::Matrix{Float32}, dims::Tuple{Int64})
   @ Base ./reshapedarray.jl:45
 [3] materialize!(A::PhysicalParameter{Float32}, B::Base.Broadcast.Broadcasted{Base.Broadcast.ArrayStyle{PhysicalParameter}, Nothing, typeof(identity), Tuple{PhysicalParameter{Float32}}})
   @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Types/ModelStructure.jl:223
 [4] multi_src_fg!(G::PhysicalParameter{Float32}, model::Model, q::judiVector{Float32, Matrix{Float32}}, dobs::judiVector{Float32, Matrix{Float32}}, dm::Nothing; options::JUDIOptions, kw::Base.Iterators.Pairs{Symbol, Bool, Tuple{Symbol, Symbol}, NamedTuple{(:nlind, :lin), Tuple{Bool, Bool}}})
   @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/propagation.jl:88
 [5] #multi_exp_fg!#186
   @ ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/misfit_fg.jl:155 [inlined]
 [6] fwi_objective!(G::PhysicalParameter{Float32}, model::Model, q::judiVector{Float32, Matrix{Float32}}, dobs::judiVector{Float32, Matrix{Float32}}; options::JUDIOptions, kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/misfit_fg.jl:136
 [7] fwi_objective(model::Model, q::judiVector{Float32, Matrix{Float32}}, dobs::judiVector{Float32, Matrix{Float32}}; options::JUDIOptions, kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/misfit_fg.jl:101
 [8] top-level scope
   @ /mnt/HDD_2TB/VikingGraben/line12/inversion/scripts/fwi_acoustic.jl:90

The simplified code I use:

# JUDI options
buffer_size = 0f0    # limit model (meters)

# Load data and create data vector
block = segy_read(prestk_dir * prestk_file)
# container = segy_scan(prestk_dir, prestk_file, ["SourceX", "SourceY", "GroupX", "GroupY", "RecGroupElevation", "SourceSurfaceElevation", "dt"])
d_obs = judiVector(block; segy_depth_key = "RecGroupElevation")

srcx = Float32.(get_header(block, "SourceX")[:,1])
grpx = Float32.(get_header(block, "GroupX")[:,1])
min_x = minimum([minimum(srcx), minimum(grpx)])-buffer_size
max_x = maximum([maximum(srcx), maximum(grpx)])+buffer_size

# Load starting model
n, d, o, m0 = read(h5open(model_file, "r"), "n", "d", "o", "m")

# Trim model
m0x = o[1]:d[1]:o[1]+(size(m0)[1]-1)*d[1]
x_ind = [i for i in eachindex(m0x) if min_x-d[1] <= m0x[i] <= max_x+d[1]]
m0 = m0[x_ind,:]
n = (length(x_ind), n[2])
d = (d[1], d[2])
o = (o[1]+(x_ind[1]-1)*d[1], o[2])
model0 = Model(n, d, o, m0)

# Set up wavelet and source vector
src_geometry = Geometry(block; key = "source", segy_depth_key = "SourceSurfaceElevation")
f0 = 0.006     # kHz
wavelet = ricker_wavelet(src_geometry.t[1], src_geometry.dt[1], f0)
q = judiVector(src_geometry, wavelet)

# JUDI options
jopt = JUDI.Options(
    limit_m = true,
    buffer_size = buffer_size,
    optimal_checkpointing=false)

# Select batch and calculate gradient (set to a single shot to accelerate crash experiment)
fval, gradient = fwi_objective(model0, q[10], d_obs[10], options=jopt)

Here:
o = (4968.5, 0.0)
n = (1061, 450)
d = (12.5, 12.5)
min_x = 4975.0f0 (from segy source and rec positions)
max_x = 18212.0f0 (from segy source and rec positions)

Each shot in SEGY contains 120 receivers

In the error the following numbers may be treated as:
477450 is equal to *(n...)
117000/n[2] = 260

`twri_objective` fails to run with `dobs` judiVector constructed from `SeisCon`

Hi,

I slightly modified modeling_basic_2D.jl example so that after modeling wavefields dobs is constructed from SeisCon object.
To do that I save SEGY to tmp dir in the directory where modeling_basic_2D.jl is located and after that I construct SeisCon and form dobs:

#' # Modeling and inversion with JUDI
#' ---
#' title: Overview of JUDI modeling and inversion usage
#' author: Mathias Louboutin, Philipp Witte
#' date: April 2022
#' ---

#' This example script is written using [Weave.jl](https://github.com/JunoLab/Weave.jl) and can be converted to different format for documentation and usage
#' This example is converted to a markdown file for the documentation.

#' # Import JUDI, Linear algebra utilities and Plotting
using JUDI, SegyIO, PyPlot, LinearAlgebra

#+ echo = false; results = "hidden"
close("all")

#' # Create a JUDI model structure
#' In JUDI, a `Model` structure contains the grid information (origin, spacing, number of gridpoints)
#' and the physical parameters. The squared slowness is always required as the base physical parameter for propagation. In addition,
#' JUDI supports additional physical representations. First we accept `density` that can either be a direct input `Model(n, d, o, m, rho)` or
#' an optional keyword argument `Model(n,d,o,m;rho=rho)`. Second, we also provide VTI/TTI kernels parametrized by the THomsen parameters that can be input as keyword arguments
#' `Model(n,d,o,m; rho=rho, epsilon=epsilon;delta=delta,theta=theta,phi=phi)`. Because the thomsen parameters are optional the propagator wil lonloy use the ones provided. 
#' For example `Model(n,d,o,m; rho=rho, epsilon=epsilon;delta=delta)` will infer a VTI propagation

#' ## Create discrete parameters
# Set up model structure
n = (120, 100)   # (x,y,z) or (x,z)
d = (10., 10.)
o = (0., 0.)

# Velocity [km/s]
v = ones(Float32,n) .+ 0.5f0
v0 = ones(Float32,n) .+ 0.5f0
v[:,Int(round(end/2)):end] .= 3.5f0
rho = (v0 .+ .5f0) ./ 2

# Slowness squared [s^2/km^2]
m = (1f0 ./ v).^2
m0 = (1f0 ./ v0).^2
dm = vec(m0 - m)

# Setup model structure
nsrc = 2	# number of sources
model = Model(n, d, o, m)
model0 = Model(n, d, o, m0)

#' # Create acquisition geometry
#' In this simple usage example, we create a simple acquisiton by hand. In practice the acquisition geometry will be defined by the dataset
#' beeing inverted. We show in a spearate tutorial how to use [SegyIO.jl](https://github.com/slimgroup/SegyIO.jl) to handle SEGY seismic datasets in JUDI.

#' ## Create source and receivers positions at the surface
# Set up receiver geometry
nxrec = 120
xrec = range(0f0, stop=(n[1]-1)*d[1], length=nxrec)
yrec = 0f0 # WE have to set the y coordiante to zero (or any number) for 2D modeling
zrec = range(d[1], stop=d[1], length=nxrec)

# receiver sampling and recording time
timeD = 1250f0   # receiver recording time [ms]
dtD = 2f0    # receiver sampling interval [ms]

# Set up receiver structure
recGeometry = Geometry(xrec, yrec, zrec; dt=dtD, t=timeD, nsrc=nsrc)

#' The source geometry is a but different. Because we want to create a survey with `nsrc` shot records, we need
#' to convert the vector of sources postions `[s0, s1, ... sn]` into an array of array [[s0], [s1], ...] so that
#' JUDI understands that this is a set of indepednet `nsrc`

xsrc = convertToCell(range(0f0, stop=(n[1]-1)*d[1], length=nsrc))
ysrc = convertToCell(range(0f0, stop=0f0, length=nsrc))
zsrc = convertToCell(range(d[1], stop=d[1], length=nsrc))

# Set up source geometry (cell array with source locations for each shot)
xsrc = convertToCell(range(0f0, stop=(n[1]-1)*d[1], length=nsrc))
ysrc = convertToCell(range(0f0, stop=0f0, length=nsrc))
zsrc = convertToCell(range(d[1], stop=d[1], length=nsrc))

# Set up source structure
srcGeometry = Geometry(xsrc, ysrc, zsrc; dt=dtD, t=timeD)

#' # Source judiVector
#' Finally, with the geometry defined, we can create a source wavelet (a simple Ricker wavelet here) a our first `judiVector`
#' In JUDI, a `judiVector` is the core structure that represent a acquisition-geometry based dataset. This structure encapsulate
#' the physical locations (trace coordinates) and corrsponding data trace in a source-based structure. for a given `judiVector` `d` then
#' `d[1]` will be the shot record for the first source, or in the case of the source term, the first source wavelet and its positon.

# setup wavelet
f0 = 0.01f0     # kHz
wavelet = ricker_wavelet(timeD, dtD, f0)
q = judiVector(srcGeometry, wavelet)

#' # Modeling
#' With our survey and subsurface model setup, we can now model and image seismic data. We first define a few options. In this tutorial
#' we will choose to compute gradients/images subsampling the forward wavefield every two time steps `subsampling_factor=2` and we fix the computational
#' time step to be `1ms` wiuth `dt_comp=1.0` know to satisfy the CFL condition for this simple example. In practice, when `dt_comp` isn't provided, JUDI will compute the CFL
#' condition for the propagation.

segy_path = @__DIR__
segy_path *= "/tmp/"
segy_name = "shot"

rm(segy_path, force=true, recursive=true)
mkpath(segy_path)

# Write shots as segy files to disk
opt = Options(optimal_checkpointing=false, isic=false, subsampling_factor=2, dt_comp=1.0,
              save_data_to_disk=true, file_path=segy_path, file_name=segy_name)

#' Linear Operators
#' The core idea behind JUDI is to abstract seismic inverse problems in term of linear algebra. In its simplest form, seismic inversion can be formulated as
#' ```math
#' \underset{\mathbf{m}}{\text{argmin}} \ \ \phi(\mathbf{m}) = \frac{1}{2} ||\mathbf{P}_r \mathbf{F}(\mathbf{m}) \mathbf{P}_s^{\top} \mathbf{q} - \mathbf{d} ||_2^2 \\
#' \text{   } \\
#' \nabla_{\mathbf{m}} \phi(\mathbf{m}) = \mathbf{J}(\mathbf{m}, \mathbf{q})^{\top} (\mathbf{P}_r \mathbf{F}(\mathbf{m}) \mathbf{P}_s^{\top} \mathbf{q} - \mathbf{d})
#' ```
#' 
#' where $\mathbf{P}_r$ is the receiver projection (measurment operator) and $\mathbf{P}_s^{\top}$ is the source injection operator (adjoint of measurment at the source location).
#' Therefore, we bastracted these operation to be able to define these operators

# Setup operators
Pr = judiProjection(recGeometry)
F = judiModeling(model; options=opt)
F0 = judiModeling(model0; options=opt)
Ps = judiProjection(srcGeometry)
J = judiJacobian(Pr*F0*adjoint(Ps), q)

#' # Model and image data

#' We first model synthetic data using our defined source and true model 
# Nonlinear modeling
d_obs = Pr*F*adjoint(Ps)*q

block = segy_scan(segy_path, segy_name, ["GroupX","GroupY","RecGroupElevation","SourceSurfaceElevation","dt"])
dobs = judiVector(block)   # linearized observed data

#' Plot the shot record
fig = figure()
# imshow(d_obs.data[1], vmin=-1, vmax=1, cmap="PuOr", extent=[xrec[1], xrec[end], timeD/1000, 0], aspect="auto")
imshow(dobs.data[1][1].data, vmin=-1, vmax=1, cmap="PuOr", extent=[xrec[1], xrec[end], timeD/1000, 0], aspect="auto")
xlabel("Receiver position (m)")
ylabel("Time (s)")
title("Synthetic data")
display(fig)

#' Because we have abstracted the linear algebra, we can solve the adjoint wave-equation as well 
#' where the data becomes the source. This adjoint solve will be part of the imaging procedure.
# # Adjoint
qad = Ps*adjoint(F)*adjoint(Pr)*dobs

#' We can easily now test the adjointness of our operator with the standard dot test. Because we
#' intend to conserve our linear algebra abstraction, `judiVector` implements all the necessary linear 
#' algebra functions such as dot product or norm to be used directly.
# <x, F'y>
dot1 = dot(q, qad)
# <F x, y>
dot2 = dot(dobs, dobs)
# Compare
@show dot1, dot2, (dot2 - dot2)/(dot1 + dot2)

#' # Inversion
#' Our main goal is to provide an unversion framework for seismic inversion. To this end, as shown earlier,
#' users can easily define the Jacobian operator and compute an RTM image (i.e FWI gradient) with a simple matrix-vector product.
#' Once again, we provide both the Jacobian and its adjoint and we can compute Born linearized data.

# Linearized modeling J*dm
dD = J*dm
# Adjoint jacobian, RTM image
rtm = adjoint(J)*dD

#' We show the linearized data.
fig = figure()
# imshow(dD.data[1], vmin=-1, vmax=1, cmap="PuOr", extent=[xrec[1], xrec[end], timeD/1000, 0], aspect="auto")
imshow(dD.data[1][1].data, vmin=-1, vmax=1, cmap="PuOr", extent=[xrec[1], xrec[end], timeD/1000, 0], aspect="auto")
xlabel("Receiver position (m)")
ylabel("Time (s)")
title("Linearized data")
display(fig)


#' And the RTM image
fig = figure()
imshow(rtm', vmin=-1e2, vmax=1e2, cmap="Greys", extent=[0, (n[1]-1)*d[1], (n[2]-1)*d[2], 0 ], aspect="auto")
xlabel("Lateral position(m)")
ylabel("Depth (m)")
title("RTM image")
display(fig)

#' ## Inversion utility functions
#' We currently introduced the lineaar operators that allow to write seismic modeling and inversion in a high-level, linear algebra way. These linear operators allow the script to closely follow the mathematics and to be readable and understandable.
#' 
#' However, these come with overhead. In particular, consider the following compuation on the FWI gradient:
#' 
#' ```julia
#' d_syn = F*q
#' r = judiJacobian(F, q)' * (d_syn - d_obs)
#' ```
#' 
#' In this two lines, the forward modeling is performed twice: once to compute `d_syn` then once again to compute the Jacobian adjoint. In order to avoid this overhead for practical inversion, we provide utility function that directly comput the gradient and objective function (L2- misfit) of FWI, LSRTM and TWRI with minimum overhead.

#' FWI misfit and gradient
# evaluate FWI objective function
f, g = fwi_objective(model0, q, dobs; options=opt)

#' Plot gradient
fig = figure()
imshow(g', vmin=-1e2, vmax=1e2, cmap="Greys", extent=[0, (n[1]-1)*d[1], (n[2]-1)*d[2], 0 ], aspect="auto")
xlabel("Lateral position(m)")
ylabel("Depth (m)")
title("FWI gradient")
display(fig)


#' LSRTM misfit and gradient
# evaluate LSRTM objective function
fj, gj = lsrtm_objective(model0, q, dD, dm; options=opt)
fjn, gjn = lsrtm_objective(model0, q, dobs, dm; nlind=true, options=opt)

#' Plot gradients
fig = figure()
imshow(gj', vmin=-1, vmax=1, cmap="Greys", extent=[0, (n[1]-1)*d[1], (n[2]-1)*d[2], 0 ], aspect="auto")
xlabel("Lateral position(m)")
ylabel("Depth (m)")
title("LSRTM gradient")
display(fig)

fig = figure()
imshow(gjn', vmin=-1, vmax=1, cmap="Greys", extent=[0, (n[1]-1)*d[1], (n[2]-1)*d[2], 0 ], aspect="auto")
xlabel("Lateral position(m)")
ylabel("Depth (m)")
title("LSRTM gradient with background data substracted")
display(fig)

#' By extension, lsrtm_objective is the same as fwi_objecive when `dm` is zero
#' And with computing of the residual. Small noise can be seen in the difference
#' due to floating point roundoff errors with openMP, but running with 
#' OMP_NUM_THREADS=1 (no parllelism) produces the exact (difference == 0) same result
#' gjn2 == g
fjn2, gjn2 = lsrtm_objective(model0, q, dobs, 0f0.*dm; nlind=true, options=opt)
fig = figure()

#' Plot gradient
imshow(gjn2', vmin=-1e2, vmax=1e2, cmap="Greys", extent=[0, (n[1]-1)*d[1], (n[2]-1)*d[2], 0 ], aspect="auto")
xlabel("Lateral position(m)")
ylabel("Depth (m)")
title("LSRTM gradient with zero perturbation")
display(fig)


#' # TWRI
#' Finally, JUDI implements TWRI, an augmented method to tackle cycle skipping. Once again we provide a computationnally efficient wrapper function that returns the objective value and necessary gradients
f, gm, gy = twri_objective(model0, q, dobs, nothing; options=opt, optionswri=TWRIOptions(params=:all))
# With on-the-fly DFT, experimental
f, gmf = twri_objective(model0, q, dobs, nothing; options=Options(frequencies=[[.009, .011], [.008, .012]]), optionswri=TWRIOptions(params=:m))

#' Plot gradients
fig = figure()
imshow(gm', vmin=-1, vmax=1, cmap="Greys", extent=[0, (n[1]-1)*d[1], (n[2]-1)*d[2], 0 ], aspect="auto")
xlabel("Lateral position(m)")
ylabel("Depth (m)")
title("TWRI gradient w.r.t m")
display(fig)

fig = figure()
imshow(gy.data[1], vmin=-1e2, vmax=1e2, cmap="PuOr", extent=[xrec[1], xrec[end], timeD/1000, 0], aspect="auto")
xlabel("Receiver position (m)")
ylabel("Time (s)")
title("TWRI gradient w.r.t y")
display(fig)

At line f, gm, gy = twri_objective(model0, q, dobs, nothing; options=opt, optionswri=TWRIOptions(params=:all)) I get an error:

ERROR: MethodError: Cannot `convert` an object of type SeisCon to an object of type Matrix{Float32}
Closest candidates are:
  convert(::Type{Array{T, N}}, ::StaticArraysCore.SizedArray{S, T, N, N, Array{T, N}}) where {S, T, N} at /home/kerim/Documents/Colada/r/julia-1.6/.julia/packages/StaticArrays/8Dz3j/src/SizedArray.jl:88
  convert(::Type{Array{T, N}}, ::StaticArraysCore.SizedArray{S, T, N, M, TData} where {M, TData<:AbstractArray{T, M}}) where {T, S, N} at /home/kerim/Documents/Colada/r/julia-1.6/.julia/packages/StaticArrays/8Dz3j/src/SizedArray.jl:82
  convert(::Type{T}, ::AbstractArray) where T<:Array at array.jl:532
  ...
Stacktrace:
 [1] twri_objective(model_full::Model, source::judiVector{Float32, Matrix{Float32}}, dObs::judiVector{Float32, SeisCon}, y::Nothing, options::JUDIOptions, optionswri::TWRIOptions)
   @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/twri_objective.jl:87
 [2] run_and_reduce(func::Function, #unused#::Nothing, nsrc::Int64, arg_func::JUDI.var"#192#194"{JUDIOptions, TWRIOptions, Model, judiVector{Float32, Matrix{Float32}}, judiVector{Float32, SeisCon}})
   @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/propagation.jl:37
 [3] twri_objective(model::Model, source::judiVector{Float32, Matrix{Float32}}, dObs::judiVector{Float32, SeisCon}, y::Nothing; options::JUDIOptions, optionswri::TWRIOptions)
   @ JUDI ~/Documents/Colada/r/julia-1.6/.julia/dev/JUDI/src/TimeModeling/Modeling/twri_objective.jl:152
 [4] top-level scope
   @ ~/Documents/Colada/r/julia-1.6/.julia/dev/ColadaSeismic/examples/modeling_basic_2D.jl:251

02_fwi_example_NLopt

Discussed in #135

Originally posted by venividivici666 August 14, 2022
When I try the "02_fwi_example_NLopt", the penultimate step did not run and no error was reported (figure below), I don't know why.
image

ERROR: LoadError: type Int64 has no field n

Hi, I am getting an error while running the example program in examples/software_paper/lsrtm_marmousi_easgd.jl

Warning: Fixed length trace flag set in stream: IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=1086467600, maxsize=Inf, ptr=3601, mark=-1)
└ @ SegyIO ~/.julia/packages/SegyIO/qkvUT/src/read/read_file.jl:26
ERROR: LoadError: type Int64 has no field n
Stacktrace:
[1] getproperty(x::Int64, f::Symbol)
@ Base ./Base.jl:42
[2] top-level scope
@ ~/.julia/environments/v1.7/lsrtm_marmousi_easgd.jl:52
in expression starting at /public/home/user/.julia/environments/v1.7/lsrtm_marmousi_easgd.jl:52

The error comes from:
x = zeros(Float32, prod(model0.n).n, p)

I tried to cast n to int64 but that doesn't seem to work.Do you have any suggestion for me. thank you.(^▽^)

LoadError: MethodError: no method matching Model(::Tuple{Int64, Int64}, ::Tuple{Float64, Float64}, ::Tuple{Int64, Int64}

Hi, I am getting an error while running the example program in examples/compressive_splsrtm/Sigsbee2A/rtm_sigsbee.jl

ERROR: LoadError: MethodError: no method matching Model(::Tuple{Int64, Int64}, ::Tuple{Float64, Float64}, ::Tuple{Int64, Int64}, ::Matr
Closest candidates are:
Model(::Any, ::Any, ::Any, ::Any, ::Any) at ~/.julia/packages/JUDI/Xrqx6/src/TimeModeling/Types/ModelStructure.jl:267
Model(::Union{Vector{Int32}, Vector{Int64}, Tuple{Integer, Integer}, Tuple{Integer, Integer, Integer}}, ::Union{Tuple{AbstractFloat, ctor{AbstractFloat}}, ::Union{Tuple{AbstractFloat, AbstractFloat}, Tuple{AbstractFloat, AbstractFloat, AbstractFloat}, Vector{AbstractFckages/JUDI/Xrqx6/src/TimeModeling/Types/ModelStructure.jl:277
Model(::Union{Vector{Int32}, Vector{Int64}, Tuple{Integer, Integer}, Tuple{Integer, Integer, Integer}}, ::Union{Tuple{AbstractFloat, ctor{AbstractFloat}}, ::Union{Tuple{AbstractFloat, AbstractFloat}, Tuple{AbstractFloat, AbstractFloat, AbstractFloat}, Vector{AbstractFling/Types/ModelStructure.jl:289

..
Stacktrace:
[1] top-level scope
@ ~/.julia/environments/v1.7/rtm_sigsbee.jl:13
in expression starting at /public/home/user/.julia/environments/v1.7/rtm_sigsbee.jl:13

It looks like the error is caused by a version update. Because there was no error in the previous version.

The current version is julia1.7+JUDI3.0.2, the previous version is julia1.4+JUDI3.0.0.

Do you have any suggestion for me. thank you.(^▽^)

can't show judiVector in jupyter notebook

I am now at version 3.0.1. This errors when doing

q

in a single cell in jupyter notebook (it works totally find in Julia's REPL in terminal) where q is a judiVector as source. Seems to be an error about something here

show(io::IO, ms::judiMultiSourceVector) = print(io, "$(string(typeof(ms))) wiht $(ms.nsrc) sources")
any thought?

StackOverflowError:

Stacktrace:
     [1] make_typealias(x::Type)
       @ Base ./show.jl:562
     [2] show_typealias(io::IOBuffer, x::Type)
       @ Base ./show.jl:723
     [3] _show_type(io::IOBuffer, x::Type)
       @ Base ./show.jl:886
     [4] show(io::IOBuffer, x::Type)
       @ Base ./show.jl:881
     [5] show_typeparams(io::IOBuffer, env::Core.SimpleVector, orig::Core.SimpleVector, wheres::Vector{TypeVar})
       @ Base ./show.jl:640
     [6] show_datatype(io::IOBuffer, x::DataType, wheres::Vector{TypeVar})
       @ Base ./show.jl:1011
     [7] show_datatype
       @ ./show.jl:989 [inlined]
     [8] _show_type(io::IOBuffer, x::Type)
       @ Base ./show.jl:889
     [9] show(io::IOBuffer, x::Type)
       @ Base ./show.jl:881
    [10] print(io::IOBuffer, x::Type)
       @ Base ./strings/io.jl:35
    [11] print_to_string(xs::Type)
       @ Base ./strings/io.jl:144
    [12] string
       @ ./strings/io.jl:185 [inlined]
    [13] show(io::IOContext{IOBuffer}, ms::judiVector{Float32, Matrix{Float32}})
       @ JUDI ~/.julia/dev/JUDI/src/TimeModeling/Types/abstract.jl:12
    [14] sprint(f::Function, args::judiVector{Float32, Matrix{Float32}}; context::IOContext{IOBuffer}, sizehint::Int64)
       @ Base ./strings/io.jl:112
    [15] alignment(io::IOContext{IOBuffer}, x::judiVector{Float32, Matrix{Float32}})
       @ Base ./show.jl:2730
    [16] alignment(io::IOContext{IOBuffer}, X::AbstractVecOrMat, rows::Vector{Int64}, cols::Vector{Int64}, cols_if_complete::Int64, cols_otherwise::Int64, sep::Int64)
       @ Base ./arrayshow.jl:68
    [17] _print_matrix(io::IOContext{IOBuffer}, X::AbstractVecOrMat, pre::String, sep::String, post::String, hdots::String, vdots::String, ddots::String, hmod::Int64, vmod::Int64, rowsA::UnitRange{Int64}, colsA::UnitRange{Int64})
       @ Base ./arrayshow.jl:204
    [18] print_matrix(io::IOContext{IOBuffer}, X::judiVector{Float32, Matrix{Float32}}, pre::String, sep::String, post::String, hdots::String, vdots::String, ddots::String, hmod::Int64, vmod::Int64) (repeats 2 times)
       @ Base ./arrayshow.jl:169
    [19] print_array
       @ ./arrayshow.jl:355 [inlined]
    [20] show(io::IOContext{IOBuffer}, #unused#::MIME{Symbol("text/plain")}, X::judiVector{Float32, Matrix{Float32}})
       @ Base ./arrayshow.jl:396
    [21] show(io::IOContext{IOBuffer}, m::String, x::judiVector{Float32, Matrix{Float32}})
       @ Base.Multimedia ./multimedia.jl:111
    [22] sprint(::Function, ::String, ::Vararg{Any}; context::IOContext{IOBuffer}, sizehint::Int64)
       @ Base ./strings/io.jl:112
    [23] print_matrix_row(io::IOContext{IOBuffer}, X::AbstractVecOrMat, A::Vector{Tuple{Int64, Int64}}, i::Int64, cols::Vector{Int64}, sep::String)
       @ Base ./arrayshow.jl:106
    [24] _print_matrix(io::IOContext{IOBuffer}, X::AbstractVecOrMat, pre::String, sep::String, post::String, hdots::String, vdots::String, ddots::String, hmod::Int64, vmod::Int64, rowsA::UnitRange{Int64}, colsA::UnitRange{Int64})
       @ Base ./arrayshow.jl:210
--- the last 7 lines are repeated 1488 more times ---
 [10441] print_matrix(io::IOContext{IOBuffer}, X::judiVector{Float32, Matrix{Float32}}, pre::String, sep::String, post::String, hdots::String, vdots::String, ddots::String, hmod::Int64, vmod::Int64) (repeats 2 times)
       @ Base ./arrayshow.jl:169
 [10442] print_array
       @ ./arrayshow.jl:355 [inlined]
 [10443] show(io::IOContext{IOBuffer}, #unused#::MIME{Symbol("text/plain")}, X::judiVector{Float32, Matrix{Float32}})
       @ Base ./arrayshow.jl:396
 [10444] limitstringmime(mime::MIME{Symbol("text/plain")}, x::judiVector{Float32, Matrix{Float32}})
       @ IJulia ~/.julia/packages/IJulia/AQu2H/src/inline.jl:43
 [10445] display_mimestring
       @ ~/.julia/packages/IJulia/AQu2H/src/display.jl:71 [inlined]
 [10446] display_dict(x::judiVector{Float32, Matrix{Float32}})
       @ IJulia ~/.julia/packages/IJulia/AQu2H/src/display.jl:102
 [10447] #invokelatest#2
       @ ./essentials.jl:716 [inlined]
 [10448] invokelatest
       @ ./essentials.jl:714 [inlined]
 [10449] execute_request(socket::ZMQ.Socket, msg::IJulia.Msg)
       @ IJulia ~/.julia/packages/IJulia/AQu2H/src/execute_request.jl:112
 [10450] #invokelatest#2
       @ ./essentials.jl:716 [inlined]
 [10451] invokelatest
       @ ./essentials.jl:714 [inlined]
 [10452] eventloop(socket::ZMQ.Socket)
       @ IJulia ~/.julia/packages/IJulia/AQu2H/src/eventloop.jl:8

`judiTopmute` ERROR: n not defined

Hi,

It seems n is missing here. It should probably be:

judiTopmute(n::NTuple{N, Integer}, wb::Array{T, Nw}, taperwidth::Integer) where {T, N, Nw} = TopMute(prod(n), wb, taperwidth)

# instead of:
# judiTopmute(::NTuple{N, Integer}, wb::Array{T, Nw}, taperwidth::Integer) where {T, N, Nw} = TopMute(prod(n), wb, taperwidth)

True model not found

I have been trying to reproduce the figures in the README, but I cannot find the true model. Would this be something which can be added to the repository? Maybe in the data folder? Cheers!

Source geometry is confusing

MFE

using JUDI
using SegyIO
datapath = joinpath(dirname(pathof(JUDI)))*"/../data/"
nsrc = 2
block = segy_read(datapath*"unit_test_shot_records_$(nsrc).segy"; warn_user=false)
src_geometry = Geometry(block; key="source", segy_depth_key="SourceSurfaceElevation")
println(src_geometry.xloc)    

This is a part of the test and it outputs src_geometry.xloc as

julia> println(src_geometry.xloc) 
Float32[100.0, 1100.0]

I personally find it quite confusing because there are 2 sources but only here is 1 vector for xloc. Typically this means they are simultaneous but in this case they are not.

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

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

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.