Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Starting to add documentation #36

Merged
merged 11 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ repos:
rev: "v1.11.1"
hooks:
- id: mypy
additional_dependencies:
- types-markdown

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.6.1"
Expand Down
4 changes: 4 additions & 0 deletions docs/background-theory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Background theory

1. [Notation](./theory/notation.md)
1. [Residue computation](./theory/residues.md)
30 changes: 30 additions & 0 deletions docs/developer-setup.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,32 @@

--8<-- "CONTRIBUTING.md"

## Install from source

To install spurt from source, you will need:

- Python 3.9 or newer + pip

The latest source code can be installed using

```
$ pip install git+https://github.com/isce-framework/spurt.git
```

Alternatively, clone the repository and install the local copy using

```
$ git clone https://github.com/isce-framework/spurt.git
$ cd spurt
$ pip install .
```


## Running the test suite

To run the test suite, with pytest and pytest-cov installed

```
$ cd spurt
$ python3 -m pytest
```
2 changes: 1 addition & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
--8<-- "README.md:19:84"

For a more complete tutorial, see our [notebooks](notebooks)
For background material and walkthroughs, see our [tutorials](tutorials.md) page.

For help with installing locally and contributing, see the [full developer setup instructions](developer-setup.md).
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
1. [Getting started](./getting-started.md)
1. [Tutorials](tutorials.md)
1. [Code Reference](reference/summary.md)
1. [Background theory](background-theory.md)
<!-- 1. [How-To Guides](how-to-guides.md) -->
<!-- 1. [Background theory](background-theory.md) -->
265 changes: 265 additions & 0 deletions docs/mdx_bib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
# Source: https://github.com/bobmyhill/mdx_bib/blob/6b13bbbc407617a5e93ed0f8a0e5e4c52f73f677/mdx_bib.py
import re
import string
from collections import Counter, OrderedDict
from xml.etree import ElementTree as etree

from markdown.extensions import Extension
from markdown.inlinepatterns import Pattern
from markdown.preprocessors import Preprocessor
from markdown.treeprocessors import Treeprocessor
from pybtex.database.input import bibtex
from pybtex.exceptions import PybtexError

BRACKET_RE = re.compile(r"\[([^\[]+)\]")
CITE_RE = re.compile(r"@(\w+)")
DEF_RE = re.compile(r"\A {0,3}\[@(\w+)\]:\s*(.*)")
INDENT_RE = re.compile(r"\A\t| {4}(.*)")

CITATION_RE = r"@(\w+)"


class Bibliography:
"""Keep track of document references and citations for exporting."""

def __init__(self, extension, bibtex_file, order):
self.extension = extension
self.order = order

self.citations = OrderedDict()
self.references = {}

if bibtex_file:
try:
parser = bibtex.Parser()
self.bibsource = parser.parse_file(bibtex_file).entries
self.labels = {
id: self.formatCitation(self.bibsource[id]) for id in self.bibsource
}
for value, occurrences in Counter(self.labels.values()).items():
if occurrences > 1:
for xkey, xvalue in self.labels.items():
i = 0
if xvalue == value:
self.labels[xkey] = (
f"{xvalue}{string.ascii_lowercase[i]}"
)
i += 1

except PybtexError:
print("Error loading bibtex file")
self.bibsource = {}
self.labels = {}
else:
self.bibsource = {}

def addCitation(self, citekey):
self.citations[citekey] = self.citations.get(citekey, 0) + 1

def setReference(self, citekey, reference):
self.references[citekey] = reference

def citationID(self, citekey):
return "cite-" + citekey

def referenceID(self, citekey):
return "ref-" + citekey

def formatAuthor(self, author):
out = f"{author.last_names[0]} {author.first_names[0][0]}."
if author.middle_names:
out += f"{author.middle_names[0][0]}."
return out.replace("{", "").replace("}", "")

def formatAuthorSurname(self, author):
out = author.last_names[0]
return out.replace("{", "").replace("}", "")

