{ "cells": [ { "cell_type": "markdown", "metadata": { "collapsed": true, "pycharm": { "name": "#%% md\n" } }, "source": [ "# Useful Alyx REST queries\n", "Examples of using ONE to query Alyx via Django REST queries.\n", "\n", "Alyx queries require and internet connection and are slower than the local cache queries using\n", "one.search, however it is much more powerful. Searching for datasets or sessions based solely on\n", "the fields in `one.search_terms` should be done using one.search. This script demonstrates some\n", "of the more complex queries that must be done remotely." ] }, { "cell_type": "code", "execution_count": 1, "outputs": [], "source": [ "from pprint import pprint\n", "from one.api import ONE, OneAlyx\n", "\n", "one = ONE(base_url='https://openalyx.internationalbrainlab.org')\n", "assert isinstance(one, OneAlyx) and not one.offline" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" }, "ExecuteTime": { "end_time": "2023-08-31T12:49:40.857578Z", "start_time": "2023-08-31T12:49:35.057036600Z" } } }, { "cell_type": "markdown", "source": [ "## Exploring the REST endpoints\n", "Full documentation of using Alyx REST interface can be found at\n", "https://openalyx.internationalbrainlab.org/docs\n", "\n", "This URL is itself a REST endpoint, so you can list the endpoints through ONE:" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 2, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['brain-regions', 'cache', 'cache.zip', 'channels', 'chronic-insertions', 'data-formats', 'data-repository', 'data-repository-type', 'dataset-types', 'datasets', 'downloads', 'fields-of-view', 'files', 'fov-location', 'imaging-stack', 'insertions', 'labs', 'locations', 'new-download', 'notes', 'procedures', 'projects', 'register-file', 'revisions', 'sessions', 'subjects', 'surgeries', 'sync-file-status', 'tags', 'tasks', 'trajectories', 'uploaded', 'users', 'water-administrations', 'water-requirement', 'water-restricted-subjects', 'water-restriction', 'water-type', 'weighings']\n" ] } ], "source": [ "print(one.alyx.list_endpoints()) # Can also be done with `one.alyx.rest()`" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" }, "ExecuteTime": { "end_time": "2023-08-31T12:49:40.931142500Z", "start_time": "2023-08-31T12:49:40.860571700Z" } } }, { "cell_type": "markdown", "source": [ "The main GET requests are 'list' and 'read'. The parameters for each are described in the\n", "`rest_schemas` property. For example, for the parameters available for listing sessions..." ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": 3, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "**FILTERS**\n", "\n", "- **subject**: subject nickname `/sessions?subject=Algernon`\n", "- **dataset_types**: dataset type(s) `/sessions?dataset_types=trials.table,camera.times`\n", "- **datasets**: dataset name(s) `/sessions?datasets=_ibl_leftCamera.times.npy`\n", "- **number**: session number\n", "- **users**: experimenters (exact)\n", "- **date_range**: date `/sessions?date_range=2020-01-12,2020-01-16`\n", "- **lab**: lab name (exact)\n", "- **task_protocol** (icontains)\n", "- **location**: location name (icontains)\n", "- **project**: project name (icontains)\n", "- **json**: queries on json fields, for example here `tutu`\n", " - exact/equal lookup: `/sessions?extended_qc=tutu,True`,\n", " - gte lookup: `/sessions/?extended_qc=tutu__gte,0.5`,\n", "- **extended_qc** queries on json fields, for example here `qc_bool` and `qc_pct`,\n", " values and fields come by pairs, using semi-colon as a separator\n", " - exact/equal lookup: `/sessions?extended_qc=qc_bool;True`,\n", " - gte lookup: `/sessions/?extended_qc=qc_pct__gte;0.5`,\n", " - chained lookups: `/sessions/?extended_qc=qc_pct__gte;0.5;qc_bool;True`,\n", "- **performance_gte**, **performance_lte**: percentage of successful trials gte/lte\n", "- **brain_region**: returns a session if any channel name icontains the value:\n", " `/sessions?brain_region=visual cortex`\n", "- **atlas_acronym**: returns a session if any of its channels name exactly matches the value\n", " `/sessions?atlas_acronym=SSp-m4`, cf Allen CCFv2017\n", "- **atlas_id**: returns a session if any of its channels id matches the provided value:\n", " `/sessions?atlas_id=950`, cf Allen CCFv2017\n", "- **qc**: returns sessions for which the qc statuses matches provided string. Should be\n", "one of CRITICAL, ERROR, WARNING, NOT_SET, PASS\n", " `/sessions?qc=CRITICAL`\n", "- **histology**: returns sessions for which the subject has an histology session:\n", " `/sessions?histology=True`\n", "- **django**: generic filter allowing lookups (same syntax as json filter)\n", " `/sessions?django=project__name__icontains,matlab\n", " filters sessions that have matlab in the project name\n", " `/sessions?django=~project__name__icontains,matlab\n", " does the exclusive set: filters sessions that do not have matlab in the project name\n", "\n", "[===> session model reference](/admin/doc/models/actions.session)\n" ] } ], "source": [ "print(one.alyx.rest_schemes['sessions']['list']['description'])" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" }, "ExecuteTime": { "end_time": "2023-08-31T12:49:40.943108800Z", "start_time": "2023-08-31T12:49:40.893998Z" } } }, { "cell_type": "markdown", "source": [ "This information is also available using the `print_endpoint_info` method, which prints the REST\n", "params and their respective data types:" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "execution_count": 4, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "'list'\n", "\t\"atlas_acronym\": string, \n", "\t\"atlas_id\": number, \n", "\t\"atlas_name\": string, \n", "\t\"auto_datetime\": string, \n", "\t\"dataset_types\": string, \n", "\t\"datasets\": string, \n", "\t\"date_range\": string, \n", "\t\"django\": string, \n", "\t\"end_time\": string, \n", "\t\"extended_qc\": string, \n", "\t\"histology\": string, \n", "\t\"id\": string, \n", "\t\"json\": string, \n", "\t\"lab\": string, \n", "\t\"limit\": integer, Number of results to return per page.\n", "\t\"location\": string, \n", "\t\"n_correct_trials\": number, \n", "\t\"n_trials\": number, \n", "\t\"name\": string, \n", "\t\"narrative\": string, \n", "\t\"nickname\": string, \n", "\t\"number\": number, \n", "\t\"offset\": integer, The initial index from which to return the results.\n", "\t\"parent_session\": string, \n", "\t\"performance_gte\": number, \n", "\t\"performance_lte\": number, \n", "\t\"procedures\": string, \n", "\t\"project\": string, \n", "\t\"projects\": string, \n", "\t\"qc\": string, \n", "\t\"start_time\": string, \n", "\t\"subject\": string, \n", "\t\"tag\": string, \n", "\t\"task_protocol\": string, \n", "\t\"type\": string, \n", "\t\"users\": string, \n" ] } ], "source": [ "one.alyx.print_endpoint_info('sessions', action='list');" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" }, "ExecuteTime": { "end_time": "2023-08-31T12:49:41.015805400Z", "start_time": "2023-08-31T12:49:40.943108800Z" } } }, { "cell_type": "markdown", "source": [ "## Example queries\n", "### convert session dicts to eids\n", "The output of the below queries can be easily converted to eID strings with the following line:\n", "```python\n", "eids = one.to_eid(ses)\n", "```\n", "\n", "### list sessions that have histology available\n", "```python\n", "# The sessions endpoint has a `histology` parameter:\n", "ses = one.alyx.rest('sessions', 'list', histology=True)\n", "\n", "# The generic way is to use the `django` parameter:\n", "ses = one.alyx.rest('sessions', 'list',\n", " django='subject__actions_sessions__procedures__name,Histology')\n", "```\n", "\n", "### list experiments spanning channel locations\n", "By default the channels are assigned to the regions ID available in the Allen Institute brain atlas volume.\n", "Users may want to query higher level regions, so the query will return all insertions or sessions that have at least one channel in the brain region or in one of its descendants.\n", "For example a query in Somatomotor areas would get all the leaf nodes belonging to that region and encompass somatomotor layers and primary and secondary motor areas.\n", "\n", "The table of brain regions as per the Allen Atlas is available [on alyx](https://openalyx.internationalbrainlab.org/admin/experiments/brainregion/)\n", "\n", "For sessions:\n", "```python\n", "ses = one.alyx.rest('sessions', 'list', atlas_id=500)\n", "ses = one.alyx.rest('sessions', 'list', atlas_acronym=\"MO\")\n", "ses = one.alyx.rest('sessions', 'list', atlas_name=\"Somatomotor areas\")\n", "```\n", "\n", "For insertions:\n", "```python\n", "insertions = one.alyx.rest('insertions', 'list', atlas_id=500)\n", "insertions = one.alyx.rest('insertions', 'list', atlas_acronym=\"MO\")\n", "insertions = one.alyx.rest('insertions', 'list', atlas_name=\"Somatomotor areas\")\n", "```\n", "\n", "\n", "### list sessions that do not have matlab in the project name\n", "```python\n", "ses = one.alyx.rest('sessions', 'list', django='~projects__name__icontains,matlab')\n", "```\n", "\n", "### list insertions that have alignment resolved\n", "```python\n", "ins = one.alyx.rest('insertions', 'list', django='json__extended_qc__alignment_resolved,True')\n", "```\n", "\n", "### list names of users who have aligned specified insertion\n", "```python\n", "insertion_uuid = 'b749446c-18e3-4987-820a-50649ab0f826'\n", "traj = one.alyx.rest('trajectories', 'list',\n", " provenance='Ephys aligned histology track',\n", " probe_insertion=insertion_uuid)\n", "names = traj[0]['json'].keys()\n", "```\n", "\n", "### list probe insertions for a given task protocol\n", "```python\n", "ins = one.alyx.rest('insertions', 'list', django='session__task_protocol__icontains,choiceworld')\n", "```\n", "\n", "### list spiken sorting tasks that have errored in a given lab\n", "```python\n", "errored = one.alyx.rest('tasks', 'list', status='Errored', lab='angelakilab', name='SpikeSorting')\n", "```\n", "\n", "### list ephys sessions that have errored tasks\n", "```python\n", "ses = one.alyx.rest('sessions', 'list', task_protocol='ephys', django='tasks__status,40')\n", "```\n", "\n", "### rerun / set errored tasks to Waiting\n", "```python\n", "# List tasks with given status\n", "tasks = one.alyx.rest('tasks', 'list', name='EphysDLC', status='Errored')\n", "\n", "# OR tasks with specific log error message\n", "tasks = one.alyx.rest('tasks', 'list', name='EphysDLC',\n", " django=\"log__icontains,TimeoutError: [Errno 110]\")\n", "# Set tasks to Waiting so they get rerun\n", "for t in tasks:\n", " one.alyx.rest('tasks', 'partial_update', id=t['id'], data={'log': \"\", 'status': 'Waiting'})\n", "```\n", "\n", "### list sessions where extended QC exists for any video\n", "```python\n", "keys = ('videoLeft', 'videoRight', 'videoBody')\n", "one.alyx.rest('sessions', 'list', django=f'extended_qc__has_any_keys,{keys}')\n", "```\n", "\n", "### list sessions associated with a given release tag\n", "```python\n", "tag = '2021_Q1_IBL_et_al_Behaviour'\n", "one.alyx.rest('sessions', 'list', django=f'data_dataset_session_related__tags__name,{tag}')\n", "```" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "markdown", "source": [ "## Field lookup reference\n", "With the `django` parameter you can write custom filters. The syntax is `'field1__lookup,query,\n", "field2__lookup,query'` (the field and lookup query are separated by two underscores). For example\n", "`'nickname__icontains,ks,death_date__isnull,True'`. Multiple lookups are separated by commas,\n", "forming a logical AND (it is not possible to construct OR queries, instead make separate queries).\n", "\n", "The lookups translate to a [SQL WHERE clause](https://www.w3schools.com/SQl/sql_where.asp).\n", "\n", "### Related field lookups\n", "Some fields are actually related tables, whose fields can also used in the filter. For example,\n", "the `subject` field of the `sessions` table contains all the subject table fields. Lookups can\n", "be applied to these fields in the same way: `field__subfield__lookup,query` e.g.\n", "`sessions__subject__nickname__icontains,dop` ('find sessions where the subject's name contains\n", "\"dop\"').\n", "\n", "See the django [QuerySet API documentation](https://docs.djangoproject.com/en/3.2/ref/models/querysets/#field-lookups)\n", "and [PostgreSQL specific documentation](https://docs.djangoproject.com/en/3.2/ref/contrib/postgres/fields/) for more details.\n", "\n", "### JSON field lookups\n", "\n", "JSON fields can be filtered in the same way as related tables. For example, the `sessions`\n", "table contains a 'extended_qc' JSON field that contains a map of QC checks and their outcomes.\n", "The fields and values can be used in lookup queries. For more info, see [Querying JSONField](https://docs.djangoproject.com/en/3.2/topics/db/queries/#querying-jsonfield).\n", "\n", "Here's how the extended_qc field looks:" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } }, { "cell_type": "code", "source": [ "ses = one.alyx.rest('sessions', 'read', id='4ecb5d24-f5cc-402c-be28-9d0f7cb14b3a')\n", "pprint(ses['extended_qc'])" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" }, "ExecuteTime": { "end_time": "2023-08-31T12:49:41.098676Z", "start_time": "2023-08-31T12:49:40.984889200Z" } }, "execution_count": 5, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'_dlcBody_if_mean_in_box': True,\n", " '_dlcBody_if_points_all_nan': True,\n", " '_dlcBody_lick_detection': None,\n", " '_dlcBody_mean_in_bbox': True,\n", " '_dlcBody_pupil_blocked': None,\n", " '_dlcBody_pupil_diameter_snr': None,\n", " '_dlcBody_time_trace_length_match': True,\n", " '_dlcBody_trace_all_nan': True,\n", " '_dlcBody_whisker_pupil_block': True,\n", " '_dlcLeft_if_mean_in_box': True,\n", " '_dlcLeft_if_points_all_nan': True,\n", " '_dlcLeft_lick_detection': True,\n", " '_dlcLeft_mean_in_bbox': True,\n", " '_dlcLeft_pupil_blocked': True,\n", " '_dlcLeft_pupil_diameter_snr': [True, 49.355],\n", " '_dlcLeft_time_trace_length_match': True,\n", " '_dlcLeft_trace_all_nan': True,\n", " '_dlcLeft_whisker_pupil_block': True,\n", " '_dlcRight_if_mean_in_box': True,\n", " '_dlcRight_if_points_all_nan': True,\n", " '_dlcRight_lick_detection': True,\n", " '_dlcRight_mean_in_bbox': True,\n", " '_dlcRight_pupil_blocked': True,\n", " '_dlcRight_pupil_diameter_snr': [True, 6.703],\n", " '_dlcRight_time_trace_length_match': True,\n", " '_dlcRight_trace_all_nan': True,\n", " '_dlcRight_whisker_pupil_block': True,\n", " '_task_audio_pre_trial': 1.0,\n", " '_task_correct_trial_event_sequence': 1.0,\n", " '_task_detected_wheel_moves': 0.9961977186311787,\n", " '_task_errorCue_delays': 0.9186046511627907,\n", " '_task_error_trial_event_sequence': 0.9767441860465116,\n", " '_task_goCue_delays': 1.0,\n", " '_task_iti_delays': 0.3314393939393939,\n", " '_task_n_trial_events': 0.9905482041587902,\n", " '_task_negative_feedback_stimOff_delays': 0.9418604651162791,\n", " '_task_passed_trial_checks': 0.32325141776937616,\n", " '_task_positive_feedback_stimOff_delays': 1.0,\n", " '_task_response_feedback_delays': 0.996219281663516,\n", " '_task_response_stimFreeze_delays': 0.9847908745247148,\n", " '_task_reward_volume_set': 1.0,\n", " '_task_reward_volumes': 1.0,\n", " '_task_stimFreeze_delays': 0.9792060491493384,\n", " '_task_stimOff_delays': 0.9924385633270322,\n", " '_task_stimOff_itiIn_delays': 0.9980988593155894,\n", " '_task_stimOn_delays': 0.998109640831758,\n", " '_task_stimOn_goCue_delays': 0.998109640831758,\n", " '_task_stimulus_move_before_goCue': 0.9980988593155894,\n", " '_task_trial_length': 0.996219281663516,\n", " '_task_wheel_freeze_during_quiescence': 1.0,\n", " '_task_wheel_integrity': 0.999999010009791,\n", " '_task_wheel_move_before_feedback': 0.9961977186311787,\n", " '_task_wheel_move_during_closed_loop': 0.9961977186311787,\n", " '_task_wheel_move_during_closed_loop_bpod': 1.0,\n", " '_videoBody_brightness': True,\n", " '_videoBody_camera_times': [True, 0],\n", " '_videoBody_dropped_frames': [True, 0, 0],\n", " '_videoBody_file_headers': True,\n", " '_videoBody_focus': True,\n", " '_videoBody_framerate': [True, 29.943],\n", " '_videoBody_pin_state': [True, 9, 0],\n", " '_videoBody_position': True,\n", " '_videoBody_resolution': True,\n", " '_videoBody_timestamps': True,\n", " '_videoBody_wheel_alignment': None,\n", " '_videoLeft_brightness': True,\n", " '_videoLeft_camera_times': [True, 0],\n", " '_videoLeft_dropped_frames': [True, 0, 0],\n", " '_videoLeft_file_headers': True,\n", " '_videoLeft_focus': True,\n", " '_videoLeft_framerate': [True, 59.767],\n", " '_videoLeft_pin_state': [True, 9, 0],\n", " '_videoLeft_position': True,\n", " '_videoLeft_resolution': True,\n", " '_videoLeft_timestamps': True,\n", " '_videoLeft_wheel_alignment': [True, 0],\n", " '_videoRight_brightness': False,\n", " '_videoRight_camera_times': [True, 0],\n", " '_videoRight_dropped_frames': [True, 21, 0],\n", " '_videoRight_file_headers': True,\n", " '_videoRight_focus': True,\n", " '_videoRight_framerate': [True, 150.015],\n", " '_videoRight_pin_state': [True, 6, 0],\n", " '_videoRight_position': True,\n", " '_videoRight_resolution': True,\n", " '_videoRight_timestamps': True,\n", " '_videoRight_wheel_alignment': [True, 1],\n", " 'behavior': 1,\n", " 'dlcBody': 'PASS',\n", " 'dlcLeft': 'PASS',\n", " 'dlcRight': 'PASS',\n", " 'task': 'WARNING',\n", " 'videoBody': 'WARNING',\n", " 'videoLeft': 'WARNING',\n", " 'videoRight': 'FAIL'}\n" ] } ] }, { "cell_type": "markdown", "source": [ "#### Looking up fields\n", "```python\n", "# Find sessions where task QC is marked as 'FAIL'\n", "one.alyx.rest('sessions', 'list', django='extended_qc__task__iexact,fail')\n", "```\n", "\n", "Lists can be accessed using indices:\n", "```python\n", "# Find sessions where first value (zero-index) of '_videoLeft_pin_state' is greater than 5\n", "one.alyx.rest('sessions', 'list', django='extended_qc___videoLeft_pin_state__0__gt,5')\n", "```\n", "\n", "Any search depth is allowed, and lookups such as `isnull`, `startswith`, `gte`, etc. are permitted.\n", "\n", "#### contains\n", "The returned objects are those where the given dict of key-value pairs are all contained in the\n", "top-level of the field.\n", "```python\n", "# Find sessions where extended QC has 'dlcLeft' and 'videoLeft' both pass:\n", "d = {'dlcLeft': 'PASS', 'videoLeft': 'PASS'}\n", "one.alyx.rest('sessions', 'list', django=f'extended_qc__contains,{d}')\n", "```\n", "\n", "#### contained_by\n", "This is the inverse of the contains lookup - the objects returned will be those where the key-value\n", "pairs on the object are a subset of those in the value passed.\n", "```python\n", "# Find sessions where extended QC has 'dlcLeft' and 'videoLeft' are missing or do not pass:\n", "d = {'dlcLeft': 'PASS', 'videoLeft': 'PASS'}\n", "one.alyx.rest('sessions', 'list', django=f'extended_qc__contained_by,{d}')\n", "```\n", "\n", "#### has_key\n", "JSON field contains a given key.\n", "```python\n", "# Find sessions where extended QC has 'dlcLeft' field:\n", "one.alyx.rest('sessions', 'list', django='extended_qc__has_key,dlcLeft')\n", "```\n", "\n", "#### has_keys\n", "JSON contains all of the listed keys. The list should be surrounded by parentheses or\n", "square brackets, e.g. `'field__has_keys,['field1', 'field2']'` or `'field__has_keys,('field1', 'field2')'`\n", "```python\n", "# Find sessions where extended QC 'behavior' and 'ephys' fields:\n", "keys = ['behavior', 'ephys']\n", "one.alyx.rest('sessions', 'list', django=f'extended_qc__has_keys,{keys}')\n", "```\n", "\n", "#### has_any_keys\n", "JSON contains at least one of the listed keys. The list should be surrounded by parentheses or\n", "square brackets, e.g. `'field__has_any_keys,['field1', 'field2']'` or `'field__has_any_keys,('field1', 'field2')'`\n", "```python\n", "# Find sessions where extended QC exists for any video\n", "keys = ('videoLeft', 'videoRight', 'videoBody')\n", "one.alyx.rest('sessions', 'list', django=f'extended_qc__has_any_keys,{keys}')\n", "```\n", "\n", "### exact\n", "An exact match. When the lookup is omitted it is assumed to be `exact`:\n", "```python\n", "one.alyx.rest('sessions', 'list', django='subject__nickname__exact,KS022')\n", "one.alyx.rest('sessions', 'list', django='subject__nickname,KS022') # equivalent\n", "```\n", "\n", "### iexact\n", "Case insensitive exact match:\n", "```python\n", "one.alyx.rest('sessions', 'list', django='subject__nickname__exact,ks022')\n", "```\n", "\n", "### contains\n", "### icontains\n", "Search for records where a given field contains a substring, case insensitive. For examples to\n", "query insertions with a task protocol containing 'choiceworld':\n", "```python\n", "ins = one.alyx.rest('insertions', 'list', django='session__task_protocol__icontains,choiceworld')\n", "```\n", "\n", "### in\n", "In a given iterable; often a list, tuple, or queryset. It’s not a common use case, but strings\n", "(being iterables) are accepted. For example to query session for several subjects:\n", "```python\n", "subjects = ['DY_003', 'DY_006']\n", "ses = one.alyx.rest('sessions', 'list', django=f\"subject__nickname__in,{subjects}\")\n", "```\n", "
\n", "NB: This example query can be done more efficiently with `one.search(subject=['DY_003', 'DY_006'])`\n", "
\n", "\n", "### gt\n", "### gte\n", "### lt\n", "Less than. Works for datetime, date and numerical fields:\n", "```python\n", "one.alyx.rest('sessions', 'list', django='session__qc__lt,40') # Where QC less than 40\n", "```\n", "### lte\n", "Less than or equal. Works for datetime, date and numerical fields. For example to get\n", "insertions for sessions on or before a given date:\n", "```python\n", "one.alyx.rest('insertions', 'list', django='session__start_time__date__lte,2021-07-22')\n", "```\n", "\n", "### startswith\n", "### istartswith\n", "### endswith\n", "### iendswith\n", "\n", "### not\n", "A tilda can be used to negate any query filter, for example, to query sessions that **do not**\n", "have matlab in the project names:\n", "```python\n", "ses = one.alyx.rest('sessions', 'list', django='~projects__name__icontains,matlab')\n", "```\n", "\n", "### range\n", "\n", "### date\n", "Extract the date part from a date_time field. For example to search for a given date:\n", "```python\n", "date = '2021-02-05'\n", "weighings = one.alyx.rest('weighings', 'list', django=f'date_time__date,{date}')\n", "```\n", "\n", "### year\n", "Extract the year from a date_time field.\n", "\n", "### iso_year\n", "### month\n", "### day\n", "### week\n", "### week_day\n", "### iso_week_day\n", "### quarter\n", "### time\n", "### hour\n", "### minute\n", "### second\n", "\n", "### isnull\n", "### regex\n", "Case-sensitive regular expression match. The regular expressions should be supported by\n", "PostgreSQL. More info on the syntax [here](https://www.postgresql.org/docs/9.3/functions-matching.html).\n", "```python\n", "# For a given session, find datasets that belong to a probe collection\n", "eid = '4ecb5d24-f5cc-402c-be28-9d0f7cb14b3a'\n", "one.alyx.rest('datasets', 'list', session=eid, django='collection__regex,.*probe.*', exists=True)\n", "```\n", "
\n", "NB: This example query can be done more efficiently with `one.list(eid, collection='*probe*')`\n", "
\n", "\n", "### iregex\n", "Case-insensitive regular expression match. The regular expressions should be supported by\n", "PostgreSQL. More info on the syntax [here](https://www.postgresql.org/docs/9.3/functions-matching.html).\n", "\n", "```python\n", "# List datasets for a given session that are related to either the right or left videos\n", "eid = '4ecb5d24-f5cc-402c-be28-9d0f7cb14b3a'\n", "query = 'name__iregex,(right|left)camera'\n", "one.alyx.rest('datasets', 'list', session=eid, django=query, exists=True)\n", "```\n", "
\n", "NB: This example query can be done more efficiently with `one.list_datasets(eid, filename={'object': ['leftCamera', 'rightCamera']})`\n", "
" ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } } } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 0 }