Repository: isce-framework/dolphin (language: python)

Issue:
Enforce consistency between jax and jaxlib
Consistency between jax and jaxlib can be enforced by installing the most recent versions via pip, which is currently not possible through conda where the two packages are out of sync.

This is necessary as dolphin would crash early on in processing if the two packages are not in sync.


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/draft-pdf.yml b/.github/workflows/draft-pdf.yml
new file mode 100644
index 00000000..e183892b
--- /dev/null
+++ b/.github/workflows/draft-pdf.yml
@@ -0,0 +1,21 @@
+name: Draft PDF
+on: [push]
+
+jobs:
+  paper:
+    runs-on: ubuntu-latest
+    name: Paper Draft
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+      - name: Build draft PDF
+        uses: openjournals/openjournals-draft-action@master
+        with:
+          journal: joss
+          # This should be the path to the paper within your repo.
+          paper-path: paper/paper.md
+      - name: Upload
+        uses: actions/upload-artifact@v3
+        with:
+          name: paper
+          path: paper/paper.pdf
diff --git a/docs/references.bib b/docs/references.bib
index 67f70d1c..fdb1e6a4 100644
--- a/docs/references.bib
+++ b/docs/references.bib
@@ -41,6 +41,37 @@ @article{Ansari2021StudySystematicBias
   keywords = {Big Data,Decorrelation,deformation estimation,differential interferometric synthetic aperture radar (SAR) (DInSAR),distributed scatterers (DSs),error analysis,Fading channels,Moisture,near real-time (NRT) processing,phase inconsistencies,signal decorrelation,Strain,Synthetic aperture radar,Systematics,Time series analysis,time-series analysis}
 }
 
