{ "info": { "author": "Pawe\u0142 A. Pierzchlewicz", "author_email": "paul@teacode.io", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Topic :: Software Development :: Build Tools" ], "description": "# Saffy\nSignal Analysis Framework For You\n\nA simple signal analysis framework, which aims at clarity of code and reproducibility of solutions. The plugin architecture\naims to encourage building modular code among scientists and data analysts. It provides a basic structure for signal\nstorage and a pipeline for analysis.\n\n## Install\n\n`pip3 install saffy`\n\n###### From Source\nUsing a virtualenv is recommended! \n\nDownload the package to your project directory\n\n`git clone https://github.com/PPierzc/saffy.git`\n\nInstall dependencies\n\n`pip3 install -r ./saffy/requirements.txt`\n\n## Usage\n```python\nimport saffy\nsig = saffy.SignalManager(generator=signal_data)\n```\n\n#### Basic SignalManager instance structure\n| field | description |\n|--------|------|\n| fs | sampling frequency |\n| num_channels | number of channels |\n| channel_names | name for each channel |\n| data | the signal in the structure of (epoch x channel x signal) |\n| t | time vector |\n| epochs | number of epochs |\n| tags | position of tags in signal |\n| spectrum | matrix of spectrum |\n| spectrum_freqs| vector of frequencies |\n| phase | matrix of phase |\n\n#### SignalManager init function\nIt takes one labelled argument: `generator` or `filename`.\n\n###### Generator\nA dictionary of the structure\n```\ndata = {\n 'fs': # float,\n 'num_channels': # integer,\n 'channel_names': # list of strings,\n 'epochs': # integer,\n 't': # time array,\n 'tags': # list,\n 'data': # Signal Matrix\n }\n```\n\n```python\nsaffy.SignalManager(generator=data)\n```\n\n###### Filename\nThe name of the file generated by Svarog. 3 files eg. `data.raw`, `data.xml`, `data.tag`\n\n```python\nsaffy.SignalManager(filename='data')\n```\n\n## Plugins\nPlugins are classes that inherit from the PluginManager. They extend the functionality of the basic Signal Manager.\nSome plugins are provided out of the box\n\n#### Filters\nAdds basic filters\n\n#### Graphics\nAdds functions to display the signal data\n\n#### Welch\nCalculating the Welch Spectrum\n\n#### Hilbert\nCalculating the Hilbert Transform\n\n### Creating Custom Plugins\nYou might want to add some custom features.\n\nThe proposed convention for plugin development is the following.\nAll data that is to be stored extra, should be stored in the form of a dictionary assigned to a variable of the same name\nas the plugin.\n\nPlugin functions should be preceded by the plugin name. \n\n```python\nimport saffy\n\nclass CustomPlugin(saffy.PluginManager):\n def __init__(self, *args, **kwargs):\n super().__init__(*args, **kwargs)\n\n self.custom = {\n 'param': 'some value'\n }\n\n def custom_function(self):\n # do something\n pass\n\nsaffy.SignalManager.register_plugin(CustomPlugin)\n\nsig = saffy.SignalManager(generator=signal_data)\n\nsig.custom_function()\n```\n\n## Example\nA short example of how to use saffy for EEG data analysis.\n\n```python\ndef generate_signal():\n data = {\n 'fs': 512,\n 'num_channels': 3,\n 'channel_names': ['C3', 'C4', 'd1'],\n 'epochs': 1\n }\n\n T = 20\n t = np.arange(0, T, 1 / data['fs'])\n\n mu_freq = 10\n beta_freq = 23\n net_freq = 50\n\n data['data'] = np.zeros((data['epochs'], data['num_channels'], len(t)))\n\n for epoch in range(data['epochs']):\n data['data'][epoch][0] += (0.1 * t + 0.1) * sin(t, mu_freq)\n data['data'][epoch][0] += (0.1 * t + 0.1) * sin(t, beta_freq)\n data['data'][epoch][0] += sin(t, net_freq)\n data['data'][epoch][0] += 0.3 * noise(t)\n\n data['data'][epoch][1] += (0.1 * t + 0.1) * sin(t, mu_freq)\n data['data'][epoch][1] += (0.1 * t + 0.1) * sin(t, beta_freq)\n data['data'][epoch][1] += sin(t, net_freq)\n data['data'][epoch][1] += 0.3 * noise(t)\n\n data['data'][epoch][2][::5*data['fs']] = 1\n data['data'][epoch][2][0] = 0\n\n data['t'] = t\n data['tags'] = []\n\n return data\n\nEEG = saffy.SignalManager(generator=generate_signal())\n\nEEG.set_tags_from_channel('d1')\nEEG.remove_channel('d1')\n\nPRE_EEG = EEG.copy('pre')\nPRE_EEG.set_epochs_from_tags(-4, -2)\n\nPRE_EEG.welch_spectrum()\nPRE_EEG.spectrum = np.mean(PRE_EEG.spectrum, axis=0)\nPRE_EEG.spectrum = np.reshape(PRE_EEG.spectrum, (1, *PRE_EEG.spectrum.shape))\n\nPOST_EEG = EEG.copy('post')\nPOST_EEG.set_epochs_from_tags(0.5, 2.5)\n\nPOST_EEG.welch_spectrum()\nPOST_EEG.spectrum = np.mean(POST_EEG.spectrum, axis=0)\nPOST_EEG.spectrum = np.reshape(POST_EEG.spectrum, (1, *POST_EEG.spectrum.shape))\n\nfig, ax = plt.subplots(\n nrows=max([PRE_EEG.num_channels, POST_EEG.num_channels]),\n ncols=1,\n sharex=True,\n sharey=True,\n figsize=(10, 10)\n)\n\nPRE_EEG.graphics_spectrum_plot(\n fig,\n ax,\n 'Change',\n label='Pre'\n)\n\nPOST_EEG.graphics_spectrum_plot(\n fig,\n ax,\n color='#0000ff',\n label='Post'\n)\n\nfor a in ax:\n a.legend()\n\nplt.show()\nplt.close()\n```\n![alt text](examples/example.png)\n\n## Contributing\nIf you like the project and want to add something to it then please create a pull request.\n- The title should shortly summarize the goal of your addition\n- In the description go in depth with the changes you have made and why.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/PPierzc/saffy", "keywords": "python,signal,analysis,EEG,neuroinformatics", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "saffy", "package_url": "https://pypi.org/project/saffy/", "platform": "", "project_url": "https://pypi.org/project/saffy/", "project_urls": { "Homepage": "https://github.com/PPierzc/saffy" }, "release_url": "https://pypi.org/project/saffy/0.1.12/", "requires_dist": [ "cycler (==0.10.0)", "kiwisolver (==1.0.1)", "matplotlib (==3.0.3)", "mne (==0.17.1)", "numpy (==1.16.2)", "obci-readmanager (==1.1.3)", "pandas (==0.24.2)", "pyparsing (==2.3.1)", "python-dateutil (==2.8.0)", "pytz (==2018.9)", "scipy (==1.2.1)", "seaborn (==0.9.0)", "six (==1.12.0)" ], "requires_python": "", "summary": "Signal Analysis Framework For You", "version": "0.1.12" }, "last_serial": 5086649, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "4a14bd7d83df1dcd80c75c91df53381b", "sha256": "720514f8079046b251b2977313316e13b22bd83fb69af849779f53d84d4606e7" }, "downloads": -1, "filename": "Saffy-0.1.tar.gz", "has_sig": false, "md5_digest": "4a14bd7d83df1dcd80c75c91df53381b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5238, "upload_time": "2019-03-24T17:25:36", "url": "https://files.pythonhosted.org/packages/10/d8/aefac9fdbd0336d5a5d303ef45c9e7e6751455f89cac506c601ced1447bb/Saffy-0.1.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "0a2d91f02fd945d093c4ca5c8839eced", "sha256": "adfc1bfdf1bc1b1fd3a4b70143c7dd6a6141956ad0da564e4e43949fd7141365" }, "downloads": -1, "filename": "saffy-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "0a2d91f02fd945d093c4ca5c8839eced", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 10579, "upload_time": "2019-03-27T13:25:27", "url": "https://files.pythonhosted.org/packages/07/fa/986d4bea4c5b2f580475278dfc106b10aa19ab218ce34caa70f8838cc6e5/saffy-0.1.1-py3-none-any.whl" } ], "0.1.10": [ { "comment_text": "", "digests": { "md5": "8eba28abb712f1dc1a57d41c532ad727", "sha256": "2b328132d7b635027d2d252acb3bb61cb1a215513737a4eb5bd8f0002c8295a3" }, "downloads": -1, "filename": "saffy-0.1.10-py3-none-any.whl", "has_sig": false, "md5_digest": "8eba28abb712f1dc1a57d41c532ad727", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 14813, "upload_time": "2019-03-27T13:28:51", "url": "https://files.pythonhosted.org/packages/f9/f1/d1a3d9f471af2233adac4cfb9c6ec409190f05e9f861faecb929190d3b64/saffy-0.1.10-py3-none-any.whl" } ], "0.1.11": [ { "comment_text": "", "digests": { "md5": "3c350cfa903eaf67c018651a820c4a05", "sha256": "c81f3b0d704e4c4b3f43b699977c5bc84b991b5b0bedefbad8f44a2ea21f4128" }, "downloads": -1, "filename": "saffy-0.1.11-py3-none-any.whl", "has_sig": false, "md5_digest": "3c350cfa903eaf67c018651a820c4a05", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 10856, "upload_time": "2019-03-27T13:57:31", "url": "https://files.pythonhosted.org/packages/43/16/04949d5fd97c21d49886bc832389852e23252db88600709d06bbf4a1a181/saffy-0.1.11-py3-none-any.whl" } ], "0.1.12": [ { "comment_text": "", "digests": { "md5": "3dfe240de2f4fb63deef314c1296f459", "sha256": "379fda5ff2f1486d6865065b2cba2d4d9840d291c5f67c55b91f7a6e011a6429" }, "downloads": -1, "filename": "saffy-0.1.12-py3-none-any.whl", "has_sig": false, "md5_digest": "3dfe240de2f4fb63deef314c1296f459", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11091, "upload_time": "2019-03-31T15:31:20", "url": "https://files.pythonhosted.org/packages/32/3b/20c68c9fcfd5a73dc34b125c7c8aca65175b10460ae9c7bbf44cb05e1d7c/saffy-0.1.12-py3-none-any.whl" } ], "0.1.12.dev0": [ { "comment_text": "", "digests": { "md5": "3f61d356e82358952b91d84e2bc0440b", "sha256": "afa7e9d0ed346a4191b4efb7e1efc50f37a93d65be023d665c90996bfc55fdbd" }, "downloads": -1, "filename": "saffy-0.1.12.dev0-py3-none-any.whl", "has_sig": false, "md5_digest": "3f61d356e82358952b91d84e2bc0440b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11452, "upload_time": "2019-04-02T11:25:16", "url": "https://files.pythonhosted.org/packages/68/04/a44bbbe89779cca74b6faf467712b908e6f80ca4a929e4ddddb5c1a4b924/saffy-0.1.12.dev0-py3-none-any.whl" } ], "0.1.12.dev1": [ { "comment_text": "", "digests": { "md5": "26d623dfcf9030e1a7b3d112dcac524e", "sha256": "3348b465798de3ff902df2e9e066a64d4fb6459fac97dc426f78142cfc88b527" }, "downloads": -1, "filename": "saffy-0.1.12.dev1-py3-none-any.whl", "has_sig": false, "md5_digest": "26d623dfcf9030e1a7b3d112dcac524e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11583, "upload_time": "2019-04-03T07:44:39", "url": "https://files.pythonhosted.org/packages/9c/f7/e4e3bca5f9feafa6fd26db811b4c76d9a6ad43240a7b1aeb2568dd100185/saffy-0.1.12.dev1-py3-none-any.whl" } ], "0.1.8": [ { "comment_text": "", "digests": { "md5": "0668a73f8524d3103db792f8b9b95cf1", "sha256": "51cabf0856c6f916588527f00837ac9446abf74db1733a1b15c6db8b40dd91ed" }, "downloads": -1, "filename": "Saffy-0.1.8-py3-none-any.whl", "has_sig": false, "md5_digest": "0668a73f8524d3103db792f8b9b95cf1", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12560, "upload_time": "2019-03-24T19:11:36", "url": "https://files.pythonhosted.org/packages/5a/1f/d3c3f3d55b44a68a65e45377d904174996106f3d029f8909f97e0080bdaf/Saffy-0.1.8-py3-none-any.whl" } ], "0.1.9": [ { "comment_text": "", "digests": { "md5": "953eef5a301b832694810856891bd59c", "sha256": "68934f4682f71ccd4676e02468156da55d14d7ebf26a4afe76e70982c91fb504" }, "downloads": -1, "filename": "saffy-0.1.9-py3-none-any.whl", "has_sig": false, "md5_digest": "953eef5a301b832694810856891bd59c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12696, "upload_time": "2019-03-25T08:13:53", "url": "https://files.pythonhosted.org/packages/87/ed/bf5d9272ecb176095c693ad62988a23380febed380fef44a74d14454936a/saffy-0.1.9-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "519442c0ad7ae4619763701a41c09807", "sha256": "cd77cee84c7e4295b18a450a276ce90d01d2d4999023c658414c60d1af62be87" }, "downloads": -1, "filename": "Saffy-0.1.9-py3-none-any.whl", "has_sig": false, "md5_digest": "519442c0ad7ae4619763701a41c09807", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12690, "upload_time": "2019-03-24T22:03:21", "url": "https://files.pythonhosted.org/packages/db/01/a3608dabde8c50896221907635f74fe1e600c23dd1e6bb9b32dcee1888c7/Saffy-0.1.9-py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3dfe240de2f4fb63deef314c1296f459", "sha256": "379fda5ff2f1486d6865065b2cba2d4d9840d291c5f67c55b91f7a6e011a6429" }, "downloads": -1, "filename": "saffy-0.1.12-py3-none-any.whl", "has_sig": false, "md5_digest": "3dfe240de2f4fb63deef314c1296f459", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11091, "upload_time": "2019-03-31T15:31:20", "url": "https://files.pythonhosted.org/packages/32/3b/20c68c9fcfd5a73dc34b125c7c8aca65175b10460ae9c7bbf44cb05e1d7c/saffy-0.1.12-py3-none-any.whl" } ] }