{ "info": { "author": "Connor Wolf", "author_email": "github@imaginaryindustries.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta" ], "description": "pySignalHound\r\n=============\r\n\r\nA python wrapper for the Test Equipment Plus SignalHound series of spectrum \r\nanalyzers.\r\n\r\nThe primary file is \"SignalHound.py\". It defines one class, \"SignalHound()\", \r\nthat currently can only open the first signal-hound analyser it finds.\r\n\r\nPredominantly, all C API errors should be caught, and re-raised as python \r\nexceptions with helpful error messages.\r\n\r\nAlso, there is *some* error checking for function parameters. I should probably \r\ngo through and add `{library}.{function}.restype = {something}` type hints to \r\nall the function calls, but I think the fact that I'm explicitly casting all \r\nparameters to ctypes values should somewhat ameliorate that need.\r\n\r\n~~At the moment, the one function that takes a callback (`bbStartRawSweepLoop`) \r\nproperly wraps a passed python function, so it gets called via the C callback,\r\nthough it still relys on the user decoding the C function call arguments. I \r\nwant to do something about that in the near future.~~ (Raw sweep mode is \r\ndepreciated.)\r\n\r\nCurrently, I can only test with a BB60C, as that is the only unit I have \r\non-hand. It should work with a BB60A without too much trouble, though (it has \r\nprovisions for it, and I did my initial dev work with a BB60A. I just upgraded \r\nlater).\r\n\r\n\r\n---\r\n\r\nInstallation:\r\n\r\n`python setup.py install`\r\n\r\nThis will drop the `bb_api.dll` dll in your `{python-dir}/DLLs/` directory, as \r\nwell as install the SignalHound wrapper.\r\n\r\n---\r\n\r\nThe primary API contained in the `SignalHound/__init__.py` file.\r\n\r\n`bb_api_h.py` is a transliteration of the bb_api.h file from the C api, and \r\nprimarily defines most of the configuration constants used for controlling \r\nthe SignalHound. It contains no executable code.\r\n\r\n`tests.py` contains a number of different hardware test facilities.\r\n\r\n`tests.py` is a good proof-of-concept demo. It's currently messy, but it shows \r\nthe capabilities of both python and the SignalHound.\r\n\r\n - `python tests.py radio {frequency-in-hz}` will do real-time software\r\n decoding and playback of FM radio.\r\n - `python tests.py raw-pipe` will log the full-rate 160 MBPS data-stream to \r\n disk in real-time (requires a SSD).\r\n - `python tests.py callback` demonstrates the ability to have the C api \r\n callback into pure python code\r\n\r\n Utilities:\r\n - `python tests.py status` prints the connected hardware version, serial, \r\n - firmware version, and API version, as well as querying the hardware \r\n - diagnostics values.\r\n - `python tests.py reset` triggers a firmware-level reset of the hardware, \r\n - equivalent to disconnecting and reconnecting the USB interface.\r\n\r\nWhile `tests.py` is functional, it's very messily written. Cleanup is needed. \r\nThe API files themselves are fairly coherent, however.\r\nThe ability to configure some of the test-modes is also a good idea, though it \r\nalso needs to be implemented.\r\n\r\n`spectraLog.py` is the script that is why I wrote the API in the first place. \r\nIt does long-duration (days!) spectrum logging for site-survey purposes and \r\nanalysis. It is a fully-multi-process tool that does on-the-fly averaging of \r\nthe incoming data-stream to reduce disk load.\r\n\r\nNote: `spectraLog.py` is aggressively multi-process, and you **must** stop it \r\nby typing \"q\" + \\[enter\\], to properly signal all the running processes to \r\nexit. A typical Ctrl+C will just signal the process attached to the console to \r\nexit, but due to a quirk in the `multiprocessing` module, I cannot properly \r\ninstall a signal handler to catch the Ctrl+C in a proper manner. Yes, this is \r\nirritating. I will probably look at solving it eventually.\r\n\r\nAll the behaviour of `spectraLog.py` is controlled by the configuration \r\nvariables in `settings.py` in the `SpectraLogger` directory. This file also \r\ncontains fairly extensive documentation, and should be fairly self-explanitory. \r\nThe `spectraLog.py` tool exposes *most* of the functionality of the signalhound, \r\nthough most of the raw-data modes are either not supported or poorly \r\n(or entirely un)tested.\r\n\r\n\r\n---\r\n\r\nCurrently, there is also a prototype visualization tool as well (`main.py` in \r\nthe `RealtimeSpectraLogTool` directory):\r\n\r\n![Image 1](http://fake-name.github.io/pySignalHound/img/Demo1.png)\r\n\r\nThe visualization tool connects to a running acquisition session, and retreives \r\nscans from the currently running acquisition. The advantage of this is that it \r\ncan connect and disconnect from a running acquisition, all without interrupting \r\nthe actual data-logging in the acquisition.\r\n\r\nAlso, the current interface for the visualization and acquisition scripts is \r\nover TCP, so you can connect to a running acquisition on one computer, and view \r\nthe plots of the data on a different computer \r\n(`python main.py {computer running acq's IP}`).\r\n\r\nThe visualization tool also generates some simple statistics for the acquired \r\ndata, as well as automatically highlighting all the peaks above a certain \r\nthreshold in the display (adjustable with the slider at the top of the window).\r\n\r\nLastly, it features a mouse-cursor that gives the minimum, maximum, and mean \r\nvalue of the data under the mouse cursor in realtime, as well as highlighting\r\nthe data-points in the column that is mouse-overed (each column is 1 pixel, and \r\ngiven the fact that displays are typically 1000-3000 pixels wide, and the sweeps \r\nare generally ~16Kitems, each pixel \"column\" has >10 items).\r\nThe cursor is the vertical green line in the screenshots.\r\n\r\nEach datapoint is highlighted with a red circle.\r\n\r\n![Image 2](http://fake-name.github.io/pySignalHound/img/Demo2.png)\r\n\r\nThe visualization also has extensions to support the custom pseudo-sweeping\r\nmode that is implemented in `internalSweepSpectraAcqThread.py`. This is a \r\nspecial acquisition mode that is implemented for some of the astrophysics \r\ndata-acquisition we want to do. Basically, it runs the hardware in `realtime` \r\nmode, but every `n` scans in realtime mode, it halts the acquisition, changes \r\nthe frequency, and starts acquiring in realtime at the new frequency. It has \r\nconfigurable overlap for each frequency step. as well as configurable frequency \r\nand span.\r\n\r\nIn the stepped mode, only the latest data row is active with regard to the \r\ncursor, though the entire swept range is displayed. The older data is the \r\nslightly darker grey colour.\r\n\r\n---\r\n\r\nThe special pseudo-sweeping mode is specifically to allow much greater control \r\nand insight into the integration time of the SignalHound. One of the issues \r\nwith the SignalHound's internal `sweeping` mode is the actual percentage of the \r\ntime the system is *actually* acquiring data is not well known. In the \r\n`realtime` mode, the observation time is 100%, so it's clearly established, \r\nbut the bandwidth is limited to 20 Mhz.\r\n\r\nBy stepping the system through frequencies at a low rate (typically > 10 \r\nseconds per frequency), we can achieve a observation time efficiency of nearly \r\n100% / number of observation bands, which allows us to rigidly quantify actual\r\nsignal strength when integrating data over many hours.\r\n\r\nSince the signals we're interested in are astrophysical phenomenon, and we \r\nexpect to *need* many hours or days of integration time to resolve the signals \r\nfrom both the system and physical noise, being able to define precisely the \r\nactual duration each frequency was acquired for is vital.\r\n\r\nThe SignalHound does take some time to re-tune the frontend when stepping \r\nfrequencies (~1 second), which is unfortunate, but the loss here can simply be \r\noffset by integrating at each frequency for a longer period of time.\r\n\r\nUnfortunately, the SignalHound API does not allow re-tuning of the frontend \r\nwhile acquiring in `realtime` mode. Interestingly enough, you *can* call the `configureCenterSpan` function on a running acquisition, and it returns with \r\na \"succeeded\" call status, but appears to do nothing.\r\n\r\n---\r\n\r\nDependencies:\r\n\r\n`SignalHound.py` requires:\r\n - Numpy\r\n - Windows or Linux Python 2.7.* install (cygwin's python install does not\r\n have a functional `ctypes.wintypes`)\r\n\r\n`tests.py` additionally requires:\r\n - `pyaudio` (for the \"radio\" test only)\r\n\r\nThe `SpectraLogger\\main.py` long-term spectra logging tool additionally requires:\r\n - h5py (For writing log files)\r\n - colorama (better console output)\r\n\r\nThe `RealtimeSpectraLogTool\\main.py` also requires:\r\n - wxPython >= 2.9\r\n\r\n---\r\n\r\n\r\n* ----------------------------------------------------------------------------\r\n* \"THE BEER-WARE LICENSE\":\r\n* Connor Wolf wrote this file. As long as you retain\r\n* this notice you can do whatever you want with this stuff. If we meet some day,\r\n* and you think this stuff is worth it, you can buy me a beer in return.\r\n* (Only I don't drink, so a soda will do). Connor\r\n* Also, support the Signal-Hound devs. Their hardware is pretty damn awesome.\r\n* ----------------------------------------------------------------------------", "description_content_type": null, "docs_url": null, "download_url": "https://github.com/fake-name/pySignalHound", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/fake-name/pySignalHound", "keywords": "", "license": "UNKNOWN", "maintainer": "", "maintainer_email": "", "name": "PySignalHound", "package_url": "https://pypi.org/project/PySignalHound/", "platform": "Windows only", "project_url": "https://pypi.org/project/PySignalHound/", "project_urls": { "Download": "https://github.com/fake-name/pySignalHound", "Homepage": "https://github.com/fake-name/pySignalHound" }, "release_url": "https://pypi.org/project/PySignalHound/0.0.2/", "requires_dist": null, "requires_python": null, "summary": "Wrapper for SignalHound spectrum analysers.", "version": "0.0.2" }, "last_serial": 1305016, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "53b6f103850dcb3fb1c326dd35b1f0f7", "sha256": "227350e9dc5482d070552f82d619eb95dc27186f11bd8c150c53946aca102d94" }, "downloads": -1, "filename": "PySignalHound-0.0.1.zip", "has_sig": false, "md5_digest": "53b6f103850dcb3fb1c326dd35b1f0f7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 38794, "upload_time": "2014-11-13T07:30:38", "url": "https://files.pythonhosted.org/packages/ce/67/12d203e1be8601219eda584acb587d244e24e9fac37543c4d2a5b00c8be1/PySignalHound-0.0.1.zip" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "f2d3e20c72fff11256ba4749830805c5", "sha256": "eedca60ad18151c797862a53c2384d36535f8cf43be48a7687f6d61fecd640b0" }, "downloads": -1, "filename": "PySignalHound-0.0.2.zip", "has_sig": false, "md5_digest": "f2d3e20c72fff11256ba4749830805c5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39085, "upload_time": "2014-11-13T07:39:20", "url": "https://files.pythonhosted.org/packages/a2/1a/620bc407ec24960d37c197ec2a355b94731f23009b0f193f08527ee079ae/PySignalHound-0.0.2.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "f2d3e20c72fff11256ba4749830805c5", "sha256": "eedca60ad18151c797862a53c2384d36535f8cf43be48a7687f6d61fecd640b0" }, "downloads": -1, "filename": "PySignalHound-0.0.2.zip", "has_sig": false, "md5_digest": "f2d3e20c72fff11256ba4749830805c5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39085, "upload_time": "2014-11-13T07:39:20", "url": "https://files.pythonhosted.org/packages/a2/1a/620bc407ec24960d37c197ec2a355b94731f23009b0f193f08527ee079ae/PySignalHound-0.0.2.zip" } ] }