Skip to content

Commit

Permalink
Improve docs (#16)
Browse files Browse the repository at this point in the history
* add authors

* update RST syntax

* improve documentation, add new example

* implement real or imaginary plot in curveshow

* new example

* improve thumbnails

* add disks example
  • Loading branch information
cako authored Mar 12, 2023
1 parent 4a0c005 commit 4269751
Show file tree
Hide file tree
Showing 15 changed files with 340 additions and 360 deletions.
2 changes: 2 additions & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Carlos Alberto da Costa Filho, [@cako](https://github.com/cako)
Matteo Ravasi, [@mrava87](https://github.com/mrava87)
53 changes: 25 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
[![Documentation](https://github.com/PyLops/curvelops/actions/workflows/pages/pages-build-deployment/badge.svg?branch=gh-pages)](https://pylops.github.io/curvelops/)
[![Slack Status](https://img.shields.io/badge/chat-slack-green.svg)](https://pylops.slack.com)

# curvelops

Python wrapper for [CurveLab](http://www.curvelet.org)'s 2D and 3D curvelet transforms. It uses the [PyLops](https://pylops.readthedocs.io/) design framework to provide the forward and inverse curvelet transforms as matrix-free linear operations. If you are still confused, check out [some examples](https://github.com/PyLops/curvelops/tree/main/examples) below or the [PyLops website](https://pylops.readthedocs.io/)!
Python wrapper for [CurveLab](http://www.curvelet.org)'s 2D and 3D curvelet
transforms. It uses the [PyLops](https://pylops.readthedocs.io/) design
framework to provide the forward and inverse curvelet transforms as matrix-free
linear operations. If you are still confused, check out
[some examples](https://github.com/PyLops/curvelops/tree/main/examples) below
or the [PyLops website](https://pylops.readthedocs.io/)!

## Installation

Expand All @@ -9,13 +17,14 @@ Installing `curvelops` requires the following external components:
- [FFTW](http://www.fftw.org/download.html) 2.1.5
- [CurveLab](http://curvelet.org/software.html) >= 2.0.2

Both of these packages _must be installed manually_. See more information below.
Both of these packages _must be installed manually_. See more information in
the [Documentation](https://pylops.github.io/curvelops/installation.html#requirements).
After these are installed, you may install `curvelops` with:

```bash
export FFTW=/path/to/fftw
export FDCT=/path/to/CurveLab
python3 -m pip install git+https://github.com/PyLops/curvelops@0.21
export FFTW=/path/to/fftw-2.1.5
export FDCT=/path/to/CurveLab-2.1.3
python3 -m pip install git+https://github.com/PyLops/curvelops@0.22
```

as long as you are using a `pip>=10.0`. To check, run `python3 -m pip --version`.
Expand All @@ -35,35 +44,23 @@ xinv = FDCT.H @ c
np.testing.assert_allclose(x, xinv)
```

An excellent place to see how to use the library is the `examples/` folder. `Demo_Single_Curvelet` for example contains a `curvelops` version of the CurveLab Matlab demo.
An excellent place to see how to use the library is the
[Gallery](https://pylops.github.io/curvelops/gallery/index.html). You can also
find more examples in the
[`notebooks/`](https://github.com/PyLops/curvelops/tree/main/notebooks) folder.

![Demo](https://github.com/PyLops/curvelops/raw/main/docssrc/source/static/demo.png)
![Reconstruction](https://github.com/PyLops/curvelops/raw/main/docssrc/source/static/reconstruction.png)

## Tips and Tricks for Dependencies

### FFTW

For FFTW 2.1.5, you must compile with position-independent code support. Do that with

```bash
./configure --with-pic --prefix=/home/user/opt/fftw-2.1.5 --with-gcc=/usr/bin/gcc
```

The `--prefix` and `--with-gcc` are optional and determine where it will install FFTW and where to find the GCC compiler, respectively. We recommend using the same compile for FFTW, CurveLab and `curvelops`.

### CurveLab

In the file `makefile.opt` set `FFTW_DIR`, `CC` and `CXX` variables as required in the instructions. To keep things consistent, set `FFTW_DIR=/home/user/opt/fftw-2.1.5` (or whatever directory was used in the `--prefix` option above). For the other options (`CC` and `CXX`), use the same compiler which was used to compile FFTW.

### curvelops

The `FFTW` variable is the same as `FFTW_DIR` as provided in the CurveLab installation. The `FDCT` variable points to the root of the CurveLab installation. It will be something like `/path/to/CurveLab-2.1.3` for the latest version.

## Useful links

* [Paul Goyes](https://github.com/PAULGOYES) has kindly contributed a rundown of how to install curvelops: [link to YouTube video (in Spanish)](https://www.youtube.com/watch?v=LAFkknyOpGY).

## Disclaimer
## Note

This package contains no CurveLab code apart from function calls. It is provided to simplify the use of CurveLab in a Python environment. Please ensure you own a CurveLab license as per required by the authors. See the [CurveLab website](http://curvelet.org/software.html) for more information. All CurveLab rights are reserved to Emmanuel Candes, Laurent Demanet, David Donoho and Lexing Ying.
This package contains no CurveLab code apart from function calls. It is
provided to simplify the use of CurveLab in a Python environment. Please ensure
you own a CurveLab license as per required by the authors. See the
[CurveLab website](http://curvelet.org/software.html) for more information. All
CurveLab rights are reserved to Emmanuel Candes, Laurent Demanet, David Donoho
and Lexing Ying.
12 changes: 10 additions & 2 deletions curvelops/plot/_curvelet.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def curveshow(
k_space: bool = False,
basesize: int = 5,
showaxis: bool = False,
real: bool = True,
kwargs_imshow: Optional[dict] = None,
) -> List[Figure]:
"""Display curvelet coefficients in each wedge as images.
Expand All @@ -43,6 +44,9 @@ def curveshow(
``rows = floor(sqrt(nangles))`` and ``cols = ceil(nangles / rows)``
showaxis : :obj:`bool`, optional
Turn on axis lines and labels, by default False.
real : :obj:`bool`, optional
Plot real or imaginary part of curvelet coefficients. Only applicable
when ``k_space`` is False.
kwargs_imshow : ``Optional[dict]``, optional
Arguments to be passed to :obj:`matplotlib.pyplot.imshow`.
Expand Down Expand Up @@ -85,6 +89,7 @@ def fft(x):
else:
kwargs_imshow = {**_kwargs_imshow_default, **kwargs_imshow}

figsize_aspect = c_struct[0][0].shape[0] / c_struct[0][0].shape[1]
figs_axes = []
for iscale, c_scale in enumerate(c_struct):
nangles = len(c_scale)
Expand All @@ -93,7 +98,7 @@ def fft(x):
fig, axes = plt.subplots(
rows,
cols,
figsize=(basesize * cols, basesize * rows),
figsize=(basesize * cols, figsize_aspect * basesize * rows),
)
fig.suptitle(f"Scale {iscale} ({nangles} wedge{'s' if nangles > 1 else ''})")
figs_axes.append((fig, axes))
Expand All @@ -103,7 +108,10 @@ def fft(x):
if k_space:
ax.imshow(np.abs(fft(c_wedge)), **kwargs_imshow)
else:
ax.imshow(c_wedge.real, **kwargs_imshow)
if real:
ax.imshow(c_wedge.real, **kwargs_imshow)
else:
ax.imshow(c_wedge.imag, **kwargs_imshow)
if nangles > 1:
ax.set(title=f"Wedge {iwedge}")
if not showaxis:
Expand Down
15 changes: 15 additions & 0 deletions docssrc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,5 +219,20 @@
exclude_patterns = ["_build", "**.ipynb_checkpoints", "**.ipynb", "**.md5"]
source_suffix = ".rst"

# Copybutton config
copybutton_prompt_text = r">>> |\.\.\. |\$ |In \[\d*\]: | {2,5}\.\.\.: | {5,8}: "
copybutton_prompt_is_regexp = True

# Pydata config
html_theme_options = {
"github_url": "https://github.com/PyLops/curvelops",
"external_links": [{"url": "https://github.com/PyLops/pylops", "name": "PyLops"}],
"header_links_before_dropdown": 10,
"show_toc_level": 2,
}
html_context = {
"github_user": "PyLops",
"github_repo": "curvelops",
"github_version": "main",
"doc_path": "docssrc",
}
5 changes: 2 additions & 3 deletions docssrc/source/contributing.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
============
Contributing
============

Expand All @@ -7,7 +6,7 @@ in the `GitHub repo <https://github.com/PyLops/pylops>`__. You are also
welcome to join the `PyLops slack channel <https://pylops.slack.com/>`__.

Installation for developers
===========================
---------------------------

Developers should clone the
`main <https://github.com/PyLops/curvelops/tree/main>`__ branch of the
Expand Down Expand Up @@ -35,7 +34,7 @@ Developers should also install `pre-commit <https://pre-commit.com/>`__ hooks wi
Developer workflow
==================
------------------

Developers should start from a fresh copy of main with

Expand Down
3 changes: 1 addition & 2 deletions docssrc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
========
Overview
========

Expand All @@ -19,7 +18,7 @@ Visit :ref:`Installation` and then get started with the

.. attention::
`CurveLab <http://www.curvelet.org>`__ is a proprietary library which must be
sourced independently by the user. It is free for academic use. This package
sourced independently by the user. It is free for academic use. Curvelops
contains no CurveLab code apart from function calls.

.. note::
Expand Down
9 changes: 4 additions & 5 deletions docssrc/source/installation.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
.. _installation:

============
Installation
============

.. _requirements:

Requirements
============
------------

Installing Curvelops requires the following external components:

Expand All @@ -17,7 +16,7 @@ Installing Curvelops requires the following external components:
Both of these packages must be installed manually.

Installing FFTW
---------------
~~~~~~~~~~~~~~~
Download and install with:


Expand All @@ -35,7 +34,7 @@ install FFTW and where to find the GCC compiler, respectively. We recommend
using the same compiler for FFTW and CurveLab.

Installing CurveLab
-------------------
~~~~~~~~~~~~~~~~~~~
After downloading the latest version of CurveLab, run

.. code-block:: console
Expand All @@ -54,7 +53,7 @@ the ouput of ``which g++`` (or whatever C++ compiler is the equivalent of
the selected ``CC`` compiler).

Installing Curvelops
====================
--------------------

Once FFTW and CurveLab are installed, install Curvelops with:

Expand Down
1 change: 0 additions & 1 deletion docssrc/source/modules.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.. _API:

===
API
===

Expand Down
309 changes: 0 additions & 309 deletions examples/Demo_Sigmoid_Visualization.ipynb

This file was deleted.

3 changes: 2 additions & 1 deletion examples/plot_curvelets_in_fk.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
This example shows the regions in the FK domain where each
curvelet coefficient occupies.
"""
# sphinx_gallery_thumbnail_number = 5

# %%
import matplotlib as mpl
import matplotlib.pyplot as plt
Expand Down Expand Up @@ -87,7 +89,6 @@ def create_dirac_wedge(Cop, scale, wedge):
axes = np.atleast_1d(axes).ravel()
wedge_scale_fk_abs = np.zeros_like(data_empty)
for iw, (fdct_wedge, ax) in enumerate(zip(fdct_scale, axes), start=1):

dirac_wedge = create_dirac_wedge(Cop, j - 1, iw - 1)
dirac_wedge_fk = np.fft.fftshift(
np.fft.fft2(np.fft.ifftshift(dirac_wedge), norm="ortho")
Expand Down
3 changes: 2 additions & 1 deletion examples/plot_seismic_regularization.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
r"""
3. Seismic Regularization
5. Seismic Regularization
=========================
This example shows how to use the Curvelet transform to
condition a missing-data seismic regularization problem.
"""
# sphinx_gallery_thumbnail_number = 2

# %%
import warnings
Expand Down
9 changes: 5 additions & 4 deletions examples/plot_sigmoid.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
r"""
2. Sigmoid Example
==================
This example shows the effectiveness of curvelets in
describing a typing subsurface structure. It compares
the Curvelet transform with the Wavelet and Seislet
transforms.
This example shows the effectiveness of curvelets in describing a typical
subsurface structure. It compares the Curvelet transform with the Wavelet
and Seislet transforms.
"""
# sphinx_gallery_thumbnail_number = 3

# %%
import matplotlib.pyplot as plt
import numpy as np
Expand Down
108 changes: 108 additions & 0 deletions examples/plot_sigmoid_coefficients.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
r"""
3. Visualizing Curvelet Coefficients
====================================
This example shows the how to visualize curvelet coefficients of an image,
using as example a typical subsurface structure.
"""
# sphinx_gallery_thumbnail_number = 3

# %%
import matplotlib.pyplot as plt
import numpy as np

from curvelops import FDCT2D, apply_along_wedges, curveshow

# %%
# Input data
# ==========

# %%
inputfile = "../testdata/sigmoid.npz"

d = np.load(inputfile)
d = d["sigmoid"]
nx, nt = d.shape
dx, dt = 0.005, 0.004
x, t = np.arange(nx) * dx, np.arange(nt) * dt

# %%
aspect = dt / dx
opts_plot = dict(
extent=(x[0], x[-1], t[-1], t[0]),
cmap="gray",
interpolation="lanczos",
aspect=aspect,
)
vmax = 0.5 * np.max(np.abs(d))
figsize_aspect = aspect * nt / nx
fig, ax = plt.subplots(figsize=(8, figsize_aspect * 8), sharey=True, sharex=True)
ax.imshow(d.T, vmin=-vmax, vmax=vmax, **opts_plot)
ax.set(xlabel="Position [m]", ylabel="Time [s]", title=f"Data shape {d.shape}")
fig.tight_layout()

# %%
# Create Curvelet Transform
# =========================
nbscales = 4
nbangles_coarse = 8
allcurvelets = False # Last scale will be a wavelet transform

# %%
Cop = FDCT2D(
d.shape,
nbscales=nbscales,
nbangles_coarse=nbangles_coarse,
allcurvelets=allcurvelets,
)

# %%
# Convert to a list of lists of ndarrays.
d_fdct_struct = Cop.struct(Cop @ d)

# %%
# Real part of FDCT coefficients
# ==============================
# Curvelet coefficients are essentially directionally-filtered, shrunk versions
# of the original signal. Note that the "shrinking" does not preserve aspect
# ratio.

# %%
for j, c_scale in enumerate(d_fdct_struct, start=1):
nangles = len(c_scale)
rows = int(np.floor(np.sqrt(nangles)))
cols = int(np.ceil(nangles / rows))
fig, axes = plt.subplots(
rows,
cols,
figsize=(5 * rows, figsize_aspect * 5 * rows),
)
fig.suptitle(f"Scale {j} ({len(c_scale)} wedge{'s' if len(c_scale) > 1 else ''})")
axes = np.atleast_1d(axes).ravel()
vmax = 0.5 * max(np.abs(Cweg).max() for Cweg in c_scale)
for iw, (fdct_wedge, ax) in enumerate(zip(c_scale, axes), start=1):
# Note that wedges are transposed in comparison to the input vector.
# This is due to the underlying implementation of the transform. In
# order to plot in the same manner as the data, we must first
# transpose the wedge. We will using the transpose of the wedge for
# visualization.
c = fdct_wedge.real.T
ax.imshow(c.T, vmin=-vmax, vmax=vmax, **opts_plot)
ax.set(title=f"Wedge {iw} shape {c.shape}")
ax.axis("off")
fig.tight_layout()

# %%
# Imaginagy part of FDCT coefficients
# ===================================
# Curvelops includes much of the above logic wrapped in the following
# :py:class:`curvelops.plot.cuveshow`. Since we

# Normalize each coefficient by max abs
y_norm = apply_along_wedges(d_fdct_struct, lambda w, *_: w / np.abs(w).max())

# %%
figs = curveshow(
y_norm,
real=False,
kwargs_imshow={**opts_plot, "vmin": -0.5, "vmax": 0.5},
)
Loading

0 comments on commit 4269751

Please sign in to comment.