## GMSO: General Molecular Simulation Object
![](https://anaconda.org/conda-forge/gmso/badges/license.svg)
[![](https://anaconda.org/conda-forge/gmso/badges/version.svg)](https://anaconda.org/conda-forge/gmso)
[![CI](https://github.com/mosdef-hub/gmso/actions/workflows/CI.yaml/badge.svg)](https://github.com/mosdef-hub/gmso/actions/workflows/CI.yaml)
[![codecov](https://codecov.io/gh/mosdef-hub/gmso/branch/master/graph/badge.svg?token=rqPGwmXDzu)](undefined)

`GMSO`is a flexible storage of chemical topology for molecular simulation.
With a few lines of `GMSO` code, together with [`mBuild`](https://mbuild.mosdef.org) and [`foyer`](https://foyer.mosdef.org), users can rapidly prototype arbitrary parameterized chemical systems and generate data files for a wide variety of simulation engines.

To learn more, get started, or contribute, check out our [Documentation](https://gmso.mosdef.org).

#### GMSO within the MoSDeF Ecosystem

This is an example using `mBuild` and `Foyer` to build a `GMSO` topology and write out to [`LAMMPS`](https://docs.lammps.org/).
```python
import foyer
import forcefield_utilities as ffutils
from mbuild.lib.molecules import Ethane
from gmso.external.convert_mbuild import from_mbuild
from gmso.parameterization import apply
from gmso.formats.lammpsdata import write_lammpsdata
# Start with a mBuild compound
mb_ethane = Ethane()
oplsaa = ffutils.FoyerFFs().load('oplsaa').to_gmso_ff()
# atomtype the system with foyer, and convert the resulting structure to a topology
gmso_ethane = from_mbuild(mb_ethane)
apply(top=gmso_ethane,
      forcefields=oplsaa,
      identify_connections=True)
# Write out lammps datafile
write_lammpsdata(gmso_ethane, filename='ethane.lammps', atom_style='full')
```

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

`GMSO` is designed to be a general and flexible representation of chemical topolgies for molecular simulation.
With an emphasis on assuming as little as possible about the chemical system, model, or engine, `GMSO` can enable support for a variety of systems.
`GMSO` is a part of the [MoSDeF (Molecular Simulation and Design Framework)](https://mosdef.org) ecosystem, and is intended to be the backend replacement for the [`foyer` package](https://foyer.mosdef.org).
Libraries in the MoSDeF ecosystem are designed to provide utilities neccessary to streamline
a researcher's simulation workflow. When setting up simulation studies,
we also recommend users to follow the [TRUE](https://www.tandfonline.com/doi/full/10.1080/00268976.2020.1742938)
(Transparent, Reproducible, Usable-by-others, and Extensible) standard, which is a set of common
practices meant to improve the reproducibility of computational simulation research.

Goals and Features
------------------

`GMSO`'s goal is to provide a flexible backend framework to store topological information of a chemical system in a reproducible fashion.
**Topology** in this case is defined as the information needed to initialize a molecular simulation.
Depending on the type of simulation performed, this ranges from:
* particle positions
* particle connectivity
* box information
* forcefield data
    - functional forms defined as [`sympy` expressions](https://www.sympy.org)
    - parameters with defined units
    - partial charges
    - tabulated data
    - etc.
* Other optional data
    - particle mass
    - elemental data
    - etc.

With these driving goals for `GMSO`, the following features are enabled:
1. __Supporting a variety of models__ in the molecular simulation/computational
  chemistry community_:
  No assumptions are made about an interaction site
  representing an atom or bead, instead these can be atomistic,
  united-atom/coarse-grained, polarizable, and other models!

1. __Greater flexibility for exotic potentials__: The [`AtomType`](./gmso/core/atom_type.py) (and [analogue
  classes for intramolecular interactions](./gmso/core)) uses [`sympy`](https://www.sympy.org) to store any
  potential that can be represented by a mathematical expression.

1. __Adaptable for new engines__: by not being designed for
  compatibility with any particular molecular simulation engine or ecosystem,
  it becomes more tractable for developers in the community to add glue for
  engines that are not currently supported.

1. __Compatibility with existing community tools__: No single molecular simulation
  tool will ever be a silver bullet, so ``GMSO`` includes functions to convert
  between various file formats and libraries. These can be used in their own right to convert between objects in-memory
  and also to support conversion to file formats not natively supported at
  any given time. Currently supported conversions include:
    * [`ParmEd`](./gmso/external/convert_parmed.py)
    * [`OpenMM`](./gmso/external/convert_openmm.py)
    * [`mBuild`](./gmso/external/convert_mbuild.py)
    * more in the future!

1. __Native support for reading and writing many common file formats__: We natively have support for:
    * [`XYZ`](./gmso/formats/xyz.py)
    * [`GRO`](./gmso/formats/gro.py)
    * [`TOP`](gmso/formats/top.py)
    * [`LAMMPSDATA`](gmso/formats/lammpsdata.py)
    * indirect support, through other libraries, for many more!

Installation
------------
For full, detailed instructions, refer to the [documentation for installation](https://gmso.mosdef.org/en/latest/installation.html)

### `conda` installation quickstart
`GMSO` is available on `conda` and can be installed as:
```bash
conda install -c conda-forge gmso
```

### Installing from source

Dependencies of GMSO are listed in the files ``environment.yml`` (lightweight environment specification containing minimal dependencies) and ``environment-dev.yml`` (comprehensive environment specification including optional and testing packages for developers).
The ``gmso`` or ``gmso-dev`` conda environments can be created with

```.. code-block:: bash
git clone https://github.com/mosdef-hub/gmso.git
cd gmso
# for gmso conda environment
conda env create -f environment.yml
conda activate gmso

# for gmso-dev
conda env create -f environment-dev.yml
conda activate gmso-dev

# install a non-editable version of gmso
pip install .
```

### Install an editable version from source

Once all dependencies have been installed and the ``conda`` environment has been created, the ``GMSO`` itself can be installed.

``` code-block:: bash
cd gmso
conda activate gmso-dev # or gmso depending on your installation
pip install -e .
```
Documentation
-------------

The full documentation can be found at [gmso.mosdef.org](https://gmso.mosdef.org).


# Quantum Refinement Module

[![CI pipeline on Mamba](https://github.com/qrefine/qrefine/actions/workflows/ci-mamba.yaml/badge.svg)](https://github.com/qrefine/qrefine/actions/workflows/ci-mamba.yaml)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Dockerhub](https://img.shields.io/badge/dockerhub-images-important.svg?logo=Docker")](https://hub.docker.com/r/qrefine/cctbx-qr)

Quantum Chemistry can improve bio-macromolecular structures,
especially when only low-resolution data derived from crystallographic
or cryo-electron microscopy experiments are available. Quantum-based
refinement utilizes chemical restraints derived from quantum chemical
methods instead of the standard parameterized library-based restraints
used in experimental refinement packages. The motivation for a quantum
refinement is twofold: firstly, the restraints have the potential to
be more accurate, and secondly, the restraints can be more easily
applied to new molecules such as drugs or novel cofactors.

However, accurately refining bio-macromolecules using a quantum
chemical method is challenging due to issues related to
scaling. Quantum chemistry has proven to be very useful for studying
bio-macromolecules by employing a divide and conquer type approach. We
have developed a new fragmentation approach for achieving a
quantum-refinement of bio-macromolecules.

## Installation

Depending on your use case, installation of qrefine follows 3 paths:
 - cctbx user
 - phenix installer user
 - phenix source user

Requirements:
 - python >= 3.9
 - conda (miniconda)

We require a minimum python version of 3.9!

### Phenix route
Note: you may need to use sudo depending on the permissions of your Phenix installation.

#### Phenix source

```
 source phenix_env.sh
 git clone https://github.com/qrefine/qrefine modules/qrefine
 # request to install aimnet2 is optional
 sh modules/qrefine/config/update_phenix.sh [aimnet2]
 qrefine.python -m pip install git+https://github.com/zubatyuk/aimnet2calc.git
```

#### Phenix installer

```
  source path_to_phenix/phenix_env.sh
  git clone https://github.com/qrefine/qrefine
  cd qrefine
  # request to install aimnet2 is optional
  sh build_into_phenix_install.sh [aimnet2]
```

#### cctbx (open-source)

2.  Clone this repo and enter it's directory.

```
git clone https://github.com/qrefine/qrefine.git qrefine && cd qrefine
```

3.  Use the provided `environment.yaml` to generate a new conda environment called `qrefine`. After installation activate the enviroment. The activation (unless set to automatic) has to be done for every new shell:

    - full installation with pytorch/cuda
      ```
      conda env create -n qrefine -f environment.yaml
      conda activate qrefine
      ```

4.  A couple of configuration steps are needed to setup `qrefine` within `cctbx`.

```
bash ./build_into_conda.sh
```

5.  run the given `source <path>/setpaths.sh` command at the end of the script. Also this needs to sourced for every new shell.

#### AIMNET2 (and torchani) plugins

For cctbx:

```
  conda env update -f config/aimnet2.yaml
  qrefine.python -m pip install git+https://github.com/zubatyuk/aimnet2calc.git
```

For Phenix either use the provided script `config/update_phenix.sh` as described above or install into the phenix conda env

```
  # identify your phenix directory
  conda env list
  conda env update -f -p /path/to/phenix/conda_base config/aimnet2.yaml
  qrefine.python -m pip install git+https://github.com/zubatyuk/aimnet2calc.git
```

Set the following in your Terminal for optimal performance. Save it to your .bashrc (or similar).

```
  export NUMBA_CUDA_USE_NVIDIA_BINDING=1
```

To check if the cuda components are working run:

```
  qrefine.python -c "import numba.cuda; print(numba.cuda.is_available())"
  qrefine.python -c "import torch; print(torch.cuda.is_available())"
```

(Optional) Check if the cuda AEV version of torchani was installed:

    ```
    mamba list | grep torchani
    ls $(qrefine.python -c 'import site; print(site.getsitepackages()[0])')/torchani/cuaev
    ```

    It should say `torchani=*=cuda...` and the `cuaev` directory is present. If not you can try the the pip/wheel installation:

    ```
    mamba remove torchani
    pip install torchani
    ```

### Apple Silicon

We cannot recommend to run qrefine with *clustering* on Apple Silicon machines as the pair interaction is unreliable (unknown cause).
When following the cctbx installation route use the following to create the env:
   ```
    conda env create -n qrefine -f config/arm64-osx.yaml
   ```

For Phenix installations we recommend to switch the blas implementation to apple's accelerate in
   ```
    conda install -p <phenix_conda> libblas=*=*accelerate
   ```

### conda packages (work in progres)

[![Anaconda](https://anaconda.org/qrefine/qrefine/badges/latest_release_date.svg)](https://anaconda.org/qrefine/qrefine)
[![Anaconda](https://anaconda.org/qrefine/qrefine/badges/version.svg)](https://anaconda.org/qrefine/qrefine)
[![Anaconda](https://anaconda.org/qrefine/qrefine/badges/platforms.svg)](https://anaconda.org/qrefine/qrefine)

A conda package is provided for qrefine. We currently make use of the nightly build of cctbx. Use `conda >=23.10` or `mamba`
**The conda-forge setup https://github.com/conda-forge/miniforge#miniforge3 is recommended.**

During quick development cycles the conda packages will lag behind as they are build manually.

```
conda create -n QR qrefine -c qrefine -c cctbx-nightly
conda activate QR
qr.test
```

### Run Tests

Tests need to be run in an empty directory.

```
 mkdir tests
 cd tests
 qr.test
```

If any of the tests fail, please raise an issue here: [issue tracker](https://github.com/qrefine/qrefine/issues)

### Documentation

Can be found at: https://qrefine.com/qr.html

### Commandline options

If you want to see the available options and default values please type:

```
 qr.refine --show-defaults
```

### Example

command line options are added ike this:

```
qr.refine tests/unit/data_files/helix.pdb engine=mopac clustering=0 gradient_only=1
```

### Contact us

The best way to get a hold of us is by sending us an email: qrefine@googlegroups.com

### Developers

- [Pavel Afonine](https://github.com/pafonine)
- [Malgorzata Biczysko](https://github.com/biczysko)
- [Mark Waller](https://github.com/mpwaller)
- [Nigel Moriarty](https://github.com/nwmoriarty)
- [Holger Kruse](https://github.com/hokru)
- [Min Zheng](https://github.com/zhengmin317)
- [Lum Wang](https://github.com/Mooooony)

### Citations:

Min Zheng, Jeffrey Reimers, Mark P. Waller, and Pavel V. Afonine,
Q|R: Quantum-based Refinement,
(2017) Acta Cryst. D73, 45-52.
DOI: [10.1107/S2059798316019847](http://scripts.iucr.org/cgi-bin/paper?S2059798316019847)

Min Zheng, Nigel W. Moriarty, Yanting Xu, Jeffrey Reimers, Pavel V. Afonine, and Mark P. Waller,
Solving the scalability issue in quantum-based refinement: Q|R#1
(2017) Acta Cryst. D73, 1020-1028.
DOI: [10.1107/S2059798317016746](http://scripts.iucr.org/cgi-bin/paper?S2059798317016746)

Min Zheng, Malgorzata Biczysko, Yanting Xu, Nigel W. Moriarty, Holger Kruse, Alexandre Urzhumtsev, Mark P. Waller, and Pavel V. Afonine,
Including Crystallographic Symmetry in Quantum-based Refinement: Q|R#2
(2020) Acta Cryst. D76, 41-50.
DOI: [10.1107/S2059798319015122](http://scripts.iucr.org/cgi-bin/paper?S2059798319015122)

Lum Wang, Holger Kruse, Oleg V. Sobolev, Nigel W. Moriarty, Mark P. Waller, Pavel V. Afonine, and Malgorzata Biczysko,
Real-space quantum-based refinement for cryo-EM: Q|R#3
(2020) Acta Cryst. D76, 1184-1191.
DOI：[10.1107/S2059798320013194](https://doi.org/10.1107/S2059798320013194)
bioRxiv 2020.05.25.115386.
DOI:[0.1101/2020.05.25.115386](https://www.biorxiv.org/content/10.1101/2020.05.25.115386v1)

Yaru Wang, Holger Kruse, Nigel W. Moriarty, Mark P. Waller, Pavel V. Afonine, and Malgorzata Biczysko,
Optimal clustering for quantum refinement of biomolecular structures: Q|R#4
(2023) Theor. Chem. Acc. 142, 100.
DOI: [10.1007/s00214-023-03046-0](https://doi.org/10.1007/s00214-023-03046-0)
bioRxiv 2022.11.24.517825
DOI:[10.1101/2022.11.24.517825](https://doi.org/10.1101/2022.11.24.517825)

#### Clustering

Min Zheng, Mark P. Waller,
Yoink: An interaction‐based partitioning API,
(2018) Journal of Computational Chemistry, 39, 799–806.
DOI: [10.1002/jcc.25146](https://doi.org/10.1002/jcc.25146)

Min Zheng, Mark P. Waller,
Toward more efficient density-based adaptive QM/MM methods,
(2017)Int J. Quant. Chem e25336
DOI: [10.1002/qua.25336](https://doi.org/10.1002/qua.25336)

Min Zheng, Mark P. Waller, Adaptive QM/MM Methods,
(2016) WIREs Comput. Mol. Sci., 6, 369–385.
DOI: [10.1002/wcms.1255](https://doi.org/10.1002/wcms.1255)

Mark P. Waller, Sadhana Kumbhar, Jack Yang,
A Density‐Based Adaptive Quantum Mechanical/Molecular Mechanical Method
(2014) ChemPhysChem 15, 3218–3225.
DOI: [10.1002/cphc.201402105](https://doi.org/10.1002/cphc.201402105)


About Babel
===========

Babel is a Python library that provides an integrated collection of
utilities that assist with internationalizing and localizing Python
applications (in particular web-based applications.)

Details can be found in the HTML files in the ``docs`` folder.

For more information please visit the Babel web site:

http://babel.pocoo.org/

Join the chat at https://gitter.im/python-babel/babel

Contributing to Babel
=====================

If you want to contribute code to Babel, please take a look at our
`CONTRIBUTING.md <https://github.com/python-babel/babel/blob/master/CONTRIBUTING.md>`__.

If you know your way around Babels codebase a bit and like to help
further, we would appreciate any help in reviewing pull requests. Please
contact us at https://gitter.im/python-babel/babel if you're interested!


= RIDE
ifdef::env-github[:outfilesuffix: .adoc]

RIDE is an IDE (Integrated Development Environment) exclusive for https://robotframework.org[Robot Framework] tests or tasks automation framework.

'''

Robot Framework supports, since version 6.1, files with localized definitions. RIDE was updated to accept those files, and we are working on a localization project to have its GUI in the same languages supported by Robot Framework.
You can help in this localization project at https://crowdin.com/project/robotframework-ride[Crowdin] image:https://badges.crowdin.net/robotframework-ride/localized.svg[Crowdin, link=https://crowdin.com/project/robotframework-ride]

=== Instant Communication ===

Join our **#ride** channel in Robot Framework Slack: https://robotframework.slack.com
(signup page, with insecure connection warning: https://slack.robotframework.org/)

=== "Support" sites ===

We have a RIDE section topic in https://forum.robotframework.org/c/tools/ride/21[Tools>RIDE].

You can use the tag *robotframework-ide* to search and ask on https://stackoverflow.com/questions/tagged/robotframework-ide[StackOverflow].

== **Welcome to the development version of RIDE - next major release will be version 2.1**

If you are looking for the latest released version, you can get the source code from **https://github.com/robotframework/RIDE/releases[releases]** or from branch **https://github.com/robotframework/RIDE/tree/release/2.0.8.1[release/2.0.8.1]**

See the https://github.com/robotframework/RIDE/blob/master/doc/releasenotes/ride-2.0.8.1.rst[release notes] for latest release version 2.0.8.1

**Version https://github.com/robotframework/RIDE/tree/release/2.0.8.1[2.0.8.1] was the last release supporting Python 3.6 and 3.7**

**Version https://github.com/robotframework/RIDE/tree/release/1.7.4.2[1.7.4.2] was the last release supporting Python 2.7**

**The current development version is based on 2.0.8.1, supports Python from 3.8 up to 3.12 (09th February 2024).**

Currently the unit tests are tested on Python 3.10, and 3.12 (which is the recommended version).
Likewise, the current version of wxPython, is 4.2.1, but RIDE is known to work with 4.0.7 and 4.1.1 versions.

(3.6 < python <= 3.11) Install current released version (*2.0.8.1*) with:

`pip install -U robotframework-ride`

(3.8 < python <= 3.12) Install current development version (**2.1dev53**) with:

`pip install -U https://github.com/robotframework/RIDE/archive/master.zip`

// (3.6 < python < 3.11) Install current Beta version (2.1a1) with:
// [source, shell]
// pip install -U --pre robotframework-ride

**See the https://github.com/robotframework/RIDE/wiki/F%2eA%2eQ%2e[FAQ] at https://github.com/robotframework/RIDE/wiki[Wiki]**

== Unit testing statuses:

// Linux (py36, py37, py38, py39): image:https://app.travis-ci.com/HelioGuilherme66/RIDE.svg?branch=master[Unit Tests, link=https://app.travis-ci.com/github/HelioGuilherme66/RIDE]
Linux (Fedora 40: py3.12, Ubuntu 22.04: py3.10): image:https://img.shields.io/github/actions/workflow/status/HelioGuilherme66/RIDE/linux.yml[Unit Tests, link=https://github.com/HelioGuilherme66/RIDE/actions/workflows/linux.yml]

Windows (Python 3.11): image:https://ci.appveyor.com/api/projects/status/github/HelioGuilherme66/RIDE?branch=master&svg=true[Unit Tests, link=https://ci.appveyor.com/project/HelioGuilherme66/ride]

Quality Gate Status: image:https://sonarcloud.io/api/project_badges/measure?project=HelioGuilherme66_RIDE&metric=alert_status[SonarCloud, link=https://sonarcloud.io/summary/new_code?id=HelioGuilherme66_RIDE]

'''
=== Links ===

* https://crowdin.com/project/robotframework-ride[Localization at Crowdin]
* https://pypi.python.org/pypi/robotframework-ride[Downloads at PyPi]
* Statistics at https://pypistats.org/packages/robotframework-ride[PyPi Stats] and https://libraries.io/pypi/robotframework-ride[Libraries.io]
* Usage instructions and some tips and tricks can be found from the https://github.com/robotframework/RIDE/wiki[Wiki]
* Bug report/enhancement request? Use the https://github.com/robotframework/RIDE/issues[issue tracker]
* Any questions? Do not hesitate to use the https://groups.google.com/group/robotframework-users/[mailing list], or https://forum.robotframework.org/c/tools/ride/21[Robot Framework Forum->Tools>RIDE], or https://stackoverflow.com/questions/tagged/robotframework-ide[StackOverflow].
* Development information is in https://github.com/robotframework/RIDE/blob/master/BUILD.rest[BUILD] file

'''

== Stargazers over time ==

image:https://starchart.cc/robotframework/RIDE.svg[Stargazers over time, link=https://starchart.cc/robotframework/RIDE]


.. image:: https://img.shields.io/pypi/v/inflect.svg
   :target: https://pypi.org/project/inflect

.. image:: https://img.shields.io/pypi/pyversions/inflect.svg

.. image:: https://github.com/jaraco/inflect/actions/workflows/main.yml/badge.svg
   :target: https://github.com/jaraco/inflect/actions?query=workflow%3A%22tests%22
   :alt: tests

.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json
    :target: https://github.com/astral-sh/ruff
    :alt: Ruff

.. image:: https://readthedocs.org/projects/inflect/badge/?version=latest
   :target: https://inflect.readthedocs.io/en/latest/?badge=latest

.. image:: https://img.shields.io/badge/skeleton-2024-informational
   :target: https://blog.jaraco.com/skeleton

.. image:: https://tidelift.com/badges/package/pypi/inflect
   :target: https://tidelift.com/subscription/pkg/pypi-inflect?utm_source=pypi-inflect&utm_medium=readme

NAME
====

inflect.py - Correctly generate plurals, singular nouns, ordinals, indefinite articles; convert numbers to words.

SYNOPSIS
========

.. code-block:: python

    import inflect

    p = inflect.engine()

    # METHODS:

    # plural plural_noun plural_verb plural_adj singular_noun no num
    # compare compare_nouns compare_nouns compare_adjs
    # a an
    # present_participle
    # ordinal number_to_words
    # join
    # inflect classical gender
    # defnoun defverb defadj defa defan

    # UNCONDITIONALLY FORM THE PLURAL

    print("The plural of ", word, " is ", p.plural(word))

    # CONDITIONALLY FORM THE PLURAL

    print("I saw", cat_count, p.plural("cat", cat_count))

    # FORM PLURALS FOR SPECIFIC PARTS OF SPEECH

    print(
        p.plural_noun("I", N1),
        p.plural_verb("saw", N1),
        p.plural_adj("my", N2),
        p.plural_noun("saw", N2),
    )

    # FORM THE SINGULAR OF PLURAL NOUNS

    print("The singular of ", word, " is ", p.singular_noun(word))

    # SELECT THE GENDER OF SINGULAR PRONOUNS

    print(p.singular_noun("they"))  # 'it'
    p.gender("feminine")
    print(p.singular_noun("they"))  # 'she'

    # DEAL WITH "0/1/N" -> "no/1/N" TRANSLATION:

    print("There ", p.plural_verb("was", errors), p.no(" error", errors))

    # USE DEFAULT COUNTS:

    print(
        p.num(N1, ""),
        p.plural("I"),
        p.plural_verb(" saw"),
        p.num(N2),
        p.plural_noun(" saw"),
    )
    print("There ", p.num(errors, ""), p.plural_verb("was"), p.no(" error"))

    # COMPARE TWO WORDS "NUMBER-INSENSITIVELY":

    if p.compare(word1, word2):
        print("same")
    if p.compare_nouns(word1, word2):
        print("same noun")
    if p.compare_verbs(word1, word2):
        print("same verb")
    if p.compare_adjs(word1, word2):
        print("same adj.")

    # ADD CORRECT "a" OR "an" FOR A GIVEN WORD:

    print("Did you want ", p.a(thing), " or ", p.an(idea))

    # CONVERT NUMERALS INTO ORDINALS (i.e. 1->1st, 2->2nd, 3->3rd, etc.)

    print("It was", p.ordinal(position), " from the left\n")

    # CONVERT NUMERALS TO WORDS (i.e. 1->"one", 101->"one hundred and one", etc.)
    # RETURNS A SINGLE STRING...

    words = p.number_to_words(1234)
    # "one thousand, two hundred and thirty-four"
    words = p.number_to_words(p.ordinal(1234))
    # "one thousand, two hundred and thirty-fourth"

    # GET BACK A LIST OF STRINGS, ONE FOR EACH "CHUNK"...

    words = p.number_to_words(1234, wantlist=True)
    # ("one thousand","two hundred and thirty-four")

    # OPTIONAL PARAMETERS CHANGE TRANSLATION:

    words = p.number_to_words(12345, group=1)
    # "one, two, three, four, five"

    words = p.number_to_words(12345, group=2)
    # "twelve, thirty-four, five"

    words = p.number_to_words(12345, group=3)
    # "one twenty-three, forty-five"

    words = p.number_to_words(1234, andword="")
    # "one thousand, two hundred thirty-four"

    words = p.number_to_words(1234, andword=", plus")
    # "one thousand, two hundred, plus thirty-four"
    # TODO: I get no comma before plus: check perl

    words = p.number_to_words(555_1202, group=1, zero="oh")
    # "five, five, five, one, two, oh, two"

    words = p.number_to_words(555_1202, group=1, one="unity")
    # "five, five, five, unity, two, oh, two"

    words = p.number_to_words(123.456, group=1, decimal="mark")
    # "one two three mark four five six"
    # TODO: DOCBUG: perl gives commas here as do I

    # LITERAL STYLE ONLY NAMES NUMBERS LESS THAN A CERTAIN THRESHOLD...

    words = p.number_to_words(9, threshold=10)  # "nine"
    words = p.number_to_words(10, threshold=10)  # "ten"
    words = p.number_to_words(11, threshold=10)  # "11"
    words = p.number_to_words(1000, threshold=10)  # "1,000"

    # JOIN WORDS INTO A LIST:

    mylist = p.join(("apple", "banana", "carrot"))
    # "apple, banana, and carrot"

    mylist = p.join(("apple", "banana"))
    # "apple and banana"

    mylist = p.join(("apple", "banana", "carrot"), final_sep="")
    # "apple, banana and carrot"

    # REQUIRE "CLASSICAL" PLURALS (EG: "focus"->"foci", "cherub"->"cherubim")

    p.classical()  # USE ALL CLASSICAL PLURALS

    p.classical(all=True)  # USE ALL CLASSICAL PLURALS
    p.classical(all=False)  # SWITCH OFF CLASSICAL MODE

    p.classical(zero=True)  #  "no error" INSTEAD OF "no errors"
    p.classical(zero=False)  #  "no errors" INSTEAD OF "no error"

    p.classical(herd=True)  #  "2 buffalo" INSTEAD OF "2 buffalos"
    p.classical(herd=False)  #  "2 buffalos" INSTEAD OF "2 buffalo"

    p.classical(persons=True)  # "2 chairpersons" INSTEAD OF "2 chairpeople"
    p.classical(persons=False)  # "2 chairpeople" INSTEAD OF "2 chairpersons"

    p.classical(ancient=True)  # "2 formulae" INSTEAD OF "2 formulas"
    p.classical(ancient=False)  # "2 formulas" INSTEAD OF "2 formulae"

    # INTERPOLATE "plural()", "plural_noun()", "plural_verb()", "plural_adj()", "singular_noun()",
    # a()", "an()", "num()" AND "ordinal()" WITHIN STRINGS:

    print(p.inflect("The plural of {0} is plural('{0}')".format(word)))
    print(p.inflect("The singular of {0} is singular_noun('{0}')".format(word)))
    print(p.inflect("I saw {0} plural('cat',{0})".format(cat_count)))
    print(
        p.inflect(
            "plural('I',{0}) "
            "plural_verb('saw',{0}) "
            "plural('a',{1}) "
            "plural_noun('saw',{1})".format(N1, N2)
        )
    )
    print(
        p.inflect(
            "num({0}, False)plural('I') "
            "plural_verb('saw') "
            "num({1}, False)plural('a') "
            "plural_noun('saw')".format(N1, N2)
        )
    )
    print(p.inflect("I saw num({0}) plural('cat')\nnum()".format(cat_count)))
    print(p.inflect("There plural_verb('was',{0}) no('error',{0})".format(errors)))
    print(p.inflect("There num({0}, False)plural_verb('was') no('error')".format(errors)))
    print(p.inflect("Did you want a('{0}') or an('{1}')".format(thing, idea)))
    print(p.inflect("It was ordinal('{0}') from the left".format(position)))

    # ADD USER-DEFINED INFLECTIONS (OVERRIDING INBUILT RULES):

    p.defnoun("VAX", "VAXen")  # SINGULAR => PLURAL

    p.defverb(
        "will",  # 1ST PERSON SINGULAR
        "shall",  # 1ST PERSON PLURAL
        "will",  # 2ND PERSON SINGULAR
        "will",  # 2ND PERSON PLURAL
        "will",  # 3RD PERSON SINGULAR
        "will",  # 3RD PERSON PLURAL
    )

    p.defadj("hir", "their")  # SINGULAR => PLURAL

    p.defa("h")  # "AY HALWAYS SEZ 'HAITCH'!"

    p.defan("horrendous.*")  # "AN HORRENDOUS AFFECTATION"

DESCRIPTION
===========

The methods of the class ``engine`` in module ``inflect.py`` provide plural
inflections, singular noun inflections, "a"/"an" selection for English words,
and manipulation of numbers as words.

Plural forms of all nouns, most verbs, and some adjectives are
provided. Where appropriate, "classical" variants (for example: "brother" ->
"brethren", "dogma" -> "dogmata", etc.) are also provided.

Single forms of nouns are also provided. The gender of singular pronouns
can be chosen (for example "they" -> "it" or "she" or "he" or "they").

Pronunciation-based "a"/"an" selection is provided for all English
words, and most initialisms.

It is also possible to inflect numerals (1,2,3) to ordinals (1st, 2nd, 3rd)
and to English words ("one", "two", "three").

In generating these inflections, ``inflect.py`` follows the Oxford
English Dictionary and the guidelines in Fowler's Modern English
Usage, preferring the former where the two disagree.

The module is built around standard British spelling, but is designed
to cope with common American variants as well. Slang, jargon, and
other English dialects are *not* explicitly catered for.

Where two or more inflected forms exist for a single word (typically a
"classical" form and a "modern" form), ``inflect.py`` prefers the
more common form (typically the "modern" one), unless "classical"
processing has been specified
(see `MODERN VS CLASSICAL INFLECTIONS`).

FORMING PLURALS AND SINGULARS
=============================

Inflecting Plurals and Singulars
--------------------------------

All of the ``plural...`` plural inflection methods take the word to be
inflected as their first argument and return the corresponding inflection.
Note that all such methods expect the *singular* form of the word. The
results of passing a plural form are undefined (and unlikely to be correct).
Similarly, the ``si...`` singular inflection method expects the *plural*
form of the word.

The ``plural...`` methods also take an optional second argument,
which indicates the grammatical "number" of the word (or of another word
with which the word being inflected must agree). If the "number" argument is
supplied and is not ``1`` (or ``"one"`` or ``"a"``, or some other adjective that
implies the singular), the plural form of the word is returned. If the
"number" argument *does* indicate singularity, the (uninflected) word
itself is returned. If the number argument is omitted, the plural form
is returned unconditionally.

The ``si...`` method takes a second argument in a similar fashion. If it is
some form of the number ``1``, or is omitted, the singular form is returned.
Otherwise the plural is returned unaltered.

The various methods of ``inflect.engine`` are:

``plural_noun(word, count=None)``

 The method ``plural_noun()`` takes a *singular* English noun or
 pronoun and returns its plural. Pronouns in the nominative ("I" ->
 "we") and accusative ("me" -> "us") cases are handled, as are
 possessive pronouns ("mine" -> "ours").

``plural_verb(word, count=None)``

 The method ``plural_verb()`` takes the *singular* form of a
 conjugated verb (that is, one which is already in the correct "person"
 and "mood") and returns the corresponding plural conjugation.

``plural_adj(word, count=None)``

 The method ``plural_adj()`` takes the *singular* form of
 certain types of adjectives and returns the corresponding plural form.
 Adjectives that are correctly handled include: "numerical" adjectives
 ("a" -> "some"), demonstrative adjectives ("this" -> "these", "that" ->
 "those"), and possessives ("my" -> "our", "cat's" -> "cats'", "child's"
 -> "childrens'", etc.)

``plural(word, count=None)``

 The method ``plural()`` takes a *singular* English noun,
 pronoun, verb, or adjective and returns its plural form. Where a word
 has more than one inflection depending on its part of speech (for
 example, the noun "thought" inflects to "thoughts", the verb "thought"
 to "thought"), the (singular) noun sense is preferred to the (singular)
 verb sense.

 Hence ``plural("knife")`` will return "knives" ("knife" having been treated
 as a singular noun), whereas ``plural("knifes")`` will return "knife"
 ("knifes" having been treated as a 3rd person singular verb).

 The inherent ambiguity of such cases suggests that,
 where the part of speech is known, ``plural_noun``, ``plural_verb``, and
 ``plural_adj`` should be used in preference to ``plural``.

``singular_noun(word, count=None)``

 The method ``singular_noun()`` takes a *plural* English noun or
 pronoun and returns its singular. Pronouns in the nominative ("we" ->
 "I") and accusative ("us" -> "me") cases are handled, as are
 possessive pronouns ("ours" -> "mine"). When third person
 singular pronouns are returned they take the neuter gender by default
 ("they" -> "it"), not ("they"-> "she") nor ("they" -> "he"). This can be
 changed with ``gender()``.

Note that all these methods ignore any whitespace surrounding the
word being inflected, but preserve that whitespace when the result is
returned. For example, ``plural(" cat  ")`` returns " cats  ".

``gender(genderletter)``

 The third person plural pronoun takes the same form for the female, male and
 neuter (e.g. "they"). The singular however, depends upon gender (e.g. "she",
 "he", "it" and "they" -- "they" being the gender neutral form.) By default
 ``singular_noun`` returns the neuter form, however, the gender can be selected with
 the ``gender`` method. Pass the first letter of the gender to
 ``gender`` to return the f(eminine), m(asculine), n(euter) or t(hey)
 form of the singular. e.g.
 gender('f') followed by singular_noun('themselves') returns 'herself'.

Numbered plurals
----------------

The ``plural...`` methods return only the inflected word, not the count that
was used to inflect it. Thus, in order to produce "I saw 3 ducks", it
is necessary to use:

.. code-block:: python

    print("I saw", N, p.plural_noun(animal, N))

Since the usual purpose of producing a plural is to make it agree with
a preceding count, inflect.py provides a method
(``no(word, count)``) which, given a word and a(n optional) count, returns the
count followed by the correctly inflected word. Hence the previous
example can be rewritten:

.. code-block:: python

    print("I saw ", p.no(animal, N))

In addition, if the count is zero (or some other term which implies
zero, such as ``"zero"``, ``"nil"``, etc.) the count is replaced by the
word "no". Hence, if ``N`` had the value zero, the previous example
would print (the somewhat more elegant)::

    I saw no animals

rather than::

    I saw 0 animals

Note that the name of the method is a pun: the method
returns either a number (a *No.*) or a ``"no"``, in front of the
inflected word.

Reducing the number of counts required
--------------------------------------

In some contexts, the need to supply an explicit count to the various
``plural...`` methods makes for tiresome repetition. For example:

.. code-block:: python

    print(
        plural_adj("This", errors),
        plural_noun(" error", errors),
        plural_verb(" was", errors),
        " fatal.",
    )

inflect.py therefore provides a method
(``num(count=None, show=None)``) which may be used to set a persistent "default number"
value. If such a value is set, it is subsequently used whenever an
optional second "number" argument is omitted. The default value thus set
can subsequently be removed by calling ``num()`` with no arguments.
Hence we could rewrite the previous example:

.. code-block:: python

    p.num(errors)
    print(p.plural_adj("This"), p.plural_noun(" error"), p.plural_verb(" was"), "fatal.")
    p.num()

Normally, ``num()`` returns its first argument, so that it may also
be "inlined" in contexts like:

.. code-block:: python

    print(p.num(errors), p.plural_noun(" error"), p.plural_verb(" was"), " detected.")
    if severity > 1:
        print(
            p.plural_adj("This"), p.plural_noun(" error"), p.plural_verb(" was"), "fatal."
        )

However, in certain contexts (see `INTERPOLATING INFLECTIONS IN STRINGS`)
it is preferable that ``num()`` return an empty string. Hence ``num()``
provides an optional second argument. If that argument is supplied (that is, if
it is defined) and evaluates to false, ``num`` returns an empty string
instead of its first argument. For example:

.. code-block:: python

    print(p.num(errors, 0), p.no("error"), p.plural_verb(" was"), " detected.")
    if severity > 1:
        print(
            p.plural_adj("This"), p.plural_noun(" error"), p.plural_verb(" was"), "fatal."
        )

Number-insensitive equality
---------------------------

inflect.py also provides a solution to the problem
of comparing words of differing plurality through the methods
``compare(word1, word2)``, ``compare_nouns(word1, word2)``,
``compare_verbs(word1, word2)``, and ``compare_adjs(word1, word2)``.
Each  of these methods takes two strings, and  compares them
using the corresponding plural-inflection method (``plural()``, ``plural_noun()``,
``plural_verb()``, and ``plural_adj()`` respectively).

The comparison returns true if:

- the strings are equal, or
- one string is equal to a plural form of the other, or
- the strings are two different plural forms of the one word.

Hence all of the following return true:

.. code-block:: python

    p.compare("index", "index")  # RETURNS "eq"
    p.compare("index", "indexes")  # RETURNS "s:p"
    p.compare("index", "indices")  # RETURNS "s:p"
    p.compare("indexes", "index")  # RETURNS "p:s"
    p.compare("indices", "index")  # RETURNS "p:s"
    p.compare("indices", "indexes")  # RETURNS "p:p"
    p.compare("indexes", "indices")  # RETURNS "p:p"
    p.compare("indices", "indices")  # RETURNS "eq"

As indicated by the comments in the previous example, the actual value
returned by the various ``compare`` methods encodes which of the
three equality rules succeeded: "eq" is returned if the strings were
identical, "s:p" if the strings were singular and plural respectively,
"p:s" for plural and singular, and "p:p" for two distinct plurals.
Inequality is indicated by returning an empty string.

It should be noted that two distinct singular words which happen to take
the same plural form are *not* considered equal, nor are cases where
one (singular) word's plural is the other (plural) word's singular.
Hence all of the following return false:

.. code-block:: python

    p.compare("base", "basis")  # ALTHOUGH BOTH -> "bases"
    p.compare("syrinx", "syringe")  # ALTHOUGH BOTH -> "syringes"
    p.compare("she", "he")  # ALTHOUGH BOTH -> "they"

    p.compare("opus", "operas")  # ALTHOUGH "opus" -> "opera" -> "operas"
    p.compare("taxi", "taxes")  # ALTHOUGH "taxi" -> "taxis" -> "taxes"

Note too that, although the comparison is "number-insensitive" it is *not*
case-insensitive (that is, ``plural("time","Times")`` returns false. To obtain
both number and case insensitivity, use the ``lower()`` method on both strings
(that is, ``plural("time".lower(), "Times".lower())`` returns true).

Related Functionality
=====================

Shout out to these libraries that provide related functionality:

* `WordSet <https://jaracotext.readthedocs.io/en/latest/#jaraco.text.WordSet>`_
  parses identifiers like variable names into sets of words suitable for re-assembling
  in another form.

* `word2number <https://pypi.org/project/word2number/>`_ converts words to
  a number.

For Enterprise
==============

Available as part of the Tidelift Subscription.

This project and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.

`Learn more <https://tidelift.com/subscription/pkg/pypi-PROJECT?utm_source=pypi-PROJECT&utm_medium=referral&utm_campaign=github>`_.


..
    This file is part of Invenio.
    Copyright (C) 2015-2018 CERN.

    Invenio is free software; you can redistribute it and/or modify it
    under the terms of the MIT License; see LICENSE file for more details.

======================
 Invenio Framework v3
======================

Warning
-------
The main development effort is currently on the `InvenioRDM project <https://inveniosoftware.org/products/rdm/>`_
and there will be no new releases of Invenio framework. However, each Invenio module is
actively maintained as part of `InvenioRDM. <https://github.com/inveniosoftware/invenio-app-rdm>`_

**Open Source framework for large-scale digital repositories.**

.. image:: https://img.shields.io/github/license/inveniosoftware/invenio.svg
    :target: https://github.com/inveniosoftware/invenio/blob/master/LICENSE

.. image:: https://img.shields.io/badge/Discord-join%20chat-%237289da
    :target: https://discord.gg/8qatqBC

Invenio Framework is like a Swiss Army knife of battle-tested, safe and secure
modules providing you with all the features you need to build a trusted digital
repository.

**Our other products**

Looking for a turn-key Research Data Management platform? Checkout `InvenioRDM <https://inveniosoftware.org/products/rdm/>`_

Looking for a modern Integrated Library System? Checkout `InvenioILS <https://inveniosoftware.org/products/ils/>`_

**Built with Invenio Framework**

See examples on https://inveniosoftware.org/products/framework/ and https://inveniosoftware.org/showcase/.


# Grow.dev

[![PyPi](https://img.shields.io/pypi/v/grow.svg)](https://pypi.python.org/pypi/grow)
[![GitHub Actions][github-image]][github-url]
[![Downloads](https://img.shields.io/github/downloads/grow/grow/total.svg)](https://github.com/grow/grow/releases)
[![Code Coverage](https://codecov.io/gh/grow/grow/branch/master/graph/badge.svg)](https://codecov.io/gh/grow/grow)

Grow is a declarative tool for rapidly building, launching, and maintaining high-quality static HTML.

- Easy installation
- Jinja template engine
- Content managed in YAML and JSON files
- Data-binding between content and templates
- Configuration-based site architecture
- Easy URL changes
- Flexible internationalization and translation
- Integration with external CMSes
- Integration with Google Sheets
- Fast builds

## Quick start

One time only: install `Pipenv` and `libyaml`.

```bash
# On Mac with Homebrew (https://brew.sh/).
brew install pipenv libyaml

# On Ubuntu.
sudo apt install -y pipenv libyaml-dev

# On other distributions.
sudo apt install python-pip; pip install pipenv
```

Next: install and run Grow using a starter.

```bash
git clone https://github.com/grow/starter
cd starter
pipenv install
pipenv run grow install
pipenv run grow run
```

## Documentation

Visit https://grow.dev to read the documentation.

[github-image]: https://github.com/grow/grow/workflows/Test/badge.svg
[github-url]: https://github.com/grow/grow/actions


.. figure:: https://user-images.githubusercontent.com/8652625/40595190-1e16e90e-626e-11e8-9dc7-207d691c6d6d.jpg
    :align: center
    :alt: The Harvesters

    Pieter Bruegel the Elder, The Harvesters, 1565, (c) The Metropolitan Museum of Art

.. image:: https://readthedocs.org/projects/harvesters/badge/?version=latest
    :target: https://harvesters.readthedocs.io/en/latest/?badge=latest

.. image:: https://img.shields.io/pypi/v/harvesters.svg
    :target: https://pypi.org/project/harvesters

.. image:: https://zenodo.org/badge/133908095.svg
   :target: https://zenodo.org/badge/latestdoi/133908095

----

.. contents:: Table of Contents
    :depth: 1

----

About Harvester
===============

Harvester is a Python library that aims to make the image acquisition process in your computer vision application breathtakingly easy. Like the peasants/harvesters in the above drawing, it gathers the image data as its harvest and fills up your bucket/buffer.

You can freely use, modify, distribute Harvester under `Apache License-2.0 <https://www.apache.org/licenses/LICENSE-2.0>`_ without worrying about the use of your software: personal, internal or commercial.

Tasks Harvester Does for You
============================

The main features of Harvester are:

* Image acquisition through GenTL Producers
* Multiple loading of GenTL Producers in a single Python script
* GenICam feature node manipulation

Note that the second item implies you can involve various types of transport layers in your Python script. Each transport layer has own advantages and disadvantages and you should choose appropriate one based on your application's requirement. You just need to acquire images for some purposes and the GenTL Producers deliver the images somehow. It truly is the great benefit of the GenTL Standard! And of course, not only GenTL Producers but Harvester offer you a way to manipulate multiple GenICam compliant entities such as a camera in a single Python script with an intuitive manner.

Need a GUI?
===========

Do you need a GUI? Harvester has a sister project that is called **Harvester GUI**. Please visit there if you are interested in it:

https://github.com/genicam/harvesters_gui

.. image:: https://user-images.githubusercontent.com/8652625/43035346-c84fe404-8d28-11e8-815f-2df66cbbc6d0.png
    :align: center
    :alt: Image data visualizer

Asking Questions
================

We have prepared an FAQ page. Perhaps your issue could be resolved just reading through it:

https://github.com/genicam/harvesters/wiki/FAQ

If any article was not mentioning about the issue you are facing, please try to visit the following page and check if there's a ticket that is relevant to the issue. If nothing has been mentioned yet, feel free to create an issue ticket so that we can help you:

https://github.com/genicam/harvesters/issues

Links
=====

.. list-table::

    - - Documentation
      - https://harvesters.readthedocs.io/en/latest/
    - - Digital Object Identifier
      - https://zenodo.org/record/3554804#.Xd4HSi2B01I
    - - EMVA website
      - https://www.emva.org/standards-technology/genicam/genicam-downloads/
    - - Harvester GUI
      - https://github.com/genicam/harvesters_gui
    - - Issue tracker
      - https://github.com/genicam/harvesters/issues
    - - PyPI
      - https://pypi.org/project/harvesters/
    - - Source repository
      - https://github.com/genicam/harvesters

Harvester on IPython
====================

The following code block shows Harvester is running on IPython. An acquired image is delivered as the payload of a buffer and the buffer can be fetched by calling the ``fetch`` method of the ``ImageAcquirer`` class. Once you get an image you should be able to immediately start image processing. If you're running on the Jupyter notebook, you should be able to visualize the image data using Matplotlib. This step should be helpful to check what's going on your trial in the image processing flow.

.. code-block:: python

    (genicam) kznr@Kazunaris-MacBook:~% ipython
    Python 3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 11:07:29)
    Type 'copyright', 'credits' or 'license' for more information
    IPython 6.5.0 -- An enhanced Interactive Python. Type '?' for help.

    In [1]: from harvesters.core import Harvester

    In [2]: import numpy as np  # This is just for a demonstration.

    In [3]: h = Harvester()

    In [4]: h.add_file('/Users/kznr/dev/genicam/bin/Maci64_x64/TLSimu.cti')

    In [5]: h.update()

    In [6]: len(h.device_info_list)
    Out[6]: 4

    In [7]: h.device_info_list[0]
    Out[7]: {'display_name': 'TLSimuMono (SN_InterfaceA_0)', 'id_': 'TLSimuMono', 'model': 'TLSimuMono', 'serial_number': 'SN_InterfaceA_0', 'tl_type': 'Custom', 'user_defined_name': 'Center', 'vendor': 'EMVA_D', 'version': '1.2.3'}

    In [8]: ia = h.create(0)

    In [9]: ia.remote_device.node_map.Width.value = 8

    In [10]: ia.remote_device.node_map.Height.value = 8

    In [11]: ia.remote_device.node_map.PixelFormat.value = 'Mono8'

    In [12]: ia.start()

    In [13]: with ia.fetch() as buffer:
        ...:     # Let's create an alias of the 2D image component:
        ...:     component = buffer.payload.components[0]
        ...:
        ...:     # Note that the number of components can be vary. If your
        ...:     # target remote device transmits a multi-part information, then
        ...:     # you'd get two or more components in the payload. However, now
        ...:     # we're working with a remote device that transmits only a 2D image.
        ...:     # So we manipulate only index 0 of the list object, components.
        ...:
        ...:     # Let's see the acquired data in 1D:
        ...:     _1d = component.data
        ...:     print('1D: {0}'.format(_1d))
        ...:
        ...:     # Reshape the NumPy array into a 2D array:
        ...:     _2d = component.data.reshape(
        ...:         component.height, component.width
        ...:     )
        ...:     print('2D: {0}'.format(_2d))
        ...:
        ...:     # Here are some trivial calculations:
        ...:     print(
        ...:         'AVE: {0}, MIN: {1}, MAX: {2}'.format(
        ...:             np.average(_2d), _2d.min(), _2d.max()
        ...:         )
        ...:     )
        ...:
    1D: [123 124 125 126 127 128 129 130 124 125 126 127 128 129 130 131 125 126
     127 128 129 130 131 132 126 127 128 129 130 131 132 133 127 128 129 130
     131 132 133 134 128 129 130 131 132 133 134 135 129 130 131 132 133 134
     135 136 130 131 132 133 134 135 136 137]
    2D: [[123 124 125 126 127 128 129 130]
     [124 125 126 127 128 129 130 131]
     [125 126 127 128 129 130 131 132]
     [126 127 128 129 130 131 132 133]
     [127 128 129 130 131 132 133 134]
     [128 129 130 131 132 133 134 135]
     [129 130 131 132 133 134 135 136]
     [130 131 132 133 134 135 136 137]]
    AVE: 130.0, MIN: 123, MAX: 137

    In [14]: ia.stop()

    In [15]: ia.destroy()

    In [16]: h.reset()

    In [17]: quit
    (genicam) kznr@Kazunaris-MacBook:~%

Terminology
===========

Before start talking about the detail, let's take a look at some important terminologies that frequently appear in this document. These terminologies are listed as follows:

* *The GenApi-Python Binding*: A Python module that communicates with the GenICam GenApi reference implementation.

* *A GenTL Producer*: A library that has C interface and offers consumers a way to communicate with cameras over physical transport layer dependent technology hiding the detail from the consumer.

* *The GenTL-Python Binding*: A Python module that communicates with GenTL Producers.

* *Harvester*: An image acquisition engine.

* *Harvester GUI*: A Harvester-based graphical user interface.

* *A GenICam compliant device*: It's typically a camera. Just involving the GenICam reference implementation, it offers consumers a way to dynamically configure/control the target remote devices.

The following diagram shows the hierarchy and relationship of the relevant modules:

.. figure:: https://user-images.githubusercontent.com/8652625/155761972-c131d638-a0cc-4c51-aa3b-752d8f3d1284.svg
    :align: center
    :alt: Module hierarchy

Getting Started with Harvester
==============================

Are you ready to start working with Harvester? You can learn some more topics
on these pages:

* `INSTALL.rst <docs/INSTALL.rst>`_: Learn how to install Harvester and its prerequisites.
* `TUTORIAL.rst <docs/TUTORIAL.rst>`_: Learn how Harvester can be used on  a typical image acquisition workflow.

Open Source Resources
=====================

Harvester uses the following open source libraries/resources:

* Pympler

  | License: `Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0.html>`_
  | Copyright (c) Jean Brouwers, Ludwig Haehne, Robert Schuppenies

  | https://pythonhosted.org/Pympler/
  | https://github.com/pympler/pympler
  | https://pypi.org/project/Pympler/

* Versioneer

  | License: `The Creative Commons "Public Domain Dedication" license  (CC0-1.0) <https://creativecommons.org/publicdomain/zero/1.0/>`_
  | Copyright (c) 2018 Brian Warner

  | https://github.com/warner/python-versioneer

Acknowledgement
===============

The following individuals have directly or indirectly contributed to the development activity of Harvester; they truly are wonderful GenICam colleagues:

Rod Barman, Stefan Battmer, David Beek, Jan Becvar, David Bernecker, Chris Beynon, Eric Bourbonnais, Benedikt Busch, George Chamberlain, Thomas Detjen, Friedrich Dierks, Dana Diezemann, Emile Dodin, Reynold Dodson, Sascha Dorenbeck, Jozsa Elod, Erik Eloff, Katie Ensign, Andreas Ertl, James Falconer, Werner Feith, Maciej Gara, Andreas Gau, Sebastien Gendreau, Francois Gobeil, Werner Goeman, Jean-Paul Goglio, Markus Grebing, Eric Gross, Ioannis Hadjicharalambous, Uwe Hagmaier, Tim Handschack, Christopher Hartmann, Reinhard Heister, Gerhard Helfrich, Jochem Herrmann, Heiko Hirschmueller, Tom Hopfner, David Hoese, Karsten Ingeman Christensen, Severi Jaaskelainen, Alfred Johannesson, Mattias Johannesson, Mark Jones, Mattias Josefsson, Martin Kersting, Stephan Kieneke, Tom Kirchner, Lutz Koschorreck, Frank Krehl, Maarten Kuijk, Max Larin, Ralf Lay, Min Liu, Sergey Loginonvskikh, Thomas Lueck, Alain Marchand, Rocco Matano, Masahide Matsubara, Stephane Maurice, Robert McCurrach, Mike Miethig, Thies Moeller, Roman Moie, Katsura Muramatsu, Silvan Murer, Marcel Naggatz, Hartmut Nebelung, Damian Nesbitt, Quang Nhan Nguyen, Klaus-Henning Noffz, Jonas Olofsson, Neerav Patel, Jan Pech, Merlin Plock, Joerg Preckwinkel, Benjamin Pussacq, Dave Reaves, Thomas Reuter, Gordon Rice, Andreas Rittinger, Ryan Robe, Nicolas P. Rougier, Felix Ruess, Matthias Schaffland, Michael Schmidt, Jan Scholze, Martin Schwarzbauer, Rupert Stelz, Madhura Suresh, Chendra Hadi Suryanto, Andrew Wei Chuen Tan, Timo Teifel, Albert Theuwissen, Laval Tremblay, Tim Vlaar, Silvio Voitzsch, Stefan Von Weihe, Frederik Voncken, Roman Wagner, Ansger Waschki, Anne Wendel, Michael Williamson, Jean-Michel Wintgens, Manfred Wuetschner, Jang Xu, Christoph Zierl, Sebastian Yap, and Juraj Zopp


##  Fast, Scalable Quantized Neural Network Inference on FPGAs

[![GitHub Discussions](https://img.shields.io/badge/discussions-join-green)](https://github.com/Xilinx/finn/discussions)
[![ReadTheDocs](https://readthedocs.org/projects/finn/badge/?version=latest&style=plastic)](http://finn.readthedocs.io/)

FINN is an experimental framework from Integrated Communications and AI Lab of AMD Research & Advanced Development to explore deep neural network inference on FPGAs.
It specifically targets quantized neural
networks, with emphasis on
generating dataflow-style architectures customized for each network.
The resulting FPGA accelerators are highly efficient and can yield high throughput and low latency.
The framework is fully open-source in order to give a higher degree of flexibility, and is intended to enable neural network research spanning several layers of the software/hardware abstraction stack.

We have a separate repository [finn-examples](https://github.com/Xilinx/finn-examples) that houses pre-built examples for several neural networks.
For more general information about FINN, please visit the [project page](https://xilinx.github.io/finn/) and check out the [publications](https://xilinx.github.io/finn/publications).

## Getting Started

Please see the [Getting Started](https://finn.readthedocs.io/en/latest/getting_started.html) page for more information on requirements, installation, and how to run FINN in different modes. Due to the complex nature of the dependencies of the project, **we only support Docker-based execution of the FINN compiler at this time**.

## What's New in FINN?

* Please find all news under [GitHub discussions Announcements](https://github.com/Xilinx/finn/discussions/categories/announcements).

## Documentation

You can view the documentation on [readthedocs](https://finn.readthedocs.io). Additionally, there is a series of [Jupyter notebook tutorials](https://github.com/Xilinx/finn/tree/main/notebooks), which we recommend running from inside Docker for a better experience.

## Community

We have [GitHub discussions](https://github.com/Xilinx/finn/discussions) where you can ask questions. You can use the GitHub issue tracker to report bugs, but please don't file issues to ask questions as this is better handled in GitHub discussions.

We also heartily welcome contributions to the project, please check out the [contribution guidelines](CONTRIBUTING.md) and the [list of open issues](https://github.com/Xilinx/finn/issues). Don't hesitate to get in touch over [GitHub discussions](https://github.com/Xilinx/finn/discussions) to discuss your ideas.

In the past, we also had a [Gitter channel](https://gitter.im/xilinx-finn/community). Please be aware that this is no longer maintained by us but can still be used to search for questions previous users had.

## Citation

The current implementation of the framework is based on the following publications. Please consider citing them if you find FINN useful.

    @article{blott2018finn,
      title={FINN-R: An end-to-end deep-learning framework for fast exploration of quantized neural networks},
      author={Blott, Michaela and Preu{\ss}er, Thomas B and Fraser, Nicholas J and Gambardella, Giulio and O’brien, Kenneth and Umuroglu, Yaman and Leeser, Miriam and Vissers, Kees},
      journal={ACM Transactions on Reconfigurable Technology and Systems (TRETS)},
      volume={11},
      number={3},
      pages={1--23},
      year={2018},
      publisher={ACM New York, NY, USA}
    }

    @inproceedings{finn,
    author = {Umuroglu, Yaman and Fraser, Nicholas J. and Gambardella, Giulio and Blott, Michaela and Leong, Philip and Jahre, Magnus and Vissers, Kees},
    title = {FINN: A Framework for Fast, Scalable Binarized Neural Network Inference},
    booktitle = {Proceedings of the 2017 ACM/SIGDA International Symposium on Field-Programmable Gate Arrays},
    series = {FPGA '17},
    year = {2017},
    pages = {65--74},
    publisher = {ACM}
    }

## Old version

We previously released an early-stage prototype of a toolflow that took in Caffe-HWGQ binarized network descriptions and produced dataflow architectures. You can find it in the [v0.1](https://github.com/Xilinx/finn/tree/v0.1) branch in this repository.
Please be aware that this version is deprecated and unsupported, and the main branch does not share history with that branch so it should be treated as a separate repository for all purposes.


# SMART
<img src="docs/img/smart-banner.png" width="820" height="185">

[![Build Status](https://travis-ci.com/RTIInternational/SMART.svg?&branch=master)](https://travis-ci.com/RTIInternational/SMART) [![Documentation Status](https://readthedocs.org/projects/smart-app/badge/?version=latest)](https://smart-app.readthedocs.io/en/latest/?badge=latest)

SMART is an open source application designed to help data scientists and research teams efficiently build labeled training datasets for supervised machine learning tasks.

- **[SMART Landing Page](https://rtiinternational.github.io/SMART/)**
- **[SMART User Documentation](https://smart-app.readthedocs.io/en/latest/#)**
- **[SMART Publication](http://jmlr.org/papers/v20/18-859.html)**

If you use SMART for a research publication, please consider citing:

```Chew, R., Wenger, M., Kery, C., Nance, J., Richards, K., Hadley, E., & Baumgartner, P. (2019). SMART: An Open Source Data Labeling Platform for Supervised Learning. Journal of Machine Learning Research, 20(82), 1-5.```

## Development

The simplest way to start developing is to go to the `envs/dev` directory and run the rebuild script with `./rebuild.sh`.  This will: clean up any old containers/volumes, rebuild the images, run all migrations, and seed the database with some testing data.

The testing data includes three users `root`, `user1`, `test_user` and all of their passwords are `password555`. There is also a handful of projects with randomly labeled data by the various users.

### Docker containers

This project uses `docker` containers organized by `docker-compose` to ease dependency management in development.  All dependencies are controlled through docker.

#### Initial Startup

First, install docker and docker-compose. Then navigate to `envs/dev` and to build all the images run:

```bash
docker-compose build
```

Next, create the docker volumes where persistent data will be stored.

```bash
docker volume create --name=vol_smart_pgdata
docker volume create --name=vol_smart_data
```

Then, migrate the database to ensure the schema is prepared for the application.

```bash
docker-compose run --rm backend ./migrate.sh
```

### Workflow During Development

Run `docker-compose up` to start all docker containers.  This will start up the containers in the foreground so you can see the logs.  If you prefer to run the containers in the background use `docker-compose up -d`. When switching between branches there is no need to run any additional commands (except build if there is dependency change).

### Dependency Changes

If there is ever a dependency change than you will need to re-build the containers using the following commands:

```shell
docker-compose build <container with new dependency>
docker-compose rm <container with new dependency>
docker-compose up
```

If your database is blank, you will need to run migrations to initialize all the required schema objects; you can start a blank backend container and run the migration django management command with the following command:

```shell
docker-compose run --rm backend ./migrate.sh
```

#### Dependency management in Python

We use [pip-tools](https://github.com/jazzband/pip-tools) to manage Python dependencies. To change the dependencies:

1. Edit [requirements.in](./backend/docker/requirements.in) file to add, remove, or update dependencies as needed. Include only the primary dependencies—those directly required by our source code—in this file. pip-tools will automatically manage and incorporate any transitive dependencies. For routine maintenance, you may specify both primary and transitive dependencies with pinned versions to ensure consistent updates.
1. Run `docker-compose run --rm backend pip-compile docker/requirements.in` to generate a new [requirements.txt](./backend/docker/requirements.txt). Note that pip-tools uses the existing `requirements.txt` file when building a new one, so that it can maintain existing versions. To upgrade a package to the newest version compatible with the other libraries, just remove it from the existing `requirements.txt` before running pip-compile.
    - If you encounter an error while running with docker, a possible workaround is to create a virtual environment within `backend/docker`, install `pip-tools` within that environment, and then run `pip-compile requirements.in` directly from there. This method bypasses network issues that might occur within Docker.
1. Run `docker-compose build backend` to install the updated requirements into the Docker image.

### Custom Environment Variables

The various services will be available on your machine at their standard ports, but you can override the port numbers if they conflict with other running services. For example, you don't want to run SMART's instance of Postgres on port 5432 if you already have your own local instance of Postgres running on port 5432. To override a port, create a file named `.env` in the `envs/dev` directory that looks something like this:

``` shell
# Default is 5432
EXTERNAL_POSTGRES_PORT=5433

# Default is 3000
EXTERNAL_FRONTEND_PORT=3001
```

The `.env` file is ignored by `.gitignore`.

### Timezones

All date-times in the SMART backend and database are set to UTC (Coordinated Universal Time) as reccomended by the [Django docs](https://docs.djangoproject.com/en/4.1/topics/i18n/timezones/). By default the history and download date-times are set to Eastern New York time. To change this, go to `SMART/backend/django/smart/settings.py` and update the `TIME_ZONE_FRONTEND` variable to the desired time-zone.

### Running tests

Backend tests use [py.test](https://docs.pytest.org/en/latest/) and [flake8](http://flake8.pycqa.org/en/latest/).  To run them, use the following `docker-compose` command from the `env/dev` directory:

```
docker-compose run --rm backend ./run_tests.sh <args>
```

Where `<args>` are arguments to be passed to py.test.  Use `py.test -h` to see all the options, but a few useful ones are highlighted below:

 - `-x`: Stop running after the first failure
 - `-s`: Print stdout from the test run (allows you to see temporary print statements in your code)
 - `-k <expression>`: Only run tests with names containing "expression"; you can use Python expressions for more precise control.  See `py.test -h` for more info
 - `--reuse-db`: Don't drop/recreate the database between test runs.  This is useful for for reducing test runtime.  You must not pass this flag if the schema has changed since the last test run.

Frontend tests use [mocha](https://mochajs.org/api/mocha.js.html) and [eslint](https://eslint.org/docs/user-guide/getting-started).  To run them, use the following `docker-compose` command from the `env/dev` directory:

```
docker-compose run --rm smart_frontend ./run_tests.sh
```

### Contributing

If you would like to contribute to SMART feel free to submit issues and pull requests addressing any bugs or features. Before submitting a pull request make sure to follow the few guidelines below:

* Clearly explain the bug you are experiencing or the feature you wish to implement in the description.
* For new features include unit tests to ensure the feature is working correctly and the new feature is maintainable going forward.
* For bug fixes include unit tests to ensure that previously untested code is now covered.
* Make sure your branch passes all the existing backend and frontend tests.
* It is recommended that you enable pre-commit hooks. These are format checks that run whenever you commit to the project.
   * In order to run the pre-commit hooks you will need to have [pre-commit](https://pre-commit.com/) installed in your local environment.
   * Once your environment is active you will need to install the pre-commit hooks with `pre-commit install`
   * This project uses the following formatters:
       * [black](https://github.com/python/black): The uncompromising Python code formatter
       * [flake8](https://github.com/PyCQA/flake8): Your tool for style guide enforcement
       * [docformatter](https://github.com/myint/docformatter): Formats docstrings to follow [PEP 257](https://www.python.org/dev/peps/pep-0257/)
       * [isort](https://github.com/timothycrosley/isort): A python utility to sort imports
       * [eslint](https://github.com/eslint/eslint): A fully pluggable tool for identifying and reporting on patterns in JavaScript


# Lexos
[![Build status](https://ci.appveyor.com/api/projects/status/vqyfuqr15gfqj544/branch/master?svg=true)](https://ci.appveyor.com/project/chantisnake/lexos/branch/master)
[![Build Status](https://travis-ci.com/WheatonCS/Lexos.svg?branch=master)](https://travis-ci.com/WheatonCS/Lexos)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![DOI](https://zenodo.org/badge/10040275.svg)](https://zenodo.org/record/1403869#.W4LuCRgpA5k)

## Summary

Lexos is a suite of tools designed to facilitate the computational analysis of literary and historical texts. It offers an integrated workflow in which the pre-processing ("scrubbing"), analysis, and visualization steps can be accomplished in a single, web-based environment. Scrubbing features include handling punctuation, stop words, markup tags, and character consolidations, as well as document segmentation, culling, and n-gram tokenization. Analytical tools include basic document statistics, hierarchical and k-means cluster analysis, cosine similarity ranking, and z-score analysis. Visualizations include word and bubble clouds, comparative "multiclouds", and rolling window analysis. Analytical tools produce line, PCA, Voronoi cell, and dendrogram graphs. Each of the tools has export functionality.

Lexos is aimed at entry-level users as well as advanced scholars using small to medium-sized text corpora. It places particular emphasis on the processing of ancient and non-standard languages, as well as non-Western languages that do not use the Roman alphabet.

Lexos is produced by the [Lexomics Research Group](http://lexomics.wheatoncollege.edu). An online version of Lexos v4.0 is available at [http://lexos.wheatoncollege.edu/](http://lexos.wheatoncollege.edu/).

## Release history

This repo reflects ongoing development since our Summer 2019: Lexos v4.0

### New Features in v4.0

- A new UI for all tools.
- Several features have been promoted from beta, including Scrape URLs, Bootstrap Consensus Tree, and Content Analysis.
- Several color themes can now be selected from the header bar.
- A walkthrough for each page is now available.
- Active documents can be selected at any point from the footer.
- Visualizations now have selectable color schemes.
- Several tools now have PNG and SVG download options.
- Several scrub options are now more robust and inclusive.
- More helpful/descriptive error handling.
- Redesigned and rewritten help section and tooltips.

### Removed Features in v4.0

- Video guides removed (replaced with page walkthroughs).
- "Assign Temporary Labels" function was removed from the tools that used it.
- Some advanced word cloud and Bubbleviz options were removed.
- TF-IDF distance metric option removed.

## Installation

Installation instructions for Lexos v4.0 are available in the project Wiki.

- [Windows Install Guide](https://github.com/WheatonCS/Lexos/wiki/Windows-Install-Guide)
- [macOS Install Guide](https://github.com/WheatonCS/Lexos/wiki/macOS-Install-Guide)
- [Linux Install Guide](https://github.com/WheatonCS/Lexos/wiki/Linux-Install-Guide)

### System Architecture (in brief)

Lexos v4.0 is written in Python 3.7 (as distributed in [Anaconda](https://www.continuum.io/downloads) 2019.03) using the
[Flask](http://flask.pocoo.org/) microframework, based on Werkzeug and Jinja2.

The front end is designed using [jQuery](https://jquery.com/). We increasingly incorporate the viz from
[D3.js](http://d3js.org/) and the [Plotly](https://plot.ly/python/) Python graphing library in our visualizations and the power in the
[scikit-learn](http://scikit-learn.org/stable/) modules for text and statistical processing.

The directions for setting up the development environment for testing (using `localhost:5000`) on your local machine can be found on our [wiki](https://github.com/WheatonCS/Lexos/wiki) page.

## Dependencies

Lexos requires the following Python packages:

`beautifulsoup-4, biopython, chardet, colorlover, flask, gensim, lxml, matplotlib, natsort, numpy, pandas, plotly, requests, scikit-learn, scipy, werkzeug`

Lexos works on Chrome and Firefox. Other browsers are not supported, and some features may not function.

## License Information

See the file LICENSE for information on the
Terms & Conditions for usage and a DISCLAIMER OF ALL WARRANTIES.

## Citation Information

Kleinman, S., LeBlanc, M.D., Drout, M., and Feng, W. (2019). _Lexos_. v4.0 [https://github.com/WheatonCS/Lexos/](https://github.com/WheatonCS/Lexos/).
doi:10.5281/zenodo.1403869.


.. image:: https://storage.googleapis.com/pylinac_demo_files/Pylinac-GREEN.png
    :width: 100%
    :target: https://github.com/jrkerns/pylinac
    :align: center

.. image:: https://img.shields.io/pypi/v/pylinac?logo=pypi
    :target: https://pypi.python.org/pypi/pylinac
    :alt: Latest Version

.. image:: https://img.shields.io/pypi/pyversions/pylinac?logo=python
    :alt: PyPI - Python Version

.. image:: https://img.shields.io/pypi/wheel/pylinac
    :alt: PyPI - Wheel

.. image:: https://img.shields.io/github/license/jrkerns/pylinac
    :target: https://choosealicense.com/licenses/mit/
    :alt: MIT

.. image:: https://img.shields.io/readthedocs/pylinac/latest?logo=readthedocs
   :target: https://pylinac.readthedocs.io/en/latest/
   :alt: Read the Docs (version)

.. image:: https://img.shields.io/pypi/dm/pylinac
    :alt: PyPI - Downloads

.. image:: https://img.shields.io/github/commit-activity/m/jrkerns/pylinac
    :alt: GitHub commit activity (branch)

.. image:: https://img.shields.io/badge/JOSS-10.21105%2Fjoss.06001-brightgreen
   :alt: JOSS Paper
   :target: https://joss.theoj.org/papers/10.21105/joss.06001

.. contents::
    :class: this-will-duplicate-information-and-it-is-still-useful-here

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

Pylinac provides TG-142 quality assurance (QA) tools to Python programmers in the field of
therapy and diagnostic medical physics.

Pylinac contains high-level modules for automatically analyzing images and data generated by linear accelerators, CT simulators, and other radiation oncology equipment.
Most scripts can be utilized with less than 10 lines of code.

The library also contains lower-level `modules & tools <http://pylinac.readthedocs.org/en/latest/core_modules.html>`_
for creating your own image analysis algorithms.

The major attributes of the package are:

* Simple, concise image analysis API
* Automatic analysis of imaging and performance metrics like MTF, Contrast, ROIs, etc.
* PDF report generation for solid documentation
* Automatic phantom registration even if you don't set up your phantom perfect
* Image loading from file, ZIP archives, or URLs

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

Install via ``pip``:

.. code-block:: bash

    $ pip install pylinac

See the `Installation page <https://pylinac.readthedocs.io/en/latest/installation.html>`_ for further details.

Citation
--------

You may cite the pylinac library in publications; see `the paper <https://joss.theoj.org/papers/10.21105/joss.06001>`__ in the Journal of Open Source Software.
The citation string is:

Kerns, J. R., (2023). Pylinac: Image analysis for routine quality assurance in radiotherapy. Journal of Open Source Software, 8(92), 6001, https://doi.org/10.21105/joss.06001

And the BibTeX entry:

.. code-block::

  @article{Kerns2023, doi = {10.21105/joss.06001}, url = {https://doi.org/10.21105/joss.06001}, year = {2023}, publisher = {The Open Journal}, volume = {8}, number = {92}, pages = {6001}, author = {James R. Kerns}, title = {Pylinac: Image analysis for routine quality assurance in radiotherapy}, journal = {Journal of Open Source Software} }

Documentation
-------------

To get started, install the package, run the demos, view the API docs, and learn the module design, visit the
`Full Documentation <http://pylinac.readthedocs.org/>`_ on Read The Docs.

Features
--------

Low-level Tooling
~~~~~~~~~~~~~~~~~

DICOM, XIM & Image Loading
##########################

Load DICOM files, XIM, and TIFF images:

.. code-block:: python

  from pylinac import image
  from pylinac.core.image import XIM

  my_dcm = image.load("path/to/my/image.dcm")
  my_dcm.metadata.GantryAngle  # the GantryAngle tag of the DICOM file
  # these won't have the metadata property as they aren't DICOM
  my_tiff = image.load("path/to/my/image.tiff")
  my_jpg = image.load("path/to/my/image.jpg")

  my_xim_file = r"C:\TDS\H12345\QA\image.xim"
  xim_img = XIM(my_xim_file)

  # plot the image
  xim_img.plot()

  # see the XIM properties
  print(xim_img.properties)

Read more about DICOM and pixel loading: `Image Loading <http://pylinac.readthedocs.org/en/latest/topics/images.html>`_.
Read more about XIM images: `XIM Images <http://pylinac.readthedocs.org/en/latest/topics/xim.html>`_.

Image Manipulation
##################

Images can be manipulated in a variety of ways. This is helpful when combined with the loading utilities above:

.. code-block:: python

      from pylinac import image

      # load an image
      my_img = image.load("path/to/my/image.dcm")

      # rotate the image
      my_img.rotate(90)

      # flip the image
      my_img.flipud()

      # crop the image
      my_img.crop(pixels=50, edges=("left", "top"))

      # invert the image
      my_img.bit_invert()

      # normalize the array (max value = 1)
      my_img.normalize()

      # plot the image
      my_img.plot()

      # save the image back out to DICOM
      my_img.save("path/to/new.dcm")

Convert TIFF to DICOM:

.. code-block:: python

    from pylinac import image

    # load the TIFF image
    new_dicom = image.tiff_to_dicom(
        "path/to/my/image.tiff", sid=1000, gantry=90, coll=0, couch=0, dpi=400
    )

    # save out the FILE to DICOM
    new_dicom.save("path/to/new.dcm")

Compute Gamma
#############

Compute gamma between two arrays:

.. code-block:: python

    from pylinac import image

    # load the images
    img1 = image.load("path/to/image1.dcm")
    img2 = image.load("path/to/image2.dcm")

    # compute gamma
    gamma = image.gamma_2d(
        reference=img1.array,
        evaluation=img2.array,
        dose_to_agreement=1,
        distance_to_agreement=1,
        gamma_cap_value=2,
        global_dose=True,
        dose_threshold=5,
    )

    # plot the gamma map
    plt.imshow(gamma)

Compute gamma for 1D profiles:

.. code-block:: python

    from pylinac import profile

    # load the images and profiles
    img1 = image.load("path/to/image1.dcm")
    img2 = image.load("path/to/image2.dcm")
    mid_img1_profile = img1.array[img1.shape[0] // 2, :]
    mid_img2_profile = img2.array[img2.shape[0] // 2, :]

    # compute gamma
    gamma = profile.gamma_1d(
        reference=mid_img1_profile,
        evaluation=mid_img2_profile,
        dose_to_agreement=1,
        distance_to_agreement=1,
        gamma_cap_value=2,
        global_dose=True,
        dose_threshold=5,
    )

    # plot the gamma map
    plt.plot(gamma)

Compute Custom Metrics on Profiles
##################################

Pylinac comes with several built-in metrics that can be computed on 1D profiles, each of which can be
configured.

`Writing new metrics <https://pylinac.readthedocs.io/en/latest/topics/profiles.html#writing-plugins>`__ is also easy.

* `Left Penumbra <https://pylinac.readthedocs.io/en/latest/topics/profiles.html#penumbra-left>`__ using ``LeftPenumbralMetric``
* `Right Penumbra <https://pylinac.readthedocs.io/en/latest/topics/profiles.html#penumbra-right>`__  using ``RightPenumbralMetric``
* `FFF "Top" <https://pylinac.readthedocs.io/en/latest/topics/profiles.html#top-position>`__ using ``TopPosition``
* `Flatness (Difference) <https://pylinac.readthedocs.io/en/latest/topics/profiles.html#flatness-difference>`__ using ``FlatnessDifferenceMetric``
* `Flatness (Ratio) <https://pylinac.readthedocs.io/en/latest/topics/profiles.html#flatness-ratio>`__ using ``FlatnessRatioMetric``
* `Symmetry (Point Difference) <https://pylinac.readthedocs.io/en/latest/topics/profiles.html#symmetry-point-difference>`__ using ``SymmetryPointDifferenceMetric``
* `Symmetry (Point Difference Quotient) <https://pylinac.readthedocs.io/en/latest/topics/profiles.html#symmetry-point-difference-quotient>`__ using ``SymmetryPointDifferenceQuotientMetric``

Calculate the penumbra of a profile using the built-in ``LeftPenumbraMetric``:

.. code-block:: python

    from pylinac import profile
    from pylinac.metrics.profile import LeftPenumbraMetric

    # load the image and profile
    img = image.load("path/to/image.dcm")
    mid_profile = FWXMProfile(img.array[img.shape[0] // 2, :])

    # compute the penumbra
    left_penumbra = mid_profile.compute(metrics=[LeftPenumbraMetric(upper=80, lower=20)])

    print(left_penumbra)  # prints the penumbra value

Read more about 1D metrics: `Profiles & 1D Metrics <http://pylinac.readthedocs.org/en/latest/topics/profiles.html#metric-plugins>`_.

Convert Gantry, Collimator, Couch Coordinate Systems
####################################################

Convert gantry, collimator, and couch coordinates to and from each other:

.. code-block:: python

    from pylinac.core.scale import convert, MachineScale

    gantry = 0
    coll = 90
    couch = 45

    new_gantry, new_coll, new_couch = convert(
        input_scale=MachineScale.Varian,
        output_scale=MachineScale.IEC61217,
        gantry=gantry,
        collimator=coll,
        rotation=couch,
    )

Read more: `Coordinate Systems <http://pylinac.readthedocs.org/en/latest/topics/scale.html>`_.

Generate Synthetic Images
#########################

Want to generate images to test out your image analysis algorithms? Pylinac can do that.

Generate an AS1000 50x50mm, centered open field image at gantry 45:

.. code-block:: python

  from matplotlib import pyplot as plt

  from pylinac.core.image_generator import AS1000Image
  from pylinac.core.image_generator.layers import FilteredFieldLayer, GaussianFilterLayer

  as1000 = AS1000Image()  # this will set the pixel size and shape automatically
  as1000.add_layer(
      FilteredFieldLayer(field_size_mm=(50, 50))
  )  # create a 50x50mm square field
  as1000.add_layer(
      GaussianFilterLayer(sigma_mm=2)
  )  # add an image-wide gaussian to simulate penumbra/scatter
  as1000.generate_dicom(
      file_out_name="my_AS1000.dcm", gantry_angle=45
  )  # create a DICOM file with the simulated image
  # plot the generated image
  plt.imshow(as1000.image)

Read More: `Image Generator <https://pylinac.readthedocs.io/en/latest/image_generator.html>`_.

TG-51
~~~~~

`TG-51 & TRS-398 Absolute Dose Calibration <http://pylinac.readthedocs.org/en/latest/calibration_docs.html>`__ -
Input the raw data and pylinac can calculate either individual values (kQ, PDDx, Pion, etc) or use the
provided classes to input all measurement data and have it calculate all factors and dose values automatically.

Example script:

.. code-block:: python

        from pylinac import tg51, trs398

        ENERGY = 6
        TEMP = 22.1
        PRESS = tg51.mmHg2kPa(755.0)
        CHAMBER = "30013"  # PTW
        P_ELEC = 1.000
        ND_w = 5.443  # Gy/nC
        MU = 200
        CLINICAL_PDD = 66.5

        tg51_6x = tg51.TG51Photon(
            unit="TrueBeam1",
            chamber=CHAMBER,
            temp=TEMP,
            press=PRESS,
            n_dw=ND_w,
            p_elec=P_ELEC,
            measured_pdd10=66.4,
            lead_foil=None,
            clinical_pdd10=66.5,
            energy=ENERGY,
            voltage_reference=-300,
            voltage_reduced=-150,
            m_reference=(25.65, 25.66, 25.65),
            m_opposite=(25.64, 25.65, 25.65),
            m_reduced=(25.64, 25.63, 25.63),
            mu=MU,
            tissue_correction=1.0,
        )

        # Done!
        print(tg51_6x.dose_mu_dmax)

        # examine other parameters
        print(tg51_6x.pddx)
        print(tg51_6x.kq)
        print(tg51_6x.p_ion)

        # change readings if you adjust output
        tg51_6x.m_reference_adjusted = (25.44, 25.44, 25.43)
        # print new dose value
        print(tg51_6x.dose_mu_dmax_adjusted)

        # generate a PDF for record-keeping
        tg51_6x.publish_pdf(
            "TB1 6MV TG-51.pdf",
            notes=["My notes", "I used Pylinac to do this; so easy!"],
            open_file=False,
        )

        # TRS-398 is very similar and just as easy!

Planar Phantom Analysis
~~~~~~~~~~~~~~~~~~~~~~~

`Planar Phantom Analysis (Leeds TOR, StandardImaging QC-3 & QC-kV, Las Vegas, Doselab MC2 (kV & MV), SNC kV & MV, PTW EPID QC) <http://pylinac.readthedocs.org/en/latest/planar_imaging.html>`__ -
Features:

* **Automatic phantom localization** - Set up your phantom any way you like; automatic positioning,
  angle, and inversion correction mean you can set up how you like, nor will setup variations give you headache.
* **High and low contrast determination** - Analyze both low and high contrast ROIs. Set thresholds
  as you see fit.

Example script:

.. code-block:: python

      from pylinac import LeedsTOR, StandardImagingQC3, LasVegas, DoselabMC2kV, DoselabMC2MV

      leeds = LeedsTOR("my_leeds.dcm")
      leeds.analyze()
      leeds.plot_analyzed_image()
      leeds.publish_pdf()

      qc3 = StandardImagingQC3("my_qc3.dcm")
      qc3.analyze()
      qc3.plot_analyzed_image()
      qc3.publish_pdf("qc3.pdf")

      lv = LasVegas("my_lv.dcm")
      lv.analyze()
      lv.plot_analyzed_image()
      lv.publish_pdf("lv.pdf", open_file=True)  # open the PDF after publishing

      ...

Winston-Lutz Analysis
~~~~~~~~~~~~~~~~~~~~~

`Winston-Lutz Analysis <http://pylinac.readthedocs.org/en/latest/winston_lutz.html>`_ -
The Winston-Lutz module analyzes EPID images taken of a small radiation field and BB to determine the 2D
distance from BB to field CAX. Additionally, the isocenter size of the gantry, collimator, and couch can
all be determined *without the BB being at isocenter*. Analysis is based on
`Winkler et al <http://iopscience.iop.org/article/10.1088/0031-9155/48/9/303/meta;jsessionid=269700F201744D2EAB897C14D1F4E7B3.c2.iopscience.cld.iop.org>`_
, `Du et al <http://scitation.aip.org/content/aapm/journal/medphys/37/5/10.1118/1.3397452>`_, and
`Low et al <https://aapm.onlinelibrary.wiley.com/doi/abs/10.1118/1.597475>`_.

Features:

* **Couch shift instructions** - After running a WL test, get immediate feedback on how to shift the couch.
  Couch values can also be passed in and the new couch values will be presented so you don't have to do that pesky conversion.
  "Do I subtract that number or add it?"
* **Automatic field & BB positioning** - When an image or directory is loaded, the field CAX and the BB
  are automatically found, along with the vector and scalar distance between them.
* **Isocenter size determination** - Using backprojections of the EPID images, the 3D gantry isocenter size
  and position can be determined *independent of the BB position*. Additionally, the 2D planar isocenter size
  of the collimator and couch can also be determined.
* **Image plotting** - WL images can be plotted separately or together, each of which shows the field CAX, BB and
  scalar distance from BB to CAX.
* **Axis deviation plots** - Plot the variation of the gantry, collimator, couch, and EPID in each plane
  as well as RMS variation.
* **File name interpretation** - Rename DICOM filenames to include axis information for linacs that don't include
  such information in the DICOM tags. E.g. "myWL_gantry45_coll0_couch315.dcm".

Example script:

.. code-block:: python

    from pylinac import WinstonLutz

    wl = WinstonLutz("wl/image/directory")  # images are analyzed upon loading
    wl.plot_summary()
    print(wl.results())
    wl.publish_pdf("my_wl.pdf")

Starshot Analysis
~~~~~~~~~~~~~~~~~

`Starshot Analysis <http://pylinac.readthedocs.org/en/latest/starshot_docs.html>`_ -
The Starshot module analyses a starshot image made of radiation spokes, whether gantry, collimator, MLC or couch.
It is based on ideas from `Depuydt et al <http://iopscience.iop.org/0031-9155/57/10/2997>`_
and `Gonzalez et al <http://dx.doi.org/10.1118/1.1755491>`_.

Features:

* **Analyze scanned film images, single EPID images, or a set of EPID images** -
  Any image that you can load in can be analyzed, including 1 or a set of EPID DICOM images and
  films that have been digitally scanned.
* **Any image size** - Have machines with different EPIDs? Scanned your film at different resolutions? No problem.
* **Dose/OD can be inverted** - Whether your device/image views dose as an increase in value or a decrease, pylinac
  will detect it and invert if necessary.
* **Automatic noise detection & correction** - Sometimes there's dirt on the scanned film; sometimes there's a dead pixel on the EPID.
  Pylinac will detect these spurious noise signals and can avoid or account for them.
* **Accurate, FWHM star line detection** - Pylinac uses not simply the maximum value to find the center of a star line,
  but analyzes the entire star profile to determine the center of the FWHM, ensuring small noise or maximum value bias is avoided.
* **Adaptive searching** - If you passed pylinac a set of parameters and a good result wasn't found, pylinac can recover and
  do an adaptive search by adjusting parameters to find a "reasonable" wobble.

Example script:

.. code-block:: python

    from pylinac import Starshot

    star = Starshot("mystarshot.tif")
    star.analyze(radius=0.75, tolerance=1.0, fwhm=True)
    print(star.results())  # prints out wobble information
    star.plot_analyzed_image()  # shows a matplotlib figure
    star.publish_pdf()  # publish a PDF report

VMAT Analysis
~~~~~~~~~~~~~

`VMAT QA <http://pylinac.readthedocs.org/en/latest/vmat_docs.html>`_ -
The VMAT module consists of two classes: ``DRGS`` and ``DRMLC``, which are capable of loading an EPID DICOM Open field image and MLC field image and analyzing the
images according to the Varian RapidArc QA tests and procedures, specifically the Dose-Rate & Gantry-Speed (DRGS) and MLC speed (MLCS) tests.

Features:

* **Do both tests** - Pylinac can handle either DRGS or DRMLC tests.
* **Adjust for offsets** - Older VMAT patterns were off-center. Pylinac will find the field regardless.

Example script:

.. code-block:: python

    from pylinac import DRGS, DRMLC

    drgs = DRGS(image_paths=["path/to/DRGSopen.dcm", "path/to/DRGSdmlc.dcm"])
    drgs.analyze(tolerance=1.5)
    print(drgs.results())  # prints out ROI information
    drgs.plot_analyzed_image()  # shows a matplotlib figure
    drgs.publish_pdf("mydrgs.pdf")  # generate a PDF report

CatPhan, Quart, ACR, Cheese Phantom Analysis
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

`CatPhan, Quart, ACR phantom QA <http://pylinac.readthedocs.org/en/latest/cbct_docs.html>`_ -
The CBCT module automatically analyzes DICOM images of a CatPhan 504, 503, 600, 604, Quart DVT, and ACR CT/MR acquired when doing CT, CBCT, or MR quality assurance. It can load a folder or zip file that
the images are in and automatically correct for phantom setup in 6 axes.
CatPhans analyze the HU regions and image scaling (CTP404), the high-contrast line pairs (CTP528) to calculate the modulation transfer function (MTF), and the HU
uniformity (CTP486) on the corresponding slice. Quart and ACR analyze similar metrics where possible.

Features:

* **Automatic phantom registration** - Your phantom can be tilted, rotated, or translated--pylinac will register the phantom.
* **Automatic testing of all major modules** - Major modules are automatically registered and analyzed.
* **Any scan protocol** - Scan your CatPhan with any protocol; or even scan it in a regular CT scanner.
  Any field size or field extent is allowed.
* **Customize modules** - You can easily override settings in the event you have a custom scenario such as a partial scan.

Example script:

.. code-block:: python

    from pylinac import (
        CatPhan504,
        CatPhan503,
        CatPhan600,
        CatPhan604,
        QuartDVT,
        ACRCT,
        ACRMRILarge,
    )

    # for this example, we'll use the CatPhan504
    cbct = CatPhan504("my/cbct_image_folder")
    cbct.analyze(
        hu_tolerance=40,
        scaling_tolerance=1,
        thickness_tolerance=0.2,
        low_contrast_threshold=1,
    )
    print(cbct.results())
    cbct.plot_analyzed_image()
    cbct.publish_pdf("mycbct.pdf")

Trajectory & Dynalog Analysis
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

`Log Analysis <http://pylinac.readthedocs.org/en/latest/log_analyzer.html>`_ -
The log analyzer module reads and parses Varian linear accelerator machine logs, both Dynalogs and Trajectory logs. The module also
calculates actual and expected fluences as well as performing gamma evaluations. Data is structured to be easily accessible and
easily plottable.

Unlike most other modules of pylinac, the log analyzer module has no end goal. Data is parsed from the logs, but what is done with that
info, and which info is analyzed is up to the user.

Features:

* **Analyze Dynalogs or Trajectory logs** - Either platform is supported. Tlog versions 2.1 and 3.0 supported.
* **Save Trajectory log data to CSV** - The Trajectory log binary data format does not allow for easy export of data. Pylinac lets you do
  that so you can use Excel or other software that you use with Dynalogs.
* **Plot or analyze any axis** - Every data axis can be plotted: the actual, expected, and even the difference.
* **View actual or expected fluences & calculate gamma** - View fluences and gamma maps for any log.
* **Anonymization** - Anonymize your logs so you can share them with others.

Example script:

.. code-block:: python

    from pylinac import load_log

    tlog = load_log("tlog.bin")
    # after loading, explore any Axis of the Varian structure
    tlog.axis_data.gantry.plot_actual()  # plot the gantry position throughout treatment
    tlog.fluence.gamma.calc_map(doseTA=1, distTA=1, threshold=10, resolution=0.1)
    tlog.fluence.gamma.plot_map()  # show the gamma map as a matplotlib figure
    tlog.publish_pdf()  # publish a PDF report

    dlog = load_log("dynalog.dlg")
    ...

Picket Fence MLC Analysis
~~~~~~~~~~~~~~~~~~~~~~~~~

`Picket Fence MLC Analysis <http://pylinac.readthedocs.org/en/latest/picketfence.html>`_ -
The picket fence module is meant for analyzing EPID images where a "picket fence" MLC pattern has been made.
Physicists regularly check MLC positioning through this test. This test can be done using film and one can
"eyeball" it, but this is the 21st century and we have numerous ways of quantifying such data. This module
attains to be one of them. It will load in an EPID dicom image and determine the MLC peaks, error of each MLC
pair to the picket, and give a few visual indicators for passing/warning/failing.

Features:

* **Preset & customizable MLC configurations** - Standard configurations are built-in and you can create your own configuration of leaves if needed.
* **Easy-to-read pass/warn/fail overlay** - Analysis gives you easy-to-read tools for determining the status of an MLC pair.
* **Any Source-to-Image distance** - Whatever your clinic uses as the SID for picket fence, pylinac can account for it.
* **Account for panel translation** - Have an off-CAX setup? No problem. Translate your EPID and pylinac knows.
* **Account for panel sag** - If your EPID sags at certain angles, just tell pylinac and the results will be shifted.

Example script:

.. code-block:: python

    from pylinac import PicketFence

    pf = PicketFence("mypf.dcm")
    pf.analyze(tolerance=0.5, action_tolerance=0.25)
    print(pf.results())
    pf.plot_analyzed_image()
    pf.publish_pdf()

Open Field Analysis
~~~~~~~~~~~~~~~~~~~

`Open Field Analysis <http://pylinac.readthedocs.org/en/latest/field_analysis.html>`_ -
Field analysis from a digital image such as EPID DICOM or 2D device array can easily be analyzed. The module contains built-in
flatness and symmetry equation definitions but is extensible to quickly create custom F&S equations.

Features:
* **EPID or device data** - Any EPID image or the SNC Profiler.
* **Built-in F&S equations** - The common Elekta, Varian, and Siemens definitions are included
* **Extensible equations** - Adding custom equations for image metrics are easy

Example script:

.. code-block:: python

    from pylinac import FieldAnalysis, DeviceFieldAnalysis, Protocol

    fa = FieldAnalysis(path="myFS.dcm")  # equivalently, DeviceFieldAnalysis
    fa.analyze(protocol=Protocol.VARIAN)
    # print results
    print(fa.results())
    # get results as a dict
    fa.results_data()
    # plot results
    fa.plot_analyzed_image()
    # publish a PDF file
    fa.publish_pdf(filename="my field analysis.pdf")

Discussion
----------

Have questions? Ask them on the `pylinac discourse server <https://forum.pylinac.com>`_.

Contributing
------------

Contributions to pylinac can be many. The most useful things a non-programmer can contribute are images to analyze and bug reports. If
you have VMAT images, starshot images, machine log files, CBCT DICOM files, or anything else you want analyzed, upload them privately
`here <https://forms.gle/RBR5ubFvjogE9iC67>`_.

See the full `Contributing page <https://pylinac.readthedocs.io/en/latest/contributing.html>`_ for more details.