[![pipeline status](https://git.ligo.org/gwinc/pygwinc/badges/master/pipeline.svg)](https://git.ligo.org/gwinc/pygwinc/commits/master)
# Python Gravitational Wave Interferometer Noise Calculator
[![aLIGO](https://gwinc.docs.ligo.org/pygwinc/ifo/aLIGO.png "Canonical
IFOs")](IFO.md)
`pygwinc` is a multi-faceted tool for processing and plotting noise
budgets for ground-based gravitational wave detectors. It's primary
feature is a collection of mostly analytic [noise calculation
functions](#noise-functions) for various sources of noise affecting
detectors (`gwinc.noise`):
* quantum noise
* mirror coating thermal noise
* mirror substrate thermal noise
* suspension fiber thermal noise
* seismic noise
* Newtonian/gravity-gradient noise
* residual gas noise
`pygwinc` is also a generalized noise budgeting tool (`gwinc.nb`) that
allows users to create arbitrary noise budgets (for any experiment,
not just ground-based GW detectors) using measured or analytically
calculated data. See the [budget interface](#Budget-interface)
section below.
`pygwinc` includes canonical budgets for various well-known current
and future GW detectors (`gwinc.ifo`):
* [aLIGO](https://gwinc.docs.ligo.org/pygwinc/ifo/aLIGO.png)
* [A+](https://gwinc.docs.ligo.org/pygwinc/ifo/Aplus.png)
* [Voyager](https://gwinc.docs.ligo.org/pygwinc/ifo/Voyager.png)
* [Cosmic Explorer 1](https://gwinc.docs.ligo.org/pygwinc/ifo/CE1.png)
* [Cosmic Explorer 2 (Silica)](https://gwinc.docs.ligo.org/pygwinc/ifo/CE2silica.png)
* [Cosmic Explorer 2 (Silicon)](https://gwinc.docs.ligo.org/pygwinc/ifo/CE2silicon.png)
See [IFO.md](IFO.md) for the latest CI-generated plots and hdf5 cached
data.
The [`inspiral_range`](https://git.ligo.org/gwinc/inspiral-range)
package can be used to calculate various common "inspiral range"
figures of merit for gravitational wave detector budgets. See the
[inspiral range](#inspiral-range) section below.
## usage
### command line interface
`pygwinc` provides a command line interface that can be used to
calculate and plot the various canonical IFO noise budgets described
above. For most distributions this should be available via
`gwinc` at the command line, or `python3 -m gwinc` otherwise:
```shell
$ gwinc aLIGO
```
Or [custom budgets](#budget-interface) may also be processed by providing
the path to the budget module/package:
```shell
$ gwinc path/to/mybudget
```
Budget plots can be saved in various formats (.png, .svg, .pdf):
```shell
$ gwinc --save aLIGO.png aLIGO
```
Or trace data can be saved to an
[HDF5](https://en.wikipedia.org/wiki/Hierarchical_Data_Format) file:
```shell
$ gwinc --save aLIGO.hdf5 aLIGO
```
Trace HDF5 files can also be plotted directly:
```shell
$ gwinc aLIGO.hdf5
```
The `--range` option can be used to include the values of various
inspiral ranges for the overall noise in the output.
IFO parameters can be manipulated from the command line with the
`--ifo` option:
```shell
$ gwinc aLIGO --ifo Optics.SRM.Tunephase=3.14
```
You can also dump the IFO parameters to a [YAML-formatted parameter
file](#yaml-parameter-files):
```shell
$ gwinc --yaml aLIGO > my_aLIGO.yaml
$ edit my_aLIGO.yaml
$ gwinc -d my_aLIGO.yaml aLIGO
aLIGO my_aLIGO.yaml
Materials.Coating.Philown 5e-05 3e-05
$ gwinc my_aLIGO.yaml
```
Stand-alone YAML files assume the nominal ['aLIGO' budget
description](gwinc/ifo/aLIGO).
The command line interface also includes an "interactive" mode which
provides an [IPython](https://ipython.org/) shell for interacting with
a processed budget:
```shell
$ gwinc -i Aplus
GWINC interactive shell
The 'ifo' Struct and 'trace' data are available for inspection.
Use the 'whos' command to view the workspace.
You may interact with the plot using the 'plt' functions, e.g.:
In [.]: plt.title("My Special Budget")
In [.]: plt.savefig("mybudget.pdf")
In [1]:
```
See command help for more info:
```shell
$ gwinc --help
```
### library interface
For custom plotting, parameter optimization, etc. all functionality can be
accessed directly through the `gwinc` library interface:
```python
>>> import gwinc
>>> budget = gwinc.load_budget('aLIGO')
>>> trace = budget.run()
>>> fig = trace.plot()
>>> fig.show()
```
A default frequency array is used, but alternative frequencies can be
provided to `load_budget()` either in the form of a numpy array:
```python
>>> import numpy as np
>>> freq = np.logspace(1, 3, 1000)
>>> budget = gwinc.load_budget('aLIGO', freq=freq)
```
or frequency specification string ('FLO:[NPOINTS:]FHI'):
```python
>>> budget = gwinc.load_budget('aLIGO', freq='10:1000:1000')
```
The `load_budget()` function takes most of the same inputs as the
command line interface (e.g. IFO names, budget module paths, YAML
parameter files), and returns the instantiated `Budget` object defined
in the specified budget module (see [budget
interface](#budget-interface) below). The budget `ifo` `gwinc.Struct`
is available in the `budget.ifo` attribute.
The budget `run()` method calculates all budget noises and the noise
total and returns a `BudgetTrace` object with `freq`, `psd`, and `asd`
properties. The budget sub-traces are available through a dictionary
(`trace['Quantum']`) interface and via attributes
(`trace.Quantum`).
The budget `freq` and `ifo` attributes can be updated at run time by
passing them as keyword arguments to the `run()` method:
```python
>>> budget = load_budget('aLIGO')
>>> freq = np.logspace(1, 3, 1000)
>>> ifo = Struct.from_file('/path/to/ifo_alt.yaml')
>>> trace = budget.run(freq=freq, ifo=ifo)
```
## noise functions
The `pygwinc` analytical noise functions are available in the
`gwinc.noise` package. This package includes multiple sub-modules for
the different types of noises, e.g. `suspensionthermal`,
`coatingthermal`, `quantum`, etc.)
The various noise functions need many different parameters to
calculate their noise outputs. Many parameters are expected to be in
the form of object attributes of a class-like container that is passed
to the calculation function. The pygwinc
[`Struct`](#gwinc.Struct-objects) object is designed to hold such
parameters.
For instance, the `coating_brownian` function expects a `materials`
structure as input argument, that holds the various mirror materials
parameters (e.g. `materials.Substrate.MirrorY`):
```python
def coating_brownian(f, materials, wavelength, wBeam, dOpt):
...
# extract substructures
sub = materials.Substrate
...
# substrate properties
Ysub = sub.MirrorY
```
## `gwinc.Struct` objects
`pygwinc` provides a `Struct` class that can hold parameters in
attributes and additionally acts like a dictionary, for passing to the
noise calculation functions. `Struct`s can be created from
dictionaries, or loaded from various file formats (see below).
### YAML parameter files
The easiest way to store all budget parameters is in a YAML file.
YAML files can be loaded directly into `gwinc.Struct` objects via
the `Struct.from_file()` class method:
```python
from gwinc import Struct
ifo = Struct.from_file('/path/to/ifo.yaml')
```
YAML parameter files can also be given to the `load_budget()` function
as described above, in which case the base 'aLIGO' budget structure
will be assumed and returned, with the YAML Struct inserted in the
`Budget.ifo` class attribute.
Here are the included ifo.yaml files for all the canonical IFOs:
* [aLIGO.yaml](gwinc/ifo/aLIGO/ifo.yaml)
* [Aplus.yaml](gwinc/ifo/Aplus/ifo.yaml)
* [Voyager.yaml](gwinc/ifo/Voyager/ifo.yaml)
* [CE1.yaml](gwinc/ifo/CE1/ifo.yaml)
* [CE2.yaml](gwinc/ifo/CE2/ifo.yaml)
The `Struct.from_file()` class method can also load MATLAB structs
defined in .mat files, for compatibility with
[matgwinc](https://git.ligo.org/gwinc/matgwinc), and MATLAB .m files,
although the later requires the use of the [python MATLAB
engine](https://www.mathworks.com/help/matlab/matlab-engine-for-python.html).
## budget interface
`pygwinc` provides a generic noise budget interface, `gwinc.nb`, that
can be used to define custom noise budgets (it also underlies the
"canonical" budgets included in `gwinc.ifo`). Budgets are defined in
a "budget module" which includes `BudgetItem` definitions.
### BudgetItem classes
The `gwinc.nb` package provides three `BudgetItem` classes that can be
inherited to define the various components of a budget:
* `nb.Noise`: a noise source
* `nb.Calibration`: a noise calibration
* `nb.Budget`: a group of noises
The primary action of a `BudgetItem` happens in it's `calc()` method.
For `Noise` classes, the `calc` method should return the noise PSD at
the specified frequency points. For the `Calibration` class, `calc`
should return a frequency response. `Budget` classes should not have
a special `calc` method defined as they already know how to calculate
the overall noise from their constituent noises and calibrations.
Additionally `BudgetItem`s have two other methods, `load` and
`update`, that can be overridden by the user to handle arbitrary data
processing. These are useful for creating budgets from "live" dynamic
noise measurements and the like. The three core methods therefore
are:
* `load()`: initial loading of static data
* `update(**kwargs)`: update data/attributes
* `calc()`: return final data array
Generally these methods are not called directly. Instead, the `Noise`
and `Budget` classes include a `run` method that smartly executes them
in sequence and returns a `BudgetTrace` object for the budget.
See the built-in `BudgetItem` documentation for more info
(e.g. `pydoc3 gwinc.nb.BudgetItem`)
### budget module definition
A budget module is a standard python module (single `.py` file) or
package (directory containing `__inti__.py` file) containing
`BudgetItem` definitions describing the various noises and
calibrations of a budget, as well as the overall budget calculation
itself. Each budget module should include one `nb.Budget` class
definition named after the module name.
Here's an example of a budget module named `MyBudget`. It defines two
`Noise` classes and one `Calibration` class, as well as the overall
`Budget` class (name `MyBudget` that puts them all together):
```shell
$ find MyBudget
MyBudget/
MyBudget/__init__.py
MyBudget/ifo.yaml
$
```
```python
# MyBudget/__init__.py
import numpy as np
from gwinc import nb
from gwinc import noise
class SuspensionThermal(nb.Noise):
"""Suspension thermal noise"""
style = dict(
label='Suspension Thermal',
color='#ad900d',
linestyle='--',
)
def calc(self):
n = noise.suspensionthermal.suspension_thermal(
self.freq, self.ifo.Suspension)
return 2 * n
class MeasuredNoise(nb.Noise):
style = dict(
label='Measured Noise',
color='#838209',
linestyle='-',
)
def load(self):
psd, freq = np.loadtxt('/path/to/measured/psd.txt')
self.data = self.interpolate(freq, psd)
def calc(self):
return self.data
class MyCalibration(nb.Calibration):
def calc(self):
return np.ones_like(self.freq) * 1234
class MyBudget(nb.Budget):
noises = [
SuspensionThermal,
MeasuredNoise,
]
calibrations = [
MyCalibration,
]
```
The `style` attributes of the various `Noise` classes define plot
style for the noise.
This budget can be loaded with the `gwinc.load_budget()` function, and
processed as usual with the `Budget.run()` method:
```python
budget = load_budget('/path/to/MyBudget', freq)
trace = budget.run()
```
Other than the necessary `freq` initialization argument that defines
the frequency array, any additional keyword arguments are assigned as
class attributes to the budget object, and to all of it's constituent
sub noises/calibrations/budgets.
Note that the `SuspensionThermal` Noise class above uses the
`suspension_thermal` analytic noise calculation function, which takes
a "suspension" Struct as input argument. In this case, this
suspension Struct is extracted from the `self.ifo` Struct at
`self.ifo.Suspension`.
If a budget module defined as a package includes an `ifo.yaml`
[parameter file](#parameter-files) in the package directory, the
`load_budget()` function will automatically load the YAML data into an
`ifo` `gwinc.Struct` and assign it to the `budget.ifo` attribute.
The IFOs included in `gwinc.ifo` provide examples of the use of the
budget interface (e.g. [gwinc.ifo.aLIGO](gwinc/ifo/aLIGO)).
### the "precomp" decorator
The `BudgetItem` supports "precomp" functions that can be used to
calculate common derived values needed in multiple `BudgetItems`.
They are specified using the `nb.precomp` decorator applied to the
`BudgetItem.calc()` method. These functions are executed during the
`update()` method call, supplied with the budget `freq` and `ifo`
attributes as input arguments. The execution state of the precomp
functions is cached at the Budget level, to prevent needlessly
re-calculating them multiple times. For example:
```python
from gwinc import nb
def precomp_foo(freq, ifo):
pc = Struct()
...
return pc
def precomp_bar(freq, ifo):
pc = Struct()
...
return pc
class Noise0(nb.Noise):
@nb.precomp(foo=precomp_foo)
def calc(self, foo):
...
class Noise1(nb.Noise):
@nb.precomp(foo=precomp_foo)
@nb.precomp(bar=precomp_bar)
def calc(self, foo, bar):
...
class MyBudget(nb.Budget):
noises = [
Noise0,
Noise1,
]
```
When `MyBudget.run()` is called, all the `precomp` functions will be
executed, e.g.:
```python
precomp_foo(self.freq, self.ifo)
precomp_bar(self.freq, self.ifo)
```
But the `precomp_foo` function will only be calculated once even
though it's specified as needed by both `Noise0` and `Noise1`.
### extracting single noise terms
There are various way to extract single noise terms from the Budget
interface. The most straightforward way is to run the full budget,
and extract the noise data the output traces dictionary:
```python
budget = load_budget('/path/to/MyBudget', freq)
trace = budget.run()
quantum_trace = trace['Quantum']
```
You can also calculate the final calibrated output noise for just a
single term using the Budget `calc_noise()` method:
```python
data = budget.calc_noise('Quantum')
```
You can also calculate a noise at it's source, without applying any
calibrations, by using the Budget `__getitem__` interface to extract
the specific Noise BudgetItem for the noise you're interested in, and
running it's `calc_trace()` method directly:
```python
data = budget['Quantum'].calc_trace()
```
# inspiral range
The [`inspiral_range`](https://git.ligo.org/gwinc/inspiral-range)
package can be used to calculate various common "inspiral range"
figures of merit for gravitational wave detector budgets. Here's an
example of how to use it to calculate the inspiral range of the
baseline 'Aplus' detector:
```python
import gwinc
import inspiral_range
import numpy as np
freq = np.logspace(1, 3, 1000)
budget = gwinc.load_budget('Aplus', freq)
trace = budget.run()
range = inspiral_range.range(
freq, trace.psd,
m1=30, m2=30,
)
```
See the [`inspiral_range`](https://git.ligo.org/gwinc/inspiral-range)
package for more details.
<!-- ## comparison with MATLAB gwinc -->
<!-- `pygwinc` includes the ability use MATLAB gwinc directly via the -->
<!-- MATLAB python interface (see the CLI '--matlab' option above). This -->
<!-- also allows for easy direct comparison between the pygwinc and -->
<!-- matgwinc noise budgets. -->
<!-- If you have a local checkout of matgwinc (at e.g. /path/to/gwinc) and -->
<!-- a local installation of MATLAB and it's python interface (at -->
<!-- e.g. /opt/matlab/python/lib/python3.6/site-packages) you can run the -->
<!-- comparison as so: -->
<!-- ```shell -->
<!-- $ export GWINCPATH=/path/to/matgwinc -->
<!-- $ export PYTHONPATH=/opt/matlab/python/lib/python3.6/site-packages -->
<!-- $ python3 -m gwinc.test -p aLIGO -->
<!-- ``` -->
<!-- This will produce a summary page of the various noise spectra that -->
<!-- differ between matgwinc and pygwinc. -->
<!-- Latest comparison plots from continuous integration: -->
<!-- * [aLIGO comparison](https://gwinc.docs.ligo.org/pygwinc/aLIGO_test.png) -->
<!-- * [A+ comparison](https://gwinc.docs.ligo.org/pygwinc/A+_test.png) -->
Raw data
{
"_id": null,
"home_page": "https://git.ligo.org/gwinc/pygwinc",
"name": "gwinc",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": null,
"author": "LIGO Scientific Collaboration",
"author_email": "jameson.rollins@ligo.org",
"download_url": "https://files.pythonhosted.org/packages/a2/d0/42c117bba240457fd946cfc2842999023a1339eb9be87623b58ef12c779a/gwinc-0.6.2.tar.gz",
"platform": null,
"description": "[![pipeline status](https://git.ligo.org/gwinc/pygwinc/badges/master/pipeline.svg)](https://git.ligo.org/gwinc/pygwinc/commits/master)\n\n# Python Gravitational Wave Interferometer Noise Calculator\n\n[![aLIGO](https://gwinc.docs.ligo.org/pygwinc/ifo/aLIGO.png \"Canonical\nIFOs\")](IFO.md)\n\n`pygwinc` is a multi-faceted tool for processing and plotting noise\nbudgets for ground-based gravitational wave detectors. It's primary\nfeature is a collection of mostly analytic [noise calculation\nfunctions](#noise-functions) for various sources of noise affecting\ndetectors (`gwinc.noise`):\n\n* quantum noise\n* mirror coating thermal noise\n* mirror substrate thermal noise\n* suspension fiber thermal noise\n* seismic noise\n* Newtonian/gravity-gradient noise\n* residual gas noise\n\n`pygwinc` is also a generalized noise budgeting tool (`gwinc.nb`) that\nallows users to create arbitrary noise budgets (for any experiment,\nnot just ground-based GW detectors) using measured or analytically\ncalculated data. See the [budget interface](#Budget-interface)\nsection below.\n\n`pygwinc` includes canonical budgets for various well-known current\nand future GW detectors (`gwinc.ifo`):\n\n* [aLIGO](https://gwinc.docs.ligo.org/pygwinc/ifo/aLIGO.png)\n* [A+](https://gwinc.docs.ligo.org/pygwinc/ifo/Aplus.png)\n* [Voyager](https://gwinc.docs.ligo.org/pygwinc/ifo/Voyager.png)\n* [Cosmic Explorer 1](https://gwinc.docs.ligo.org/pygwinc/ifo/CE1.png)\n* [Cosmic Explorer 2 (Silica)](https://gwinc.docs.ligo.org/pygwinc/ifo/CE2silica.png)\n* [Cosmic Explorer 2 (Silicon)](https://gwinc.docs.ligo.org/pygwinc/ifo/CE2silicon.png)\n\nSee [IFO.md](IFO.md) for the latest CI-generated plots and hdf5 cached\ndata.\n\nThe [`inspiral_range`](https://git.ligo.org/gwinc/inspiral-range)\npackage can be used to calculate various common \"inspiral range\"\nfigures of merit for gravitational wave detector budgets. See the\n[inspiral range](#inspiral-range) section below.\n\n\n## usage\n\n### command line interface\n\n`pygwinc` provides a command line interface that can be used to\ncalculate and plot the various canonical IFO noise budgets described\nabove. For most distributions this should be available via\n`gwinc` at the command line, or `python3 -m gwinc` otherwise:\n```shell\n$ gwinc aLIGO\n```\nOr [custom budgets](#budget-interface) may also be processed by providing\nthe path to the budget module/package:\n```shell\n$ gwinc path/to/mybudget\n```\n\nBudget plots can be saved in various formats (.png, .svg, .pdf):\n```shell\n$ gwinc --save aLIGO.png aLIGO\n```\nOr trace data can be saved to an\n[HDF5](https://en.wikipedia.org/wiki/Hierarchical_Data_Format) file:\n```shell\n$ gwinc --save aLIGO.hdf5 aLIGO\n```\nTrace HDF5 files can also be plotted directly:\n```shell\n$ gwinc aLIGO.hdf5\n```\n\nThe `--range` option can be used to include the values of various\ninspiral ranges for the overall noise in the output.\n\nIFO parameters can be manipulated from the command line with the\n`--ifo` option:\n```shell\n$ gwinc aLIGO --ifo Optics.SRM.Tunephase=3.14\n```\nYou can also dump the IFO parameters to a [YAML-formatted parameter\nfile](#yaml-parameter-files):\n```shell\n$ gwinc --yaml aLIGO > my_aLIGO.yaml\n$ edit my_aLIGO.yaml\n$ gwinc -d my_aLIGO.yaml aLIGO\n aLIGO my_aLIGO.yaml\nMaterials.Coating.Philown 5e-05 3e-05\n$ gwinc my_aLIGO.yaml\n```\nStand-alone YAML files assume the nominal ['aLIGO' budget\ndescription](gwinc/ifo/aLIGO).\n\nThe command line interface also includes an \"interactive\" mode which\nprovides an [IPython](https://ipython.org/) shell for interacting with\na processed budget:\n```shell\n$ gwinc -i Aplus\nGWINC interactive shell\n\nThe 'ifo' Struct and 'trace' data are available for inspection.\nUse the 'whos' command to view the workspace.\n\nYou may interact with the plot using the 'plt' functions, e.g.:\n\nIn [.]: plt.title(\"My Special Budget\")\nIn [.]: plt.savefig(\"mybudget.pdf\")\n\nIn [1]: \n```\n\nSee command help for more info:\n```shell\n$ gwinc --help\n```\n\n\n### library interface\n\nFor custom plotting, parameter optimization, etc. all functionality can be\naccessed directly through the `gwinc` library interface:\n```python\n>>> import gwinc\n>>> budget = gwinc.load_budget('aLIGO')\n>>> trace = budget.run()\n>>> fig = trace.plot()\n>>> fig.show()\n```\nA default frequency array is used, but alternative frequencies can be\nprovided to `load_budget()` either in the form of a numpy array:\n```python\n>>> import numpy as np\n>>> freq = np.logspace(1, 3, 1000)\n>>> budget = gwinc.load_budget('aLIGO', freq=freq)\n```\nor frequency specification string ('FLO:[NPOINTS:]FHI'):\n```python\n>>> budget = gwinc.load_budget('aLIGO', freq='10:1000:1000')\n```\n\nThe `load_budget()` function takes most of the same inputs as the\ncommand line interface (e.g. IFO names, budget module paths, YAML\nparameter files), and returns the instantiated `Budget` object defined\nin the specified budget module (see [budget\ninterface](#budget-interface) below). The budget `ifo` `gwinc.Struct`\nis available in the `budget.ifo` attribute.\n\nThe budget `run()` method calculates all budget noises and the noise\ntotal and returns a `BudgetTrace` object with `freq`, `psd`, and `asd`\nproperties. The budget sub-traces are available through a dictionary\n(`trace['Quantum']`) interface and via attributes\n(`trace.Quantum`).\n\nThe budget `freq` and `ifo` attributes can be updated at run time by\npassing them as keyword arguments to the `run()` method:\n```python\n>>> budget = load_budget('aLIGO')\n>>> freq = np.logspace(1, 3, 1000)\n>>> ifo = Struct.from_file('/path/to/ifo_alt.yaml')\n>>> trace = budget.run(freq=freq, ifo=ifo)\n```\n\n\n## noise functions\n\nThe `pygwinc` analytical noise functions are available in the\n`gwinc.noise` package. This package includes multiple sub-modules for\nthe different types of noises, e.g. `suspensionthermal`,\n`coatingthermal`, `quantum`, etc.)\n\nThe various noise functions need many different parameters to\ncalculate their noise outputs. Many parameters are expected to be in\nthe form of object attributes of a class-like container that is passed\nto the calculation function. The pygwinc\n[`Struct`](#gwinc.Struct-objects) object is designed to hold such\nparameters.\n\nFor instance, the `coating_brownian` function expects a `materials`\nstructure as input argument, that holds the various mirror materials\nparameters (e.g. `materials.Substrate.MirrorY`):\n```python\ndef coating_brownian(f, materials, wavelength, wBeam, dOpt):\n ...\n # extract substructures\n sub = materials.Substrate\n ...\n # substrate properties\n Ysub = sub.MirrorY\n```\n\n\n## `gwinc.Struct` objects\n\n`pygwinc` provides a `Struct` class that can hold parameters in\nattributes and additionally acts like a dictionary, for passing to the\nnoise calculation functions. `Struct`s can be created from\ndictionaries, or loaded from various file formats (see below).\n\n\n### YAML parameter files\n\nThe easiest way to store all budget parameters is in a YAML file.\nYAML files can be loaded directly into `gwinc.Struct` objects via\nthe `Struct.from_file()` class method:\n```python\nfrom gwinc import Struct\nifo = Struct.from_file('/path/to/ifo.yaml')\n```\n\nYAML parameter files can also be given to the `load_budget()` function\nas described above, in which case the base 'aLIGO' budget structure\nwill be assumed and returned, with the YAML Struct inserted in the\n`Budget.ifo` class attribute.\n\nHere are the included ifo.yaml files for all the canonical IFOs:\n\n* [aLIGO.yaml](gwinc/ifo/aLIGO/ifo.yaml)\n* [Aplus.yaml](gwinc/ifo/Aplus/ifo.yaml)\n* [Voyager.yaml](gwinc/ifo/Voyager/ifo.yaml)\n* [CE1.yaml](gwinc/ifo/CE1/ifo.yaml)\n* [CE2.yaml](gwinc/ifo/CE2/ifo.yaml)\n\nThe `Struct.from_file()` class method can also load MATLAB structs\ndefined in .mat files, for compatibility with\n[matgwinc](https://git.ligo.org/gwinc/matgwinc), and MATLAB .m files,\nalthough the later requires the use of the [python MATLAB\nengine](https://www.mathworks.com/help/matlab/matlab-engine-for-python.html).\n\n\n## budget interface\n\n`pygwinc` provides a generic noise budget interface, `gwinc.nb`, that\ncan be used to define custom noise budgets (it also underlies the\n\"canonical\" budgets included in `gwinc.ifo`). Budgets are defined in\na \"budget module\" which includes `BudgetItem` definitions.\n\n### BudgetItem classes\n\nThe `gwinc.nb` package provides three `BudgetItem` classes that can be\ninherited to define the various components of a budget:\n\n* `nb.Noise`: a noise source\n* `nb.Calibration`: a noise calibration\n* `nb.Budget`: a group of noises\n\nThe primary action of a `BudgetItem` happens in it's `calc()` method.\nFor `Noise` classes, the `calc` method should return the noise PSD at\nthe specified frequency points. For the `Calibration` class, `calc`\nshould return a frequency response. `Budget` classes should not have\na special `calc` method defined as they already know how to calculate\nthe overall noise from their constituent noises and calibrations.\n\nAdditionally `BudgetItem`s have two other methods, `load` and\n`update`, that can be overridden by the user to handle arbitrary data\nprocessing. These are useful for creating budgets from \"live\" dynamic\nnoise measurements and the like. The three core methods therefore\nare:\n\n* `load()`: initial loading of static data\n* `update(**kwargs)`: update data/attributes\n* `calc()`: return final data array\n\nGenerally these methods are not called directly. Instead, the `Noise`\nand `Budget` classes include a `run` method that smartly executes them\nin sequence and returns a `BudgetTrace` object for the budget.\n\nSee the built-in `BudgetItem` documentation for more info\n(e.g. `pydoc3 gwinc.nb.BudgetItem`)\n\n\n### budget module definition\n\nA budget module is a standard python module (single `.py` file) or\npackage (directory containing `__inti__.py` file) containing\n`BudgetItem` definitions describing the various noises and\ncalibrations of a budget, as well as the overall budget calculation\nitself. Each budget module should include one `nb.Budget` class\ndefinition named after the module name.\n\nHere's an example of a budget module named `MyBudget`. It defines two\n`Noise` classes and one `Calibration` class, as well as the overall\n`Budget` class (name `MyBudget` that puts them all together):\n```shell\n$ find MyBudget\nMyBudget/\nMyBudget/__init__.py\nMyBudget/ifo.yaml\n$\n```\n\n```python\n# MyBudget/__init__.py\n\nimport numpy as np\nfrom gwinc import nb\nfrom gwinc import noise\n\n\nclass SuspensionThermal(nb.Noise):\n \"\"\"Suspension thermal noise\"\"\"\n style = dict(\n label='Suspension Thermal',\n color='#ad900d',\n linestyle='--',\n )\n\n def calc(self):\n n = noise.suspensionthermal.suspension_thermal(\n self.freq, self.ifo.Suspension)\n return 2 * n\n\n\nclass MeasuredNoise(nb.Noise):\n style = dict(\n label='Measured Noise',\n color='#838209',\n linestyle='-',\n )\n\n def load(self):\n psd, freq = np.loadtxt('/path/to/measured/psd.txt')\n self.data = self.interpolate(freq, psd)\n\n def calc(self):\n return self.data\n\n\nclass MyCalibration(nb.Calibration):\n def calc(self):\n return np.ones_like(self.freq) * 1234\n\n\nclass MyBudget(nb.Budget):\n noises = [\n SuspensionThermal,\n MeasuredNoise,\n ]\n \n calibrations = [\n MyCalibration,\n ]\n```\n\nThe `style` attributes of the various `Noise` classes define plot\nstyle for the noise.\n\nThis budget can be loaded with the `gwinc.load_budget()` function, and\nprocessed as usual with the `Budget.run()` method:\n```python\nbudget = load_budget('/path/to/MyBudget', freq)\ntrace = budget.run()\n```\n\nOther than the necessary `freq` initialization argument that defines\nthe frequency array, any additional keyword arguments are assigned as\nclass attributes to the budget object, and to all of it's constituent\nsub noises/calibrations/budgets.\n\nNote that the `SuspensionThermal` Noise class above uses the\n`suspension_thermal` analytic noise calculation function, which takes\na \"suspension\" Struct as input argument. In this case, this\nsuspension Struct is extracted from the `self.ifo` Struct at\n`self.ifo.Suspension`.\n\nIf a budget module defined as a package includes an `ifo.yaml`\n[parameter file](#parameter-files) in the package directory, the\n`load_budget()` function will automatically load the YAML data into an\n`ifo` `gwinc.Struct` and assign it to the `budget.ifo` attribute.\n\nThe IFOs included in `gwinc.ifo` provide examples of the use of the\nbudget interface (e.g. [gwinc.ifo.aLIGO](gwinc/ifo/aLIGO)).\n\n\n### the \"precomp\" decorator\n\nThe `BudgetItem` supports \"precomp\" functions that can be used to\ncalculate common derived values needed in multiple `BudgetItems`.\nThey are specified using the `nb.precomp` decorator applied to the\n`BudgetItem.calc()` method. These functions are executed during the\n`update()` method call, supplied with the budget `freq` and `ifo`\nattributes as input arguments. The execution state of the precomp\nfunctions is cached at the Budget level, to prevent needlessly\nre-calculating them multiple times. For example:\n```python\nfrom gwinc import nb\n\n\ndef precomp_foo(freq, ifo):\n pc = Struct()\n ...\n return pc\n\n\ndef precomp_bar(freq, ifo):\n pc = Struct()\n ...\n return pc\n\n\nclass Noise0(nb.Noise):\n @nb.precomp(foo=precomp_foo)\n def calc(self, foo):\n ...\n\nclass Noise1(nb.Noise):\n @nb.precomp(foo=precomp_foo)\n @nb.precomp(bar=precomp_bar)\n def calc(self, foo, bar):\n ...\n\nclass MyBudget(nb.Budget):\n noises = [\n Noise0,\n Noise1,\n ]\n```\nWhen `MyBudget.run()` is called, all the `precomp` functions will be\nexecuted, e.g.:\n```python\nprecomp_foo(self.freq, self.ifo)\nprecomp_bar(self.freq, self.ifo)\n```\nBut the `precomp_foo` function will only be calculated once even\nthough it's specified as needed by both `Noise0` and `Noise1`.\n\n\n### extracting single noise terms\n\nThere are various way to extract single noise terms from the Budget\ninterface. The most straightforward way is to run the full budget,\nand extract the noise data the output traces dictionary:\n\n```python\nbudget = load_budget('/path/to/MyBudget', freq)\ntrace = budget.run()\nquantum_trace = trace['Quantum']\n```\n\nYou can also calculate the final calibrated output noise for just a\nsingle term using the Budget `calc_noise()` method:\n```python\ndata = budget.calc_noise('Quantum')\n```\n\nYou can also calculate a noise at it's source, without applying any\ncalibrations, by using the Budget `__getitem__` interface to extract\nthe specific Noise BudgetItem for the noise you're interested in, and\nrunning it's `calc_trace()` method directly:\n```python\ndata = budget['Quantum'].calc_trace()\n```\n\n\n# inspiral range\n\nThe [`inspiral_range`](https://git.ligo.org/gwinc/inspiral-range)\npackage can be used to calculate various common \"inspiral range\"\nfigures of merit for gravitational wave detector budgets. Here's an\nexample of how to use it to calculate the inspiral range of the\nbaseline 'Aplus' detector:\n```python\nimport gwinc\nimport inspiral_range\nimport numpy as np\n\nfreq = np.logspace(1, 3, 1000)\nbudget = gwinc.load_budget('Aplus', freq)\ntrace = budget.run()\n\nrange = inspiral_range.range(\n freq, trace.psd,\n m1=30, m2=30,\n)\n```\n\nSee the [`inspiral_range`](https://git.ligo.org/gwinc/inspiral-range)\npackage for more details.\n\n\n<!-- ## comparison with MATLAB gwinc -->\n\n<!-- `pygwinc` includes the ability use MATLAB gwinc directly via the -->\n<!-- MATLAB python interface (see the CLI '--matlab' option above). This -->\n<!-- also allows for easy direct comparison between the pygwinc and -->\n<!-- matgwinc noise budgets. -->\n\n<!-- If you have a local checkout of matgwinc (at e.g. /path/to/gwinc) and -->\n<!-- a local installation of MATLAB and it's python interface (at -->\n<!-- e.g. /opt/matlab/python/lib/python3.6/site-packages) you can run the -->\n<!-- comparison as so: -->\n<!-- ```shell -->\n<!-- $ export GWINCPATH=/path/to/matgwinc -->\n<!-- $ export PYTHONPATH=/opt/matlab/python/lib/python3.6/site-packages -->\n<!-- $ python3 -m gwinc.test -p aLIGO -->\n<!-- ``` -->\n<!-- This will produce a summary page of the various noise spectra that -->\n<!-- differ between matgwinc and pygwinc. -->\n\n<!-- Latest comparison plots from continuous integration: -->\n\n<!-- * [aLIGO comparison](https://gwinc.docs.ligo.org/pygwinc/aLIGO_test.png) -->\n<!-- * [A+ comparison](https://gwinc.docs.ligo.org/pygwinc/A+_test.png) -->\n",
"bugtrack_url": null,
"license": "UNLICENSE",
"summary": "Gravitation Wave Interferometer Noise Calculator",
"version": "0.6.2",
"project_urls": {
"Bug Tracker": "https://git.ligo.org/gwinc/pygwinc/issues",
"Homepage": "https://git.ligo.org/gwinc/pygwinc",
"Source Code": "https://git.ligo.org/gwinc/pygwinc"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1f2acc9946bf406d4fa6a0b38d1531eca30ed93772131a4d263214e900ec4d8e",
"md5": "f79bc474d1d66c29d9b5a12bc6c68179",
"sha256": "9250265e8a7bde0ab31b0d8fc14b1fcbaecbcd8e6b6ea6a2400871efdeaad528"
},
"downloads": -1,
"filename": "gwinc-0.6.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "f79bc474d1d66c29d9b5a12bc6c68179",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 132312,
"upload_time": "2024-10-15T19:23:21",
"upload_time_iso_8601": "2024-10-15T19:23:21.365029Z",
"url": "https://files.pythonhosted.org/packages/1f/2a/cc9946bf406d4fa6a0b38d1531eca30ed93772131a4d263214e900ec4d8e/gwinc-0.6.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a2d042c117bba240457fd946cfc2842999023a1339eb9be87623b58ef12c779a",
"md5": "5440b3f23a38b0271710c04a80678a24",
"sha256": "17e4b2b227ce11bb7616592d1e2e5e57fbd4bc9baa5f8fb5669d41b2141f8840"
},
"downloads": -1,
"filename": "gwinc-0.6.2.tar.gz",
"has_sig": false,
"md5_digest": "5440b3f23a38b0271710c04a80678a24",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 649126,
"upload_time": "2024-10-15T19:23:23",
"upload_time_iso_8601": "2024-10-15T19:23:23.433400Z",
"url": "https://files.pythonhosted.org/packages/a2/d0/42c117bba240457fd946cfc2842999023a1339eb9be87623b58ef12c779a/gwinc-0.6.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-15 19:23:23",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "gwinc"
}