# Isso – a commenting server similar to Disqus

Isso – *Ich schrei sonst* – is a lightweight commenting server written in
Python and JavaScript. It aims to be a drop-in replacement for
[Disqus](http://disqus.com).

## Features

- **Comments written in Markdown**
  Users can edit or delete own comments (within 15 minutes by default).
  Comments in moderation queue are not publicly visible before activation.
- **SQLite backend**
  *Because comments are not Big Data.*
- **Disqus & WordPress Import**
  You can migrate your Disqus/WordPress comments without any hassle.
- **Configurable JS client**
  Embed a single JS file, 65kB (20kB gzipped) and you are done.

See **[isso-comments.de](https://isso-comments.de/)** for a **live demo**, more
details and [documentation](https://isso-comments.de/docs/).

## Screenshot

![Isso in Action](https://user-images.githubusercontent.com/10212877/167268553-3f30b448-25ff-4850-afef-df2f2e599c93.png)

## Getting started

### Requirements

- Python 3.8+ (+ devel headers)
- SQLite 3.3.8 or later
- a working C compiler

Install Isso from [PyPi](https://pypi.python.org/pypi/isso/):

```console
pip install isso
```

Then, follow the [Quickstart](https://isso-comments.de/docs/guides/quickstart/) guide.

If you're stuck, follow the [Install guide](https://isso-comments.de/docs/reference/installation/),
see [Troubleshooting](https://isso-comments.de/docs/guides/troubleshooting/) and browse
the [the full documentation](https://isso-comments.de/docs/).

## Docker

A Docker image with the latest stable release is provided at
`ghcr.io/isso-comments/isso:latest`. See
[Using Docker](https://isso-comments.de/docs/reference/installation/#using-docker).

## Contributing

- Pull requests are very much welcome! These might be
  [good first issues](https://github.com/posativ/isso/labels/good-first-issue)
- See [Ways to Contribute](https://isso-comments.de/docs/contributing/)
- [Translate](https://isso-comments.de/docs/contributing/#translations)

### Development

<!-- TODO also mention "Development & Testing" section once new docs uploaded -->
Refer to the docs for
[Installing from Source](https://isso-comments.de/docs/reference/installation/#install-from-source).

### Help

- Join `#isso` via [Matrix](https://matrix.to/#/#isso:libera.chat) or via IRC on
  [Libera.Chat](https://libera.chat/)
- Ask a question on [GitHub Discussions](https://github.com/posativ/isso/discussions).

## License

MIT, see [LICENSE](LICENSE).


[![PyPI version](https://badge.fury.io/py/udocker.svg)](https://badge.fury.io/py/udocker)
[![Build Status](https://jenkins.eosc-synergy.eu/buildStatus/icon?job=indigo-dc%2Fudocker%2Fmaster)](https://jenkins.eosc-synergy.eu/job/indigo-dc/job/udocker/job/master/)

[![SQAaaS badge](https://github.com/EOSC-synergy/SQAaaS/raw/master/badges/badges_150x116/badge_software_gold.png)](https://api.eu.badgr.io/public/assertions/_HIuuD5PRMipzM62mWTk3Q "SQAaaS gold badge achieved")

---
![logo](docs/logo-small.png)

udocker is a basic user tool to execute simple docker containers in user
space without requiring root privileges. Enables download and execution
of docker containers by non-privileged users in Linux systems where
docker is not available. It can be used to pull and execute docker
containers in Linux batch systems and interactive clusters that are
managed by other entities such as grid infrastructures or externally
managed batch or interactive systems.

udocker does not require any type of privileges nor the deployment of
services by system administrators. It can be downloaded and executed
entirely by the end user. The limited root functionality provided by
some of the udocker execution modes is either simulated or provided
via user namespaces.

udocker is a wrapper around several tools and libraries to mimic a
subset of the docker capabilities including pulling images and running
containers with minimal functionality.

## Documentation

The full documentation is available at:

* [udocker documentation](https://indigo-dc.github.io/udocker/)
* [Installation manual](https://indigo-dc.github.io/udocker/installation_manual.html)
* [User manual](https://indigo-dc.github.io/udocker/user_manual.html)
* [Reference card](https://indigo-dc.github.io/udocker/reference_card.html)

## How does it work

udocker is written in Python, it has a minimal set of dependencies so
that can be executed in a wide range of Linux systems.

udocker does not make use of docker nor requires its presence.

udocker "executes" the containers by simply providing a chroot like
environment over the extracted container. The current implementation
supports different methods to mimic chroot thus enabling execution of
containers under a chroot like environment without requiring privileges.
udocker transparently supports several methods to execute the containers
based on external tools and libraries such as:

* PRoot
* Fakechroot
* runc
* crun
* Singularity

With the exception of Singularity the tools and libraries to support
execution are downloaded and deployed by udocker during the installation
process. This installation is performed in the user home directory
and does not require privileges. The udocker related files such as
libraries, executables, documentation, licenses, container images and
extracted directory trees are placed by default under `$HOME/.udocker`.

## Advantages

* Can be deployed by the end-user
* Does not require privileges for installation
* Does not require privileges for execution
* Does not require compilation, just transfer the Python code
* Encapsulates several tools and execution methods
* Includes the required tools already statically compiled to work
  across systems
* Provides a docker like command line interface
* Supports a subset of docker commands:
  search, pull, import, export, load, save, login, logout, create and run
* Understands docker container metadata
* Allows loading of docker and OCI containers
* Supports NVIDIA GPGPU applications
* Can execute in systems and environments where Linux namespaces
  support is unavailable
* Runs both on new and older Linux distributions including:
  CentOS 6, CentOS 7, CentOS 8, Ubuntu 14, Ubuntu 16, Ubuntu 18, Ubuntu 20,
  Ubuntu 21, Alpine, Fedora, etc

## Python 2 and Python 3

Since v1.3.0, udocker supports Python 2.6, 2.7 and Python >= 3.6.
The original udocker v1.1.x for Python 2 is no longer maintained
but is still available
[here](https://github.com/indigo-dc/udocker/tree/v1.1.8).

## Syntax

```txt
        Commands:
          search <repo/expression>      :Search dockerhub for container images
          pull <repo/image:tag>         :Pull container image from dockerhub
          create <repo/image:tag>       :Create container from a pulled image
          run <container>               :Execute container
          run <repo/image:tag>          :Pull, create and execute container

          images -l                     :List container images
          ps -m -s                      :List created containers
          name <container_id> <name>    :Give name to container
          rmname <name>                 :Delete name from container
          rename <name> <new_name>      :Change container name
          clone <container_id>          :Duplicate container
          rm <container-id>             :Delete container
          rmi <repo/image:tag>          :Delete image
          tag <repo/image:tag> <repo2/image2:tag2> :Tag image

          import <tar> <repo/image:tag> :Import tar file (exported by docker)
          import - <repo/image:tag>     :Import from stdin (exported by docker)
          export -o <tar> <container>   :Export container directory tree
          export - <container>          :Export container directory tree
          load -i <imagefile>           :Load image from file (saved by docker)
          load                          :Load image from stdin (saved by docker)
          save -o <imagefile> <repo/image:tag>  :Save image with layers to file

          inspect <repo/image:tag>      :Return low level information on image
          inspect -p <container>        :Return path to container location
          verify <repo/image:tag>       :Verify a pulled or loaded image
          manifest inspect <repo/image:tag> :Print manifest metadata

          protect <repo/image:tag>      :Protect repository
          unprotect <repo/image:tag>    :Unprotect repository
          protect <container>           :Protect container
          unprotect <container>         :Unprotect container

          mkrepo <top-repo-dir>         :Create another repository in location
          setup                         :Change container execution settings
          login                         :Login into docker repository
          logout                        :Logout from docker repository

          help                          :This help
          run --help                    :Command specific help
          version                       :Shows udocker version

        Options common to all commands must appear before the command:
          -D                            :Debug
          --quiet                       :Less verbosity
          --repo=<directory>            :Use repository at directory
          --insecure                    :Allow insecure non authenticated https
          --allow-root                  :Allow execution by root NOT recommended
```

## Examples

Some examples of usage:

Search container images in dockerhub and listing tags.

```bash
udocker search  fedora
udocker search  ubuntu
udocker search  debian

udocker search --list-tags ubuntu
```

Pull from dockerhub and list the pulled images.

```bash
udocker pull   fedora:39
udocker pull   busybox
udocker pull   iscampos/openqcd
udocker images
```

Pull from a registry other than dockerhub.

```bash
udocker search  quay.io/bio
udocker search  --list-tags  quay.io/biocontainers/scikit-bio
udocker pull    quay.io/biocontainers/scikit-bio:0.2.3--np112py35_0
udocker images
```

Pull a different architecture such as arm64 instead of amd64.

```bash
udocker manifest inspect centos/centos8
udocker pull --platform=linux/arm64 centos/centos8
udocker tag centos/centos8  mycentos/centos8:arm64
```

Create a container from a pulled image, assign a name to the created
container and run it. A created container can be run multiple times
until it is explicitly removed. Files modified or added to the container
remain available across executions until the container is removed.

```bash
udocker create --name=myfed  fedora:29
udocker run  myfed  cat /etc/redhat-release
```

The three steps of pulling, creating and running can be also achieved
in a single command, however this will be much slower for multiple
invocations of the same container, as a new container will be created
for each invocation. This approach will also consume more storage space.
The following example creates a new container for each invocation.

```bash
udocker run  fedora:29  cat /etc/redhat-release
```

Execute mounting the host /home/u457 into the container directory /home/cuser.
Notice that you can "mount" any host directory inside the container.
Depending on the execution mode the "mount" is implemented differently and
may have restrictions.

```bash
udocker run -v /home/u457:/home/cuser -w /home/user myfed  /bin/bash
udocker run -v /var -v /proc -v /sys -v /tmp  myfed  /bin/bash
```

Place a script in your host /tmp and execute it in the container. Notice
that the behavior of `--entrypoint` changed from the previous versions
for better compatibility with docker.

```bash
udocker run  -v /tmp  --entrypoint="" myfed  /bin/bash -c 'cd /tmp; ./myscript.sh'

udocker run  -v /tmp  --entrypoint=/bin/bash  myfed  -c 'cd /tmp; ./myscript.sh'
```

Execute mounting the host /var, /proc, /sys and /tmp in the same container
directories. Notice that the content of these container directories will
be obfuscated by the host files.

```bash
udocker run -v /var -v /proc -v /sys -v /tmp  myfed  /bin/bash
```

Install software inside the container.

```bash
udocker run  --user=root myfed  yum install -y firefox pulseaudio gnash-plugin
```

Run as some user. The usernames should exist in the container.

```bash
udocker run --user 1000:1001  myfed  /bin/id
udocker run --user root   myfed  /bin/id
udocker run --user jorge  myfed  /bin/id
```

Running Firefox.

```bash
udocker run --bindhome --hostauth --hostenv \
   -v /sys -v /proc -v /var/run -v /dev --user=jorge --dri myfed  firefox
```

Change execution engine mode from PRoot to Fakechroot and run.

```bash
udocker setup  --execmode=F3  myfed

udocker run --bindhome --hostauth --hostenv \
   -v /sys -v /proc -v /var/run -v /dev --user=jorge --dri myfed  firefox
```

Change execution engine mode to accelerated PRoot.

```bash
udocker setup  --execmode=P1  myfed
```

Change execution engine to runc.

```bash
udocker setup  --execmode=R1  myfed
```

Change execution engine to Singularity. Requires the availability of
Singularity in the host system.

```bash
./udocker setup  --execmode=S1  myfed
```

Install software running as root emulation in Singularity:

```bash
udocker setup  --execmode=S1  myfed
udocker run  --user=root myfed  yum install -y firefox pulseaudio gnash-plugin
```

Change execution to enable nvidia ready applications. Requires that
the nvidia drivers are installed in the host system.

```bash
udocker setup  --nvidia  mytensorflow
```

## Security

By default udocker via PRoot offers the emulation of the root user. This
emulation mimics a real root user (e.g getuid will return 0). This is just
an emulation no root privileges are involved. This feature makes possible
the execution of some tools that do not require actual privileges but which
refuse to work if the username or id are not root or 0. This enables for
instance software installation using rpm, yum or dnf inside the container.

udocker does not offer robust isolation features such as the ones offered
by docker. Therefore if the containers content is not trusted then these
containers should not be executed with udocker as they will run inside the
user environment. For this reason udocker should not be run by privileged
users.

Container images and filesystems will be unpacked and stored in the user
home directory under `$HOME/.udocker` or other location of choice. Therefore
the containers data will be subjected to the same filesystem protections as
other files owned by the user. If the containers have sensitive information
the files and directories should be adequately protected by the user.

udocker does not require privileges and runs under the identity of the user
invoking it. Users can downloaded udocker and execute it without requiring
system administrators intervention.

udocker also provides execution with runc, crun and Singularity, these modes
make use of rootless namespaces and enable a normal user to execute as root
with the limitations that apply to user namespaces and to these tools.

When executed by normal unprivileged users, udocker limits privilege
escalation issues since it does not use or require system privileges.

## General Limitations

Since root privileges are not involved any operation that really
requires such privileges will not be possible. The following  are
examples of operations that are not possible:

* accessing host protected devices and files
* listening on TCP/IP privileged ports (range below 1024)
* mount file-systems
* the su command will not work
* change the system time
* changing routing tables, firewall rules, or network interfaces

If the containers require such privilege capabilities then docker
should be used instead.

udocker is not meant to create containers. Creation of containers
is better performed using docker and dockerfiles.

udocker does not provide all the docker features, and is not intended
as a docker replacement.

udocker is mainly oriented at providing a run-time environment for
containers execution in user space. udocker is particularly suited to
run user applications encapsulated in docker containers.

Debugging or using strace with the PRoot engine will not work as both
the debuggers and PRoot use the same tracing mechanism.

## Execution mode specific limitations

udocker offers multiple execution modes leveraging several external tools
such as PRoot (P mode), Fakechroot (F mode), runC (R mode), crun (R mode)
and Singularity (S mode).

When using execution Fakechroot modes such as F2, F3 and F4 the created
containers cannot be moved across hosts. In this case convert back to a Pn
mode before transfer.
This is not needed if the hosts are part of an homogeneous cluster where
the mount points and directory structure is the same. This limitation
applies whenever the absolute realpath to the container directory changes.

The default accelerated mode of PRoot (mode P1) may exhibit problems in Linux
kernels above 4.0 due to kernel changes and upstream issues, in this case use
mode P2 or any of the other execution modes.

```bash
./udocker setup  --execmode=P2  my-container-id
```

The Fakechroot modes (Fn modes) require shared libraries compiled against
the libc shipped with the container. udocker provides these libraries for
several Linux distributions, these shared libraries are installed by
udocker under:

```bash
$HOME/.udocker/lib/libfakechroot-*
```

The runc and crun modes (R modes) require a kernel with user namespaces enabled.

The singularity mode (S mode) requires the availability of Singularity in
the host system. Singularity is not shipped with udocker.

## Metadata generation

The `codemeta.json` metadata file was initially generated with `codemetapy`
package:

```bash
codemetapy udocker --with-orcid --affiliation "LIP Lisbon" \
  --buildInstructions "https://https://github.com/indigo-dc/udocker/blob/master/docs/installation_manual.md#3-source-code-and-build" \
  --citation "https://doi.org/10.1016/j.cpc.2018.05.021" \
  --codeRepository "https://github.com/indigo-dc/udocker" \
  --contIntegration "https://jenkins.eosc-synergy.eu/job/indigo-dc/job/udocker/job/master/" --contributor "Mario David" \
  --copyrightHolder "LIP"  --copyrightYear "2016" --creator "Jorge Gomes" \
  --dateCreated "2021-05-26" --maintainer "Jorge Gomes" \
  --readme "https://github.com/indigo-dc/udocker/blob/master/README.md" \
  --referencePublication "https://doi.org/10.1016/j.cpc.2018.05.021" \
  --releaseNotes "https://github.com/indigo-dc/udocker/blob/master/changelog" \
  -O codemeta.json
```

Further updates may be needed to add the correct values in the metadata file.

## Contributing

See: [Contributing](CONTRIBUTING.md)

## Citing

See: [Citing](CITING.md)

When citing udocker please use the following:

* Jorge Gomes, Emanuele Bagnaschi, Isabel Campos, Mario David,
  Luís Alves, João Martins, João Pina, Alvaro López-García, Pablo Orviz,
  Enabling rootless Linux Containers in multi-user environments: The udocker
  tool, Computer Physics Communications, Available online 6 June 2018,
  ISSN 0010-4655, <https://doi.org/10.1016/j.cpc.2018.05.021>

## Licensing

Redistribution, commercial use and code changes must regard all licenses
shipped with udocker. These include the [udocker license](LICENSE) and the
individual licences of the external tools and libraries packaged for use
with udocker. For further information see the
[software licenses section](https://indigo-dc.github.io/udocker/installation_manual.html#62-software-licenses)
of the installation manual.

## Acknowledgements

* Docker <https://www.docker.com/>
* PRoot <https://proot-me.github.io/>
* Fakechroot <https://github.com/dex4er/fakechroot/wiki>
* Patchelf <https://github.com/NixOS/patchelf>
* runC <https://runc.io/>
* crun <https://github.com/containers/crun>
* Singularity <https://www.sylabs.io/>
* Open Container Initiative <https://www.opencontainers.org/>
* INDIGO DataCloud <https://www.indigo-datacloud.eu>
* DEEP-Hybrid-DataCloud <https://deep-hybrid-datacloud.eu>
* EOSC-hub <https://eosc-hub.eu>
* EGI-ACE <https://www.egi.eu/projects/egi-ace/>
* EOSC-Synergy <https://www.eosc-synergy.eu/>
* DT-Geo <https://dtgeo.eu/>
* LIP [https://www.lip.pt](https://www.lip.pt/?section=home&page=homepage&lang=en)
* INCD [https://www.incd.pt](https://www.incd.pt/?lang=en)

This work was performed in the framework of the H2020 project INDIGO-Datacloud
(RIA 653549) and further developed with co-funding by the projects EOSC-hub
(Horizon 2020) under Grant number 777536, DEEP-Hybrid-DataCloud
(Horizon 2020) under Grant number 777435, DT-Geo (Horizon Europe) under Grant
number 101058129. Software Quality Assurance is performed with the support of
by the project EOSC-Synergy (Horizon 2020).
The authors wish to acknowleadge the support of INCD-Infraestrutura Nacional de
Computação Distribuída (funded by FCT, P2020, Lisboa2020, COMPETE and FEDER
under the project number 22153-01/SAICT/2016).


aioquic
=======

.. image:: https://img.shields.io/pypi/l/aioquic.svg
   :target: https://pypi.python.org/pypi/aioquic
   :alt: License

.. image:: https://img.shields.io/pypi/v/aioquic.svg
   :target: https://pypi.python.org/pypi/aioquic
   :alt: Version

.. image:: https://img.shields.io/pypi/pyversions/aioquic.svg
   :target: https://pypi.python.org/pypi/aioquic
   :alt: Python versions

.. image:: https://github.com/aiortc/aioquic/workflows/tests/badge.svg
   :target: https://github.com/aiortc/aioquic/actions
   :alt: Tests

.. image:: https://img.shields.io/codecov/c/github/aiortc/aioquic.svg
   :target: https://codecov.io/gh/aiortc/aioquic
   :alt: Coverage

.. image:: https://readthedocs.org/projects/aioquic/badge/?version=latest
   :target: https://aioquic.readthedocs.io/
   :alt: Documentation

What is ``aioquic``?
--------------------

``aioquic`` is a library for the QUIC network protocol in Python. It features
a minimal TLS 1.3 implementation, a QUIC stack and an HTTP/3 stack.

QUIC was standardised in `RFC 9000`_ and HTTP/3 in `RFC 9114`_.
``aioquic`` is regularly tested for interoperability against other
`QUIC implementations`_.

To learn more about ``aioquic`` please `read the documentation`_.

Why should I use ``aioquic``?
-----------------------------

``aioquic`` has been designed to be embedded into Python client and server
libraries wishing to support QUIC and / or HTTP/3. The goal is to provide a
common codebase for Python libraries in the hope of avoiding duplicated effort.

Both the QUIC and the HTTP/3 APIs follow the "bring your own I/O" pattern,
leaving actual I/O operations to the API user. This approach has a number of
advantages including making the code testable and allowing integration with
different concurrency models.

Features
--------

- minimal TLS 1.3 implementation conforming with `RFC 8446`_
- QUIC stack conforming with `RFC 9000`_ (QUIC v1) and `RFC 9369`_ (QUIC v2)
   * IPv4 and IPv6 support
   * connection migration and NAT rebinding
   * logging TLS traffic secrets
   * logging QUIC events in QLOG format
- HTTP/3 stack conforming with `RFC 9114`_
   * server push support
   * WebSocket bootstrapping conforming with `RFC 9220`_
   * datagram support conforming with `RFC 9297`_

Installing
----------

The easiest way to install ``aioquic`` is to run:

.. code:: bash

    pip install aioquic

Building from source
--------------------

If there are no wheels for your system or if you wish to build ``aioquic``
from source you will need the OpenSSL development headers.

Linux
.....

On Debian/Ubuntu run:

.. code-block:: console

   sudo apt install libssl-dev python3-dev

On Alpine Linux run:

.. code-block:: console

   sudo apk add openssl-dev python3-dev bsd-compat-headers libffi-dev

OS X
....

On OS X run:

.. code-block:: console

   brew install openssl

You will need to set some environment variables to link against OpenSSL:

.. code-block:: console

   export CFLAGS=-I$(brew --prefix openssl)/include
   export LDFLAGS=-L$(brew --prefix openssl)/lib

Windows
.......

On Windows the easiest way to install OpenSSL is to use `Chocolatey`_.

.. code-block:: console

   choco install openssl

You will need to set some environment variables to link against OpenSSL:

.. code-block:: console

  $Env:INCLUDE = "C:\Progra~1\OpenSSL\include"
  $Env:LIB = "C:\Progra~1\OpenSSL\lib"

Running the examples
--------------------

`aioquic` comes with a number of examples illustrating various QUIC usecases.

You can browse these examples here: https://github.com/aiortc/aioquic/tree/main/examples

License
-------

``aioquic`` is released under the `BSD license`_.

.. _read the documentation: https://aioquic.readthedocs.io/en/latest/
.. _QUIC implementations: https://github.com/quicwg/base-drafts/wiki/Implementations
.. _cryptography: https://cryptography.io/
.. _Chocolatey: https://chocolatey.org/
.. _BSD license: https://aioquic.readthedocs.io/en/latest/license.html
.. _RFC 8446: https://datatracker.ietf.org/doc/html/rfc8446
.. _RFC 9000: https://datatracker.ietf.org/doc/html/rfc9000
.. _RFC 9114: https://datatracker.ietf.org/doc/html/rfc9114
.. _RFC 9220: https://datatracker.ietf.org/doc/html/rfc9220
.. _RFC 9297: https://datatracker.ietf.org/doc/html/rfc9297
.. _RFC 9369: https://datatracker.ietf.org/doc/html/rfc9369


[![latest-release](https://img.shields.io/github/tag/dfki-ric/phobos.svg?label=version&style=flat)](https://github.com/dfki-ric/phobos/releases)
[![DOI](https://joss.theoj.org/papers/10.21105/joss.01326/status.svg)](https://doi.org/10.21105/joss.01326)
[![license](https://img.shields.io/github/license/dfki-ric/phobos.svg?style=flat)](https://github.com/dfki-ric/phobos/blob/master/COPYING)
[![made-with-sphinx-doc](https://img.shields.io/badge/Made%20with-Sphinx-1f425f.svg)](https://www.sphinx-doc.org/)
[![API-Docs](https://github.com/dfki-ric/phobos/actions/workflows/gh-pages.yml/badge.svg)](http://dfki-ric.github.io/phobos)

![Phobos](https://github.com/dfki-ric/phobos/wiki/img/phobos_logo_small.png)

Phobos is both a CLI tool and add-on for the open-source 3D modeling software
[Blender v3.3LTS](https://www.blender.org/download/lts/3-3/) to support your robot model creation and editing.

The Blender add-on enables the creation of WYSIWYG robot
models for use in robot frameworks like [ROS](http://wiki.ros.org/) and
[ROCK](https://github.com/rock-core) or in real-time simulations such as
[MARS](https://github.com/rock-simulation/mars) or
[Gazebo](http://gazebosim.org/). Phobos exports formats such as **URDF**,
**SDF** or **SMURF** and common mesh formats (**Stereolithography** (.stl),
**Wavefront** (.obj) or **Collada** (.dae)).

Phobos was initiated and is currently developed at the [Robotics Innovation
Center](http://robotik.dfki-bremen.de/en/startpage.html) of the [German
Research Center for Artificial Intelligence (DFKI)](http://www.dfki.de) in
Bremen, together with the [Robotics
Group](http://www.informatik.uni-bremen.de/robotik/index_en.php) of the
[University of Bremen](http://www.uni-bremen.de/en.html).

Please contact [Henning Wiedemann](https://robotik.dfki-bremen.de/de/ueber-uns/mitarbeiter/hewi04.html)
for any inquiries, or any questions and feedback not suited for the issues
page.

## Version 2.0.0
With version 2.0.0 we did a refactoring of Phobos and its now possible to use phobos as a normal python package and command line tool (see below).

When running the new Phobos on a model created with an older version of Phobos, make sure to have a backup.
For most cases you should be able to update your model by simply exporting it to smurf and then importing it again from that smurf file.
Due to the changes between Blender 2 to 3 it might be necessary to check whether your materials already use the Specular BSDF or Principled BSDF shaders, if not you'd have to update this manually.

If you encounter any problems with this new version please do not hesitate to open an issue [here](https://github.com/dfki-ric/phobos/issues).

## Questions or Ideas you want to discuss?
Please have a look at our [GitHub discussions](https://github.com/dfki-ric/phobos/discussions).

## Found a bug or want to request a feature?
Please let us know by opening an issue [here](https://github.com/dfki-ric/phobos/issues).

## Documentation
- User documentation: [Phobos Wiki](https://github.com/dfki-ric/phobos/wiki)
- Source documentation: [Phobos' Github Page](http://dfki-ric.github.io/phobos).

## Citing

Phobos has been published in the [Journal of Open Source Software](https://doi.org/10.21105/joss.01326).
We ask users to cite the use of Phobos, as it allows us to keep the project alive.

When citing, please provide this information:

  - Phobos version you were using (see the [wiki](https://github.com/dfki-ric/phobos/wiki/Installation#versions-and-branching) for information about versions)
  - If you were using additional Phobos plugins or configurations.
  - The general [Phobos paper](https://doi.org/10.21105/joss.01326).

If you are on the hunt for a BiBTeX entry, check out the [FAQ section](https://github.com/dfki-ric/phobos/wiki/FAQ#how-do-i-cite-phobos).

## Installation

### Blender
>UPDATING: If you already have phobos installed and want to update.
> You have to remove the old version of Phobos first and close Blender.
> Then proceed with the installation steps explained below.

>NOTE (WINDOWS): If you are using blender under Windows, make sure you have the latest version of [Microsoft Visual C++ Redistributable](https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170) installed.  Otherwise Blender's python won't work properly.

To install Phobos in blender download the phobos.zip of the release or zip the phobos subdirectory (e.g. `zip -r phobos.zip phobos`)
Phobos has several python dependencies, those have to be installed in blender before you can use phobos.
There are two ways of installing Phobos:

- Recommended:
  1. Directly install the phobos.zip in blender: `Blender->Edit->Preferences->Addons->Install` and activate it.
  2. Restart Blender.
  3. Activate Phobos Add-on again.
- (Offers inspection of the requirements before installing them) Before installing the phobos.zip you can run the script install_requirements.py with blender's python.
  1. ```bash
     ${BLENDER_EXECUTABLE} -b --python install_requirements.py
     ```
  2. Install the phobos.zip in blender: `Blender->Edit->Preferences->Addons->Install` and activate it.

After installation the phobos main menu can be found on the right hand side of the 3D Viewport.
If not already visible, one can find a very small arrow to open the Blender toolbar (purple circle showing it in the image).

![Small arrow to open the phobos toolbar widget.](https://github.com/dfki-ric/phobos/wiki/img/blender_phobos_menu_open.png)

Phobos is currently tested and running with Blender v3.3 LTS.

### CLI
Install the requirements by executing `install_requirements.py` with the python you want to install phobos to:
```bash
cd phobos
python3 install_requirements.py
```

Then just install it using pip:
```bash
cd phobos
pip install .
```
or with autoproj:
1) Add the package to your buildconf/package_set
2) Install via `amake`

## Overview

### Blender

![Model of the SpaceClimber robot in Blender, next to the Phobos toolbar
displayed on the
left.](https://github.com/dfki-ric/phobos/wiki/img/phobos_spaceclimber.png)

*Model of the
[SpaceClimber](http://robotik.dfki-bremen.de/en/research/projects/spaceclimber-1.html)
robot in Blender, next to the Phobos toolbar displayed on the left.*

Phobos makes use of Blender's hierarchical object graph and its bone objects.
These objects, normally used for animating 3D characters, allow to store 3D
coordinate systems and apply constraints to their movements, for instance to
restrict the movement of an object to a certain range on a specific axis. This
allows to replicate the links and joints defined in a **URDF** model and together
with the hierarchical tree of parent and child objects, the complete, branching
kinematic chain of a robot can be represented. By attaching meshes or
primitives to the bones, Phobos allows to add visual and collision objects to
a model. Additional objects allow storing further information, e.g. centers of
mass of each part of a robot, thus refining the physical representation. Sensor
objects can be added to correctly place and orient devices such as laser
scanners, cameras or contact sensors. Making use of Blender's custom object
properties, any necessary information can be added to the model, from inertia
tensors to opening angles of cameras.

![Decomposition of the different elements from which Phobos models are composed
in Blender.](https://github.com/dfki-ric/phobos/wiki/img/phobos_elements.png)

*Decomposition of the different elements from which Phobos models are composed
in Blender. These elements can be arranged in Blender on different layers, thus
avoiding confusion or obstruction of view when editing very complex models.*

### CLI

You can either use CLI-phobos as a normal python package or use the scripts provided with it.

For the latter do `phobos --help` to get a list of the currently available scripts.
It will also tell you which dependencies are missing for some scripts.

## Features

- WYSIWYG editor for robot models using Blender
- CLI tools for fast and easy model handling and inspection
- CI tool to run phobos headless in your CI-pipeline for atomated model processing and maintenance
- Import and export of **URDF**, **SDF** **SMURF** and other
  [formats](https://github.com/dfki-ric/phobos/wiki/Formats)
- Easy definition of robot kinematics (links and joints)
- Visualisation of different model components, even joint constraints
- Numerous tools for fast editing:
  - Batch editing of object properties
  - Auto-generation of collision objects
  - Auto-generation of inertia tensors from mass and shape
  - Calculation of merged inertia for complex links
  - Verbose logging
- Saving and loading of model poses
- Annotation of objects from motors/sensors to joints/links
- Save/load different export configurations for the same model
- Export with defined floating point precision
- Model integrity checks
- Tools for maintaining your own model database
- Library containing Python examples for automatic model adaption
- All the cool features Blender already provides (rendering, animation, etc.)

## License

Phobos is distributed under the [3-Clause BSD License](https://opensource.org/licenses/BSD-3-Clause).


EEmeter: tools for calculating metered energy savings
=====================================================

.. image:: https://travis-ci.org/openeemeter/eemeter.svg?branch=master
  :target: https://travis-ci.org/openeemeter/eemeter
  :alt: Build Status

.. image:: https://img.shields.io/github/license/openeemeter/eemeter.svg
  :target: https://github.com/openeemeter/eemeter
  :alt: License

.. image:: https://readthedocs.org/projects/eemeter/badge/?version=master
  :target: https://eemeter.readthedocs.io/?badge=master
  :alt: Documentation Status

.. image:: https://img.shields.io/pypi/v/eemeter.svg
  :target: https://pypi.python.org/pypi/eemeter
  :alt: PyPI Version

.. image:: https://codecov.io/gh/openeemeter/eemeter/branch/master/graph/badge.svg
  :target: https://codecov.io/gh/openeemeter/eemeter
  :alt: Code Coverage Status

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
  :target: https://github.com/ambv/black
  :alt: Code Style

---------------

**EEmeter** — an open source toolkit for implementing and developing standard
methods for calculating normalized metered energy consumption (NMEC) and
avoided energy use.

Background - why use the EEMeter library
----------------------------------------

At time of writing (Sept 2018), the OpenEEmeter, as implemented in the eemeter
package and sibling `eeweather package <http://eeweather.openee.io>`_, contains the
most complete open source implementation of the
`CalTRACK Methods <https://caltrack.org/>`_, which
specify a family of ways to calculate and aggregate estimates avoided energy
use at a single meter particularly suitable for use in pay-for-performance
(P4P) programs.

The eemeter package contains a toolkit written in the python langage which may
help in implementing a CalTRACK compliant analysis.

It contains a modular set of of functions, parameters, and classes which can be
configured to run the CalTRACK methods and close variants.

.. note::

    Please keep in mind that use of the OpenEEmeter is neither necessary nor
    sufficient for compliance with the CalTRACK method specification. For example,
    while the CalTRACK methods set specific hard limits for the purpose of
    standardization and consistency, the EEmeter library can be configured to edit
    or entirely ignore those limits. This is becuase the emeter package is used not
    only for compliance with, but also for *development of* the CalTRACK methods.

    Please also keep in mind that the EEmeter assumes that certain data cleaning
    tasks specified in the CalTRACK methods have occurred prior to usage with the
    eemeter. The package proactively exposes warnings to point out issues of this
    nature where possible.

Installation
------------

EEmeter is a python package and can be installed with pip.

::

    $ pip install eemeter

Features
--------

- Reference implementation of standard methods

  - CalTRACK Daily Method
  - CalTRACK Monthly Billing Method
  - CalTRACK Hourly Method

- Flexible sources of temperature data. See `EEweather <https://eeweather.openee.io>`_.
- Candidate model selection
- Data sufficiency checking
- Model serialization
- First-class warnings reporting
- Pandas dataframe support
- Visualization tools

Roadmap for 2020 development
----------------------------

The OpenEEmeter project growth goals for the year fall into two categories:

1. Community goals - we want help our community thrive and continue to grow.
2. Technical goals - we want to keep building the library in new ways that make it
   as easy as possible to use.

Community goals
~~~~~~~~~~~~~~~

1. Develop project documentation and tutorials

A number of users have expressed how hard it is to get started when tutorials are
out of date. We will dedicate time and energy this year to help create high quality
tutorials that build upon the API documentation and existing tutorials.

2. Make it easier to contribute

As our user base grows, the need and desire for users to contribute back to the library
also grows, and we want to make this as seamless as possible. This means writing and
maintaining contribution guides, and creating checklists to guide users through the
process.

Technical goals
~~~~~~~~~~~~~~~

1. Implement new CalTRACK recommendations

The CalTRACK process continues to improve the underlying methods used in the
OpenEEmeter. Our primary technical goal is to keep up with these changes and continue
to be a resource for testing and experimentation during the CalTRACK methods setting
process.

2. Hourly model visualizations

The hourly methods implemented in the OpenEEMeter library are not yet packaged with
high quality visualizations like the daily and billing methods are. As we build and
package new visualizations with the library, more users will be able to understand,
deploy, and contribute to the hourly methods.

3. Weather normal and unusual scenarios

The EEweather package, which supports the OpenEEmeter, comes packaged with publicly
available weather normal scenarios, but one feature that could help make that easier
would be to package methods for creating custom weather year scenarios.

4. Greater weather coverage

The weather station coverage in the EEweather package includes full coverage of US and
Australia, but with some technical work, it could be expanded to include greater, or
even worldwide coverage.

License
-------

This project is licensed under [Apache 2.0](LICENSE).

Other resources
---------------

- `CONTRIBUTING <CONTRIBUTING.md>`_: how to contribute to the project.
- `MAINTAINERS <MAINTAINERS.md>`_: an ordered list of project maintainers.
- `CHARTER <CHARTER.md>`_: open source project charter.
- `CODE_OF_CONDUCT <CODE_OF_CONDUCT.md>`_: Code of conduct for contributors.


.. -*- mode: rst -*-

=========================
 sphinxcontrib-spelling
=========================

This package contains sphinxcontrib.spelling, a spelling checker for
Sphinx-based documentation.  It uses PyEnchant_ to produce a report
showing misspelled words.

Refer to the `main documentation page
<https://sphinxcontrib-spelling.readthedocs.io/en/latest/>`__ for
installation and setup details.

License
=======

Copyright Doug Hellmann, All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Doug Hellmann not be used
in advertising or publicity pertaining to distribution of the software
without specific, written prior permission.

DOUG HELLMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL DOUG HELLMANN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

.. _PyEnchant: https://github.com/pyenchant/pyenchant


VIP - Vortex Image Processing package
=====================================

|VIP| |Versions| |travis| |License| |ArXiV| |docs| |codecov| |DOI| |Zenodo| |EMAC|

.. |VIP| image:: https://badge.fury.io/py/vip-hci.svg
        :target: https://pypi.python.org/pypi/vip-hci

.. |Versions| image:: https://img.shields.io/badge/Python-3.7%2C%203.8%2C%203.9%2C%203.10%2C%203.11-brightgreen.svg
             :target: https://pypi.python.org/pypi/vip-hci

.. |travis| image:: https://travis-ci.com/vortex-exoplanet/VIP.svg?branch=master
           :target: https://travis-ci.com/vortex-exoplanet/VIP

.. |License| image:: https://img.shields.io/badge/license-MIT-blue.svg?style=flat
            :target: https://github.com/vortex-exoplanet/VIP/blob/master/LICENSE

.. |ArXiV| image:: https://img.shields.io/badge/arXiv-1705.06184%20-yellowgreen.svg
          :target: https://arxiv.org/abs/1705.06184

.. |docs| image:: https://readthedocs.org/projects/vip/badge/?version=latest
         :target: http://vip.readthedocs.io/en/latest/?badge=latest

.. |codecov| image:: https://codecov.io/gh/vortex-exoplanet/VIP/branch/master/graph/badge.svg?token=HydCFQqLRf
            :target: https://codecov.io/gh/vortex-exoplanet/VIP

.. |DOI| image:: https://joss.theoj.org/papers/10.21105/joss.04774/status.svg
        :target: https://doi.org/10.21105/joss.04774

.. |Zenodo| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.7499314.svg
           :target: https://doi.org/10.5281/zenodo.7499314

.. |EMAC| image:: https://img.shields.io/badge/EMAC-2207--116-blue
         :target: https://emac.gsfc.nasa.gov/?cid=2207-116

::

    ---------------------------------------------------
            oooooo     oooo ooooo ooooooooo.
             `888.     .8'  `888' `888   `Y88.
              `888.   .8'    888   888   .d88'
               `888. .8'     888   888ooo88P'
                `888.8'      888   888
                 `888'       888   888
                  `8'       o888o o888o
    ---------------------------------------------------
             Vortex Image Processing package
    ---------------------------------------------------

Introduction
------------

VIP is a python package for high-contrast imaging of exoplanets and circumstellar disks.
VIP is compatible with Python 3.8, 3.9, 3.10 and 3.11 (Python 2 compatibility dropped with VIP 0.9.9, and Python 3.7 compatibility dropped with VIP 1.4.3).

The goal of VIP is to integrate open-source, efficient, easy-to-use and
well-documented implementations of high-contrast image processing algorithms to
the interested scientific community. The main repository of VIP resides on
`GitHub <https://github.com/vortex-exoplanet/VIP>`_, the standard for scientific
open source code distribution, using Git as a version control system.

Most of VIP's functionalities are mature but
it does not mean it is free from bugs. The code is continuously evolving and
therefore feedback/contributions are greatly appreciated. Please refer to `these instructions <https://vip.readthedocs.io/en/latest/Contact.html>`_ if you want to report
a bug, ask a question, suggest a new functionality or contribute to the code (the latter is particularly welcome)!

.. image:: https://github.com/carlgogo/carlgogo.github.io/blob/master/assets/images/vip.png?raw=true
    :alt: Mosaic of S/N maps

Documentation
-------------
The documentation for VIP can be found here: http://vip.readthedocs.io.

Jupyter notebook tutorial
-------------------------
Tutorials, in the form of Jupyter notebooks, showcasing VIP's usage and
other resources such as test datasets are available in the
``VIP-extras`` `repository <https://github.com/vortex-exoplanet/VIP_extras>`_.
**In order to execute the notebook tutorials, you will have to download or clone the VIP-extras repository, and open each tutorial locally with jupyter notebook.**
Alternatively, you can execute the notebooks directly on
`Binder <https://mybinder.org/v2/gh/vortex-exoplanet/VIP_extras/master>`_ (in
the tutorials directory). The first (quick-start) notebook can be visualized
online with `nbviewer
<http://nbviewer.jupyter.org/github/vortex-exoplanet/VIP_extras/blob/master/tutorials/01_quickstart.ipynb>`_.
If you are new to the Jupyter notebook application check out the `beginner's guide
<https://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/what_is_jupyter.html>`_.

TL;DR setup guide
-----------------
.. code-block:: bash

   pip install vip_hci

Installation and dependencies
-----------------------------
The benefits of using a Python package manager (distribution), such as
(ana)conda, are many. Mainly, it brings easy and robust package
management and avoids messing up with your system's default python. An
alternative is to use package managers like apt-get for Ubuntu or
Homebrew/MacPorts/Fink for macOS. We recommend using
`Miniconda <https://conda.io/miniconda>`_.

VIP depends on existing packages from the Python ecosystem, such as
``numpy``, ``scipy``, ``matplotlib``, ``pandas``, ``astropy``, ``scikit-learn``,
``scikit-image``, ``photutils`` and others. There are different ways of
installing VIP suitable for different scenarios.

Before installing the package, it is **highly recommended to create a dedicated
conda environment** to not mess up with the package versions in your base
environment. This can be done easily with (replace ``vipenv`` by the name you want
for your environment):

.. code-block:: bash

   conda create -n vipenv python=3.10 ipython

.. note::
   Installing ipython while creating the environment, as in the example above, will
   avoid a commonly reported issue which stems from trying to import VIP from
   within a base python2.7 ipython console.

For users not planning to contribute:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Once within your new environment, the easiest way to install VIP is
through the Python Package Index, aka `PyPI <https://pypi.org/>`_, with
the ``pip`` package manager. Simply run:

.. code-block:: bash

  pip install vip_hci

With ``pip`` you can easily uninstall, upgrade or install a specific version of
VIP. For upgrading the package, run:

.. code-block:: bash

  pip install --upgrade vip_hci

For potential contributors:
^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you plan to contribute or experiment with the code you need to make a
fork of the repository (click on the fork button in the top right corner) and
clone it:

.. code-block:: bash

   git clone https://github.com/<replace-by-your-username>/VIP.git

If you do not create a fork, you can still benefit from the ``git`` syncing
functionalities by cloning the repository (but will not be able to contribute):

.. code-block:: bash

   git clone https://github.com/vortex-exoplanet/VIP.git

To install VIP, then simply cd into your local VIP directory, and run the installation in editable mode pointing to developer requirements:

.. code-block:: bash

   cd VIP
   pip install -e . -r requirements-dev.txt

If cloned from your fork, make sure to link your VIP directory to the upstream
source, to be able to easily update your local copy when a new version comes
out or a bug is fixed:

.. code-block:: bash

   git add remote upstream https://github.com/vortex-exoplanet/VIP.git

If you plan to develop VIP or use it intensively, it is highly recommended to
also install the optional dependencies listed below.

Optional dependencies
^^^^^^^^^^^^^^^^^^^^^
The following dependencies are not automatically installed upon installation of VIP but may significantly improve your experience:

- VIP contains a class ``vip_hci.vip_ds9`` that enables, through ``pyds9``, the interaction with a DS9 window (displaying numpy arrays, controlling the display options, etc). To enable this feature, ``pyds9`` must be installed from the latest development version: ``pip install git+git://github.com/ericmandel/pyds9.git#egg=pyds9``
- VIP image operations (e.g. shifts, rotations, scaling) can be performed using ``OpenCV`` instead of the default FFT-based methods. While flux are less well preserved, ``OpenCV`` offers a significant speed improvement (up to a factor 50x), in particular for image rotations, which can be useful to get quick results. Installation: ``pip install opencv-python``.
- Also, you can install the Intel Math Kernel Library (``mkl``) optimizations (provided that you have a recent version of ``conda``) or ``openblas`` libraries. Either of them can be installed with ``conda install``.
- VIP offers the possibility of computing SVDs on GPU by using ``CuPy`` (starting from version 0.8.0) or ``PyTorch`` (from version 0.9.2). These remain as optional requirements, to be installed by the user, as well as a proper CUDA environment (and a decent GPU card).
- Bad pixel correction routines can be optimised with ``Numba``, which  converts some Python code, particularly ``NumPy``, into fast machine code. A factor up to ~50x times speed improvement can be obtained on large images compared to NumPy. Numba can be installed with ``conda install numba``.
- Finally, robust contrast curves and contrast grids can be calculated with ``applefy`` (``pip install Applefy``). Example usage is provided in `VIP tutorial 4 <https://vip.readthedocs.io/en/latest/tutorials/04_metrics.html>`_. See more details in `Bonse et al. (2023) <https://ui.adsabs.harvard.edu/abs/2023AJ....166...71B/abstract>`_.

Loading VIP
^^^^^^^^^^^
Finally, start Python (or IPython or a Jupyter notebook if you prefer) and check
that you are able to import VIP:

.. code-block:: python

   import vip_hci as vip

If everything went fine with the installation, you should not get any error message upon importation, and you can start finding exoplanets!

Conventions
-----------

Image Center
^^^^^^^^^^^^
By default, VIP routines are compatible with either even- or odd-dimension input frames. For VIP routines that require the star to be centered in the input images (e.g. post-processing routines involving (de)rotation or scaling), the code will assume that it is placed on (zero-based indexing):

- size/2-0.5 for odd-size input images;
- size/2 for even-size input images;

i.e. exactly on a pixel in either cases. The VIP recentering routines will place the star centroid at one of these locations accordingly.

Position angles
^^^^^^^^^^^^^^^
In VIP, all angles are measured counter-clockwise from the positive x axis (i.e. trigonometric angles), following the convention of most packages VIP leverages upon. This includes the position angles returned by algorithms in the forward modelling subpackage of VIP used to characterize directly imaged exoplanets (e.g. negative fake companion routines). This convention is different to the typical astronomical convention which measures angles east from north (for the conversion, simply subtract 90deg to angles returned by VIP).

4D IFS+ADI cubes
^^^^^^^^^^^^^^^^
For all routines compatible with 4D IFS+ADI cubes, the convention throughout VIP is to consider the zeroth axis to correspond to the spectral dimension, and the first axis to be the temporal (ADI) dimension.

Contact
-------

Answers to `frequently asked questions <https://vip.readthedocs.io/en/latest/faq.html>`_ are provided in the relevant section of the documentation.
If you have an issue with VIP, please first check it is not detailed in the FAQ.
If you find a bug or experience an unreported issue in VIP, it is recommended to post a new entry in the `Issues section <https://github.com/vortex-exoplanet/VIP/issues>`_ on GitHub. Feel free to propose a pull request if you have already identified the source of the bug/issue.

If you have a global comment, inquiry about how to solve a specific task using VIP, or suggestions to improve VIP, feel free to open a new thread in the `Discussions <https://github.com/vortex-exoplanet/VIP/discussions>`_ section. The 'Discussions' section is also used to post VIP-related announcements and discuss recent/on-going changes in VIP.
Envisioned future developments are listed in the `Projects <https://github.com/vortex-exoplanet/VIP/projects/1>`_ section. Contributions are very welcome!

If you wish to be kept informed about major VIP updates and on-going/future developments, feel free to click the 'watch' button at the top of the GitHub page.

Attribution
-----------

VIP started as the effort of `Carlos Alberto Gomez Gonzalez <https://github.com/carlos-gg>`_,
a former PhD student of `PSILab <https://sites.google.com/site/olivierabsil/psilab>`_
(ULiege, Belgium), who has led the development of VIP from 2015 to 2020.
Maintenance and current development is now led by `Valentin Christiaens <https://github.com/VChristiaens>`_.
VIP benefitted from contributions made by collaborators from several teams, including: Ralf Farkas, Julien Milli, Olivier Wertz, Henry Ngo, Alan Rainot, Gary Ruane, Corentin Doco, Miles Lucas, Gilles Orban de Xivry, Lewis Picker, Faustine Cantalloube, Iain Hammond, Christian Delacroix, Arthur Vigan, Dimitri Mawet and Olivier Absil.
More details about the respective contributions are available `here <https://github.com/vortex-exoplanet/VIP/graphs/contributors?from=2015-07-26&to=2022-03-29&type=a>`_.

Please cite `Gomez Gonzalez et al. (2017) <https://ui.adsabs.harvard.edu/abs/2017AJ....154....7G/abstract>`_ and `Christiaens et al. (2023) <https://ui.adsabs.harvard.edu/abs/2023JOSS....8.4774C/abstract>`_ whenever
you publish data reduced with VIP (Astrophysics Source Code Library reference `ascl:1603.003`).
In addition, please cite the relevant publication(s) for the algorithms you use within VIP (usually mentioned in the documentation, e.g. `Marois et al. 2006 <https://ui.adsabs.harvard.edu/abs/2006ApJ...641..556M/abstract>`_ for median-ADI).


[![Schema Linting and Tests](https://github.com/HumanCellAtlas/metadata-schema/actions/workflows/schema-tests.yml/badge.svg)](https://github.com/HumanCellAtlas/metadata-schema/actions/workflows/schema-tests.yml)

# The Human Cell Atlas: Metadata Standards

The Human Cell Atlas metadata-schema repo contains the schema specifications and supporting documentation for the HCA metadata standards.

## Table of Contents
- [Documentation](#documentation)
- [Metadata schemas and examples](#metadata-schemas-and-examples)
- [Contributing](#contributing)
- [Terminology](#terminology)
- [Scripts](#scripts)

## Documentation

Documentation supporting the metadata standard is available in the `docs/` directory. Specific topics covered include:

- Information on [how to contribute](docs/contributing.md) to the HCA metadata standards.
- Overview of the [structure](docs/structure.md) of the HCA metadata standards.
- [Evolution and update principles](docs/evolution.md) for the HCA metadata standards.
- Rationale for the [design and implementation choices](docs/rationale.md) for the HCA metadata standards.

## Metadata schemas and examples

Metadata JSON schemas are located in the `json_schema/` directory. Schemas are also hosted at [schema.humancellatlas.org](https://schema.humancellatlas.org/a).

When required, extensions to base JSON schemas have been developed and are located in the `json_schema_extensions/` directory.

The `examples/` directory contains example JSON files and spreadsheets to illustrate how the HCA metadata standards are implemented.

## Contributing

The HCA is committed to building and evolving the metadata standards based on the needs of the scientific community. Everyone is welcome to suggest updates or additions to the HCA metadata standards by [creating GitHub issues](https://github.com/HumanCellAtlas/metadata-schema/issues/new) or emailing [data-help@humancellaltas.org](data-help@humancellaltas.org). More details on [how to contribute](docs/contributing.md) to the HCA metadata standards are available.

Follow our community discussion of HCA metadata by joining the #hca-metadata channel on the [HCA Slack group](http://join-slack.humancellatlas.org/).

## Terminology

**Metadata** are the collections of descriptive information needed to understand the data supported by the HCA. Metadata is collected for entities such as, but not limited to, assays (*e.g.* fastq and tif files), analysis results (*e.g.* expression matrices), and biological samples (*e.g.* biopsy or autopsy samples). This descriptive information will be provided to the community in a structured format defined by the HCA metadata schemas.

**Schemas** are file-based specifications for the HCA metadata. The specification defines the metadata structure and fields, including field name, description, format, and ontology (where appropriate). This specification is likely to have a hierarchical structure (*e.g.* objects and sub-objects containing fields). In practice, individual JSON schemas are defined for specific entities. More details on the hierarchy of HCA metadata schemas can be found in the [structure](docs/structure.md) document.

**Modules** are schema objects that contains a specific subset of metadata fields associated with an isolated aspect of the metadata. A module schema would be one that is needed for some, but not all, data sets. Examples where this is appropriate include fields specific to a human donor, a particular single cell RNA-Seq platform like SmartSeq2, or a particular imaging experiment like MERFISH. We acknowledge the design must balance the flexibility offered by these modules with the overhead of maintaining a large number modules. We aim to only include additional modules where there is a true requirement for them due to experimental specialisation and not for convenience's sake.

**Contributors** are any members of the HCA or scientific community who suggest, contribute, or review updates to the metadata schemas.

**Submitters** are any members of the HCA or scientific community who submit data or metadata to the HCA.

**Committers** are any members of the HCA Data Coordination Platform (DCP) with commit privileges to the metadata-schema GitHub repo.

## Scripts

Any scripts - *e.g.* those required for automatic testing, generation of template spreadsheets - are located in the `src/` directory.

### Install the pre-commit hook

- Installation: `pip install pre-commit`

- Every time you clone the project: `pre-commit install`


A Python library for Juju
=========================

Source code: https://github.com/juju/python-libjuju

Bug reports: https://github.com/juju/python-libjuju/issues

Documentation: https://pythonlibjuju.readthedocs.io/en/latest/

Requirements
------------

* Python 3.9/3.10

Design Notes
------------

* Asynchronous - Uses asyncio and async/await features of Python
* Websocket-level bindings are programmatically generated (indirectly) from the
  Juju golang code, ensuring full api coverage
* Provides an OO layer which encapsulates much of the websocket api and
  provides familiar nouns and verbs (e.g. Model.deploy(), Application.add_unit(),
  etc.)

Installation
------------

.. code:: bash

  pip3 install juju

Quickstart
----------

Here's a simple example that shows basic usage of the library. The example
connects to the currently active Juju model, deploys a single unit of the
ubuntu charm, then exits:

Note : Pylibjuju requires an already bootstrapped Juju controller to connect to.

.. code:: python

  #!/usr/bin/python3

  import logging
  import sys

  from juju import jasyncio
  from juju.model import Model

  async def deploy():
      # Create a Model instance. We need to connect our Model to a Juju api
      # server before we can use it.
      model = Model()

      # Connect to the currently active Juju model
      await model.connect()

      try:
          # Deploy a single unit of the ubuntu charm, using the latest revision
          # from the stable channel of the Charm Store.
          ubuntu_app = await model.deploy(
            'ubuntu',
            application_name='my-ubuntu',
          )

          if '--wait' in sys.argv:
              # optionally block until the application is ready
              await model.wait_for_idle(status = 'active')

      finally:
          # Disconnect from the api server and cleanup.
          await model.disconnect()

  def main():
      logging.basicConfig(level=logging.INFO)

      # If you want to see everything sent over the wire, set this to DEBUG.
      ws_logger = logging.getLogger('websockets.protocol')
      ws_logger.setLevel(logging.INFO)

      # Run the deploy coroutine in an asyncio event loop, using a helper
      # that abstracts loop creation and teardown.
      jasyncio.run(deploy())

  if __name__ == '__main__':
      main()

More examples can be found in the docs, as well as in the ``examples/``
directory of the source tree which can be run using ``tox``.  For
example, to run ``examples/connect_current_model.py``, use:

.. code:: bash

  tox -e example -- examples/connect_current_model.py

REPL
^^^^

To experiment with the library in a REPL, launch python in asyncio mode

.. code:: bash

  $ python3 -m asyncio

and then, to connect to the current model and fetch status:

.. code::

  >>> from juju.model import Model
  >>> model = Model()
  >>> await model.connect_current()
  >>> status = await model.get_status()

Versioning
----------

The current Pylibjuju release policy tracks the Juju release cadence.
In particular, whenever Juju makes a latest/stable release, pylibjuju pushes out
a release with the same version in the following week. Newly generated schemas
will be updated per Juju releases.


A database of packages that still need Python 2 in Fedora, and tools to manage it.

This software is a mess. It was created for one purpose and was expected to not be needed soon.
Meanwhile, hacks are piling on.

# Deployed report

A HTML report is located at:

    https://fedora.portingdb.xyz/

Unless you want to refresh data there, or run additional reports, you can just look at that.

# Installation

This software is not released.
To install it, first set up a
[Python virtual environment](https://developer.fedoraproject.org/tech/languages/python/python-installation.html)
with Python 3.7+.
Then run directly from Git working directory:

    (venv) $ pip install --editable .  # Mind the dot at the end!

# Usage

To start a HTML report server, start:

    (venv) $ export PYTHONPATH=.
    (venv) $ python -m portingdb serve

# Check drops

There is a script that checks what python2 packages can be dropped from Fedora
during the [Mass Python 2 Package Removal](https://fedoraproject.org/wiki/Changes/Mass_Python_2_Package_Removal).

Change your Python virtual environment to include system side packages:

    (venv) $ cat venv/pyvenv.cfg
    ...
    include-system-site-packages = true
    ...

Reactivate if needed:

    (venv) $ deactivate
    $ . venv/bin/activate

And run it with:

    (venv) $ python -m portingdb --datadir data/ check-drops

See the docstring of [portingdb/check_drops.py](./portingdb/check_drops.py)
for more info.

# Freezing

   A static website with the HTML repot can be build by:

    (venv) $ export PYTHONPATH=.
    (venv) $ python elsasite.py freeze

   You can add `--serve` for he `freeze` command to immediately inspect the result.

# Contribute

- A guide for updating the data is [in `docs/`](./docs/update_portingdb.rst).
- Issue Tracker: https://github.com/fedora-python/portingdb/issues
- Source Code: https://github.com/fedora-python/portingdb

# License

This code is under the MIT license. May it serve you well.


ably-python
-----------

![.github/workflows/check.yml](https://github.com/ably/ably-python/workflows/.github/workflows/check.yml/badge.svg)
[![Features](https://github.com/ably/ably-python/actions/workflows/features.yml/badge.svg)](https://github.com/ably/ably-python/actions/workflows/features.yml)
[![PyPI version](https://badge.fury.io/py/ably.svg)](https://badge.fury.io/py/ably)

## Overview

This is a Python client library for Ably. The library currently targets the [Ably 2.0 client library specification](https://sdk.ably.com/builds/ably/specification/main/features/).

## Running example

```python
import asyncio
from ably import AblyRest

async def main():
    async with AblyRest('api:key') as ably:
        channel = ably.channels.get("channel_name")

if __name__ == "__main__":
    asyncio.run(main())
```

## Installation

### Via PyPI

The client library is available as a [PyPI](https://pypi.python.org/pypi/ably) package.

```
pip install ably
```

Or, if you need encryption features:

```
pip install 'ably[crypto]'
```

### Via GitHub

```
git clone --recurse-submodules https://github.com/ably/ably-python.git
cd ably-python
python setup.py install
```

## Breaking API Changes in Version 1.2.0

Please see our [Upgrade / Migration Guide](UPDATING.md) for notes on changes you need to make to your code to update it to use the new API
introduced by version 1.2.0.

## Usage

### Using the Rest API

> [!NOTE]
> Please note that since version 2.0.2 we also provide a synchronous variant of the REST interface which is can be accessed as `from ably.sync import AblyRestSync`.

All examples assume a client and/or channel has been created in one of the following ways:

With closing the client manually:
```python
from ably import AblyRest

async def main():
    client = AblyRest('api:key')
    channel = client.channels.get('channel_name')
    await client.close()
```

When using the client as a context manager, this will ensure that client is properly closed
while leaving the `with` block:

```python
from ably import AblyRest

async def main():
    async with AblyRest('api:key') as ably:
        channel = ably.channels.get("channel_name")
```

You can define the logging level for the whole library, and override for a
specific module:
```python
import logging
import ably

logging.getLogger('ably').setLevel(logging.WARNING)
logging.getLogger('ably.rest.auth').setLevel(logging.INFO)
```
You need to add a handler to see any output:
```python
logger = logging.getLogger('ably')
logger.addHandler(logging.StreamHandler())
```
### Publishing a message to a channel

```python
await channel.publish('event', 'message')
```

If you need to add metadata when publishing a message, you can use the `Message` constructor to create a message with custom fields:
```python
from ably.types.message import Message

message_object = Message(name="message_name",
                         data="payload",
                         extras={"headers": {"metadata_key": "metadata_value"}})
await channel.publish(message_object)
```

### Querying the History

```python
message_page = await channel.history() # Returns a PaginatedResult
message_page.items # List with messages from this page
message_page.has_next() # => True, indicates there is another page
next_page = await message_page.next() # Returns a next page
next_page.items # List with messages from the second page
```

### Current presence members on a channel

```python
members_page = await channel.presence.get() # Returns a PaginatedResult
members_page.items
members_page.items[0].client_id # client_id of first member present
```

### Querying the presence history

```python
presence_page = await channel.presence.history() # Returns a PaginatedResult
presence_page.items
presence_page.items[0].client_id # client_id of first member
```

### Getting the channel status

```python
channel_status = await channel.status() # Returns a ChannelDetails object
channel_status.channel_id # Channel identifier
channel_status.status # ChannelStatus object
channel_status.status.occupancy # ChannelOccupancy object
channel_status.status.occupancy.metrics # ChannelMetrics object
```

### Symmetric end-to-end encrypted payloads on a channel

When a 128 bit or 256 bit key is provided to the library, all payloads are encrypted and decrypted automatically using that key on the channel. The secret key is never transmitted to Ably and thus it is the developer's responsibility to distribute a secret key to both publishers and subscribers.

```python
key = ably.util.crypto.generate_random_key()
channel = rest.channels.get('communication', cipher={'key': key})
channel.publish(u'unencrypted', u'encrypted secret payload')
messages_page = await channel.history()
messages_page.items[0].data #=> "sensitive data"
```

### Generate a Token

Tokens are issued by Ably and are readily usable by any client to connect to Ably:

```python
token_details = await client.auth.request_token()
token_details.token # => "xVLyHw.CLchevH3hF....MDh9ZC_Q"
new_client = AblyRest(token=token_details)
await new_client.close()
```

### Generate a TokenRequest

Token requests are issued by your servers and signed using your private API key. This is the preferred method of authentication as no secrets are ever shared, and the token request can be issued to trusted clients without communicating with Ably.

```python
token_request = await client.auth.create_token_request(
    {
        'client_id': 'jim',
        'capability': {'channel1': '"*"'},
        'ttl': 3600 * 1000, # ms
    }
)
# => {"id": ...,
#     "clientId": "jim",
#     "ttl": 3600000,
#     "timestamp": ...,
#     "capability": "{\"*\":[\"*\"]}",
#     "nonce": ...,
#     "mac": ...}

new_client = AblyRest(token=token_request)
await new_client.close()
```

### Fetching your application's stats

```python
stats = await client.stats() # Returns a PaginatedResult
stats.items
await client.close()
```

### Fetching the Ably service time

```python
await client.time()
await client.close()
```

## Using the realtime client

### Create a client using an API key

```python
from ably import AblyRealtime

# Create a client using an Ably API key
async def main():
    client = AblyRealtime('api:key')
```

### Create a client using token auth

```python
# Create a client using kwargs, which must contain at least one auth option
# the available auth options are key, token, token_details, auth_url, and auth_callback
# see https://www.ably.com/docs/rest/usage#client-options for more details
from ably import AblyRealtime
from ably import AblyRest
async def main():
    rest_client = AblyRest('api:key')
    token_details = rest_client.request_token()
    client = AblyRealtime(token_details=token_details)
```

### Subscribe to connection state changes

```python
# subscribe to 'failed' connection state
client.connection.on('failed', listener)

# subscribe to 'connected' connection state
client.connection.on('connected', listener)

# subscribe to all connection state changes
client.connection.on(listener)

# wait for the next state change
await client.connection.once_async()

# wait for the connection to become connected
await client.connection.once_async('connected')
```

```python
# subscribe to 'failed' connection state
client.connection.on('failed', listener)

# subscribe to 'connected' connection state
client.connection.on('connected', listener)

# subscribe to all connection state changes
client.connection.on(listener)

# wait for the next state change
await client.connection.once_async()

# wait for the connection to become connected
await client.connection.once_async('connected')
```

### Get a realtime channel instance

```python
channel = client.channels.get('channel_name')
```

### Subscribing to messages on a channel

```python

def listener(message):
    print(message.data)

# Subscribe to messages with the 'event' name
await channel.subscribe('event', listener)

# Subscribe to all messages on a channel
await channel.subscribe(listener)
```

Note that `channel.subscribe` is a coroutine function and will resolve when the channel is attached

### Unsubscribing from messages on a channel

```python
# unsubscribe the listener from the channel
channel.unsubscribe('event', listener)

# unsubscribe all listeners from the channel
channel.unsubscribe()
```

### Attach to a channel

```python
await channel.attach()
```

### Detach from a channel

```python
await channel.detach()
```

### Managing a connection

```python
# Establish a realtime connection.
# Explicitly calling connect() is unnecessary unless the autoConnect attribute of the ClientOptions object is false
client.connect()

# Close a connection
await client.close()

# Send a ping
time_in_ms = await client.connection.ping()
```

## Resources

Visit https://ably.com/docs for a complete API reference and more examples.

## Requirements

This SDK supports Python 3.7+.

We regression-test the SDK against a selection of Python versions (which we update over time,
but usually consists of mainstream and widely used versions). Please refer to [check.yml](.github/workflows/check.yml)
for the set of versions that currently undergo CI testing.

## Known Limitations

Currently, this SDK only supports [Ably REST](https://ably.com/docs/rest) and realtime message subscription as documented above.
However, you can use the [MQTT adapter](https://ably.com/docs/mqtt) to implement [Ably's Realtime](https://ably.com/docs/realtime) features using Python.

See [our roadmap for this SDK](roadmap.md) for more information.

## Support, feedback and troubleshooting

Please visit https://ably.com/support for access to our knowledge base and to ask for any assistance.

You can also view the [community reported GitHub issues](https://github.com/ably/ably-python/issues).

To see what has changed in recent versions of Bundler, see the [CHANGELOG](CHANGELOG.md).

If you find any compatibility issues, please [do raise an issue](https://github.com/ably/ably-python/issues/new) in this repository or [contact Ably customer support](https://ably.com/support) for advice.

## Contributing

For guidance on how to contribute to this project, see [CONTRIBUTING.md](https://github.com/ably/ably-python/blob/main/CONTRIBUTING.md)


wavespectra
===========
Python library for ocean wave spectra.

.. image:: https://zenodo.org/badge/205463939.svg
   :target: https://zenodo.org/badge/latestdoi/205463939
.. image:: https://img.shields.io/github/actions/workflow/status/wavespectra/wavespectra/python-publish.yml
    :target: https://github.com/wavespectra/wavespectra/actions
    :alt: GitHub Workflow Status (with event)
.. image:: https://coveralls.io/repos/github/wavespectra/wavespectra/badge.svg?branch=master
    :target: https://coveralls.io/github/wavespectra/wavespectra?branch=master
.. image:: https://readthedocs.org/projects/wavespectra/badge/?version=latest
    :target: https://wavespectra.readthedocs.io/en/latest/
.. image:: https://img.shields.io/pypi/v/wavespectra.svg
    :target: https://pypi.org/project/wavespectra/
.. image:: https://img.shields.io/pypi/dm/wavespectra
    :target: https://pypistats.org/packages/wavespectra
    :alt: PyPI - Downloads
.. image:: https://anaconda.org/conda-forge/wavespectra/badges/version.svg
    :target: https://anaconda.org/conda-forge/wavespectra
.. image:: https://anaconda.org/conda-forge/wavespectra/badges/platforms.svg
    :target: https://anaconda.org/conda-forge/wavespectra
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
    :target: https://github.com/python/black
.. image:: https://img.shields.io/pypi/pyversions/wavespectra
    :target: https://pypi.org/project/wavespectra/
    :alt: PyPI - Python Version

Main contents:
--------------
* SpecArray_: extends xarray's `DataArray`_ with methods to manipulate wave spectra and calculate spectral statistics.
* SpecDataset_: wrapper around `SpecArray`_ with methods for selecting and saving spectra in different formats.

Documentation:
--------------
The documentation is hosted on ReadTheDocs at https://wavespectra.readthedocs.io/en/latest/.

Install:
--------
Where to get it
~~~~~~~~~~~~~~~
The source code is currently hosted on GitHub at: https://github.com/wavespectra/wavespectra

Binary installers for the latest released version are available at the `Python package index`_.

Install from pypi
~~~~~~~~~~~~~~~~~
.. code:: bash

   # Default install, miss some dependencies and functionality
   pip install wavespectra

   # Complete install
   pip install wavespectra[extra]

Install from conda
~~~~~~~~~~~~~~~~~~~
.. code:: bash

    # wavespectra is available in the conda-forge channel
    conda install -c conda-forge wavespectra

Install from sources
~~~~~~~~~~~~~~~~~~~~
Install requirements. Navigate to the base root of wavespectra_ and execute:

.. code:: bash

   # Default install, miss some dependencies and functionality
   pip install -r requirements/default.txt

   # Also, for complete install
   pip install -r requirements/extra.txt

Then install wavespectra:

.. code:: bash

   python setup.py install

   # Run pytest integration
   python setup.py test

Alternatively, to install in `development mode`_:

.. code:: bash

   pip install -e .

Code structure:
---------------
The two main classes SpecArray_ and SpecDataset_ are defined as `xarray accessors`_. The accessors are registered on xarray's DataArray_ and Dataset_ respectively as a new namespace called `spec`.

To use methods in the accessor classes simply import the classes into your code and they will be available to your xarray.Dataset or xarray.DataArray instances through the `spec` attribute, e.g.

.. code:: python

   import datetime
   import numpy as np
   import xarray as xr

   from wavespectra.specarray import SpecArray
   from wavespectra.specdataset import SpecDataset

   coords = {'time': [datetime.datetime(2017,01,n+1) for n in range(2)],
             'freq': [0.05,0.1],
             'dir': np.arange(0,360,120)}
   efth = xr.DataArray(data=np.random.rand(2,2,3),
                       coords=coords,
                       dims=('time','freq', 'dir'),
                       name='efth')

   In [1]: efth
   Out[1]:
   <xarray.DataArray (time: 2, freq: 2, dir: 3)>
   array([[[ 0.100607,  0.328229,  0.332708],
           [ 0.532   ,  0.665938,  0.177731]],

          [[ 0.469371,  0.002963,  0.627179],
           [ 0.004523,  0.682717,  0.09766 ]]])
   Coordinates:
     * freq     (freq) float64 0.05 0.1
     * dir      (dir) int64 0 120 240
     * time     (time) datetime64[ns] 2017-01-01 2017-01-02

   In [2]: efth.spec
   Out[2]:
   <SpecArray (time: 2, freq: 2, dir: 3)>
   array([[[ 0.100607,  0.328229,  0.332708],
           [ 0.532   ,  0.665938,  0.177731]],

          [[ 0.469371,  0.002963,  0.627179],
           [ 0.004523,  0.682717,  0.09766 ]]])
   Coordinates:
     * freq     (freq) float64 0.05 0.1
     * dir      (dir) int64 0 120 240
     * time     (time) datetime64[ns] 2017-01-01 2017-01-02

   In [3]: efth.spec.hs()
   Out[3]:
   <xarray.DataArray 'hs' (time: 2)>
   array([ 10.128485,   9.510618])
   Coordinates:
     * time     (time) datetime64[ns] 2017-01-01 2017-01-02
   Attributes:
       standard_name: sea_surface_wave_significant_height
       units: m

SpecDataset provides a wrapper around the methods in SpecArray. For instance, these produce same result:

.. code:: python

   In [4]: dset = efth.to_dataset(name='efth')

   In [5]: tm01 = dset.spec.tm01()

   In [6]: tm01.identical(dset.efth.spec.tm01())
   Out[6]: True

Data requirements:
------------------

SpecArray_ methods require DataArray_ to have the following attributes:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- wave frequency coordinate in `Hz` named as `freq` (required).
- wave frequency coordinate in `Hz` named as `freq` (required).
- wave direction coordinate in `degree` (coming from) named as `dir` (optional for 1D, required for 2D spectra).
- wave energy density data in `m2/Hz/degree` (2D) or `m2/Hz` (1D) named as `efth`

SpecDataset_ methods require xarray's Dataset_ to have the following attributes:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- spectra DataArray named as `efth`, complying with the above specifications

Examples:
---------

Define and plot spectra history from example SWAN_ spectra file:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code:: python

   from wavespectra import read_swan

   dset = read_swan('/source/wavespectra/tests/manus.spec')
   spec_hist = dset.isel(lat=0, lon=0).sel(freq=slice(0.05,0.2)).spec.oned().T
   spec_hist.plot.contourf(levels=10)

.. _SpecArray: https://github.com/wavespectra/wavespectra/blob/master/wavespectra/specarray.py
.. _SpecDataset: https://github.com/wavespectra/wavespectra/blob/master/wavespectra/specdataset.py
.. _DataArray: http://xarray.pydata.org/en/stable/generated/xarray.DataArray.html
.. _Dataset: http://xarray.pydata.org/en/stable/generated/xarray.Dataset.html
.. _readspec: https://github.com/wavespectra/wavespectra/blob/master/wavespectra/readspec.py
.. _xarray accessors: http://xarray.pydata.org/en/stable/internals.html?highlight=accessor
.. _SWAN: http://swanmodel.sourceforge.net/online_doc/swanuse/node50.html
.. _Python package index: https://pypi.python.org/pypi/wavespectra
.. _wavespectra: https://github.com/wavespectra/wavespectra
.. _development mode: https://pip.pypa.io/en/latest/reference/pip_install/#editable-installs