diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 03c0fe3ae35f1cd73a9d483e11f82993d1d65523..0709056cc85b7d5732c8533350b6e3f2d663d5ab 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -62,7 +62,7 @@ Ready to contribute? Here's how to set up `grasshopper` for local development. 1. Fork the `grasshopper` repo on GitHub. 2. Clone your fork locally:: - $ git clone git@github.com:your_name_here/grasshopper.git + $ git clone git@github.com:transientlunatic/grasshopper.git 3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:: diff --git a/Makefile b/Makefile index a8e06e1a7e94ec863fa93377d32b42a3fbc996f2..5b40e62cb20485eafcfafceead215ffd5167fa05 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,7 @@ docs: rm -f docs/modules.rst sphinx-apidoc -o docs/ grasshopper $(MAKE) -C docs clean - $(MAKE) -C docs html + $(MAKE) -C docs html $(BROWSER) docs/_build/html/index.html servedocs: docs diff --git a/docs/Makefile b/docs/Makefile index 7aa4539e389a97bb8426a42922354e6227ef6d1d..ef44c9b03ba71c6caf76127bba026e57e6a5e2c9 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -50,7 +50,7 @@ clean: rm -rf $(BUILDDIR)/* html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + $(SPHINXBUILD) -b html -d $(BUILDDIR)/doctrees $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." diff --git a/docs/conf.py b/docs/conf.py index 5b103492ed7ed08a9f6144fbd7bbf7450694902d..c3acbdcd247dd930176ebe619f50fc83687c9596 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -44,7 +44,10 @@ import grasshopper # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'numpydoc'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.autosummary', 'numpydoc', + 'matplotlib.sphinxext.mathmpl', + 'matplotlib.sphinxext.only_directives', + 'matplotlib.sphinxext.plot_directive',] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] diff --git a/docs/example.rst b/docs/example.rst index eee5d6e08478b352ee22d36786523372f0829c17..ac798dce55b6b7dc9374fdc578a7300db0b28902 100644 --- a/docs/example.rst +++ b/docs/example.rst @@ -2,3 +2,151 @@ GW150914 Example ================= +Let's have a quick look at what Grasshopper can do. In this example +we'll have a look at the sensitivities of some of the current and +historical interferometers, and then have a look at how GW150914, the +first detected gravitational wave event would have looked in the +detectors. + +Let's get started by importing astropy's units module, and numpy, +which we'll need: +:: + import astropy.units as u + import numpy as np + + +Simulating an interferometer +---------------------------- + +A number of approaches to detecting gravitational waves have been +discussed in the literature, and have been constructed, ranging from +pulsar timing arrays to Weber bars. We're going to simulate some +interferometers, like the LIGO detectors which made the detection of +GW150914. To do this, grasshopper has a package for interferometers, +with some "pre-made" interferometers. +:: + import grasshopper.interferometers as ifo + +We can now simulate some interferometers. Let's start with Advanced LIGO. +:: + aligo = ifo.AdvancedLIGO() + +We can take a look at the sensitivity curve using the `~aligo.plot()` method: + +.. plot:: + + import matplotlib.pyplot as plt + import grasshopper.interferometers as ifo + aligo = ifo.AdvancedLIGO() + + plt.style.use('ggplot') + f, ax = plt.subplots(1) + + aligo.plot(ax) + +Simulating an event +------------------- + +Now that we have an interferometer, let's have a look at an +event. We'll simulate a compact binary merger, or a "CBC". + +The first observed gravitational wave event was a CBC, a binary black +hole merger. We can simulate that event using grasshopper. +:: + import grasshopper.sources as sources + cbc = sources.CBC(frequencies=np.logspace(-4, 5, 1000) * u.hertz, + m1=32*u.solMass, m2=30*u.solMass, r=0.8*1e9*u.parsec) + +Let's have a look at the frequency behaviour of the event: + +.. plot:: + + import matplotlib.pyplot as plt + import grasshopper.sources as sources + import astropy.units as u + cbc = sources.CBC(frequencies=np.logspace(-4, 5, 1000) * u.hertz, + m1=32*u.solMass, m2=30*u.solMass, r=0.8*1e9*u.parsec) + + plt.style.use('ggplot') + f, ax = plt.subplots(1) + + cbc.plot(ax) + + +Now that we have a detector and an event we can find out the SNR of +the signal in the detector.:: + + print cbc.snr(o1_aligo) + 112.363423673 + + +That's quite a bit higher than the SNR of the observed event, so what +gives? We simulated the design sensitivity of the aLIGO detectors, but +the event was discovered in the first observing run, which was well +below design sensitivity. We can fix this by simulating the detector +with its "O1" configuration. +:: + o1_aligo = ifo.AdvancedLIGO(configuration='O1') + +Let's have a look at this and the event on a plot. +:: + import matplotlib.pyplot as plt + import grasshopper.interferometers as ifo + import grasshopper.sources as sources + import astropy.units as u + o1_aligo = ifo.AdvancedLIGO(configuration='O1') + cbc = sources.CBC(frequencies=np.logspace(-4, 5, 1000) * u.hertz, + m1=32*u.solMass, m2=30*u.solMass, r=0.8*1e9*u.parsec) + + plt.style.use('ggplot') + f, ax = plt.subplots(1) + o1_aligo.plot(ax) + cbc.plot(ax) + + +.. plot:: + + import matplotlib.pyplot as plt + import grasshopper.interferometers as ifo + import grasshopper.sources as sources + import astropy.units as u + o1_aligo = ifo.AdvancedLIGO(configuration='O1') + cbc = sources.CBC(frequencies=np.logspace(-4, 5, 1000) * u.hertz, + m1=32*u.solMass, m2=30*u.solMass, r=0.8*1e9*u.parsec) + + plt.style.use('ggplot') + f, ax = plt.subplots(1) + o1_aligo.plot(ax) + cbc.plot(ax) + +The SNR looks better now: + +>>> print cbc.snr(o1_aligo) +24.8134701645 + +How about other interferometers? + +>>> geo = ifo.GEO() +>>> iligo = ifo.InitialLIGO() +>>> tama = ifo.TAMA() +>>> virgo = ifo.VIRGO() +>>> aligo = ifo.AdvancedLIGO() +>>> o1_aligo = ifo.AdvancedLIGO(configuration='O1') +>>> elisa = ifo.EvolvedLISA() +>>> print "{} \t\t {}".format('IFO', 'SNR') +>>> print "------------------------------" +>>> for inter in [aligo, o1_aligo, elisa, iligo, virgo, geo, tama]: +... print "{} \t\t {}".format(inter.name, cbc.snr(inter)) +IFO SNR +------------------------------ +aLIGO 112.363423673 +aLIGO [O1] 24.8134701645 +eLISA 109.12468906 +Initial LIGO 6.37979047218 +VIRGO 7.86000380341 +GEO600 4.80002280092 +TAMA 0.258152593608 + +So we can see that this event wouldn't have exceeded an SNR of 8 in +any of the previous generation of detectors, but would have been loud +in eLISA. diff --git a/docs/grasshopper.rst b/docs/grasshopper.rst index e4d973e9a2f10fdec3194bbdef74092218cfb08a..1a46cedabe03da71aeea031fce8610e32977c072 100644 --- a/docs/grasshopper.rst +++ b/docs/grasshopper.rst @@ -1,6 +1,13 @@ grasshopper package =================== +Subpackages +----------- + +.. toctree:: + + grasshopper.data + Submodules ---------- @@ -36,6 +43,14 @@ grasshopper.sources module :undoc-members: :show-inheritance: +grasshopper.timingarray module +------------------------------ + +.. automodule:: grasshopper.timingarray + :members: + :undoc-members: + :show-inheritance: + Module contents --------------- diff --git a/docs/index.rst b/docs/index.rst index e36198de4dd4311236f1c81c2b62bd648b3b7cbe..4963ea3e3442a227b56fbb5628573a86b5a70b83 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -26,6 +26,7 @@ User Guide readme installation + example usage Developer Guide @@ -36,6 +37,7 @@ Developer Guide contributing authors + modules history Indices and tables