PIPython


NamePIPython JSON
Version 2.10.1.1 PyPI version JSON
download
home_pagehttp://www.physikinstrumente.com
SummaryCollection of libraries to use PI devices and process GCS data.
upload_time2024-01-24 09:41:25
maintainer
docs_urlNone
authorPhysik Instrumente (PI) GmbH & Co. KG
requires_python>=3.6
license
keywords pi pipython physikinstrumente physik instrumente gcs
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # PIPython

PIPython is a collection of Python modules to access a PI device and process
GCS data. It can be used with Python 3.6+ on Windows, Linux and OS X
and without the GCS DLL also on any other platform.

## Installation

By using PIPython you agree to the license agreement, see the provided file:

    eula.md

### From local folder 

Unzip the file PIPython.zip, open a command entry (Linux Console or Windows CMD window) and run:

    python setup.py install

For further reading open the *index.html* file in your browser and see the samples in the
*samples* folder.

### From GitHub

[PIPython on GitHub](https://github.com/PI-PhysikInstrumente/PIPython)

    git clone git@github.com:PI-PhysikInstrumente/PIPython.git
    python setup.py install

### From pypi.org

    pip install PIPython    

### Feedback 

We appreciate your feedback at:

    service@pi.de

## Quickstart

Communicate to a PI device via `GCSDevice` which wraps the GCS DLL functions
and provides methods to connect to the device. Call `GCSDevice` with the
controller name as argument.

~~~python
from pipython import GCSDevice
pidevice = GCSDevice('C-884')
pidevice.InterfaceSetupDlg()
print pidevice.qIDN()
pidevice.CloseConnection()
~~~

`GCSDevice` is a context manager which closes the connection if an exception
raises inside the `with` statement.

~~~python
from pipython import GCSDevice
with GCSDevice('C-884') as pidevice:
    pidevice.InterfaceSetupDlg()
    print(pidevice.qIDN())
~~~

See also the provided samples in the `samples` subdirectory. Be aware that some controllers may not work with every sample and vice versa. See [Available commands](#available-commands) and look out for comments in the samples. Start with `quickstart.py`.



## Requirements

### Required packages

Download these python packages with pip install:

- PyUSB
- PySocket
- PySerial

With pipython.interfaces.piusb you can connect a USB device without using the GCS DLL.
This works only with Linux and requires LibUSB which usually is provided by the OS.


### Available commands

Some GCS commands are only available for certain types of PI devices. For example, the `qPOS()` and `MOV()` commands are only available for devices working in closed-loop operation. Available GCS commands can be found in the manual or technical note of the controller. For a given device, to query for all available commands or for a specific command, use the `qHLP()` or `Has<CMD>()` commands, respectively.


## Arguments

From now on `pidevice` refers to a connected `GCSDevice` instance.


### Setter functions

Usually you can call a setter function with
- a dictionary of axes/channels and values
- a list for axes/channels and a list of the values
- a single item for axis/channel and a single value

~~~python
gcs.MOV({'X': 1.23, 'Y': 2.34})
gcs.MOV(['X', 'Y'], [1.23, 2.34])
gcs.MOV('X', 1.23)
~~~

For channels and numeric axis names you can omit the quotes.

~~~python
gcs.MOV({1: 1.23, 2: 2.34})
gcs.MOV([1, 2], [1.23, 2.34])
gcs.MOV(1, 1.23)
~~~


### Getter functions

#### GCS 2.0

Usually getter commands can be called with

- a list of axes/channels.
- a single item for axis/channel, without quotes if numeric
- without any arguments which will return the answer for all available axes/channels

~~~python
gcs.qPOS(['X', 'Y'])
gcs.qPOS('X')
gcs.qPOS(1)
gcs.qPOS()
~~~


#### GCS 3.0

Usually getter commands can be called with

- a single axis
- without any arguments which will return the answer for all available axes

~~~python
gcs.qPOS('AXIS_1')
gcs.qPOS()
~~~

## Return values

Axes or channel related answers are returned as (ordered) dictionary.

~~~python
pidevice.qPOS()
>>>{'X': 1.23, 'Y': 2.34}
~~~


If you do not provide arguments you always have to use strings as keys.

~~~python
pos = pidevice.qPOS()
print(pos['1'])
~~~

The following sample will move all `axes` to `targets` and waits until the motion has finished.
It shows how to use only the values from the returned dictionary.

~~~python
from time import sleep
...
pidevice.MOV(axes, targets)
while not all(list(pidevice.qONT(axes).values())):
    sleep(0.1)
~~~

#### GCS 2.0

If you provide arguments their types are preserved and you can use these as keys.

~~~python
pos = pidevice.qPOS([1, 2, 3])
print(pos[1])
~~~

#### GCS 3.0

If you provide arguments their types are preserved and you can use these as keys.

~~~python
pos = pidevice.qPOS('AXIS_1') # only one axis is possible
print(pos['AXIS_1'])
~~~


## Some hints...


### Helpers

In `pipython.pitools` you will find some helper funtions for your convenience. See the provided
samples for how to use them. The sample above can then be written as:

~~~python
from pipython import pitools
...
pidevice.MOV(axes, targets)
pitools.waitontarget(pidevice, axes)
~~~


### Enable debug logging

To log debug messages on the console just enter these lines prior to calling `GCSDevice`.

~~~python
from pipython import PILogger, DEBUG, INFO, WARNING, ERROR, CRITICAL

PILogger.setLevel(DEBUG)
~~~


### GCSError and error check

By default an "ERR?" command is sent after each command to query if an error
occurred on the device which then will be raised as `GCSError` exception. If communication
speed is an issue you can disable error checking.

~~~python
pidevice.errcheck = False
~~~

To handle a catched `GCSError` exception you can use the defines provided by
`gcserror` instead of pure numeric values. Remember the difference between `GCSError` which
is the exception class and `gcserror` which is the according module.

~~~python
from pipython import GCSDevice, GCSError, gcserror
with GCSDevice('C-884') as pidevice:
    try:
        pidevice.MOV('X', 1.23)
    except GCSError as exc:
        if exc == gcserror.E_1024_PI_MOTION_ERROR:
            print('There was a motion error, please check the mechanics.')
        else:
            raise
~~~

The exception class `GCSError` will translate the error code into a readable message.

~~~python
from pipython import GCSError, gcserror
raise GCSError(gcserror.E_1024_PI_MOTION_ERROR)
>>>GCSError: Motion error: position error too large, servo is switched off automatically (-1024)
~~~

#### GCS 3.0

- to reset the error state of 1 or more axes 
~~~python
for axis in device.axes:
    if axis_has_error(device):
        while check_axis_status_bit(device, axis, AXIS_STATUS_FAULT_REACTION_ACTIVE):
            pass
        print('reset axis error: ', axis)
        device.RES(axis)
~~~


### Big data

Commands like `qDRR()` for GCS 2.0 syntax, or `qREC_DAT()` for GCS 3.0 syntax
which read a large amount of GCS data return immediately with
the header dictionary containing information about the data. Then they will start
a background task that carries on reading data from the device into an internal buffer. The
`bufstate` property returns the progress of the reading as floating point number in the range
0 to 1 and turns to `True` when reading has finished. Hence, when using it in a loop check for
`is not True`. (Remember, this is not the same as `!= True`.)

#### GCS 2.0

~~~python
header = pidevice.qDRR(1, 1, 8192)
while pidevice.bufstate is not True:
    print('read data {:.1f}%...'.format(pidevice.bufstate * 100))
    sleep(0.1)
data = pidevice.bufdata
~~~

#### GCS 3.0

~~~python
header = pidevice.qREC_DAT('REC_1', 'ASCII', 1, 1, 8192)
while pidevice.bufstate is not True:
    print('read data {:.1f}%...'.format(pidevice.bufstate * 100))
    sleep(0.1)
data = pidevice.bufdata
~~~


### Textual interface

Besides the functions implemented in GCSCommands you can send GCS commands as strings to the
controller. Use `read()` for commands returning an answer, `read_gcsdata()` for commands returning
GCS data and `send()` for non-answering commands.

~~~python
print(pidevice.read('POS?'))
print(pidevice.read_gcsdata('DRR? 1 100 1'))
pidevice.send('MOV X 1.23')
~~~

They return the raw string or GCS data from the controller. If `errorcheck` is enabled the
error state is queried from the device automatically. We recommend to use the provided
functions instead of sending raw strings.

In line with the C++ GCS DLL the functions `ReadGCSCommand()` and `GcsCommandset()` are also
available. They will never query an error from the device.

~~~python
print(pidevice.ReadGCSCommand('POS?'))
pidevice.GcsCommandset('MOV X 1.23')
~~~

            

Raw data

            {
    "_id": null,
    "home_page": "http://www.physikinstrumente.com",
    "name": "PIPython",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "PI,PIPython,physikinstrumente,Physik Instrumente,GCS",
    "author": "Physik Instrumente (PI) GmbH & Co. KG",
    "author_email": "service@pi.de",
    "download_url": "https://files.pythonhosted.org/packages/e6/ad/464231164e63e3cce9f1ad027c98d74592cb66fb28fc0bd1037b2028c3fd/PIPython-2.10.1.1.tar.gz",
    "platform": null,
    "description": "# PIPython\r\n\r\nPIPython is a collection of Python modules to access a PI device and process\r\nGCS data. It can be used with Python 3.6+ on Windows, Linux and OS X\r\nand without the GCS DLL also on any other platform.\r\n\r\n## Installation\r\n\r\nBy using PIPython you agree to the license agreement, see the provided file:\r\n\r\n    eula.md\r\n\r\n### From local folder \r\n\r\nUnzip the file PIPython.zip, open a command entry (Linux Console or Windows CMD window) and run:\r\n\r\n    python setup.py install\r\n\r\nFor further reading open the *index.html* file in your browser and see the samples in the\r\n*samples* folder.\r\n\r\n### From GitHub\r\n\r\n[PIPython on GitHub](https://github.com/PI-PhysikInstrumente/PIPython)\r\n\r\n    git clone git@github.com:PI-PhysikInstrumente/PIPython.git\r\n    python setup.py install\r\n\r\n### From pypi.org\r\n\r\n    pip install PIPython    \r\n\r\n### Feedback \r\n\r\nWe appreciate your feedback at:\r\n\r\n    service@pi.de\r\n\r\n## Quickstart\r\n\r\nCommunicate to a PI device via `GCSDevice` which wraps the GCS DLL functions\r\nand provides methods to connect to the device. Call `GCSDevice` with the\r\ncontroller name as argument.\r\n\r\n~~~python\r\nfrom pipython import GCSDevice\r\npidevice = GCSDevice('C-884')\r\npidevice.InterfaceSetupDlg()\r\nprint pidevice.qIDN()\r\npidevice.CloseConnection()\r\n~~~\r\n\r\n`GCSDevice` is a context manager which closes the connection if an exception\r\nraises inside the `with` statement.\r\n\r\n~~~python\r\nfrom pipython import GCSDevice\r\nwith GCSDevice('C-884') as pidevice:\r\n    pidevice.InterfaceSetupDlg()\r\n    print(pidevice.qIDN())\r\n~~~\r\n\r\nSee also the provided samples in the `samples` subdirectory. Be aware that some controllers may not work with every sample and vice versa. See [Available commands](#available-commands) and look out for comments in the samples. Start with `quickstart.py`.\r\n\r\n\r\n\r\n## Requirements\r\n\r\n### Required packages\r\n\r\nDownload these python packages with pip install:\r\n\r\n- PyUSB\r\n- PySocket\r\n- PySerial\r\n\r\nWith pipython.interfaces.piusb you can connect a USB device without using the GCS DLL.\r\nThis works only with Linux and requires LibUSB which usually is provided by the OS.\r\n\r\n\r\n### Available commands\r\n\r\nSome GCS commands are only available for certain types of PI devices. For example, the `qPOS()` and `MOV()` commands are only available for devices working in closed-loop operation. Available GCS commands can be found in the manual or technical note of the controller. For a given device, to query for all available commands or for a specific command, use the `qHLP()` or `Has<CMD>()` commands, respectively.\r\n\r\n\r\n## Arguments\r\n\r\nFrom now on `pidevice` refers to a connected `GCSDevice` instance.\r\n\r\n\r\n### Setter functions\r\n\r\nUsually you can call a setter function with\r\n- a dictionary of axes/channels and values\r\n- a list for axes/channels and a list of the values\r\n- a single item for axis/channel and a single value\r\n\r\n~~~python\r\ngcs.MOV({'X': 1.23, 'Y': 2.34})\r\ngcs.MOV(['X', 'Y'], [1.23, 2.34])\r\ngcs.MOV('X', 1.23)\r\n~~~\r\n\r\nFor channels and numeric axis names you can omit the quotes.\r\n\r\n~~~python\r\ngcs.MOV({1: 1.23, 2: 2.34})\r\ngcs.MOV([1, 2], [1.23, 2.34])\r\ngcs.MOV(1, 1.23)\r\n~~~\r\n\r\n\r\n### Getter functions\r\n\r\n#### GCS 2.0\r\n\r\nUsually getter commands can be called with\r\n\r\n- a list of axes/channels.\r\n- a single item for axis/channel, without quotes if numeric\r\n- without any arguments which will return the answer for all available axes/channels\r\n\r\n~~~python\r\ngcs.qPOS(['X', 'Y'])\r\ngcs.qPOS('X')\r\ngcs.qPOS(1)\r\ngcs.qPOS()\r\n~~~\r\n\r\n\r\n#### GCS 3.0\r\n\r\nUsually getter commands can be called with\r\n\r\n- a single axis\r\n- without any arguments which will return the answer for all available axes\r\n\r\n~~~python\r\ngcs.qPOS('AXIS_1')\r\ngcs.qPOS()\r\n~~~\r\n\r\n## Return values\r\n\r\nAxes or channel related answers are returned as (ordered) dictionary.\r\n\r\n~~~python\r\npidevice.qPOS()\r\n>>>{'X': 1.23, 'Y': 2.34}\r\n~~~\r\n\r\n\r\nIf you do not provide arguments you always have to use strings as keys.\r\n\r\n~~~python\r\npos = pidevice.qPOS()\r\nprint(pos['1'])\r\n~~~\r\n\r\nThe following sample will move all `axes` to `targets` and waits until the motion has finished.\r\nIt shows how to use only the values from the returned dictionary.\r\n\r\n~~~python\r\nfrom time import sleep\r\n...\r\npidevice.MOV(axes, targets)\r\nwhile not all(list(pidevice.qONT(axes).values())):\r\n    sleep(0.1)\r\n~~~\r\n\r\n#### GCS 2.0\r\n\r\nIf you provide arguments their types are preserved and you can use these as keys.\r\n\r\n~~~python\r\npos = pidevice.qPOS([1, 2, 3])\r\nprint(pos[1])\r\n~~~\r\n\r\n#### GCS 3.0\r\n\r\nIf you provide arguments their types are preserved and you can use these as keys.\r\n\r\n~~~python\r\npos = pidevice.qPOS('AXIS_1') # only one axis is possible\r\nprint(pos['AXIS_1'])\r\n~~~\r\n\r\n\r\n## Some hints...\r\n\r\n\r\n### Helpers\r\n\r\nIn `pipython.pitools` you will find some helper funtions for your convenience. See the provided\r\nsamples for how to use them. The sample above can then be written as:\r\n\r\n~~~python\r\nfrom pipython import pitools\r\n...\r\npidevice.MOV(axes, targets)\r\npitools.waitontarget(pidevice, axes)\r\n~~~\r\n\r\n\r\n### Enable debug logging\r\n\r\nTo log debug messages on the console just enter these lines prior to calling `GCSDevice`.\r\n\r\n~~~python\r\nfrom pipython import PILogger, DEBUG, INFO, WARNING, ERROR, CRITICAL\r\n\r\nPILogger.setLevel(DEBUG)\r\n~~~\r\n\r\n\r\n### GCSError and error check\r\n\r\nBy default an \"ERR?\" command is sent after each command to query if an error\r\noccurred on the device which then will be raised as `GCSError` exception. If communication\r\nspeed is an issue you can disable error checking.\r\n\r\n~~~python\r\npidevice.errcheck = False\r\n~~~\r\n\r\nTo handle a catched `GCSError` exception you can use the defines provided by\r\n`gcserror` instead of pure numeric values. Remember the difference between `GCSError` which\r\nis the exception class and `gcserror` which is the according module.\r\n\r\n~~~python\r\nfrom pipython import GCSDevice, GCSError, gcserror\r\nwith GCSDevice('C-884') as pidevice:\r\n    try:\r\n        pidevice.MOV('X', 1.23)\r\n    except GCSError as exc:\r\n        if exc == gcserror.E_1024_PI_MOTION_ERROR:\r\n            print('There was a motion error, please check the mechanics.')\r\n        else:\r\n            raise\r\n~~~\r\n\r\nThe exception class `GCSError` will translate the error code into a readable message.\r\n\r\n~~~python\r\nfrom pipython import GCSError, gcserror\r\nraise GCSError(gcserror.E_1024_PI_MOTION_ERROR)\r\n>>>GCSError: Motion error: position error too large, servo is switched off automatically (-1024)\r\n~~~\r\n\r\n#### GCS 3.0\r\n\r\n- to reset the error state of 1 or more axes \r\n~~~python\r\nfor axis in device.axes:\r\n    if axis_has_error(device):\r\n        while check_axis_status_bit(device, axis, AXIS_STATUS_FAULT_REACTION_ACTIVE):\r\n            pass\r\n        print('reset axis error: ', axis)\r\n        device.RES(axis)\r\n~~~\r\n\r\n\r\n### Big data\r\n\r\nCommands like `qDRR()` for GCS 2.0 syntax, or `qREC_DAT()` for GCS 3.0 syntax\r\nwhich read a large amount of GCS data return immediately with\r\nthe header dictionary containing information about the data. Then they will start\r\na background task that carries on reading data from the device into an internal buffer. The\r\n`bufstate` property returns the progress of the reading as floating point number in the range\r\n0 to 1 and turns to `True` when reading has finished. Hence, when using it in a loop check for\r\n`is not True`. (Remember, this is not the same as `!= True`.)\r\n\r\n#### GCS 2.0\r\n\r\n~~~python\r\nheader = pidevice.qDRR(1, 1, 8192)\r\nwhile pidevice.bufstate is not True:\r\n    print('read data {:.1f}%...'.format(pidevice.bufstate * 100))\r\n    sleep(0.1)\r\ndata = pidevice.bufdata\r\n~~~\r\n\r\n#### GCS 3.0\r\n\r\n~~~python\r\nheader = pidevice.qREC_DAT('REC_1', 'ASCII', 1, 1, 8192)\r\nwhile pidevice.bufstate is not True:\r\n    print('read data {:.1f}%...'.format(pidevice.bufstate * 100))\r\n    sleep(0.1)\r\ndata = pidevice.bufdata\r\n~~~\r\n\r\n\r\n### Textual interface\r\n\r\nBesides the functions implemented in GCSCommands you can send GCS commands as strings to the\r\ncontroller. Use `read()` for commands returning an answer, `read_gcsdata()` for commands returning\r\nGCS data and `send()` for non-answering commands.\r\n\r\n~~~python\r\nprint(pidevice.read('POS?'))\r\nprint(pidevice.read_gcsdata('DRR? 1 100 1'))\r\npidevice.send('MOV X 1.23')\r\n~~~\r\n\r\nThey return the raw string or GCS data from the controller. If `errorcheck` is enabled the\r\nerror state is queried from the device automatically. We recommend to use the provided\r\nfunctions instead of sending raw strings.\r\n\r\nIn line with the C++ GCS DLL the functions `ReadGCSCommand()` and `GcsCommandset()` are also\r\navailable. They will never query an error from the device.\r\n\r\n~~~python\r\nprint(pidevice.ReadGCSCommand('POS?'))\r\npidevice.GcsCommandset('MOV X 1.23')\r\n~~~\r\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "Collection of libraries to use PI devices and process GCS data.",
    "version": "2.10.1.1",
    "project_urls": {
        "Homepage": "http://www.physikinstrumente.com"
    },
    "split_keywords": [
        "pi",
        "pipython",
        "physikinstrumente",
        "physik instrumente",
        "gcs"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4b0f5b430b353494ced748d6d5e3343815708cc94278b46a0f2593f7a14be981",
                "md5": "ba0686c64891ce1147ebb791008a5d22",
                "sha256": "6a65f55b62fea09edec4dc533febd544ff865ec00659e200773ae3448344d0eb"
            },
            "downloads": -1,
            "filename": "PIPython-2.10.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "ba0686c64891ce1147ebb791008a5d22",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 179376,
            "upload_time": "2024-01-24T09:41:24",
            "upload_time_iso_8601": "2024-01-24T09:41:24.353762Z",
            "url": "https://files.pythonhosted.org/packages/4b/0f/5b430b353494ced748d6d5e3343815708cc94278b46a0f2593f7a14be981/PIPython-2.10.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e6ad464231164e63e3cce9f1ad027c98d74592cb66fb28fc0bd1037b2028c3fd",
                "md5": "c847ce07fbf45b66a6c2cab6bbd4ccbd",
                "sha256": "2e80b7421cadb67d2dd348806941a33e0252c856eef07f65091019c14b243942"
            },
            "downloads": -1,
            "filename": "PIPython-2.10.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "c847ce07fbf45b66a6c2cab6bbd4ccbd",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 170589,
            "upload_time": "2024-01-24T09:41:25",
            "upload_time_iso_8601": "2024-01-24T09:41:25.792844Z",
            "url": "https://files.pythonhosted.org/packages/e6/ad/464231164e63e3cce9f1ad027c98d74592cb66fb28fc0bd1037b2028c3fd/PIPython-2.10.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-01-24 09:41:25",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "pipython"
}
        
Elapsed time: 0.17631s