def formatReference(self, ref):
author_list = list(map(self.formatAuthor, ref.persons["author"]))

if len(author_list) == 1:
authors = author_list[0]
else:
authors = ", ".join(author_list[:-1])
authors += f" and {author_list[-1]}"

# Harvard style
# Surname, Initial, ... and Last_Surname,
# Initial, Year. Title. Journal, Volume(Issue), pages. doi.

title = ref.fields["title"].replace("{", "").replace("}", "")
journal = ref.fields.get("journal", "")
volume = ref.fields.get("volume", "")
issue = ref.fields.get("issue", "")
year = ref.fields.get("year")
pages = ref.fields.get("pages")
doi = ref.fields.get("doi")

reference = f"<p>{authors}, {year}. {title}."
if journal:
reference += f" <i>{journal}</i>."
if volume:
reference += f" <i>{volume}</i>"
if issue:
reference += f"({issue})"
if pages:
reference += f", pp.{pages}"
reference += "."
if doi:
reference += (
f' <a href="https://dx.doi.org/{doi}" target="_blank">{doi}</a>'
)
reference += "</p>"

return reference

def formatCitation(self, ref):
author_list = list(map(self.formatAuthorSurname, ref.persons["author"]))
year = ref.fields.get("year")

if len(author_list) == 1:
citation = f"{author_list[0]}"
elif len(author_list) == 2:
citation = f"{author_list[0]} and {author_list[1]}"
else:
citation = f"{author_list[0]} et al."

citation += f", {year}"

return citation

def makeBibliography(self, root):
if self.order == "alphabetical":
raise (NotImplementedError)

div = etree.Element("div")
div.set("class", "references")

if not self.citations:
return div

table = etree.SubElement(div, "table")
tbody = etree.SubElement(table, "tbody")
for id in self.citations:
tr = etree.SubElement(tbody, "tr")
tr.set("id", self.referenceID(id))
ref_id = etree.SubElement(tr, "td")
ref_txt = etree.SubElement(tr, "td")
if id in self.references:
self.extension.parser.parseChunk(ref_txt, self.references[id])
ref_id.text = self.labels[id]
elif id in self.bibsource:
ref_txt.text = self.formatReference(self.bibsource[id])
ref_id.text = self.labels[id]
else:
ref_txt.text = "Missing citation"

return div

def clearCitations(self):
self.citations = OrderedDict()


class CitationsPreprocessor(Preprocessor):
"""Gather reference definitions and citation keys."""

def __init__(self, bibliography):
self.bib = bibliography

def subsequentIndents(self, lines, i):
"""Concatenate consecutive indented lines."""
linesOut = []
while i < len(lines):
m = INDENT_RE.match(lines[i])
if m:
linesOut.append(m.group(1))
i += 1
else:
break
return " ".join(linesOut), i

def run(self, lines):
linesOut = []
i = 0

while i < len(lines):
# Check to see if the line starts a reference definition
m = DEF_RE.match(lines[i])
if m:
key = m.group(1)
reference = m.group(2)
indents, i = self.subsequentIndents(lines, i + 1)
reference += " " + indents

self.bib.setReference(key, reference)
continue

# Look for all @citekey patterns inside hard brackets
for bracket in BRACKET_RE.findall(lines[i]):
for c in CITE_RE.findall(bracket):
self.bib.addCitation(c)
linesOut.append(lines[i])
i += 1

return linesOut


class CitationsPattern(Pattern):
"""Handles converting citations keys into links."""

def __init__(self, pattern, bibliography):
super(CitationsPattern, self).__init__(pattern)
self.bib = bibliography

def handleMatch(self, m):
id = m.group(2)
if id in self.bib.bibsource:
a = etree.Element("a")
a.set("id", self.bib.citationID(id))
a.set("href", "#" + self.bib.referenceID(id))
a.set("class", "citation")
a.text = self.bib.labels[id]
return a
return None


