{ "info": { "author": "Ben Acland", "author_email": "benacland@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 2 - Pre-Alpha", "Intended Audience :: Science/Research", "License :: OSI Approved :: BSD License", "Topic :: Scientific/Engineering :: Information Analysis" ], "description": "cili\n====\n\nCili is meant to reduce the overhead of basic eyetracking data\nprocessing. While it sets the stage for more advanced work by providing\ndata in the form of pandas DataFrames, manipulating the contents of\nthose DataFrames works like manipulating any other pandas DataFrame, so\nthat's where cili stops - we leave it to the user to learn to work with\npandas. If you're going to be dealing with eyetracking data in python,\nyou'll be glad you did.\n\nAt the moment, we support EyeLink data only. We'd be happy to support\nother manufacturers, but don't have the data on hand to do so. If you\nhave the data, and would like us to support something in particular,\nplease drop us a message at https://github.com/beOn/cili/issues, or add\nit yourself and submit a pull request.\n\nPlease note that this is an alpha release.\n\nInstallation\n============\n\nBefore installing cili, you'll need to install numpy. The rest of the\ndependencies should install when you install cili, but numpy is special.\nThen you can install cili using pip or easy\\_install:\n\n::\n\n pip install numpy\n pip install cili\n\nOr grab the latest development version from\nhttps://github.com/beOn/cili, and install using setup.py.\n\nExamples\n========\n\nParsing EyeLink Data\n--------------------\n\nCili can parse samples and events from EyeLink .asc files, and samples\nfrom EyeLink Experiment Builder .txt files. You can use the same method\nfor both, but need to ignore the second returned value if you're using a\n.txt.\n\n.. code:: python\n\n from cili.util import *\n # using .asc\n samps, events = load_eyelink_dataset(\"/some/file.asc\")\n # using .txt\n samps, _ = load_eyelink_dataset(\"/some/file.txt\")\n\nHandling Blinks and Missing Data\n--------------------------------\n\nTry as we might to recruit cooperative subjects, chances are your data\nis full of blinks; try as we might to set up the eyetracker correctly,\nchances are there's some signal dropout. Cili provides a couple of\nconvenient methods for deriving values missing for either of these\nreasons using linear interpolation.\n\nHandling blinks in EyeLink data doesn't seem to tricky at first blush,\nbut there are a couple of subtleties and related options to be aware of.\n\nFirst, EyeLink embeds every blink event within a saccade, and recommends\nthat if you plan to scrub out blinks, you should also scrub out saccades\ncontaining blinks. Cili does this automatically when you call\nmask\\_eyelink\\_blinks().\n\nSecond, EyeLink's blink marking algorithm is a little too aggressive for\nmy taste when it comes to declaring a blink's end time. Even when we\ninterpolate over the containing saccade, the reported pupil size for\nseveral dozen milliseconds after the interpolated range often contains\nabsurdly low values, with an absurdly high slope. This can add a lot of\nnoise to your data, and I can't imagine anyone arguing that these values\nhave any bearing on the eye's real state. So cili will optionally creep\nthe blink recovery time forward by looking for the first point within\n1000ms where the 100-sample rolling average of the z-scored derivative\nof the pupil timecourse drops to within .1 of the entire timecourse's\naverage. This method has worked pretty well for us, but there's still\nroom for improvement.\n\nAll non-blink signal dropout will be recorded as 0s. We don't make any\nadjustments to the dropout onset/offset times, but otherwise these\nvalues get handled in much the same way as blinks. But you should always\nclean dropout after cleaning blinks, otherwise the blink recovery index\nmethod described above won't work.\n\nSo, let's roll up our sleeves and clean some data!\n\n.. code:: python\n\n from cili.util import *\n from cili.cleanup import *\n samps, events = load_eyelink_dataset(\"/some/file.asc\")\n samps = interp_eyelink_blinks(samps, events, interp_fields=[\"pup_l\"])\n samps = interp_zeros(samps, interp_fields=[\"pup_l\"])\n\nWell that was kindof anticlimactic.\n\nNote that if you collect the right pupil, \"pup\\_l\" should be changed to\n\"pup\\_r\", and if you collect both eyes, you'll want to include both\npup\\_l and pup\\_r in interp\\_fields. EyeLink's Experiment Builder calls\nthe same values \"right\\_pupil\\_size\" and \"left\\_pupil\\_size\" in the .txt\nfiles it generates, so if your samples came from a Experiment Builder\n.txt, use those names instead.\n\nCheck the documentation on these methods FMI.\n\nSmoothing Data\n--------------\n\nIf you look closely at EyeLink data, you'll probably notice a little\nhigh frequency noise. This can be a little problematic in several\ncircumstances. To deal with it, cili provides a butterworth filter\nfunction with default settings based on previously published\npupillometry studies. You can modify the order and cutoff frequency of\nthe filter if you like, but the basic usage looks like this:\n\n.. code:: python\n\n samps = butterworth_series(samps, fields=[\"pup_l\"])\n\nFMI, check out the documentation on butterworth\\_series.\n\nEvents from a List of Dicts\n---------------------------\n\nSometimes you are interested in events recorded using something other\nthan EyeLink software. For those crazy times, if you can turn that data\ninto a list of dicts, each containing a name, onset and duration, then\nit's pretty easy to create a cili Events object. Assuming you already\nhave your list of dicts, and that it's called ``list_o_dicts``, then all\nyou do is:\n\n.. code:: python\n\n from cili.models import Events\n events = Events.from_list_of_dicts(list_o_dicts)\n\nExtracting Event-based Ranges\n-----------------------------\n\nTo my mind, this is where things start to get interesting. In many eye\ntracking and pupillometry studies, the goal is to examine a collection\nof sample ranges surrounding certain events. So cili provides a method\nfor extracting sample ranges based on event timing, returning a\nDataFrame with a MultiIndex (event #, sample #).\n\nSuppose you were interested in the 10 seconds following every event in\nsome Events object, called \"events,\" and you have a 1kHz Samples object,\nsamps. To extract this range for every event in events, you would:\n\n.. code:: python\n\n from cili.extract import extract_event_ranges\n ranges = extract_event_ranges(samps, events, end_offset=10000)\n\nOften, pupillometric sample ranges will be transformed into a %\ndeviation from baseline measure, where the baseline is an average of\nsome small range immediately preceding the range of interest. Continuing\nthe example above, let's extract baseline measures for each of the\nevents, then divide the ranges of interest by the baselines for the\nfield \"pup\\_r\":\n\n.. code:: python\n\n baselines = extract_event_ranges(samps, events, start_offset=-100, end_offset=-1).mean(level=0)\n ranges.pup_r = (ranges.pup_r / baselines.pup_r - 1).values\n\nNot so painful! For more info on range extraction, check out the\ndocumentation on extract\\_event\\_ranges. To work with the returned data\neffectively, You'll probably also want to take a minute to learn about\npandas MultiIndex objects.\n\nBorrowing Event Attributes\n--------------------------\n\nIf your events each have a field, let's say \"subject\", and you'd like to\ninsert each event's value for that field into every row of the\ncorrisponding range under a column of the same name, you can \"borrow\"\nevent attributes using borrow\\_attributes, like so:\n\n.. code:: python\n\n ranges = extract_event_ranges(samps, events, end_offset=10000, borrow_attributes=[\"subject\"])\n\nSaving and Loading\n------------------\n\nIf you keep reading and writing large .txt files, you'll die young. Or\nat least having spent too much of your time waiting for .txt files to be\nread or written. So cili uses hdf5 to speed things up. To use this,\nyou'll need to install h5py and its dependencies, as documented at\nhttp://docs.h5py.org/en/latest/build.html.\n\nOnce that's done, saving and loading Samples and Events objects is\npretty easy. It works the same way in both cases, so we'll just work\nwith samples below:\n\n.. code:: python\n\n from cili.models import Samples\n samps.save(\"some_filename.hdf\")\n samps_2 = Samples.load_saved(\"some_filename.hdf\")\n\nExporting to .txt\n-----------------\n\nIf you have to export samples or extracted ranges to a .txt file, fine.\nOk. We understand.\n\nLuckily, pandas datasets already include a function for writing csv\nfiles, any several other formats as well (check their documentation for\nthe complete list: http://pandas.pydata.org/pandas-docs/stable/io.html).\nFor example, to create a tab delimited .txt file:\n\n.. code:: python\n\n samps.to_csv(\"some_filename.txt\", sep=\"\\t\")\n\nTo create a Zamboni delimited .txt file, just set sep to \"Zamboni\".\n\nChecking For Signal Dropout\n---------------------------\n\nSometimes, for one reason or another, eyetracking sessions can go pretty\npoorly. Usually, this means that there's a high level of signal dropout\ndue to blinks, or the tracker losing track of the eye. One way to check\nfor this is to see what percentage of the timeline's pupil value(s) were\nrecorded as 0. Cili's util.py offers a convenient way to check the\ndropout rate for all of the .asc files in a directory, like so:\n\n.. code:: python\n\n util.py --dropout -d /path/to/dir/containing/ascf_iles/\n\nReporting Bugs, Requesting Features\n===================================\n\nSubmit all bug reports and feature requests using the github ticketing\nsystem: https://github.com/beOn/cili/issues\n\nPlease make an effort to provide high quality bug reports. If we get one\nthat just says, \"sample range extraction is broken,\" we'll probably\ntrash it without a second look, because the submitter is probably the\nkind of person who saps energy from everything they touch.\n\nA good bug report should include three things:\n\n1. Steps to reproduce the bug\n2. Expected result\n3. Actual result\n\nThe goal is to give the developers the ability to recreate the bug\nbefore their own eyes. If you can give us that, we'll take a very close\nlook.\n\nWhy Cili?\n=========\n\nBecause, like the mighty ciliary muscles, it brings your eye data into\nfocus.\n\nTODO: Thanks, credit to CCP Lab", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/beOn/cili", "keywords": "eyetracking pupillometry eyelink", "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "cili", "package_url": "https://pypi.org/project/cili/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/cili/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/beOn/cili" }, "release_url": "https://pypi.org/project/cili/0.5.3/", "requires_dist": null, "requires_python": null, "summary": "Eyetracking data tools based on pandas", "version": "0.5.3" }, "last_serial": 1120986, "releases": { "0.5.0": [ { "comment_text": "", "digests": { "md5": "5a576ad2064d8d7794d2fee9b423e2d7", "sha256": "06325d7abb5e81ebc4b2f313406a83882cc4d4db92d06a1d430aed3c16bdf7b6" }, "downloads": -1, "filename": "cili-0.5.0-py2.7.egg", "has_sig": true, "md5_digest": "5a576ad2064d8d7794d2fee9b423e2d7", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 36277, "upload_time": "2014-04-30T18:33:21", "url": "https://files.pythonhosted.org/packages/d8/65/20b19c9a7dde88c796903c2ec6bc5820b0776083f36e06293b410b142176/cili-0.5.0-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "34e050be1bc7b092c9de1a9b0821b0e6", "sha256": "e42fc27c3d3a219b1885b60fe8ac093a61db394ced4db91badd6c7b4e7194356" }, "downloads": -1, "filename": "cili-0.5.0.tar.gz", "has_sig": true, "md5_digest": "34e050be1bc7b092c9de1a9b0821b0e6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17803, "upload_time": "2014-04-30T18:33:32", "url": "https://files.pythonhosted.org/packages/34/a0/421288a5b5f9f11feca22b3465d760e3c6b95ca00f720de9e29acb002dd7/cili-0.5.0.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "63d0919707e0b11bc2315b916e9908a5", "sha256": "a11d96074585e16db81cc5f32e7c15a3c5be6953e82790cf9816fb68b2936b52" }, "downloads": -1, "filename": "cili-0.5.1-py2.7.egg", "has_sig": true, "md5_digest": "63d0919707e0b11bc2315b916e9908a5", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 23750, "upload_time": "2014-05-07T18:20:47", "url": "https://files.pythonhosted.org/packages/ba/7c/d0ef4ed63c8fbe748756380a9ba7836f4ac610d79e7399642ee7351f7576/cili-0.5.1-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "3e8bdb3f75119cb55ce873eccac5fe98", "sha256": "10c4700db5e4694ea80d1eec2b65dda92e6b13c1009beaf6be9c8eaa8fceed3c" }, "downloads": -1, "filename": "cili-0.5.1.tar.gz", "has_sig": true, "md5_digest": "3e8bdb3f75119cb55ce873eccac5fe98", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13499, "upload_time": "2014-05-07T18:21:01", "url": "https://files.pythonhosted.org/packages/02/47/14410d7760e58ea1b7ae63aa4f9911983bafd13158f2f44ddec5908ca84f/cili-0.5.1.tar.gz" } ], "0.5.2": [ { "comment_text": "", "digests": { "md5": "8a88c0cc183a8a7df79e08cacb5a968a", "sha256": "d10e7c60efbc9b272cae38f8612c50d8caf3ef33a01482d0da9882004885c196" }, "downloads": -1, "filename": "cili-0.5.2-py2.7.egg", "has_sig": true, "md5_digest": "8a88c0cc183a8a7df79e08cacb5a968a", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 15814, "upload_time": "2014-05-15T01:49:12", "url": "https://files.pythonhosted.org/packages/be/61/ad4052210271e55fce184099b2cf2421a23cd4ebfc59f361c0864c6c2efd/cili-0.5.2-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "41940d0113fdb19a2235a4c7674955c4", "sha256": "ec5f076171aa0ed86216b185fece0bd162b10b20efdb547a506fb633121ead1e" }, "downloads": -1, "filename": "cili-0.5.2-py2-none-any.whl", "has_sig": true, "md5_digest": "41940d0113fdb19a2235a4c7674955c4", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 20582, "upload_time": "2014-05-15T01:49:09", "url": "https://files.pythonhosted.org/packages/92/39/204bacee14bc852a11e358a46e7a7e8367b7b831e234cade30ccb72848a0/cili-0.5.2-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "53c1e263175a4bf67611b2de94064b0c", "sha256": "73bbd7ec81687c673ad495d6bb8edd8895732895ca1f5e6ea83d583fcfa3883f" }, "downloads": -1, "filename": "cili-0.5.2.tar.gz", "has_sig": true, "md5_digest": "53c1e263175a4bf67611b2de94064b0c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14481, "upload_time": "2014-05-15T01:49:06", "url": "https://files.pythonhosted.org/packages/b4/9d/ce17bc47db8553b20bd37c44a4cc234f59cfcc656fa23f9733c6ca63b716/cili-0.5.2.tar.gz" } ], "0.5.3": [ { "comment_text": "", "digests": { "md5": "d2c44c351978aae8667c00e0d819831a", "sha256": "1e8e101aeb7ed35ce595ff87f26c40f19be5eb8ef5613b21e82821143b545c1f" }, "downloads": -1, "filename": "cili-0.5.3-py2.7.egg", "has_sig": true, "md5_digest": "d2c44c351978aae8667c00e0d819831a", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 32522, "upload_time": "2014-06-11T00:16:43", "url": "https://files.pythonhosted.org/packages/40/3c/763cb72d8c6492b0a55863397bc18de1edeeae6bf345b4a7593a33de674d/cili-0.5.3-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "4f055d96ea9c3bdbf1a30c7162fd10ef", "sha256": "b92fecb865fe5da0d0fd10cab7f29068459392d712c5b721f7b9297a8369e9a3" }, "downloads": -1, "filename": "cili-0.5.3-py2-none-any.whl", "has_sig": true, "md5_digest": "4f055d96ea9c3bdbf1a30c7162fd10ef", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 21974, "upload_time": "2014-06-11T00:16:46", "url": "https://files.pythonhosted.org/packages/cf/8b/95a72358093f73c247f4b62724295a99eb8a385fd95aa24de2467b29251c/cili-0.5.3-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a7145f63c2bc4a0baf4eb3d8b7c0e58d", "sha256": "0c5d0a7e809416ecd1efee47f1a62416cfc8b57a0e96f127f6be51136a4550d5" }, "downloads": -1, "filename": "cili-0.5.3.tar.gz", "has_sig": true, "md5_digest": "a7145f63c2bc4a0baf4eb3d8b7c0e58d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15656, "upload_time": "2014-06-11T00:16:40", "url": "https://files.pythonhosted.org/packages/5b/c3/c256867b66e996c973df1217b823356b85b0e8ecdd0d0f9f31f7e3a596b1/cili-0.5.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d2c44c351978aae8667c00e0d819831a", "sha256": "1e8e101aeb7ed35ce595ff87f26c40f19be5eb8ef5613b21e82821143b545c1f" }, "downloads": -1, "filename": "cili-0.5.3-py2.7.egg", "has_sig": true, "md5_digest": "d2c44c351978aae8667c00e0d819831a", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 32522, "upload_time": "2014-06-11T00:16:43", "url": "https://files.pythonhosted.org/packages/40/3c/763cb72d8c6492b0a55863397bc18de1edeeae6bf345b4a7593a33de674d/cili-0.5.3-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "4f055d96ea9c3bdbf1a30c7162fd10ef", "sha256": "b92fecb865fe5da0d0fd10cab7f29068459392d712c5b721f7b9297a8369e9a3" }, "downloads": -1, "filename": "cili-0.5.3-py2-none-any.whl", "has_sig": true, "md5_digest": "4f055d96ea9c3bdbf1a30c7162fd10ef", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 21974, "upload_time": "2014-06-11T00:16:46", "url": "https://files.pythonhosted.org/packages/cf/8b/95a72358093f73c247f4b62724295a99eb8a385fd95aa24de2467b29251c/cili-0.5.3-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a7145f63c2bc4a0baf4eb3d8b7c0e58d", "sha256": "0c5d0a7e809416ecd1efee47f1a62416cfc8b57a0e96f127f6be51136a4550d5" }, "downloads": -1, "filename": "cili-0.5.3.tar.gz", "has_sig": true, "md5_digest": "a7145f63c2bc4a0baf4eb3d8b7c0e58d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15656, "upload_time": "2014-06-11T00:16:40", "url": "https://files.pythonhosted.org/packages/5b/c3/c256867b66e996c973df1217b823356b85b0e8ecdd0d0f9f31f7e3a596b1/cili-0.5.3.tar.gz" } ] }