Skip to content

Commit

Permalink
doc: start a docs update (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
beckermr authored Sep 7, 2024
1 parent e43167f commit 48bf965
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 10 deletions.
141 changes: 131 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,28 @@

**Disclaimer**: This project is still in an early development phase, **please use the [reference GalSim implementation](https://github.com/GalSim-developers/GalSim) for any scientific applications.**

In fact, we are still thinking about how to name this project, checkout [this poll](https://github.com/GalSim-developers/JAX-GalSim/discussions/2).

## Objective and design

See [design document](https://docs.google.com/document/d/1NalCc_5dc3Z8F4q37y-RsJS_mr9gzvfyANb2PYUpsb4/edit?usp=sharing).
## Objective and Design

The goal of this library is to reimplement GalSim functionalities in pure JAX to allow for automatic differentiation, GPU acceleration, and batched computations.

**Guiding Principles**:
### Guiding Principles

- Strive to be a drop-in replacement for GalSim, i.e. provide a close match to the GalSim API.
- Each function/feature will be tested against the reference GalSim implementation.
- This package will aim to be a **subset** of GalSim (i.e. only contains functions with a reference GalSim implementation).
- Implementations should be easy to read and understand.
- Code should be pip installable on any machine, no compilation required.
- Code should be pip-installable on any machine, no compilation required.
- Any notable differences between the JAX and reference implementations will be clearly documented.

### Notable Differences

- JAX arrays are immutable. Thus, in-place operations on images are not possible and a new image is
returned instead. Also, the RNG classes cannot fill arrays and instead return new arrays.
- JAX arrays do not support all the kinds of views that numpy arrays support. This means that some
operations that work in GalSim may not work in JAX-GalSim (e.g., real views of complex images).
- JAX-GalSim uses a different random number generator than GalSim. This leads to different results in terms of both the
generated random numbers and in terms of which RNGs have stable discarding.

## Contributing

Everyone can contribute to this project, please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) document for details.
Expand All @@ -37,6 +42,122 @@ In short, to interact with the project you can:
Issues marked with _contributions welcome_ or _good first issue_ are particularly good places to start. These are great ways to learn more
about the inner workings of GalSim and how to code in JAX.

## Current GalSim capabilities coverage

0%
## Current GalSim API Coverage

<!-- start-api-coverage -->
JAX-GalSim has implemented 22.6% of the GalSim API. See the list below for the supported APIs.

<details>

- galsim.Add
- galsim.AffineTransform
- galsim.Angle
- galsim.AngleUnit
- galsim.BaseDeviate
- galsim.BaseNoise
- galsim.BaseWCS
- galsim.BinomialDeviate
- galsim.Bounds
- galsim.BoundsD
- galsim.BoundsI
- galsim.Box
- galsim.CCDNoise
- galsim.CelestialCoord
- galsim.Chi2Deviate
- galsim.Convolution
- galsim.Convolve
- galsim.Cubic
- galsim.Deconvolution
- galsim.Deconvolve
- galsim.Delta
- galsim.DeltaFunction
- galsim.DeviateNoise
- galsim.Exponential
- galsim.FitsHeader
- galsim.FitsWCS
- galsim.GSFitsWCS
- galsim.GSObject
- galsim.GSParams
- galsim.GalSimBoundsError
- galsim.GalSimConfigError
- galsim.GalSimConfigValueError
- galsim.GalSimDeprecationWarning
- galsim.GalSimError
- galsim.GalSimFFTSizeError
- galsim.GalSimHSMError
- galsim.GalSimImmutableError
- galsim.GalSimIncompatibleValuesError
- galsim.GalSimIndexError
- galsim.GalSimKeyError
- galsim.GalSimNotImplementedError
- galsim.GalSimRangeError
- galsim.GalSimSEDError
- galsim.GalSimUndefinedBoundsError
- galsim.GalSimValueError
- galsim.GalSimWarning
- galsim.GammaDeviate
- galsim.Gaussian
- galsim.GaussianDeviate
- galsim.GaussianNoise
- galsim.Image
- galsim.ImageCD
- galsim.ImageCF
- galsim.ImageD
- galsim.ImageF
- galsim.ImageI
- galsim.ImageS
- galsim.ImageUI
- galsim.ImageUS
- galsim.Interpolant
- galsim.InterpolatedImage
- galsim.JacobianWCS
- galsim.Lanczos
- galsim.Linear
- galsim.Moffat
- galsim.Nearest
- galsim.OffsetShearWCS
- galsim.OffsetWCS
- galsim.PhotonArray
- galsim.Pixel
- galsim.PixelScale
- galsim.PoissonDeviate
- galsim.PoissonNoise
- galsim.Position
- galsim.PositionD
- galsim.PositionI
- galsim.Quintic
- galsim.Sensor
- galsim.Shear
- galsim.ShearWCS
- galsim.SincInterpolant
- galsim.Spergel
- galsim.Sum
- galsim.TanWCS
- galsim.Transform
- galsim.Transformation
- galsim.UniformDeviate
- galsim.VariableGaussianNoise
- galsim.WeibullDeviate
- galsim.fits.closeHDUList
- galsim.fits.readCube
- galsim.fits.readFile
- galsim.fits.readMulti
- galsim.fits.write
- galsim.fits.writeFile
- galsim.fitswcs.CelestialWCS
- galsim.noise.addNoise
- galsim.noise.addNoiseSNR
- galsim.random.permute
- galsim.utilities.g1g2_to_e1e2
- galsim.utilities.horner
- galsim.utilities.printoptions
- galsim.utilities.unweighted_moments
- galsim.utilities.unweighted_shape
- galsim.wcs.EuclideanWCS
- galsim.wcs.LocalWCS
- galsim.wcs.UniformWCS

</details>
<!-- end-api-coverage -->

_**Note**: The coverage list is generated automatically by the `scripts/update_api_coverage.py` script. To update it, run `python scripts/update_api_coverage.py` from the root of the repository._
86 changes: 86 additions & 0 deletions scripts/update_api_coverage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import inspect

import galsim

import jax_galsim


def _list_all_apis(module, apis=None, seen_modules=None):
apis = apis or set()
seen_modules = seen_modules or set()
mname = module.__name__
top_level = mname.split(".")[0]

for kind in ["class_or_fun", "mod"]:
for name in dir(module):
full_name = f"{mname}.{name}"

if name.startswith("_") or full_name == "jax_galsim.core":
continue

obj = getattr(module, name)

if kind == "mod" and inspect.ismodule(obj):
if (
full_name not in seen_modules
and (not inspect.isbuiltin(obj))
and hasattr(obj, "__file__")
and top_level in obj.__file__.split("/")
):
seen_modules.add(full_name)
_list_all_apis(obj, apis=apis, seen_modules=seen_modules)
elif kind == "class_or_fun" and (
inspect.isclass(obj) or inspect.isfunction(obj)
):
if not any(api.endswith(f".{name}") for api in apis):
apis.add(full_name)

return apis


def _write_to_readme(missing_apis, jax_galsim_apis, cov_frac):
with open("README.md", "r") as f:
lines = f.readlines()

start = lines.index("<!-- start-api-coverage -->\n")
end = lines.index("<!-- end-api-coverage -->\n")

middle_lines = []
middle_lines.append(
f"JAX-GalSim has implemented {100 * cov_frac:.1f}% of "
"the GalSim API. See the list below for the supported APIs.\n"
)
middle_lines.append("\n")

middle_lines.append("<details>\n")
middle_lines.append("\n")

for api in sorted(jax_galsim_apis):
middle_lines.append(f"- {api}\n")
middle_lines.append("\n")

middle_lines.append("</details>\n")

with open("README.md", "w") as f:
f.writelines(lines[: start + 1])
f.writelines(middle_lines)
f.writelines(lines[end:])


if __name__ == "__main__":
galsim_apis = _list_all_apis(galsim)
assert all(api.startswith("galsim.") for api in galsim_apis)

jax_galsim_apis = _list_all_apis(jax_galsim)
assert all(api.startswith("jax_galsim.") for api in jax_galsim_apis)

# make the import prefix match and subset to what is in both
jax_galsim_apis = {"galsim" + api[len("jax_galsim") :] for api in jax_galsim_apis}
jax_galsim_apis = galsim_apis & jax_galsim_apis

missing_apis = galsim_apis - jax_galsim_apis
assert len(missing_apis) + len(jax_galsim_apis) == len(galsim_apis)

cov_frac = 1.0 - len(missing_apis) / len(galsim_apis)

_write_to_readme(missing_apis, jax_galsim_apis, cov_frac)

0 comments on commit 48bf965

Please sign in to comment.