class CitationsTreeprocessor(Treeprocessor):
"""Add a bibliography/reference section to the end of the document."""

def __init__(self, bibliography):
self.bib = bibliography

def run(self, root):
citations = self.bib.makeBibliography(root)
root.append(citations)
self.bib.clearCitations()


class CitationsExtension(Extension):
def __init__(self, *args, **kwargs):
self.config = {
"bibtex_file": ["", "Bibtex file path"],
"order": ["unsorted", "Order of the references (unsorted, alphabetical)"],
}
super(CitationsExtension, self).__init__(*args, **kwargs)
self.bib = Bibliography(
self,
self.getConfig("bibtex_file"),
self.getConfig("order"),
)

def extendMarkdown(self, md):
md.registerExtension(self)
self.parser = md.parser
self.md = md

md.preprocessors.register(CitationsPreprocessor(self.bib), "mdx_bib", 15)
md.inlinePatterns.register(
CitationsPattern(CITATION_RE, self.bib), "mdx_bib", 175
)
md.treeprocessors.register(CitationsTreeprocessor(self.bib), "mdx_bib", 25)


def makeExtension(*args, **kwargs):
return CitationsExtension(*args, **kwargs)
36 changes: 36 additions & 0 deletions docs/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,39 @@ @article{Pepe2006ExtensionMinimumCost
issn = {0196-2892},
doi = {10.1109/TGRS.2006.873207},
}

@ARTICLE{Costantini1998MinimumCostFlow,
author={Costantini, M.},
journal={IEEE Transactions on Geoscience and Remote Sensing},
title={A novel phase unwrapping method based on network programming},
year={1998},
volume={36},
number={3},
pages={813-821},
keywords={Phase estimation;Interferometry;Synthetic aperture radar;Testing;Costs;Functional programming;Performance evaluation;Two dimensional displays;Robustness;Fast Fourier transforms},
doi={10.1109/36.673674}
}

@INPROCEEDINGS{Costantini1999SparseMCF,
author={Costantini, M. and Rosen, P.A.},
booktitle={IEEE 1999 International Geoscience and Remote Sensing Symposium. IGARSS'99 (Cat. No.99CH36293)},
title={A generalized phase unwrapping approach for sparse data},
year={1999},
volume={1},
number={},
pages={267-269 vol.1},
keywords={Interferometry;Parametric statistics;Testing;Performance evaluation;Image reconstruction;Propulsion;Laboratories;Synthetic aperture radar;Wrapping;Deformable models},
doi={10.1109/IGARSS.1999.773467}
}

@ARTICLE{Goldstein1988PhaseUnwrapping,
author={Goldstein, Richard M. and Zebker, Howard A. and Werner, Charles L.},
journal={Radio Science},
title={Satellite radar interferometry: Two-dimensional phase unwrapping},
year={1988},
volume={23},
number={4},
pages={713-720},
keywords={Radar imaging;Phase measurement;Spaceborne radar;Radar interferometry;Spatial resolution;Satellites},
doi={10.1029/RS023i004p00713}
}
14 changes: 14 additions & 0 deletions docs/theory/notation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Notation


| Symbol | Description |
|--------------------------|------------------------------------|
| $\psi_{x}^{i}$ | Wrapped phase at pixel $x$ in SLC $i$ |
| $\psi_{x}^{ij}$ | Wrapped phase at pixel $x$ in interferogram $ij$ |
| $\phi_{x}^{ij}$ | Unwrapped phase at pixel $x$ in interferogram $ij$ |
| $\Delta \psi_{xy} ^{ij}$ |Double difference wrapped phase between pixels $x$ and $y$ in interferogram $ij$|
| $\Delta \phi_{xy}^{ij}$ | Double difference unwrapped phase between pixels $x$ and $y$ in interferogram $ij$|


Wrapped phases are assumed to be in the range $\left[ -\pi, \pi \right)$.
When working with phase linked data, the phase data in inherently referenced to a particular acquisition in the stack.
Loading