+@article{Bekaert2021IntroducingOPERAProject,
+  title = {Introducing the {{OPERA Project}} for {{Systematic Surface Water}}, {{Surface Deformation}}, and {{Surface Disturbance Data Products}} from {{Satellite Observations}}},
+  author = {Bekaert, David and Fattahi, Heresh and Jones, John and Hansen, Matthew and Kwoun, Oh-Ig and Lewis, Steven and Meyer, Franz and Osmanoglu, Batuhan and Marshak, Charles and Hamlington, Benjamin and Bato, Mary Grace and Brancato, Virginia and Shiroma, Gustavo and Jung, Jungkyo and Jai, Benhan and Buckley, Sean and Cruz, Jennifer},
+  year = {2021},
+  month = dec,
+  volume = {2021},
+  pages = {G42A-07},
+  urldate = {2024-05-15}
+}
+
+@misc{Bradbury2018JAXComposableTransformations,
+  title = {{{JAX}}: Composable Transformations of {{Python}}+{{NumPy}} Programs},
+  author = {Bradbury, James and Frostig, Roy and Hawkins, Peter and Johnson, Matthew James and Leary, Chris and Maclaurin, Dougal and Necula, George and Paszke, Adam and VanderPlas, Jake and {Wanderman-Milne}, Skye and Zhang, Qiao},
+  year = {2018}
+}
+
+@article{Chen2001TwodimensionalPhaseUnwrapping,
+  title = {Two-Dimensional Phase Unwrapping with Use of Statistical Models for Cost Functions in Nonlinear Optimization},
+  author = {Chen, Curtis W. and Zebker, Howard A.},
+  year = {2001},
+  month = feb,
+  journal = {Journal of the Optical Society of America A},
+  volume = {18},
+  number = {2},
+  pages = {338},
+  issn = {1084-7529, 1520-8532},
+  doi = {10.1364/JOSAA.18.000338},
+  urldate = {2024-05-16},
+  langid = {english}
+}
+
 @article{Chen2012IonosphericArtifactsSimultaneous,
   title = {Ionospheric {{Artifacts}} in {{Simultaneous L-Band InSAR}} and {{GPS Observations}}},
   author = {Chen, Jingyi and Zebker, Howard A.},
@@ -68,6 +99,32 @@ @article{Chen2015PersistentScattererInterpolation
   keywords = {decorrelation,groundwater,InSAR deformation map,persistent scatterers}
 }
 
+@article{Fattahi2019FRInGEFullResolutionInSAR,
+  title = {{{FRInGE}}; {{Full-Resolution InSAR}} Timeseries Using {{Generalized Eigenvectors}}},
+  author = {Fattahi, H. and Agram, P. S. and Tymofyeyeva, E. and Bekaert, D. P.},
+  year = {2019},
+  month = dec,
+  volume = {2019},
+  pages = {G11B-0514},
+  urldate = {2024-05-16},
+  keywords = {1209 Tectonic deformation,1211 Non-tectonic deformation,1240 Satellite geodesy: results,1241 Satellite geodesy: technical issues,GEODESY AND GRAVITY}
+}
+
+@article{Ferretti2011NewAlgorithmProcessing,
+  title = {A New Algorithm for Processing Interferometric Data-Stacks: {{SqueeSAR}}},
+  author = {Ferretti, Alessandro and Fumagalli, Alfio and Novali, Fabrizio and Prati, Claudio and Rocca, Fabio and Rucci, Alessio},
+  year = {2011},
+  journal = {IEEE Transactions on Geoscience and Remote Sensing},
+  volume = {49},
+  number = {9},
+  pages = {3460--3470},
+  publisher = {IEEE},
+  issn = {01962892},
+  doi = {10.1109/TGRS.2011.2124465},
+  isbn = {0196-2892},
+  keywords = {1pass,Coherence matrix,distributed scatterers (DS),InSAR,permanent scatterers,space-adaptive filtering}
+}
+
 @article{Fornaro2015CAESARApproachBased,
   title = {{{CAESAR}}: {{An Approach Based}} on {{Covariance Matrix Decomposition}} to {{Improve Multibaseline}}--{{Multitemporal Interferometric SAR Processing}}},
   shorttitle = {{{CAESAR}}},
@@ -97,6 +154,24 @@ @article{Guarnieri2008ExploitationTargetStatistics
   keywords = {Decorrelation,decorrelation models,ENVISAT images,geophysical techniques,geophysics computing,image processing,Information retrieval,interferometric phases,Interferometry,line-of-sight displacement,line-of-sight motion,Maximum likelihood estimation,Monte Carlo simulations,multiimage synthetic aperture radar interferometry,Phase estimation,physical parameters,radar interferometry,Radar scattering,remote sensing by radar,residual topography,SAR interferometry applications,Statistical distributions,statistics,Statistics,stochastic processes,Surfaces,synthetic aperture radar,Synthetic aperture radar interferometry,target statistics,topography (Earth),Yield estimation}
 }
 
+@article{HoTongMinh2022CompressedSARInterferometry,
+  title = {Compressed {{SAR Interferometry}} in the {{Big Data Era}}},
+  author = {Ho Tong Minh, Dinh and Ngo, Yen-Nhi},
+  year = {2022},
+  month = jan,
+  journal = {Remote Sensing},
+  volume = {14},
+  number = {2},
+  pages = {390},
+  publisher = {Multidisciplinary Digital Publishing Institute},
+  issn = {2072-4292},
+  doi = {10.3390/rs14020390},
+  urldate = {2024-05-15},
+  copyright = {http://creativecommons.org/licenses/by/3.0/},
+  langid = {english},
+  keywords = {ComSAR,InSAR,PSDS,PSI,subsidence,TomoSAR,Vauvert}
+}
+
 @article{Mirzaee2023NonlinearPhaseLinking,
   title = {Non-Linear Phase Linking Using Joined Distributed and Persistent Scatterers},
   author = {Mirzaee, Sara and Amelung, Falk and Fattahi, Heresh},
@@ -127,6 +202,18 @@ @article{Parizzi2011AdaptiveInSARStack
   keywords = {adaptive InSAR stack multilooking,Adaptive multilooking,amplitude-based algorithm,backscatter,backscatter amplitude statistics,Coherence,coherence estimation,complex correlation,interferometric phase,interferometric synthetic aperture radar capability,interferometry,Kernel,phase signatures,Pixel,radar backscatter statistics,radar imaging,radar interferometry,Remote sensing,Shape,synthetic aperture radar,Synthetic aperture radar,synthetic aperture radar (SAR)}
 }
 
+@inproceedings{Rosen2018InSARScientificComputing,
+  title = {The {{InSAR Scientific Computing Environment}} 3.0: {{A Flexible Framework}} for {{NISAR Operational}} and {{User-Led Science Processing}}},
+  author = {Rosen, Paul A. and Gurrola, Eric M. and Agram, Piyush and Cohen, Joshua and Lavalle, Marco and Riel, Bryan V. and Fattahi, Heresh and Aivazis, Michael A.G. and Simons, Mark and Buckley, Sean M.},
+  year = {2018},
+  month = jul,
+  pages = {4897--4900},
+  publisher = {IEEE},
+  address = {Valencia},
+  doi = {10.1109/IGARSS.2018.8517504},
+  langid = {english},
+}
+
 @article{Siddiqui1962ProblemsConnectedRayleigh,
   title = {Some Problems Connected with {{Rayleigh}} Distributions},
   author = {Siddiqui, M.M.},
@@ -154,6 +241,21 @@ @article{Wang2022AccuratePersistentScatterer
   keywords = {Decorrelation,Interferometric Synthetic Aperture Radar (InSAR),Persistent Scatterer (PS),Phase measurement,phase similarity,Radar,Radar measurements,Radar scattering,Strain,surface deformation,Synthetic aperture radar}
 }
 
+@article{Yunjun2019SmallBaselineInSAR,
+  title = {Small Baseline {{InSAR}} Time Series Analysis: {{Unwrapping}} Error Correction and Noise Reduction},
+  shorttitle = {Small Baseline {{InSAR}} Time Series Analysis},
+  author = {Yunjun, Zhang and Fattahi, Heresh and Amelung, Falk},
+  year = {2019},
+  month = dec,
+  journal = {Computers \& Geosciences},
+  volume = {133},
+  pages = {104331},
+  issn = {00983004},
+  doi = {10.1016/j.cageo.2019.104331},
+  urldate = {2020-08-14},
+  langid = {english}
+}
+
 @article{Zwieback2022CheapValidRegularizers,
   title = {Cheap, Valid Regularizers for Improved Interferometric Phase Linking},
   author = {Zwieback, S.},
diff --git a/paper/Makefile b/paper/Makefile
new file mode 100644
index 00000000..6d8a9bc1
--- /dev/null
+++ b/paper/Makefile
@@ -0,0 +1,7 @@
+DOCKER_CMD = docker run --rm -it -v $(PWD):/data -u $$(id -u):$$(id -g)
+PLATFORM = linux/amd64
+
+.PHONY: build
+
+build:
+	$(DOCKER_CMD) --platform $(PLATFORM) openjournals/inara -o pdf,crossref paper.md
diff --git a/paper/README.md b/paper/README.md
new file mode 100644
index 00000000..a43a598b
--- /dev/null
+++ b/paper/README.md
@@ -0,0 +1,9 @@
+# JOSS paper submission
+
+To build the paper locally:
+
+```bash
+make build
+```
+
+The default for `make build` assumes you are running an ARM Mac; if you are not, you need to specify the `PLATFORM` variable (e.g. `PLATFORM=linux/amd64 make build`)
diff --git a/paper/codemeta.json b/paper/codemeta.json
new file mode 100644
index 00000000..f32cf658
--- /dev/null
+++ b/paper/codemeta.json
@@ -0,0 +1,44 @@
+{
+  "@context": "https://raw.githubusercontent.com/codemeta/codemeta/master/codemeta.jsonld",
+  "@type": "Code",
+  "author": [
+    {
+      "@id": "https://orcid.org/0000-0002-3055-5731",
+      "@type": "Person",
+      "email": "scott.j.staniewicz@jpl.nasa.gov",
+      "name": "Scott Staniewicz",
+      "affiliation": "NASA Jet Propulsion Laboratory"
+    },
+    {
+      "@id": "",
+      "@type": "Person",
+      "email": "",
+      "name": "Sara Mirzaee",
+      "affiliation": "NASA Jet Propulsion Laboratory"
+    },
+    {
+      "@id": "",
+      "@type": "Person",
+      "email": "",
+      "name": "Geoffrey Gunter",
+      "affiliation": "NASA Jet Propulsion Laboratory"
+    },
+    {
+      "@id": "",
+      "@type": "Person",
+      "email": "",
+      "name": "Heresh Fattahi",
+      "affiliation": "NASA Jet Propulsion Laboratory"
+    }
+  ],
+  "identifier": "",
+  "codeRepository": "https://github.com/isce-framework/dolphin",
+  "datePublished": "2024-03-05",
+  "dateModified": "2024-03-05",
+  "dateCreated": "2024-03-05",
+  "description": "An InSAR phase linking library for large scale PS/DS processing",
+  "keywords": "insar, time series, remote sensing, phase linking, deformation, persistent scatterers",
+  "license": "BSD-3 OR Apache 2.0",
+  "title": "dolphin",
+  "version": "v0.16.0"
+}
diff --git a/paper/figures/bristol-velocity-sequential.png b/paper/figures/bristol-velocity-sequential.png
new file mode 100644
index 00000000..5a2f536b
Binary files /dev/null and b/paper/figures/bristol-velocity-sequential.png differ
diff --git a/paper/figures/make_plot.py b/paper/figures/make_plot.py
new file mode 100644
index 00000000..49d0e892
--- /dev/null
+++ b/paper/figures/make_plot.py
@@ -0,0 +1,33 @@
+import sys
+from pathlib import Path
+
+import apertools.plotting
+import cartopy.crs as ccrs
+import matplotlib.pyplot as plt
+import rioxarray
+
+p = Path(__file__).parent
+
+filename = "velocity_compressed.tif"
+image = rioxarray.open_rasterio(p / filename).sel(band=1)
+image_ll = image[::4, ::4].rio.reproject("EPSG:4326")
+
+fig, ax = apertools.plotting.plot_image_with_background(
+    image_ll.where(image_ll != 0),
+    cbar_label="[mm / year]",
+    cmap="RdBu_r",
+    vmax=10,
+    vmin=-10,
+    tile_zoom_level=9,
+    figsize=(4),
+    interpolation="none",
+)
+apertools.plotting.add_ticks(ax, resolution=0.5)
+apertools.plotting.add_zebra_frame(ax, crs=ccrs.PlateCarree())
+
+fig.tight_layout()
+if len(sys.argv) > 1 and sys.argv[1] == "--show":
+    plt.show(block=True)
+
+outname = p / "bristol-velocity-sequential.png"
+fig.savefig(outname, dpi=300, transparent=True)
diff --git a/paper/figures/velocity_compressed.tif b/paper/figures/velocity_compressed.tif
new file mode 100644
index 00000000..710bf1bf
Binary files /dev/null and b/paper/figures/velocity_compressed.tif differ
diff --git a/paper/generate b/paper/generate
new file mode 100755
index 00000000..d56d7f7d
--- /dev/null
+++ b/paper/generate
@@ -0,0 +1,146 @@
+#!/usr/bin/ruby
+
+# For an OO language, this is distinctly procedural. Should probably fix that.
+require 'json'
+
+details = Hash.new({})
+
+capture_params = [
+  { :name => "title", :message => "Enter project name." },
+  { :name => "url", :message => "Enter the URL of the project repository." },
+  { :name => "description", :message => "Enter the (short) project description." },
+  { :name => "license", :message => "Enter the license this software shared under. (hit enter to skip)\nFor example MIT, BSD, GPL v3.0, Apache 2.0" },
+  { :name => "doi", :message => "Enter the DOI of the archived version of this code. (hit enter to skip)\nFor example http://dx.doi.org/10.6084/m9.figshare.828487" },
+  { :name => "keywords", :message => "Enter keywords that should be associated with this project (hit enter to skip)\nComma-separated, for example: turkey, chicken, pot pie" },
+  { :name => "version", :message => "Enter the version of your software (hit enter to skip)\nSEMVER preferred: http://semver.org e.g. v1.0.0" }
+]
+
+puts "I'm going to try and help you prepare some things for your JOSS submission"
+puts "If all goes well then we'll have a nice codemeta.json file soon..."
+puts ""
+puts "************************************"
+puts "*    First, some basic details     *"
+puts "************************************"
+puts ""
+
+# Loop through the desired captures and print out for clarity
+capture_params.each do |param|
+  puts param[:message]
+  print "> "
+  input = gets
+
+  details[param[:name]] = input.chomp
+
+  puts ""
+  puts "OK, your project has #{param[:name]}: #{input}"
+  puts ""
+end
+
+puts ""
+puts "************************************"
+puts "*        Experimental stuff        *"
+puts "************************************"
+puts ""
+
+puts "Would you like me to try and build a list of authors for you?"
+puts "(You need to be running this script in a git repository for this to work)"
+print "> (Y/N)"
+answer = gets.chomp
+
+case answer.downcase
+when "y", "yes"
+
+  # Use git shortlog to extract a list of author names and commit counts.
+  # Note we don't extract emails here as there's often different emails for
+  # each user. Instead we capture emails at the end.
+
+  git_log = `git shortlog --summary --numbered --no-merges`
+
+  # ["252\tMichael Jackson", "151\tMC Hammer"]
+  authors_and_counts = git_log.split("\n").map(&:strip)
+
+  authors_and_counts.each do |author_count|
+    count, author = author_count.split("\t").map(&:strip)
+
+    puts "Looks like #{author} made #{count} commits"
+    puts "Add them to the output?"
+    print "> (Y/N)"
+    answer = gets.chomp
+
+    # If a user chooses to add this author to the output then we ask for some
+    # additional information including their email, ORCID and affiliation.
+    case answer.downcase
+    when "y", "yes"
+      puts "What is #{author}'s email address? (hit enter to skip)"
+      print "> "
+      email = gets.chomp
+
+      puts "What is #{author}'s ORCID? (hit enter to skip)"
+      puts "For example: http://orcid.org/0000-0000-0000-0000"
+      print "> "
+      orcid = gets.chomp
+
+      puts "What is #{author}'s affiliation? (hit enter to skip)"
+      print "> "
+      affiliation = gets.chomp
+
+
+      details['authors'].merge!(author => { 'commits' => count,
+                                            'email' => email,
+                                            'orcid' => orcid,
+                                            'affiliation' => affiliation })
+
+    when "n", "no"
+      puts "OK boss..."
+      puts ""
+    end
+  end
+when "n", "no"
+  puts "OK boss..."
+  puts ""
+end
+
+puts "Reticulating splines"
+
+5.times do
+  print "."
+  sleep 0.5
+end
+
+puts ""
+puts "Generating some JSON goodness..."
+
+# TODO: work out how to use some kind of JSON template here.
+# Build the output list of authors from the inputs we've collected.
+output_authors = []
+
+details['authors'].each do |author_name, values|
+  entry = {
+    "@id" => values['orcid'],
+    "@type" => "Person",
+    "email" => values['email'],
+    "name" => author_name,
+    "affiliation" => values['affiliation']
+  }
+  output_authors << entry
+end
+
+# TODO: this is currently a static template (written out here). It would be good
+# to do something smarter here.
+output = {
+  "@context" => "https://raw.githubusercontent.com/codemeta/codemeta/master/codemeta.jsonld",
+  "@type" => "Code",
+  "author" => output_authors,
+  "identifier" => details['doi'],
+  "codeRepository" => details['url'],
+  "datePublished" => Time.now.strftime("%Y-%m-%d"),
+  "dateModified" => Time.now.strftime("%Y-%m-%d"),
+  "dateCreated" => Time.now.strftime("%Y-%m-%d"),
+  "description" => details['description'],
+  "keywords" => details['keywords'],
+  "license" => details['license'],
+  "title" => details['title'],
+  "version" => details['version']
+}
+
+File.open('codemeta.json', 'w') {|f| f.write(JSON.pretty_generate(output)) }
diff --git a/paper/paper.md b/paper/paper.md
new file mode 100644
index 00000000..7bfbb4e7
--- /dev/null
+++ b/paper/paper.md
@@ -0,0 +1,99 @@
+---
+title: "Dolphin: A Python package for large-scale InSAR PS/DS processing"
+tags:
+  - Python
+  - InSAR
+  - remote sensing
+  - phase linking
+  - time series
+  - persistent scatterers
+  - distributed scatterers
+  - interferometry
+  - surface deformation
+  - earthquake
+authors:
+  - name: Scott J. Staniewicz
+    orcid: 0000-0003-0872-7098
+    affiliation: 1
+  - name: Sara Mirzaee
+    orcid: 0000-0001-8194-5951
+    affiliation: 1
+  - name: Geoffrey M. Gunter
+    orcid: 0000-0003-4612-0887
+    affiliation: 1
+  - name: Talib Oliver-Cabrera
+    orcid: 0000-0002-2315-4710
+    affiliation: 1
+  - name: Heresh Fattahi
+    orcid: 0000-0001-6926-4387
+    affiliation: 1
+affiliations:
+  - name: Jet Propulsion Laboratory, California Institute of Technology
+    index: 1
+date: 5 March 2024
+bibliography: references.bib
+---
+
+# Summary
+
+<!-- JOSS welcomes submissions from broadly diverse research areas. For this reason, we require that authors include in the paper some sentences that explain the software functionality and domain of use to a non-specialist reader. We also require that authors explain the research applications of the software. The paper should be between 250-1000 words. Authors submitting papers significantly longer than 1000 words may be asked to reduce the length of their paper. -->
+
+<!-- A summary describing the high-level functionality and purpose of the software for a diverse, non-specialist audience. -->
+`dolphin` is a Python library for creating maps of land surface displacement using the remote sensing technique called Interferometric Synthetic Aperture Radar (InSAR). Conventional InSAR uses pairs of SAR images to get a single map of the relative displacement between the two acquisition times. `dolphin` uses state-of-the-art multi-temporal algorithms to reduce the impact of noise sources and produce long time series of displacement at fine resolution.
+
+![Average surface displacement velocity along the radar line-of-sight between February, 2017 and December, 2020. Red (blue) indicates motion towards (away from) the satellite.\label{fig:mojave}](figures/bristol-velocity-sequential.png)
+
+# Statement of need
+<!-- A Statement of need section that clearly illustrates the research purpose of the software and places it in the context of related work. -->
+
+The Sentinel-1 satellite from the European Space Agency (ESA) has provided free and open access to Synthetic Aperture Radar (SAR) data since 2014. This has led to a rapid increase in the availability of SAR data and has enabled a wide range of applications in Earth and environmental sciences. However, processing InSAR data has remained a challenge for non-experts.
+Advanced time series algorithms which combine persistent scatterer (PS) and distributed scatterer (DS) (also known as phase linking) have been developed for over a decade [@Guarnieri2008ExploitationTargetStatistics]; however, existing open source tools have not included these techniques until recently.
+<!-- Moreoever, the available tools were generally not designed to run at continental scale in a cloud computing environment. -->
+
+<!-- A list of key references, including to other software addressing related needs. Note that the references should include full names of venues, e.g., journals and conferences, not abbreviations only understood in the context of a specific discipline. -->
+<!-- While phase linking algorithms have been known for over a decade until several years ago, there were no open source libraries which could perform .  -->
+
+<!-- The original software used in phase linking literature was not made public, but researchers have since made efforts to open source these advanced algorithms. -->
+The first prototype was the [`FRInGE`](https://github.com/isce-framework/fringe) C++ library [@Fattahi2019FRInGEFullResolutionInSAR], which implements algorithms and workflows from [@Ferretti2011NewAlgorithmProcessing] and [@Ansari2018EfficientPhaseEstimation].
+<!-- was created as a proof of concept for multiple phase linking algorithms   -->
+<!-- `FRInGE`, a C++ library with Python bindings,  -->
+The [`Miaplpy`](https://github.com/insarlab/MiaplPy) Python library contains a superset of the features in `FRInGE`, as well as new algorithms developed in [@Mirzaee2023NonlinearPhaseLinking]. The MATLAB [`TomoSAR`](https://github.com/DinhHoTongMinh/TomoSAR) library was also made public in 2022, which implements the "Compressed SAR" (ComSAR) algorithm- a variant of phase linking detailed in [@HoTongMinh2022CompressedSARInterferometry].
+
+`dolphin` has been developed for the Observational Products for End-Users from Remote Sensing Analysis (OPERA) project. OPERA is a Jet Propulsion Laboratory project funded by the Satellite Needs Working Group (SNWG) tasked with generating a North American Surface Displacement product. This product is required to cover over 10 million square kilometers of land at 30 meter resolution or finer with under 72 hours of latency; as such, new software was required which could handle the heavy computational demands of the project.
+
+# Overview of Dolphin
+
+`dolphin` processes stacks of coregistered single-look complex (SLC) radar images into a time series of surface displacement. The software has pre-made workflows accessible through command line tools which call core algorithms for PS/DS processing:
+
+- The `shp` subpackage estimates the SAR backscatter distribution to find neighborhoods of statistically homogeneous pixels (SHPs) using the generalized likelihood ratio test from @Parizzi2011AdaptiveInSARStack or the Kolmogorov-Smirnov test from @Ferretti2011NewAlgorithmProcessing.
+- The `phase_link` subpackage processes the complex SAR covariance matrix into a time series of wrapped phase using the CAESAR algorithm [@Fornaro2015CAESARApproachBased], the eigenvalue-based maximum likelihood estimator of interferometric phase (EMI) [@Ansari2018EfficientPhaseEstimation], or the combined phase linking (CPL) approach from [@Mirzaee2023NonlinearPhaseLinking].
+- The `unwrap` subpackage exposes multiple phase unwrapping algorithms, including the Statistical-cost, Network-flow Algorithm for Phase Unwrapping (SNAPHU) [@Chen2001TwodimensionalPhaseUnwrapping] and the PHASS algorithm (available in the InSAR Scientific Computing Environment [@Rosen2018InSARScientificComputing]).
+- The `timeseries` module contains basic functionality to invert an overdetermined network of unwrapped interferograms into a time series and estimate the average surface velocity.
+
+The outputs of `dolphin` are also compatible with the Miami INsar Time-series software for users who are already comfortable with MintPy [@Yunjun2019SmallBaselineInSAR].
+
+While `dolphin` has been primarily tested on CPU-based workstations and cloud environments, the compute-intensive routines leverage the accelerated linear algebra (XLA) compiler within `jax` library  [@Bradbury2018JAXComposableTransformations]. This means that with only an extra installation, users can accelerate their processing by 5-20x on machines with a compatible GPU.
+
+The `dolphin` command line tool provides an interface for running the end-to-end displacement workflow on large datasets (e.g. hundreds of full-frame Sentinel-1 images) with minimal required configuration.
+For example, if a user has created a stack of coregistered SLCs in a `data/` directory, they only need to follow two steps to run the full workflow with all default parameters:
+
+1. Configure the workflow with the `config` command, indicating the location of the SLCs, which dumps the output to a YAML file:
+
+```python
+dolphin config --slc-files data/*
+```
+
+2. Run the workflow saved in the YAML configuration file with the `run` command:
+
+```python
+dolphin run dolphin_config.yaml
+```
+
+\autoref{fig:mojave} shows an example result of the final average surface velocity map created by `dolphin`. The inputs were OPERA Coregistered Single-Look Complex (CSLC) geocoded images from Sentinel-1 data between February 2017 - December 2020 over the Mojave Desert.
+
+# Acknowledgements
+
+Copyright © 2024, California Institute of Technology ("Caltech"). U.S. Government sponsorship acknowledged.
+The research was carried out at the Jet Propulsion Laboratory, California Institute of Technology, under a contract with the National Aeronautics and Space Administration (80NM0018D0004). The OPERA project has been funded by the Satellite Needs Working Group.
+
+# References
diff --git a/paper/references.bib b/paper/references.bib
new file mode 100644
index 00000000..273cbef4
--- /dev/null
+++ b/paper/references.bib
@@ -0,0 +1,268 @@
+@article{Ansari2017SequentialEstimatorEfficient,
+  title      = {Sequential {{Estimator}}: {{Toward Efficient InSAR Time Series Analysis}}},
+  shorttitle = {Sequential {{Estimator}}},
+  author     = {Ansari, Homa and De Zan, Francesco and Bamler, Richard},
+  year       = {2017},
+  month      = oct,
+  journal    = {IEEE Transactions on Geoscience and Remote Sensing},
+  volume     = {55},
+  number     = {10},
+  pages      = {5637--5652},
+  issn       = {1558-0644},
+  doi        = {10.1109/TGRS.2017.2711037},
+  keywords   = {Big Data,Coherence,coherence estimation error,data compression,differential interferometric synthetic aperture radar (DInSAR),distributed scatterers,Earth,efficiency,error analysis,low-rank approximation,Maximum likelihood estimation,maximum-likelihood estimation (MLE),Monitoring,Synthetic aperture radar,Time series analysis}
+}
+
+@article{Ansari2018EfficientPhaseEstimation,
+  title    = {Efficient {{Phase Estimation}} for {{Interferogram Stacks}}},
+  author   = {Ansari, Homa and De Zan, Francesco and Bamler, Richard},
+  year     = {2018},
+  month    = jul,
+  journal  = {IEEE Transactions on Geoscience and Remote Sensing},
+  volume   = {56},
+  number   = {7},
+  pages    = {4109--4125},
+  issn     = {1558-0644},
+  doi      = {10.1109/TGRS.2018.2826045},
+  keywords = {Big Data,coherence matrix,covariance estimation,differential interferometric synthetic aperture radar,distributed scatterers (DS),efficiency,Electromagnetic interference,error analysis,Maximum likelihood estimation,maximum-likelihood estimation,near real-time (NRT) processing,Strain,Synthetic aperture radar,Systematics,Time series analysis}
+}
+
+@article{Ansari2021StudySystematicBias,
+  title    = {Study of {{Systematic Bias}} in {{Measuring Surface Deformation With SAR Interferometry}}},
+  author   = {Ansari, H. and Zan, F. De and Parizzi, A.},
+  year     = {2021},
+  month    = feb,
+  journal  = {IEEE Transactions on Geoscience and Remote Sensing},
+  volume   = {59},
+  number   = {2},
+  pages    = {1285--1301},
+  issn     = {1558-0644},
+  doi      = {10.1109/TGRS.2020.3003421},
+  keywords = {Big Data,Decorrelation,deformation estimation,differential interferometric synthetic aperture radar (SAR) (DInSAR),distributed scatterers (DSs),error analysis,Fading channels,Moisture,near real-time (NRT) processing,phase inconsistencies,signal decorrelation,Strain,Synthetic aperture radar,Systematics,Time series analysis,time-series analysis}
+}
+
+@article{Bekaert2021IntroducingOPERAProject,
+  title   = {Introducing the {{OPERA Project}} for {{Systematic Surface Water}}, {{Surface Deformation}}, and {{Surface Disturbance Data Products}} from {{Satellite Observations}}},
+  author  = {Bekaert, David and Fattahi, Heresh and Jones, John and Hansen, Matthew and Kwoun, Oh-Ig and Lewis, Steven and Meyer, Franz and Osmanoglu, Batuhan and Marshak, Charles and Hamlington, Benjamin and Bato, Mary Grace and Brancato, Virginia and Shiroma, Gustavo and Jung, Jungkyo and Jai, Benhan and Buckley, Sean and Cruz, Jennifer},
+  year    = {2021},
+  month   = dec,
+  volume  = {2021},
+  pages   = {G42A-07},
+  urldate = {2024-05-15}
+}
+
+@misc{Bradbury2018JAXComposableTransformations,
+  title  = {{{JAX}}: Composable Transformations of {{Python}}+{{NumPy}} Programs},
+  author = {Bradbury, James and Frostig, Roy and Hawkins, Peter and Johnson, Matthew James and Leary, Chris and Maclaurin, Dougal and Necula, George and Paszke, Adam and VanderPlas, Jake and {Wanderman-Milne}, Skye and Zhang, Qiao},
+  year   = {2018}
+}
+
+@article{Chen2001TwodimensionalPhaseUnwrapping,
+  title   = {Two-Dimensional Phase Unwrapping with Use of Statistical Models for Cost Functions in Nonlinear Optimization},
+  author  = {Chen, Curtis W. and Zebker, Howard A.},
+  year    = {2001},
+  month   = feb,
+  journal = {Journal of the Optical Society of America A},
+  volume  = {18},
+  number  = {2},
+  pages   = {338},
+  issn    = {1084-7529, 1520-8532},
+  doi     = {10.1364/JOSAA.18.000338},
+  urldate = {2024-05-16},
+  langid  = {english}
+}
+
+@article{Chen2012IonosphericArtifactsSimultaneous,
+  title    = {Ionospheric {{Artifacts}} in {{Simultaneous L-Band InSAR}} and {{GPS Observations}}},
+  author   = {Chen, Jingyi and Zebker, Howard A.},
+  year     = {2012},
+  month    = apr,
+  journal  = {IEEE Transactions on Geoscience and Remote Sensing},
+  volume   = {50},
+  number   = {4},
+  pages    = {1227--1239},
+  issn     = {1558-0644},
+  doi      = {10.1109/TGRS.2011.2164805},
+  keywords = {Advanced Land Observation Satellite (ALOS) PhasedArray L-band Synthetic Aperture Radar (PALSAR),Azimuth,California,correlation signatures,Delay,dual-frequency GPS carrier phase data,global positioning system,Global Positioning System,global positioning system (GPS),GPS observations,Hawaii,Iceland,InSAR images,interferograms,interferometric synthetic aperture radar,interpretability,Ionosphere,ionospheric artifacts,ionospheric delay,ionospheric electromagnetic wave propagation,ionospheric propagation delays,ionospheric total electron content,ionospheric variability,L-band InSAR data,L-band InSAR observations,L-band SAR interferometry,neutral atmospheric delays,phase artifacts,pixel misregistration,radar imaging,radar interferometry,radiowave propagation,SAR acquisition times,Satellites,Spaceborne radar,synthetic aperture length scales,synthetic aperture radar,terrain,total electron content (TEC)}
+}
+
+@article{Chen2015PersistentScattererInterpolation,
+  title    = {A Persistent Scatterer Interpolation for Retrieving Accurate Ground Deformation over {{InSAR-decorrelated}} Agricultural Fields},
+  author   = {Chen, Jingyi and Zebker, Howard A. and Knight, Rosemary},
+  year     = {2015},
+  journal  = {Geophysical Research Letters},
+  volume   = {42},
+  number   = {21},
+  pages    = {9294--9301},
+  issn     = {19448007},
+  doi      = {10.1002/2015GL065031},
+  keywords = {decorrelation,groundwater,InSAR deformation map,persistent scatterers}
+}
+
+@article{Fattahi2019FRInGEFullResolutionInSAR,
+  title    = {{{FRInGE}}; {{Full-Resolution InSAR}} Timeseries Using {{Generalized Eigenvectors}}},
+  author   = {Fattahi, H. and Agram, P. S. and Tymofyeyeva, E. and Bekaert, D. P.},
+  year     = {2019},
+  month    = dec,
+  volume   = {2019},
+  pages    = {G11B-0514},
+  urldate  = {2024-05-16},
+  keywords = {1209 Tectonic deformation,1211 Non-tectonic deformation,1240 Satellite geodesy: results,1241 Satellite geodesy: technical issues,GEODESY AND GRAVITY}
+}
+
+@article{Ferretti2011NewAlgorithmProcessing,
+  title     = {A New Algorithm for Processing Interferometric Data-Stacks: {{SqueeSAR}}},
+  author    = {Ferretti, Alessandro and Fumagalli, Alfio and Novali, Fabrizio and Prati, Claudio and Rocca, Fabio and Rucci, Alessio},
+  year      = {2011},
+  journal   = {IEEE Transactions on Geoscience and Remote Sensing},
+  volume    = {49},
+  number    = {9},
+  pages     = {3460--3470},
+  publisher = {IEEE},
+  issn      = {01962892},
+  doi       = {10.1109/TGRS.2011.2124465},
+  isbn      = {0196-2892},
+  keywords  = {1pass,Coherence matrix,distributed scatterers (DS),InSAR,permanent scatterers,space-adaptive filtering}
+}
+
+@article{Fornaro2015CAESARApproachBased,
+  title      = {{{CAESAR}}: {{An Approach Based}} on {{Covariance Matrix Decomposition}} to {{Improve Multibaseline}}--{{Multitemporal Interferometric SAR Processing}}},
+  shorttitle = {{{CAESAR}}},
+  author     = {Fornaro, Gianfranco and Verde, Simona and Reale, Diego and Pauciullo, Antonio},
+  year       = {2015},
+  month      = apr,
+  journal    = {IEEE Transactions on Geoscience and Remote Sensing},
+  volume     = {53},
+  number     = {4},
+  pages      = {2050--2065},
+  issn       = {1558-0644},
+  doi        = {10.1109/TGRS.2014.2352853},
+  keywords   = {3-D,4-D and multidimensional (Multi-D) SAR imaging,Covariance matrices,Covariance matrix decomposition,differential SAR tomography,differential synthetic aperture radar (SAR) interferometry (DInSAR),Interferometry,Monitoring,principal component analysis (PCA),SAR interferometry (InSAR),SAR tomography,Scattering,Spatial resolution,Synthetic aperture radar,Tomography}
+}
+
+@article{Guarnieri2008ExploitationTargetStatistics,
+  title    = {On the {{Exploitation}} of {{Target Statistics}} for {{SAR Interferometry Applications}}},
+  author   = {Guarnieri, A. M. and Tebaldini, S.},
+  year     = {2008},
+  month    = nov,
+  journal  = {IEEE Transactions on Geoscience and Remote Sensing},
+  volume   = {46},
+  number   = {11},
+  pages    = {3436--3443},
+  issn     = {0196-2892},
+  doi      = {10.1109/TGRS.2008.2001756},
+  keywords = {Decorrelation,decorrelation models,ENVISAT images,geophysical techniques,geophysics computing,image processing,Information retrieval,interferometric phases,Interferometry,line-of-sight displacement,line-of-sight motion,Maximum likelihood estimation,Monte Carlo simulations,multiimage synthetic aperture radar interferometry,Phase estimation,physical parameters,radar interferometry,Radar scattering,remote sensing by radar,residual topography,SAR interferometry applications,Statistical distributions,statistics,Statistics,stochastic processes,Surfaces,synthetic aperture radar,Synthetic aperture radar interferometry,target statistics,topography (Earth),Yield estimation}
+}
+
+@article{HoTongMinh2022CompressedSARInterferometry,
+  title     = {Compressed {{SAR Interferometry}} in the {{Big Data Era}}},
+  author    = {Ho Tong Minh, Dinh and Ngo, Yen-Nhi},
+  year      = {2022},
+  month     = jan,
+  journal   = {Remote Sensing},
+  volume    = {14},
+  number    = {2},
+  pages     = {390},
+  publisher = {Multidisciplinary Digital Publishing Institute},
+  issn      = {2072-4292},
+  doi       = {10.3390/rs14020390},
+  urldate   = {2024-05-15},
+  copyright = {http://creativecommons.org/licenses/by/3.0/},
+  langid    = {english},
+  keywords  = {ComSAR,InSAR,PSDS,PSI,subsidence,TomoSAR,Vauvert}
+}
+
+@article{Mirzaee2023NonlinearPhaseLinking,
+  title    = {Non-Linear Phase Linking Using Joined Distributed and Persistent Scatterers},
+  author   = {Mirzaee, Sara and Amelung, Falk and Fattahi, Heresh},
+  year     = {2023},
+  month    = feb,
+  journal  = {Computers \& Geosciences},
+  volume   = {171},
+  pages    = {105291},
+  issn     = {00983004},
+  doi      = {10.1016/j.cageo.2022.105291},
+  urldate  = {2023-03-08},
+  langid   = {english},
+  keywords = {Distributed scatterer,MiaplPy InSAR,Phase linking,Sequential}
+}
+
+@inproceedings{Rosen2018InSARScientificComputing,
+  title     = {The {{InSAR Scientific Computing Environment}} 3.0: {{A Flexible Framework}} for {{NISAR Operational}} and {{User-Led Science Processing}}},
+  author    = {Rosen, Paul A. and Gurrola, Eric M. and Agram, Piyush and Cohen, Joshua and Lavalle, Marco and Riel, Bryan V. and Fattahi, Heresh and Aivazis, Michael A.G. and Simons, Mark and Buckley, Sean M.},
+  year      = {2018},
+  month     = jul,
+  pages     = {4897--4900},
+  publisher = {IEEE},
+  address   = {Valencia},
+  doi       = {10.1109/IGARSS.2018.8517504},
+  langid    = {english}
+}
+
+@article{Parizzi2011AdaptiveInSARStack,
+  title      = {Adaptive {{InSAR Stack Multilooking Exploiting Amplitude Statistics}}: {{A Comparison Between Different Techniques}} and {{Practical Results}}},
+  shorttitle = {Adaptive {{InSAR Stack Multilooking Exploiting Amplitude Statistics}}},
+  author     = {Parizzi, Alessandro and Brcic, Ramon},
+  year       = {2011},
+  month      = may,
+  journal    = {IEEE Geoscience and Remote Sensing Letters},
+  volume     = {8},
+  number     = {3},
+  pages      = {441--445},
+  issn       = {1558-0571},
+  doi        = {10.1109/LGRS.2010.2083631},
+  keywords   = {adaptive InSAR stack multilooking,Adaptive multilooking,amplitude-based algorithm,backscatter,backscatter amplitude statistics,Coherence,coherence estimation,complex correlation,interferometric phase,interferometric synthetic aperture radar capability,interferometry,Kernel,phase signatures,Pixel,radar backscatter statistics,radar imaging,radar interferometry,Remote sensing,Shape,synthetic aperture radar,Synthetic aperture radar,synthetic aperture radar (SAR)}
+}
+
+@article{Siddiqui1962ProblemsConnectedRayleigh,
+  title   = {Some Problems Connected with {{Rayleigh}} Distributions},
+  author  = {Siddiqui, M.M.},
+  year    = {1962},
+  month   = mar,
+  journal = {Journal of Research of the National Bureau of Standards, Section D: Radio Propagation},
+  volume  = {66D},
+  number  = {2},
+  pages   = {167},
+  issn    = {1060-1783},
+  doi     = {10.6028/jres.066D.020},
+  urldate = {2023-05-03},
+  langid  = {english}
+}
+
+@article{Wang2022AccuratePersistentScatterer,
+  title    = {Accurate {{Persistent Scatterer Identification Based}} on {{Phase Similarity}} of {{Radar Pixels}}},
+  author   = {Wang, Ke and Chen, Jingyi},
+  year     = {2022},
+  journal  = {IEEE Transactions on Geoscience and Remote Sensing},
+  volume   = {60},
+  pages    = {1--13},
+  issn     = {1558-0644},
+  doi      = {10.1109/TGRS.2022.3210868},
+  keywords = {Decorrelation,Interferometric Synthetic Aperture Radar (InSAR),Persistent Scatterer (PS),Phase measurement,phase similarity,Radar,Radar measurements,Radar scattering,Strain,surface deformation,Synthetic aperture radar}
+}
+
+@article{Yunjun2019SmallBaselineInSAR,
+  title      = {Small Baseline {{InSAR}} Time Series Analysis: {{Unwrapping}} Error Correction and Noise Reduction},
+  shorttitle = {Small Baseline {{InSAR}} Time Series Analysis},
+  author     = {Yunjun, Zhang and Fattahi, Heresh and Amelung, Falk},
+  year       = {2019},
+  month      = dec,
+  journal    = {Computers \& Geosciences},
+  volume     = {133},
+  pages      = {104331},
+  issn       = {00983004},
+  doi        = {10.1016/j.cageo.2019.104331},
+  urldate    = {2020-08-14},
+  langid     = {english}
+}
+
+@article{Zwieback2022CheapValidRegularizers,
+  title    = {Cheap, Valid Regularizers for Improved Interferometric Phase Linking},
+  author   = {Zwieback, S.},
+  year     = {2022},
+  journal  = {IEEE Geoscience and Remote Sensing Letters},
+  pages    = {1--1},
+  issn     = {1558-0571},
+  doi      = {10.1109/LGRS.2022.3197423},
+  keywords = {Coherence,Decorrelation,Dispersion,Eigenvalues and eigenfunctions,Estimation,History,Snow}
+}


Test patch:
diff --git a/.github/workflows/test-build-push.yml b/.github/workflows/test-build-push.yml
index e0d789fb..a11af40b 100644
--- a/.github/workflows/test-build-push.yml
+++ b/.github/workflows/test-build-push.yml
@@ -1,6 +1,12 @@
 name: Pytest, build docker image, push to GHCR
 
-on: [pull_request, push]
+on:
+  push:
+    branches-ignore:
+      - 'joss'
+  pull_request:
+    branches-ignore:
+      - 'joss'
 
 concurrency:
   group: ${{ github.workflow }}-${{ github.head_ref }}