diff --git a/.gitignore b/.gitignore index 7811cf1082c5ed754b89c51f7a87879ad462a29f..4161f66797c227fbf3c06fd16b56166e51c4112e 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ scratch/ *.egg-info/ scripts* .pdm-python +*.prof \ No newline at end of file diff --git a/UsingONE.ipynb b/UsingONE.ipynb index 170179c5a76061ed55cf240589bfb7e636b114f8..84d254a0544172503148974583c0faaa192fa60b 100644 --- a/UsingONE.ipynb +++ b/UsingONE.ipynb @@ -20,6 +20,11281 @@ "connector = Connector(url=\"127.0.0.1\")" ] }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ec96c21a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Parameter(name='atlas_acronym', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='atlas_id', location=<ParameterLocation.QUERY: 'query'>, schema=Number(type=<DataType.NUMBER: 'number'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, multiple_of=None, maximum=None, exclusive_maximum=None, minimum=None, exclusive_minimum=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='atlas_name', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='attribute', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='auto_datetime', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=<StringFormat.DATETIME: 'date-time'>), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='data_repository', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='dataset_types', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='date_range', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='default_data_repository', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='django', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='end_time', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=<StringFormat.DATETIME: 'date-time'>), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='exclude_procedures', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='extended_qc', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='histology', location=<ParameterLocation.QUERY: 'query'>, schema=Boolean(type=<DataType.BOOLEAN: 'boolean'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='id', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=<StringFormat.UUID: 'uuid'>), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='json', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='lab', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='limit', location=<ParameterLocation.QUERY: 'query'>, schema=Integer(type=<DataType.INTEGER: 'integer'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, multiple_of=None, maximum=None, exclusive_maximum=None, minimum=None, exclusive_minimum=None, format=None), content=None, required=False, description='Number of results to return per page.', deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='location', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='n_correct_trials', location=<ParameterLocation.QUERY: 'query'>, schema=Integer(type=<DataType.INTEGER: 'integer'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, multiple_of=None, maximum=None, exclusive_maximum=None, minimum=None, exclusive_minimum=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='n_trials', location=<ParameterLocation.QUERY: 'query'>, schema=Integer(type=<DataType.INTEGER: 'integer'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, multiple_of=None, maximum=None, exclusive_maximum=None, minimum=None, exclusive_minimum=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='name', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='narrative', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='number', location=<ParameterLocation.QUERY: 'query'>, schema=Integer(type=<DataType.INTEGER: 'integer'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, multiple_of=None, maximum=None, exclusive_maximum=None, minimum=None, exclusive_minimum=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='object', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='offset', location=<ParameterLocation.QUERY: 'query'>, schema=Integer(type=<DataType.INTEGER: 'integer'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, multiple_of=None, maximum=None, exclusive_maximum=None, minimum=None, exclusive_minimum=None, format=None), content=None, required=False, description='The initial index from which to return the results.', deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='parent_session', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=<StringFormat.UUID: 'uuid'>), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='performance_gte', location=<ParameterLocation.QUERY: 'query'>, schema=Number(type=<DataType.NUMBER: 'number'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, multiple_of=None, maximum=None, exclusive_maximum=None, minimum=None, exclusive_minimum=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='performance_lte', location=<ParameterLocation.QUERY: 'query'>, schema=Number(type=<DataType.NUMBER: 'number'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, multiple_of=None, maximum=None, exclusive_maximum=None, minimum=None, exclusive_minimum=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='procedures', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='project', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='projects', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='qc', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='start_time', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=<StringFormat.DATETIME: 'date-time'>), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='subject', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='tag', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='task_protocol', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='type', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={}),\n", + " Parameter(name='users', location=<ParameterLocation.QUERY: 'query'>, schema=String(type=<DataType.STRING: 'string'>, title=None, enum=[], example=None, description=None, default=None, nullable=False, read_only=False, write_only=False, deprecated=False, extensions={}, max_length=None, min_length=None, pattern=None, format=None), content=None, required=False, description=None, deprecated=False, style=<QueryParameterStyle.FORM: 'form'>, explode=True, extensions={})]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "connector.web_client.endpoint(\"sessions\").actions[\"list\"].operation.parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "5000341f", + "metadata": {}, + "outputs": [], + "source": [ + "sessions = connector.search(subject = \"ea04\", start_time = \"2025-11-01\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "b0f0d952", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loading sessions details: 100%|██████████| 30/30 [00:03<00:00, 8.11it/s]\n" + ] + } + ], + "source": [ + "sessions = connector.search(subject = \"ea04\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "cc3adaa7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'id': 'b7ae0fae-6831-4018-9455-2d72181bb77f',\n", + " 'subject': 'ea04',\n", + " 'users': ['wilsonmena'],\n", + " 'location': None,\n", + " 'procedures': [],\n", + " 'lab': 'HaissLab',\n", + " 'projects': [],\n", + " 'type': None,\n", + " 'task_protocol': '',\n", + " 'number': 1,\n", + " 'start_time': '2025-11-01T00:00:00+01:00',\n", + " 'end_time': None,\n", + " 'narrative': '',\n", + " 'parent_session': None,\n", + " 'n_correct_trials': None,\n", + " 'n_trials': None,\n", + " 'url': 'http://127.0.0.1/sessions/b7ae0fae-6831-4018-9455-2d72181bb77f',\n", + " 'extended_qc': None,\n", + " 'qc': 'NOT_SET',\n", + " 'wateradmin_session_related': [],\n", + " 'data_dataset_session_related': [],\n", + " 'auto_datetime': '2025-04-28T08:36:04.693721+02:00',\n", + " 'alias': 'ea04/2025-11-01/001',\n", + " 'u_alias': 'ea04_2025-11-01_001',\n", + " 'path': '//157.99.138.167/cajal_data2/ONE/MotorSense/ea04/2025-11-01/001',\n", + " 'json': None,\n", + " 'probe_insertion': [],\n", + " 'notes': [],\n", + " 'default_data_repository_path': '//157.99.138.167/cajal_data2/ONE/MotorSense',\n", + " 'default_data_repository_name': 'Cajal2MotorSense',\n", + " 'default_data_repository_pk': '70a43e0f-09b3-4c0f-996c-12edbdaff06d',\n", + " 'rel_path': 'ea04/2025-11-01/001',\n", + " 'admin_url': '/admin/actions/session/b7ae0fae-6831-4018-9455-2d72181bb77f/change/'}" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "connector.web_client.create(endpoint=\"sessions\", data={\"users\":[\"wilsonmena\"], \"subject\":\"ea04\", \"start_time\":\"2025-11-01\",\"number\":1})" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "8c0e5a20", + "metadata": {}, + "outputs": [ + { + "ename": "HTTPError", + "evalue": "[Errno 500] http://127.0.0.1:80/sessions?date_range=%5B%272025-11-01%27%2C+%272025-11-02%27%5D&subject=ea04: '[\"“[\\'2025-11-01\\'” value has an invalid date format. It must be in YYYY-MM-DD format.\"]'", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mHTTPError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[3]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m session = \u001b[43mconnector\u001b[49m\u001b[43m.\u001b[49m\u001b[43msearch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdate_range\u001b[49m\u001b[43m \u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m2025-11-01\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43m2025-11-02\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msubject\u001b[49m\u001b[43m \u001b[49m\u001b[43m=\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mea04\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\connector\\core.py:70\u001b[39m, in \u001b[36mConnector.search\u001b[39m\u001b[34m(self, endpoint, details, raises, **kwargs)\u001b[39m\n\u001b[32m 69\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34msearch\u001b[39m(\u001b[38;5;28mself\u001b[39m, endpoint=\u001b[33m\"\u001b[39m\u001b[33msessions\u001b[39m\u001b[33m\"\u001b[39m, details=\u001b[38;5;28;01mTrue\u001b[39;00m, raises=\u001b[38;5;28;01mTrue\u001b[39;00m, **kwargs):\n\u001b[32m---> \u001b[39m\u001b[32m70\u001b[39m search_result = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mweb_client\u001b[49m\u001b[43m.\u001b[49m\u001b[43msearch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mendpoint\u001b[49m\u001b[43m=\u001b[49m\u001b[43mendpoint\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdetails\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdetails\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 71\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m raises:\n\u001b[32m 72\u001b[39m search_result = \u001b[38;5;28mself\u001b[39m.raise_if_search_empty(search_result)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\web\\clients.py:145\u001b[39m, in \u001b[36mClient.search\u001b[39m\u001b[34m(self, endpoint, details, **kwargs)\u001b[39m\n\u001b[32m 138\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mid\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m kwargs.keys() \u001b[38;5;129;01mor\u001b[39;00m \u001b[33m\"\u001b[39m\u001b[33mname\u001b[39m\u001b[33m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m kwargs.keys():\n\u001b[32m 139\u001b[39m \u001b[38;5;66;03m# just in case, we warn the user if she/he supplied id or name, and the endpoint doesn't implement retrieve\u001b[39;00m\n\u001b[32m 140\u001b[39m logger.warning(\n\u001b[32m 141\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mEndpoint \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mendpoint\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m does not implement retrieve. \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 142\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mYou specified id or name but it will not work to select a specific item. Listing instead\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 143\u001b[39m )\n\u001b[32m--> \u001b[39m\u001b[32m145\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mlist\u001b[49m\u001b[43m(\u001b[49m\u001b[43mendpoint\u001b[49m\u001b[43m=\u001b[49m\u001b[43mendpoint\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdetails\u001b[49m\u001b[43m=\u001b[49m\u001b[43mdetails\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\web\\clients.py:176\u001b[39m, in \u001b[36mClient.list\u001b[39m\u001b[34m(self, endpoint, details, **kwargs)\u001b[39m\n\u001b[32m 175\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mlist\u001b[39m(\u001b[38;5;28mself\u001b[39m, *, endpoint: \u001b[38;5;28mstr\u001b[39m, details=\u001b[38;5;28;01mTrue\u001b[39;00m, **kwargs):\n\u001b[32m--> \u001b[39m\u001b[32m176\u001b[39m results = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mrest\u001b[49m\u001b[43m(\u001b[49m\u001b[43mendpoint\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mlist\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 177\u001b[39m results = [] \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m results \u001b[38;5;28;01melse\u001b[39;00m results\n\u001b[32m 178\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m.details_aggregation(results, endpoint) \u001b[38;5;28;01mif\u001b[39;00m details \u001b[38;5;28;01melse\u001b[39;00m results\n", + "\u001b[36mFile \u001b[39m\u001b[32m~\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\web\\clients.py:99\u001b[39m, in \u001b[36mClient.rest\u001b[39m\u001b[34m(self, endpoint_name, action, timeout, **kwargs)\u001b[39m\n\u001b[32m 91\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mrest\u001b[39m(\n\u001b[32m 92\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 93\u001b[39m endpoint_name: \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 96\u001b[39m **kwargs,\n\u001b[32m 97\u001b[39m ):\n\u001b[32m 98\u001b[39m operateur = \u001b[38;5;28mself\u001b[39m.path(endpoint_name).endpoint.assert_exists().actions[action]\n\u001b[32m---> \u001b[39m\u001b[32m99\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mRequest\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moperateur\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m*\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m.\u001b[49m\u001b[43mhandle\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\web\\api.py:322\u001b[39m, in \u001b[36mRequest.handle\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 321\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mhandle\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[32m--> \u001b[39m\u001b[32m322\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mhandle_response\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mget_response\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\web\\api.py:355\u001b[39m, in \u001b[36mRequest.handle_response\u001b[39m\u001b[34m(self, response)\u001b[39m\n\u001b[32m 353\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[32m 354\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m--> \u001b[39m\u001b[32m355\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mraise_from_response\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresponse\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\web\\api.py:366\u001b[39m, in \u001b[36mRequest.raise_from_response\u001b[39m\u001b[34m(self, response)\u001b[39m\n\u001b[32m 364\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m json.decoder.JSONDecodeError:\n\u001b[32m 365\u001b[39m message = response.text\n\u001b[32m--> \u001b[39m\u001b[32m366\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m requests.HTTPError(response.status_code, \u001b[38;5;28mself\u001b[39m.url, message, response=response)\n", + "\u001b[31mHTTPError\u001b[39m: [Errno 500] http://127.0.0.1:80/sessions?date_range=%5B%272025-11-01%27%2C+%272025-11-02%27%5D&subject=ea04: '[\"“[\\'2025-11-01\\'” value has an invalid date format. It must be in YYYY-MM-DD format.\"]'" + ] + } + ], + "source": [ + "session = connector.search(date_range = [\"2025-11-01\",\"2025-11-02\"], subject = \"ea04\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dfc5ba2c", + "metadata": {}, + "outputs": [], + "source": [ + "sessions = connector.search(subject = \"ea03\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "ac9ad7ba", + "metadata": {}, + "outputs": [], + "source": [ + "from alyx_connector.files.registration.rules_config import Config\n", + "config = Config()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "dc91895f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "id 95fd1f97-d636-4425-9d3a-1fb359161d96\n", + "subject ea04\n", + "users [eachirou]\n", + "location None\n", + "procedures [Two photon Imaging]\n", + "lab HaissLab\n", + "projects [MotorSense]\n", + "type None\n", + "task_protocol \n", + "number 1\n", + "start_time 2024-04-03T17:25:00+02:00\n", + "end_time 2024-04-03T18:06:00+02:00\n", + "narrative stims :\\r\\n- C2 : right\\r\\n- nothing : left\\r\\...\n", + "parent_session None\n", + "n_correct_trials None\n", + "n_trials None\n", + "url http://127.0.0.1/sessions/95fd1f97-d636-4425-9...\n", + "extended_qc None\n", + "qc NOT_SET\n", + "wateradmin_session_related []\n", + "data_dataset_session_related []\n", + "auto_datetime 2024-04-03T19:41:41.429420+02:00\n", + "alias ea04/2024-04-03/001\n", + "u_alias ea04_2024-04-03_001\n", + "path //157.99.138.167/cajal_data2/ONE/MotorSense/ea...\n", + "json {'whisker_stims': {'Stimulus right': {'0': 'No...\n", + "probe_insertion []\n", + "notes []\n", + "default_data_repository_path //157.99.138.167/cajal_data2/ONE/MotorSense\n", + "default_data_repository_name Cajal2MotorSense\n", + "default_data_repository_pk 70a43e0f-09b3-4c0f-996c-12edbdaff06d\n", + "rel_path ea04/2024-04-03/001\n", + "admin_url /admin/actions/session/95fd1f97-d636-4425-9d3a...\n", + "Name: 29, dtype: object" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session = sessions.iloc[-1]\n", + "session" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "75f29292", + "metadata": {}, + "outputs": [], + "source": [ + "file_records = config.evaluate_session(session)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "989fefee", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " <div class=\"table-container\">\n", + " <table>\n", + " <thead>\n", + " <th class=\"title\" colspan=\"10\">File :</th>\n", + " </thead>\n", + " <thead class=\"head\">\n", + " <tr>\n", + " <th>root</th>\n", + " <th>subject</th>\n", + " <th>date</th>\n", + " <th>number</th>\n", + " <th>collection</th>\n", + " <th>revision</th>\n", + " <th>object</th>\n", + " <th>attribute</th>\n", + " <th>extra</th>\n", + " <th>extension</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense</td>\n", + " <td>ea04</td>\n", + " <td>2024-04-03</td>\n", + " <td>001</td>\n", + " <td>behaviour_imaging\\whiskers</td>\n", + " <td></td>\n", + " <td>0</td>\n", + " <td></td>\n", + " <td></td>\n", + " <td>tdms</td>\n", + " </tr>\n", + " </tbody>\n", + " </table>\n", + " </div>\n", + " <style>\n", + " .table-container{\n", + " border: 1px solid rgb(173, 173, 173);\n", + " border-radius: 5px;\n", + " overflow: hidden;\n", + " display: inline-block;\n", + " }\n", + " .title{\n", + " text-align: left;\n", + " white-space: pre;\n", + " font-weight: bolder;\n", + " }\n", + " table {\n", + " font-family: consolas;\n", + " border-collapse: collapse;\n", + " }\n", + " th, td {\n", + " border: 1px solid rgb(160 160 160);\n", + " }\n", + " thead:first-of-type th {\n", + " border-top: none;\n", + " }\n", + " td {\n", + " border-bottom: 0px;\n", + " }\n", + " th:first-of-type, td:first-of-type {\n", + " border-left: none;\n", + " }\n", + " td:last-of-type, th:last-of-type {\n", + " border-right: none;\n", + " }\n", + " thead > tr > th:hover, tbody > tr > td:hover{\n", + " background-color: rgba(111, 110, 160, 0.267);\n", + " }\n", + " </style>\n", + " " + ], + "text/plain": [ + "<alyx_connector.files.parsing.files.File at 0x1f07d7a8da0>" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from alyx_connector.files.parsing import File\n", + "File(r\"\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\0.tdms\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "5d2b5087", + "metadata": {}, + "outputs": [], + "source": [ + "file_records.records[0].destination_file[\"attribute\"] = \"fesse\"" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "24488d2f", + "metadata": {}, + "outputs": [], + "source": [ + "file_records.records[0].destination_file._attribute = \"fesse\"" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "bfc3e9d4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " <div class=\"table-container\">\n", + " <table>\n", + " <thead>\n", + " <th class=\"title\" colspan=\"10\">File :</th>\n", + " </thead>\n", + " <thead class=\"head\">\n", + " <tr>\n", + " <th>root</th>\n", + " <th>subject</th>\n", + " <th>date</th>\n", + " <th>number</th>\n", + " <th>collection</th>\n", + " <th>revision</th>\n", + " <th>object</th>\n", + " <th>attribute</th>\n", + " <th>extra</th>\n", + " <th>extension</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense</td>\n", + " <td>ea04</td>\n", + " <td>2024-04-03</td>\n", + " <td>001</td>\n", + " <td>behaviour_imaging\\whiskers</td>\n", + " <td></td>\n", + " <td>behaviour</td>\n", + " <td>fesse</td>\n", + " <td>whiskers.00000</td>\n", + " <td>tdms</td>\n", + " </tr>\n", + " </tbody>\n", + " </table>\n", + " </div>\n", + " <style>\n", + " .table-container{\n", + " border: 1px solid rgb(173, 173, 173);\n", + " border-radius: 5px;\n", + " overflow: hidden;\n", + " display: inline-block;\n", + " }\n", + " .title{\n", + " text-align: left;\n", + " white-space: pre;\n", + " font-weight: bolder;\n", + " }\n", + " table {\n", + " font-family: consolas;\n", + " border-collapse: collapse;\n", + " }\n", + " th, td {\n", + " border: 1px solid rgb(160 160 160);\n", + " }\n", + " thead:first-of-type th {\n", + " border-top: none;\n", + " }\n", + " td {\n", + " border-bottom: 0px;\n", + " }\n", + " th:first-of-type, td:first-of-type {\n", + " border-left: none;\n", + " }\n", + " td:last-of-type, th:last-of-type {\n", + " border-right: none;\n", + " }\n", + " thead > tr > th:hover, tbody > tr > td:hover{\n", + " background-color: rgba(111, 110, 160, 0.267);\n", + " }\n", + " </style>\n", + " " + ], + "text/plain": [ + "<alyx_connector.files.parsing.files.File at 0x1f07cb47d70>" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_records.records[0].destination_file" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "3b41948f", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.microsoft.datawrangler.viewer.v0+json": { + "columns": [ + { + "name": "index", + "rawType": "int64", + "type": "integer" + }, + { + "name": "source_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "match", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "matching_rules", + "rawType": "object", + "type": "unknown" + }, + { + "name": "used_rule", + "rawType": "object", + "type": "string" + }, + { + "name": "valid_alf", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "path_conflicts", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "dataset_type_exists", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "rename", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "delete", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "include", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "abort", + "rawType": "object", + "type": "unknown" + }, + { + "name": "executed_actions", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_source_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_destination_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_pathstring", + "rawType": "object", + "type": "string" + }, + { + "name": "info", + "rawType": "object", + "type": "string" + } + ], + "conversionMethod": "pd.DataFrame", + "ref": "6974d75e-22e5-427e-bcdc-b2e91889b48e", + "rows": [ + [ + "0", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\0.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D5BBAA0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07CB47D70>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "Will be renamed and included" + ], + [ + "1", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\1.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D5BB9B0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D5BBB60>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "Will be renamed and included" + ], + [ + "2", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\10.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D5BBC20>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D5BBCB0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "Will be renamed and included" + ], + [ + "3", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\100.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D5BBD40>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D5BBDD0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00100.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00100.tdms", + "Will be renamed and included" + ], + [ + "4", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\101.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D5BBE60>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D5BBEF0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00101.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00101.tdms", + "Will be renamed and included" + ], + [ + "5", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\102.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D5BBF80>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634050>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00102.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00102.tdms", + "Will be renamed and included" + ], + [ + "6", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\103.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6340E0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634170>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00103.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00103.tdms", + "Will be renamed and included" + ], + [ + "7", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\104.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634200>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634290>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00104.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00104.tdms", + "Will be renamed and included" + ], + [ + "8", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\105.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634320>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6343B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00105.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00105.tdms", + "Will be renamed and included" + ], + [ + "9", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\106.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634440>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6344D0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00106.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00106.tdms", + "Will be renamed and included" + ], + [ + "10", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\107.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634560>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6345F0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00107.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00107.tdms", + "Will be renamed and included" + ], + [ + "11", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\108.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634680>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634710>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00108.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00108.tdms", + "Will be renamed and included" + ], + [ + "12", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\109.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6347A0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634830>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00109.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00109.tdms", + "Will be renamed and included" + ], + [ + "13", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\11.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6348F0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634980>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "Will be renamed and included" + ], + [ + "14", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\110.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634A10>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634AA0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00110.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00110.tdms", + "Will be renamed and included" + ], + [ + "15", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\111.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634B30>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634BC0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00111.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00111.tdms", + "Will be renamed and included" + ], + [ + "16", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\112.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634C50>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634CE0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00112.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00112.tdms", + "Will be renamed and included" + ], + [ + "17", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\113.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634D70>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634E00>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00113.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00113.tdms", + "Will be renamed and included" + ], + [ + "18", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\114.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634E90>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634F20>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00114.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00114.tdms", + "Will be renamed and included" + ], + [ + "19", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\115.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D634FB0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635040>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00115.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00115.tdms", + "Will be renamed and included" + ], + [ + "20", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\116.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6350D0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635160>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00116.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00116.tdms", + "Will be renamed and included" + ], + [ + "21", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\117.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6351F0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635280>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00117.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00117.tdms", + "Will be renamed and included" + ], + [ + "22", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\118.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635310>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6353A0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00118.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00118.tdms", + "Will be renamed and included" + ], + [ + "23", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\119.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635430>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6354C0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00119.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00119.tdms", + "Will be renamed and included" + ], + [ + "24", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\12.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635580>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635610>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "Will be renamed and included" + ], + [ + "25", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\120.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6356A0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635730>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00120.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00120.tdms", + "Will be renamed and included" + ], + [ + "26", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\121.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6357C0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635850>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00121.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00121.tdms", + "Will be renamed and included" + ], + [ + "27", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\122.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6358E0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635970>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00122.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00122.tdms", + "Will be renamed and included" + ], + [ + "28", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\123.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635A00>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635A90>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00123.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00123.tdms", + "Will be renamed and included" + ], + [ + "29", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\124.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635B20>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635BB0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00124.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00124.tdms", + "Will be renamed and included" + ], + [ + "30", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\125.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635C40>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635CD0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00125.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00125.tdms", + "Will be renamed and included" + ], + [ + "31", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\126.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635D60>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635DF0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00126.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00126.tdms", + "Will be renamed and included" + ], + [ + "32", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\127.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635E80>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635F10>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00127.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00127.tdms", + "Will be renamed and included" + ], + [ + "33", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\128.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D635FA0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636030>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00128.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00128.tdms", + "Will be renamed and included" + ], + [ + "34", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\129.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6360C0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636150>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00129.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00129.tdms", + "Will be renamed and included" + ], + [ + "35", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\13.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636210>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6362A0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "Will be renamed and included" + ], + [ + "36", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\130.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636330>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6363C0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00130.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00130.tdms", + "Will be renamed and included" + ], + [ + "37", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\131.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636450>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6364E0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00131.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00131.tdms", + "Will be renamed and included" + ], + [ + "38", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\132.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636570>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636600>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00132.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00132.tdms", + "Will be renamed and included" + ], + [ + "39", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\133.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636690>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636720>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00133.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00133.tdms", + "Will be renamed and included" + ], + [ + "40", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\134.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6367B0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636840>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00134.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00134.tdms", + "Will be renamed and included" + ], + [ + "41", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\135.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6368D0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636960>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00135.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00135.tdms", + "Will be renamed and included" + ], + [ + "42", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\136.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6369F0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636A80>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00136.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00136.tdms", + "Will be renamed and included" + ], + [ + "43", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\137.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636B10>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636BA0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00137.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00137.tdms", + "Will be renamed and included" + ], + [ + "44", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\138.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636C30>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636CC0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00138.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00138.tdms", + "Will be renamed and included" + ], + [ + "45", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\139.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636D50>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636DE0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00139.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00139.tdms", + "Will be renamed and included" + ], + [ + "46", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\14.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636EA0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636F30>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "Will be renamed and included" + ], + [ + "47", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\140.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D636FC0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D637050>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00140.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00140.tdms", + "Will be renamed and included" + ], + [ + "48", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\141.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D6370E0>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D637170>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00141.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00141.tdms", + "Will be renamed and included" + ], + [ + "49", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\142.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "True", + "False", + "True", + "[]", + "['match -> rename', 'rename_successfull -> include']", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D637200>", + "<alyx_connector.files.parsing.files.File object at 0x000001F07D637290>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00142.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea04\\2024-04-03\\001\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00142.tdms", + "Will be renamed and included" + ] + ], + "shape": { + "columns": 17, + "rows": 622 + } + }, + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>source_path</th>\n", + " <th>match</th>\n", + " <th>matching_rules</th>\n", + " <th>used_rule</th>\n", + " <th>valid_alf</th>\n", + " <th>path_conflicts</th>\n", + " <th>dataset_type_exists</th>\n", + " <th>rename</th>\n", + " <th>delete</th>\n", + " <th>include</th>\n", + " <th>abort</th>\n", + " <th>executed_actions</th>\n", + " <th>_source_file</th>\n", + " <th>_destination_file</th>\n", + " <th>_final_path</th>\n", + " <th>_final_pathstring</th>\n", + " <th>info</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td>[match -> rename, rename_successfull -> include]</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>Will be renamed and included</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td>[match -> rename, rename_successfull -> include]</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>Will be renamed and included</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td>[match -> rename, rename_successfull -> include]</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>Will be renamed and included</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td>[match -> rename, rename_successfull -> include]</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>Will be renamed and included</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td>[match -> rename, rename_successfull -> include]</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>Will be renamed and included</td>\n", + " </tr>\n", + " <tr>\n", + " <th>...</th>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>617</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>True</td>\n", + " <td>[imaging_data_rule1]</td>\n", + " <td>imaging_data_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td>[match -> rename, rename_successfull -> include]</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>Will be renamed and included</td>\n", + " </tr>\n", + " <tr>\n", + " <th>618</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>Will be excluded without change dataset_type ...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>619</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>Will be excluded without change dataset_type ...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>620</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>Will be excluded without change dataset_type ...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>621</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td><alyx_connector.files.parsing.files.File objec...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea...</td>\n", + " <td>Will be excluded without change dataset_type ...</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>622 rows × 17 columns</p>\n", + "</div>" + ], + "text/plain": [ + " source_path match \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... True \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... True \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... True \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... True \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... True \n", + ".. ... ... \n", + "617 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... True \n", + "618 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... False \n", + "619 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... False \n", + "620 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... False \n", + "621 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... False \n", + "\n", + " matching_rules used_rule valid_alf \\\n", + "0 [behavior_whiskers_rule1] behavior_whiskers_rule1 True \n", + "1 [behavior_whiskers_rule1] behavior_whiskers_rule1 True \n", + "2 [behavior_whiskers_rule1] behavior_whiskers_rule1 True \n", + "3 [behavior_whiskers_rule1] behavior_whiskers_rule1 True \n", + "4 [behavior_whiskers_rule1] behavior_whiskers_rule1 True \n", + ".. ... ... ... \n", + "617 [imaging_data_rule1] imaging_data_rule1 True \n", + "618 [] False \n", + "619 [] False \n", + "620 [] False \n", + "621 [] False \n", + "\n", + " path_conflicts dataset_type_exists rename delete include abort \\\n", + "0 False True True False True [] \n", + "1 False True True False True [] \n", + "2 False True True False True [] \n", + "3 False True True False True [] \n", + "4 False True True False True [] \n", + ".. ... ... ... ... ... ... \n", + "617 False True True False True [] \n", + "618 False False False False False [] \n", + "619 False False False False False [] \n", + "620 False False False False False [] \n", + "621 False False False False False [] \n", + "\n", + " executed_actions \\\n", + "0 [match -> rename, rename_successfull -> include] \n", + "1 [match -> rename, rename_successfull -> include] \n", + "2 [match -> rename, rename_successfull -> include] \n", + "3 [match -> rename, rename_successfull -> include] \n", + "4 [match -> rename, rename_successfull -> include] \n", + ".. ... \n", + "617 [match -> rename, rename_successfull -> include] \n", + "618 [] \n", + "619 [] \n", + "620 [] \n", + "621 [] \n", + "\n", + " _source_file \\\n", + "0 <alyx_connector.files.parsing.files.File objec... \n", + "1 <alyx_connector.files.parsing.files.File objec... \n", + "2 <alyx_connector.files.parsing.files.File objec... \n", + "3 <alyx_connector.files.parsing.files.File objec... \n", + "4 <alyx_connector.files.parsing.files.File objec... \n", + ".. ... \n", + "617 <alyx_connector.files.parsing.files.File objec... \n", + "618 <alyx_connector.files.parsing.files.File objec... \n", + "619 <alyx_connector.files.parsing.files.File objec... \n", + "620 <alyx_connector.files.parsing.files.File objec... \n", + "621 <alyx_connector.files.parsing.files.File objec... \n", + "\n", + " _destination_file \\\n", + "0 <alyx_connector.files.parsing.files.File objec... \n", + "1 <alyx_connector.files.parsing.files.File objec... \n", + "2 <alyx_connector.files.parsing.files.File objec... \n", + "3 <alyx_connector.files.parsing.files.File objec... \n", + "4 <alyx_connector.files.parsing.files.File objec... \n", + ".. ... \n", + "617 <alyx_connector.files.parsing.files.File objec... \n", + "618 <alyx_connector.files.parsing.files.File objec... \n", + "619 <alyx_connector.files.parsing.files.File objec... \n", + "620 <alyx_connector.files.parsing.files.File objec... \n", + "621 <alyx_connector.files.parsing.files.File objec... \n", + "\n", + " _final_path \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + ".. ... \n", + "617 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "618 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "619 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "620 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "621 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "\n", + " _final_pathstring \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + ".. ... \n", + "617 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "618 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "619 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "620 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "621 \\\\157.99.138.167\\cajal_data2\\ONE\\MotorSense\\ea... \n", + "\n", + " info \n", + "0 Will be renamed and included \n", + "1 Will be renamed and included \n", + "2 Will be renamed and included \n", + "3 Will be renamed and included \n", + "4 Will be renamed and included \n", + ".. ... \n", + "617 Will be renamed and included \n", + "618 Will be excluded without change dataset_type ... \n", + "619 Will be excluded without change dataset_type ... \n", + "620 Will be excluded without change dataset_type ... \n", + "621 Will be excluded without change dataset_type ... \n", + "\n", + "[622 rows x 17 columns]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = file_records.to_dataframe()\n", + "# df[df[\"abort\"]==False]\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "297f4c80", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.microsoft.datawrangler.viewer.v0+json": { + "columns": [ + { + "name": "index", + "rawType": "int64", + "type": "integer" + }, + { + "name": "source_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "match", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "matching_rules", + "rawType": "object", + "type": "unknown" + }, + { + "name": "used_rule", + "rawType": "object", + "type": "string" + }, + { + "name": "valid_alf", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "path_conflicts", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "dataset_type_exists", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "rename", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "delete", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "include", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "abort", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_source_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_destination_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_pathstring", + "rawType": "object", + "type": "string" + }, + { + "name": "info", + "rawType": "object", + "type": "string" + } + ], + "conversionMethod": "pd.DataFrame", + "ref": "8149566a-d231-4833-aebf-edda2720691a", + "rows": [ + [ + "1002", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\DELETE_LATER_JUST_A_TEST\\trials.choice.001.txt", + "True", + "['include_test_data_rule']", + "include_test_data_rule ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396879610>", + "<alyx_connector.files.parsing.File object at 0x000001B396879670>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\DELETE_LATER_JUST_A_TEST\\trials.choice.001.txt", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\DELETE_LATER_JUST_A_TEST\\trials.choice.001.txt", + "Will be included without change" + ], + [ + "1003", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\DELETE_LATER_JUST_A_TEST\\trials.choice.002.txt", + "True", + "['include_test_data_rule']", + "include_test_data_rule ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B39681BB30>", + "<alyx_connector.files.parsing.File object at 0x000001B396879970>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\DELETE_LATER_JUST_A_TEST\\trials.choice.002.txt", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\DELETE_LATER_JUST_A_TEST\\trials.choice.002.txt", + "Will be included without change" + ], + [ + "1004", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\DELETE_LATER_JUST_A_TEST\\trials.choice.003.txt", + "True", + "['include_test_data_rule']", + "include_test_data_rule ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B39681B950>", + "<alyx_connector.files.parsing.File object at 0x000001B3968798B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\DELETE_LATER_JUST_A_TEST\\trials.choice.003.txt", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\DELETE_LATER_JUST_A_TEST\\trials.choice.003.txt", + "Will be included without change" + ] + ], + "shape": { + "columns": 16, + "rows": 3 + } + }, + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>source_path</th>\n", + " <th>match</th>\n", + " <th>matching_rules</th>\n", + " <th>used_rule</th>\n", + " <th>valid_alf</th>\n", + " <th>path_conflicts</th>\n", + " <th>dataset_type_exists</th>\n", + " <th>rename</th>\n", + " <th>delete</th>\n", + " <th>include</th>\n", + " <th>abort</th>\n", + " <th>_source_file</th>\n", + " <th>_destination_file</th>\n", + " <th>_final_path</th>\n", + " <th>_final_pathstring</th>\n", + " <th>info</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>1002</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[include_test_data_rule]</td>\n", + " <td>include_test_data_rule</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1003</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[include_test_data_rule]</td>\n", + " <td>include_test_data_rule</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1004</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[include_test_data_rule]</td>\n", + " <td>include_test_data_rule</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "</div>" + ], + "text/plain": [ + " source_path match \\\n", + "1002 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "1003 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "1004 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "\n", + " matching_rules used_rule valid_alf \\\n", + "1002 [include_test_data_rule] include_test_data_rule True \n", + "1003 [include_test_data_rule] include_test_data_rule True \n", + "1004 [include_test_data_rule] include_test_data_rule True \n", + "\n", + " path_conflicts dataset_type_exists rename delete include abort \\\n", + "1002 False True False False True [] \n", + "1003 False True False False True [] \n", + "1004 False True False False True [] \n", + "\n", + " _source_file \\\n", + "1002 <alyx_connector.files.parsing.File object at 0... \n", + "1003 <alyx_connector.files.parsing.File object at 0... \n", + "1004 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _destination_file \\\n", + "1002 <alyx_connector.files.parsing.File object at 0... \n", + "1003 <alyx_connector.files.parsing.File object at 0... \n", + "1004 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _final_path \\\n", + "1002 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1003 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1004 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "\n", + " _final_pathstring \\\n", + "1002 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1003 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1004 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "\n", + " info \n", + "1002 Will be included without change \n", + "1003 Will be included without change \n", + "1004 Will be included without change " + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "f = file_records.to_dataframe()\n", + "f[f[\"used_rule\"] == \"include_test_data_rule \"]\n", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\DELETE_LATER_JUST_A_TEST\\trials.choice.001.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "b5e368d0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'ihem05_2024-11-06_002'" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session.u_alias" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "c788c08b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'id': '0dfed412-9b32-470f-a9d0-177b4f9f207c',\n", + " 'url': 'http://127.0.0.1/datasets/0dfed412-9b32-470f-a9d0-177b4f9f207c',\n", + " 'admin_url': '/admin/data/dataset/0dfed412-9b32-470f-a9d0-177b4f9f207c/change/',\n", + " 'name': 'trials.choice.txt',\n", + " 'created_by': 'tjostmou',\n", + " 'created_datetime': '2025-04-11T14:10:04.503148+02:00',\n", + " 'data_repository': 'Cajal2Interhem',\n", + " 'file_size': None,\n", + " 'version': None,\n", + " 'auto_datetime': '2025-04-11T14:10:04.504138+02:00',\n", + " 'dataset_type': 'trials.choice',\n", + " 'default_dataset': True,\n", + " 'tags': [],\n", + " 'session': 'ihem05_2024-11-06_002',\n", + " 'data_format': '.txt',\n", + " 'data_repository_pk': 'ea2cd868-ea54-4f59-a3b3-640130c44891',\n", + " 'data_format_pk': 'dd3f05b1-6104-4da7-be68-ffaad1b97651',\n", + " 'revision_pk': None,\n", + " 'dataset_type_pk': '378aa050-4924-4a9b-9fe7-b7cf86dff93f',\n", + " 'session_pk': 'dc5a61db-cbb6-48dc-bcb9-310211c8512c',\n", + " 'remote_root': '//157.99.138.167/cajal_data2/ONE/Interhem',\n", + " 'subject': 'ihem05',\n", + " 'date': '2024-11-06',\n", + " 'number': 2,\n", + " 'collection': 'DELETE_LATER_JUST_A_TEST',\n", + " 'revision': '',\n", + " 'object': 'trials',\n", + " 'attribute': 'choice',\n", + " 'extension': '.txt',\n", + " 'file_records': [{'id': 'cef2bd58-10bd-4098-a460-bc4e064817ad',\n", + " 'relative_path': 'ihem05/2024-11-06/002/DELETE_LATER_JUST_A_TEST/trials.choice.001.txt',\n", + " 'extra': '001',\n", + " 'exists': True,\n", + " 'file_name': 'trials.choice.001.txt',\n", + " 'hash': None},\n", + " {'id': '8888aece-4580-4535-90bb-a7fb85820f92',\n", + " 'relative_path': 'ihem05/2024-11-06/002/DELETE_LATER_JUST_A_TEST/trials.choice.002.txt',\n", + " 'extra': '002',\n", + " 'exists': True,\n", + " 'file_name': 'trials.choice.002.txt',\n", + " 'hash': None},\n", + " {'id': 'f4295ab5-bb26-4cec-a636-e606f62d4ecd',\n", + " 'relative_path': 'ihem05/2024-11-06/002/DELETE_LATER_JUST_A_TEST/trials.choice.003.txt',\n", + " 'extra': '003',\n", + " 'exists': True,\n", + " 'file_name': 'trials.choice.003.txt',\n", + " 'hash': None}]}" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "connector.web_client.create(endpoint=\"datasets\", \n", + " data={\n", + " \"session_pk\":\"dc5a61db-cbb6-48dc-bcb9-310211c8512c\",\n", + " \"dataset_type\":\"trials.choice\",\n", + " \"collection\":\"DELETE_LATER_JUST_A_TEST\",\n", + " \"data_format\":\".txt\",\"set_file_records\":[{\"extra\":\"001\",\"exists\":True},\n", + " {\"extra\":\"002\",\"exists\":True},\n", + " {\"extra\":\"003\",\"exists\":True}\n", + " ]\n", + " }\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d76f2877", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'session' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mNameError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43msession\u001b[49m\n", + "\u001b[31mNameError\u001b[39m: name 'session' is not defined" + ] + } + ], + "source": [ + "session" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "5ebc614f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "used_rule info \n", + " Will be excluded without change 1\n", + " Will be excluded without change dataset_type doesn't follow alyx format dataset_type:F not existing 1\n", + " Will be excluded without change dataset_type doesn't follow alyx format dataset_type:F_chan2 not existing 1\n", + " Will be excluded without change dataset_type doesn't follow alyx format dataset_type:F_corrected not existing 1\n", + " Will be excluded without change dataset_type doesn't follow alyx format dataset_type:F_corrected_chan2 not existing 1\n", + " ... \n", + " Will be excluded without change dataset_type:treat2p.version not existing 1\n", + "behavior_cam_sessings_include_rule Will be included without change 1\n", + "behavior_whiskers_rule1 Will be included without change 300\n", + "imaging_data_rule2 Will be included without change 300\n", + "include_test_data_rule Will be included without change 3\n", + "Length: 315, dtype: int64" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_records.stats()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "783a4f38", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.microsoft.datawrangler.viewer.v0+json": { + "columns": [ + { + "name": "index", + "rawType": "int64", + "type": "integer" + }, + { + "name": "source_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "match", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "matching_rules", + "rawType": "object", + "type": "unknown" + }, + { + "name": "used_rule", + "rawType": "object", + "type": "string" + }, + { + "name": "valid_alf", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "path_conflicts", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "dataset_type_exists", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "rename", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "delete", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "include", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "abort", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_source_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_destination_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_pathstring", + "rawType": "object", + "type": "string" + }, + { + "name": "info", + "rawType": "object", + "type": "string" + } + ], + "conversionMethod": "pd.DataFrame", + "ref": "ce6ad140-549c-4ecb-b825-1f67b9df8a7a", + "rows": [ + [ + "0", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "True", + "['behavior_cam_sessings_include_rule']", + "behavior_cam_sessings_include_rule ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B3E4A49340>", + "<alyx_connector.files.parsing.File object at 0x000001B39681BA10>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "Will be included without change" + ], + [ + "1", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B39541CE30>", + "<alyx_connector.files.parsing.File object at 0x000001B39681B6B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "Will be included without change" + ], + [ + "2", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B39681B4A0>", + "<alyx_connector.files.parsing.File object at 0x000001B39681B710>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "Will be included without change" + ], + [ + "3", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B39681B410>", + "<alyx_connector.files.parsing.File object at 0x000001B39681B4D0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "Will be included without change" + ], + [ + "4", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B39681B140>", + "<alyx_connector.files.parsing.File object at 0x000001B39681AF60>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "Will be included without change" + ], + [ + "5", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B39681AE10>", + "<alyx_connector.files.parsing.File object at 0x000001B39681AED0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "Will be included without change" + ], + [ + "6", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B39681AB70>", + "<alyx_connector.files.parsing.File object at 0x000001B39681AC30>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "Will be included without change" + ], + [ + "7", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B39681A8D0>", + "<alyx_connector.files.parsing.File object at 0x000001B39681A990>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "Will be included without change" + ], + [ + "8", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B39681A630>", + "<alyx_connector.files.parsing.File object at 0x000001B39681A6F0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "Will be included without change" + ], + [ + "9", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B39681A390>", + "<alyx_connector.files.parsing.File object at 0x000001B39681A450>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "Will be included without change" + ], + [ + "10", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B39681A0F0>", + "<alyx_connector.files.parsing.File object at 0x000001B39681A1B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "Will be included without change" + ], + [ + "11", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396819E50>", + "<alyx_connector.files.parsing.File object at 0x000001B396819F10>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "Will be included without change" + ], + [ + "12", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396819BB0>", + "<alyx_connector.files.parsing.File object at 0x000001B396819C70>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "Will be included without change" + ], + [ + "13", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396819910>", + "<alyx_connector.files.parsing.File object at 0x000001B3968199D0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "Will be included without change" + ], + [ + "14", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396819670>", + "<alyx_connector.files.parsing.File object at 0x000001B396819730>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "Will be included without change" + ], + [ + "15", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B3968193D0>", + "<alyx_connector.files.parsing.File object at 0x000001B396819490>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "Will be included without change" + ], + [ + "16", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396819130>", + "<alyx_connector.files.parsing.File object at 0x000001B3968191F0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "Will be included without change" + ], + [ + "17", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396818E90>", + "<alyx_connector.files.parsing.File object at 0x000001B396818F50>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "Will be included without change" + ], + [ + "18", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396818BF0>", + "<alyx_connector.files.parsing.File object at 0x000001B396818CB0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "Will be included without change" + ], + [ + "19", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396818950>", + "<alyx_connector.files.parsing.File object at 0x000001B396818A10>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "Will be included without change" + ], + [ + "20", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B3968186B0>", + "<alyx_connector.files.parsing.File object at 0x000001B396818770>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "Will be included without change" + ], + [ + "21", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B3968187D0>", + "<alyx_connector.files.parsing.File object at 0x000001B3968184A0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "Will be included without change" + ], + [ + "22", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396818530>", + "<alyx_connector.files.parsing.File object at 0x000001B396818230>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "Will be included without change" + ], + [ + "23", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396807FB0>", + "<alyx_connector.files.parsing.File object at 0x000001B396807EC0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "Will be included without change" + ], + [ + "24", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396807F80>", + "<alyx_connector.files.parsing.File object at 0x000001B396807BF0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "Will be included without change" + ], + [ + "25", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396807D70>", + "<alyx_connector.files.parsing.File object at 0x000001B396807950>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "Will be included without change" + ], + [ + "26", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396807AD0>", + "<alyx_connector.files.parsing.File object at 0x000001B3968076B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "Will be included without change" + ], + [ + "27", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396807830>", + "<alyx_connector.files.parsing.File object at 0x000001B396807410>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "Will be included without change" + ], + [ + "28", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396807590>", + "<alyx_connector.files.parsing.File object at 0x000001B396807170>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "Will be included without change" + ], + [ + "29", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B3968072F0>", + "<alyx_connector.files.parsing.File object at 0x000001B396806ED0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "Will be included without change" + ], + [ + "30", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396807050>", + "<alyx_connector.files.parsing.File object at 0x000001B396806C30>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "Will be included without change" + ], + [ + "31", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396806DB0>", + "<alyx_connector.files.parsing.File object at 0x000001B396806990>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "Will be included without change" + ], + [ + "32", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396806B10>", + "<alyx_connector.files.parsing.File object at 0x000001B3968066F0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "Will be included without change" + ], + [ + "33", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396806870>", + "<alyx_connector.files.parsing.File object at 0x000001B396806450>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "Will be included without change" + ], + [ + "34", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B3968065D0>", + "<alyx_connector.files.parsing.File object at 0x000001B3968061B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "Will be included without change" + ], + [ + "35", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396806330>", + "<alyx_connector.files.parsing.File object at 0x000001B396805F10>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "Will be included without change" + ], + [ + "36", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396806090>", + "<alyx_connector.files.parsing.File object at 0x000001B396805C70>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "Will be included without change" + ], + [ + "37", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396805DF0>", + "<alyx_connector.files.parsing.File object at 0x000001B3968059D0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "Will be included without change" + ], + [ + "38", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396805B50>", + "<alyx_connector.files.parsing.File object at 0x000001B396805730>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "Will be included without change" + ], + [ + "39", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B3968058B0>", + "<alyx_connector.files.parsing.File object at 0x000001B396804F80>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "Will be included without change" + ], + [ + "40", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396805460>", + "<alyx_connector.files.parsing.File object at 0x000001B396804FE0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "Will be included without change" + ], + [ + "41", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396804E00>", + "<alyx_connector.files.parsing.File object at 0x000001B396804BC0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "Will be included without change" + ], + [ + "42", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B3968049E0>", + "<alyx_connector.files.parsing.File object at 0x000001B396804A40>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "Will be included without change" + ], + [ + "43", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396804860>", + "<alyx_connector.files.parsing.File object at 0x000001B396804620>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "Will be included without change" + ], + [ + "44", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396804440>", + "<alyx_connector.files.parsing.File object at 0x000001B3968044A0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "Will be included without change" + ], + [ + "45", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B396804320>", + "<alyx_connector.files.parsing.File object at 0x000001B396804080>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "Will be included without change" + ], + [ + "46", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B3967EBF50>", + "<alyx_connector.files.parsing.File object at 0x000001B3967EBFB0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "Will be included without change" + ], + [ + "47", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B3967EBFE0>", + "<alyx_connector.files.parsing.File object at 0x000001B3967EBBF0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "Will be included without change" + ], + [ + "48", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B3967EBA10>", + "<alyx_connector.files.parsing.File object at 0x000001B3967EB9B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "Will be included without change" + ], + [ + "49", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001B3967EB7D0>", + "<alyx_connector.files.parsing.File object at 0x000001B3967EB650>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "Will be included without change" + ] + ], + "shape": { + "columns": 16, + "rows": 1005 + } + }, + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>source_path</th>\n", + " <th>match</th>\n", + " <th>matching_rules</th>\n", + " <th>used_rule</th>\n", + " <th>valid_alf</th>\n", + " <th>path_conflicts</th>\n", + " <th>dataset_type_exists</th>\n", + " <th>rename</th>\n", + " <th>delete</th>\n", + " <th>include</th>\n", + " <th>abort</th>\n", + " <th>_source_file</th>\n", + " <th>_destination_file</th>\n", + " <th>_final_path</th>\n", + " <th>_final_pathstring</th>\n", + " <th>info</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_cam_sessings_include_rule]</td>\n", + " <td>behavior_cam_sessings_include_rule</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>...</th>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1000</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type:...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1001</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type ...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1002</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[include_test_data_rule]</td>\n", + " <td>include_test_data_rule</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1003</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[include_test_data_rule]</td>\n", + " <td>include_test_data_rule</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1004</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[include_test_data_rule]</td>\n", + " <td>include_test_data_rule</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>1005 rows × 16 columns</p>\n", + "</div>" + ], + "text/plain": [ + " source_path match \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "... ... ... \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "1002 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "1003 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "1004 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "\n", + " matching_rules \\\n", + "0 [behavior_cam_sessings_include_rule] \n", + "1 [behavior_whiskers_rule1] \n", + "2 [behavior_whiskers_rule1] \n", + "3 [behavior_whiskers_rule1] \n", + "4 [behavior_whiskers_rule1] \n", + "... ... \n", + "1000 [] \n", + "1001 [] \n", + "1002 [include_test_data_rule] \n", + "1003 [include_test_data_rule] \n", + "1004 [include_test_data_rule] \n", + "\n", + " used_rule valid_alf path_conflicts \\\n", + "0 behavior_cam_sessings_include_rule True False \n", + "1 behavior_whiskers_rule1 True False \n", + "2 behavior_whiskers_rule1 True False \n", + "3 behavior_whiskers_rule1 True False \n", + "4 behavior_whiskers_rule1 True False \n", + "... ... ... ... \n", + "1000 True False \n", + "1001 False False \n", + "1002 include_test_data_rule True False \n", + "1003 include_test_data_rule True False \n", + "1004 include_test_data_rule True False \n", + "\n", + " dataset_type_exists rename delete include abort \\\n", + "0 True False False True [] \n", + "1 True False False True [] \n", + "2 True False False True [] \n", + "3 True False False True [] \n", + "4 True False False True [] \n", + "... ... ... ... ... ... \n", + "1000 False False False False [] \n", + "1001 False False False False [] \n", + "1002 True False False True [] \n", + "1003 True False False True [] \n", + "1004 True False False True [] \n", + "\n", + " _source_file \\\n", + "0 <alyx_connector.files.parsing.File object at 0... \n", + "1 <alyx_connector.files.parsing.File object at 0... \n", + "2 <alyx_connector.files.parsing.File object at 0... \n", + "3 <alyx_connector.files.parsing.File object at 0... \n", + "4 <alyx_connector.files.parsing.File object at 0... \n", + "... ... \n", + "1000 <alyx_connector.files.parsing.File object at 0... \n", + "1001 <alyx_connector.files.parsing.File object at 0... \n", + "1002 <alyx_connector.files.parsing.File object at 0... \n", + "1003 <alyx_connector.files.parsing.File object at 0... \n", + "1004 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _destination_file \\\n", + "0 <alyx_connector.files.parsing.File object at 0... \n", + "1 <alyx_connector.files.parsing.File object at 0... \n", + "2 <alyx_connector.files.parsing.File object at 0... \n", + "3 <alyx_connector.files.parsing.File object at 0... \n", + "4 <alyx_connector.files.parsing.File object at 0... \n", + "... ... \n", + "1000 <alyx_connector.files.parsing.File object at 0... \n", + "1001 <alyx_connector.files.parsing.File object at 0... \n", + "1002 <alyx_connector.files.parsing.File object at 0... \n", + "1003 <alyx_connector.files.parsing.File object at 0... \n", + "1004 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _final_path \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "... ... \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1002 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1003 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1004 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "\n", + " _final_pathstring \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "... ... \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1002 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1003 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1004 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "\n", + " info \n", + "0 Will be included without change \n", + "1 Will be included without change \n", + "2 Will be included without change \n", + "3 Will be included without change \n", + "4 Will be included without change \n", + "... ... \n", + "1000 Will be excluded without change dataset_type:... \n", + "1001 Will be excluded without change dataset_type ... \n", + "1002 Will be included without change \n", + "1003 Will be included without change \n", + "1004 Will be included without change \n", + "\n", + "[1005 rows x 16 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "config.apply_to_alyx(file_records)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14c7a09d", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "c9c1a7b2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'http://127.0.0.1:80/admin/actions/session/dc5a61db-cbb6-48dc-bcb9-310211c8512c/change/'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "connector.web_client.url + session.admin_url" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "0e6b55dc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'/admin/actions/session/dc5a61db-cbb6-48dc-bcb9-310211c8512c/change/'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "session.admin_url" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "7f1777e4", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.microsoft.datawrangler.viewer.v0+json": { + "columns": [ + { + "name": "index", + "rawType": "int64", + "type": "integer" + }, + { + "name": "source_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "match", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "matching_rules", + "rawType": "object", + "type": "unknown" + }, + { + "name": "used_rule", + "rawType": "object", + "type": "string" + }, + { + "name": "valid_alf", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "path_conflicts", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "dataset_type_exists", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "rename", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "delete", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "include", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "abort", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_source_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_destination_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_pathstring", + "rawType": "object", + "type": "string" + }, + { + "name": "info", + "rawType": "object", + "type": "string" + } + ], + "conversionMethod": "pd.DataFrame", + "ref": "6c71ce3e-ce48-4170-88b1-eade8cf9c05f", + "rows": [ + [ + "0", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "True", + "['behavior_cam_sessings_include_rule']", + "behavior_cam_sessings_include_rule ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF7F50>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF7E60>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "Will be included without change" + ], + [ + "1", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9D001D0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF7EC0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "Will be included without change" + ], + [ + "2", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF7F20>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF73E0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "Will be included without change" + ], + [ + "3", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF7C50>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF7D10>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "Will be included without change" + ], + [ + "4", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF79B0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF7A70>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "Will be included without change" + ], + [ + "5", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF76E0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF7500>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "Will be included without change" + ], + [ + "6", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF7440>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF7260>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "Will be included without change" + ], + [ + "7", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF71A0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF6FC0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "Will be included without change" + ], + [ + "8", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF6F00>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF6D20>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "Will be included without change" + ], + [ + "9", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF6C60>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF6A80>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "Will be included without change" + ], + [ + "10", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF69C0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF67E0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "Will be included without change" + ], + [ + "11", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF6720>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF6540>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "Will be included without change" + ], + [ + "12", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF6480>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF62A0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "Will be included without change" + ], + [ + "13", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF61E0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF6000>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "Will be included without change" + ], + [ + "14", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF5F40>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF5D60>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "Will be included without change" + ], + [ + "15", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF5CA0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF5AC0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "Will be included without change" + ], + [ + "16", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF5A00>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF5820>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "Will be included without change" + ], + [ + "17", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF5760>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF5580>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "Will be included without change" + ], + [ + "18", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF54C0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF52E0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "Will be included without change" + ], + [ + "19", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF5220>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF5040>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "Will be included without change" + ], + [ + "20", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF4F80>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF4DA0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "Will be included without change" + ], + [ + "21", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF4CE0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF4B00>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "Will be included without change" + ], + [ + "22", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF4A40>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF45C0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "Will be included without change" + ], + [ + "23", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF47A0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF4320>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "Will be included without change" + ], + [ + "24", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF4530>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF45F0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "Will be included without change" + ], + [ + "25", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF4680>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CF4170>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "Will be included without change" + ], + [ + "26", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDFEF0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDFF50>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "Will be included without change" + ], + [ + "27", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDF1D0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDFCB0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "Will be included without change" + ], + [ + "28", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDFDD0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDFA40>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "Will be included without change" + ], + [ + "29", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDF4A0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDF7A0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "Will be included without change" + ], + [ + "30", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDF200>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDF500>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "Will be included without change" + ], + [ + "31", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDEF60>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDF260>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "Will be included without change" + ], + [ + "32", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDECC0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDEFC0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "Will be included without change" + ], + [ + "33", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDEA20>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDED20>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "Will be included without change" + ], + [ + "34", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDE780>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDEA80>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "Will be included without change" + ], + [ + "35", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDE4E0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDE7E0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "Will be included without change" + ], + [ + "36", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDE240>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDE540>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "Will be included without change" + ], + [ + "37", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDDFA0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDE2A0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "Will be included without change" + ], + [ + "38", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDDD00>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDE000>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "Will be included without change" + ], + [ + "39", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDDA60>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDDD60>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "Will be included without change" + ], + [ + "40", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDD7C0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDDAC0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "Will be included without change" + ], + [ + "41", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDD520>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDD820>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "Will be included without change" + ], + [ + "42", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDD2B0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDD580>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "Will be included without change" + ], + [ + "43", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDD3A0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDD430>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "Will be included without change" + ], + [ + "44", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDD760>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDCF20>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "Will be included without change" + ], + [ + "45", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDCD40>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDCB00>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "Will be included without change" + ], + [ + "46", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDC920>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDC980>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "Will be included without change" + ], + [ + "47", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDC7A0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDC560>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "Will be included without change" + ], + [ + "48", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDC2C0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CDC1A0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "Will be included without change" + ], + [ + "49", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CC7EF0>", + "<alyx_connector.files.parsing.File object at 0x0000022AE9CC7C80>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "Will be included without change" + ] + ], + "shape": { + "columns": 16, + "rows": 1002 + } + }, + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>source_path</th>\n", + " <th>match</th>\n", + " <th>matching_rules</th>\n", + " <th>used_rule</th>\n", + " <th>valid_alf</th>\n", + " <th>path_conflicts</th>\n", + " <th>dataset_type_exists</th>\n", + " <th>rename</th>\n", + " <th>delete</th>\n", + " <th>include</th>\n", + " <th>abort</th>\n", + " <th>_source_file</th>\n", + " <th>_destination_file</th>\n", + " <th>_final_path</th>\n", + " <th>_final_pathstring</th>\n", + " <th>info</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_cam_sessings_include_rule]</td>\n", + " <td>behavior_cam_sessings_include_rule</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>...</th>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>997</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type:...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>998</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type:...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>999</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type:...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1000</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type:...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1001</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type ...</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>1002 rows × 16 columns</p>\n", + "</div>" + ], + "text/plain": [ + " source_path match \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "... ... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "\n", + " matching_rules \\\n", + "0 [behavior_cam_sessings_include_rule] \n", + "1 [behavior_whiskers_rule1] \n", + "2 [behavior_whiskers_rule1] \n", + "3 [behavior_whiskers_rule1] \n", + "4 [behavior_whiskers_rule1] \n", + "... ... \n", + "997 [] \n", + "998 [] \n", + "999 [] \n", + "1000 [] \n", + "1001 [] \n", + "\n", + " used_rule valid_alf path_conflicts \\\n", + "0 behavior_cam_sessings_include_rule True False \n", + "1 behavior_whiskers_rule1 True False \n", + "2 behavior_whiskers_rule1 True False \n", + "3 behavior_whiskers_rule1 True False \n", + "4 behavior_whiskers_rule1 True False \n", + "... ... ... ... \n", + "997 True False \n", + "998 True False \n", + "999 True False \n", + "1000 True False \n", + "1001 False False \n", + "\n", + " dataset_type_exists rename delete include abort \\\n", + "0 True False False True [] \n", + "1 True False False True [] \n", + "2 True False False True [] \n", + "3 True False False True [] \n", + "4 True False False True [] \n", + "... ... ... ... ... ... \n", + "997 False False False False [] \n", + "998 False False False False [] \n", + "999 False False False False [] \n", + "1000 False False False False [] \n", + "1001 False False False False [] \n", + "\n", + " _source_file \\\n", + "0 <alyx_connector.files.parsing.File object at 0... \n", + "1 <alyx_connector.files.parsing.File object at 0... \n", + "2 <alyx_connector.files.parsing.File object at 0... \n", + "3 <alyx_connector.files.parsing.File object at 0... \n", + "4 <alyx_connector.files.parsing.File object at 0... \n", + "... ... \n", + "997 <alyx_connector.files.parsing.File object at 0... \n", + "998 <alyx_connector.files.parsing.File object at 0... \n", + "999 <alyx_connector.files.parsing.File object at 0... \n", + "1000 <alyx_connector.files.parsing.File object at 0... \n", + "1001 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _destination_file \\\n", + "0 <alyx_connector.files.parsing.File object at 0... \n", + "1 <alyx_connector.files.parsing.File object at 0... \n", + "2 <alyx_connector.files.parsing.File object at 0... \n", + "3 <alyx_connector.files.parsing.File object at 0... \n", + "4 <alyx_connector.files.parsing.File object at 0... \n", + "... ... \n", + "997 <alyx_connector.files.parsing.File object at 0... \n", + "998 <alyx_connector.files.parsing.File object at 0... \n", + "999 <alyx_connector.files.parsing.File object at 0... \n", + "1000 <alyx_connector.files.parsing.File object at 0... \n", + "1001 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _final_path \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "\n", + " _final_pathstring \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "\n", + " info \n", + "0 Will be included without change \n", + "1 Will be included without change \n", + "2 Will be included without change \n", + "3 Will be included without change \n", + "4 Will be included without change \n", + "... ... \n", + "997 Will be excluded without change dataset_type:... \n", + "998 Will be excluded without change dataset_type:... \n", + "999 Will be excluded without change dataset_type:... \n", + "1000 Will be excluded without change dataset_type:... \n", + "1001 Will be excluded without change dataset_type ... \n", + "\n", + "[1002 rows x 16 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_records" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "f2bffb90", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.microsoft.datawrangler.viewer.v0+json": { + "columns": [ + { + "name": "index", + "rawType": "int64", + "type": "integer" + }, + { + "name": "source_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "match", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "matching_rules", + "rawType": "object", + "type": "unknown" + }, + { + "name": "used_rule", + "rawType": "object", + "type": "string" + }, + { + "name": "valid_alf", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "path_conflicts", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "dataset_type_exists", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "rename", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "delete", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "include", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "abort", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_source_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_destination_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_pathstring", + "rawType": "object", + "type": "string" + }, + { + "name": "info", + "rawType": "object", + "type": "string" + } + ], + "conversionMethod": "pd.DataFrame", + "ref": "321be72a-d466-474d-b27b-6d5a2c370b23", + "rows": [ + [ + "0", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "True", + "['behavior_cam_sessings_include_rule']", + "behavior_cam_sessings_include_rule ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06A0B30>", + "<alyx_connector.files.parsing.File object at 0x000001A7C06A06B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "Will be included without change" + ], + [ + "1", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06A0890>", + "<alyx_connector.files.parsing.File object at 0x000001A7C06A0410>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "Will be included without change" + ], + [ + "2", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06A05F0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C06A0170>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "Will be included without change" + ], + [ + "3", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06A0380>", + "<alyx_connector.files.parsing.File object at 0x000001A7C06A0440>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "Will be included without change" + ], + [ + "4", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06A01A0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C06A0500>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "Will be included without change" + ], + [ + "5", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06903B0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0693800>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "Will be included without change" + ], + [ + "6", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0693E00>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0693EC0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "Will be included without change" + ], + [ + "7", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0693950>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0693FB0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "Will be included without change" + ], + [ + "8", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06936B0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0693560>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "Will be included without change" + ], + [ + "9", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0693410>", + "<alyx_connector.files.parsing.File object at 0x000001A7C06932C0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "Will be included without change" + ], + [ + "10", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0693170>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0693020>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "Will be included without change" + ], + [ + "11", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0692ED0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0692D80>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "Will be included without change" + ], + [ + "12", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0692C30>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0692AE0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "Will be included without change" + ], + [ + "13", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0692990>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0692840>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "Will be included without change" + ], + [ + "14", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06926F0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C06925A0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "Will be included without change" + ], + [ + "15", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0692660>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0692720>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "Will be included without change" + ], + [ + "16", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06923C0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0692480>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "Will be included without change" + ], + [ + "17", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0692120>", + "<alyx_connector.files.parsing.File object at 0x000001A7C06921E0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "Will be included without change" + ], + [ + "18", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0691E80>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0691F40>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "Will be included without change" + ], + [ + "19", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0691BE0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0691CA0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "Will be included without change" + ], + [ + "20", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0691940>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0691A00>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "Will be included without change" + ], + [ + "21", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06916A0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0691760>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "Will be included without change" + ], + [ + "22", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06913D0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C06914C0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "Will be included without change" + ], + [ + "23", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0691160>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0691220>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "Will be included without change" + ], + [ + "24", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0690EC0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0690F80>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "Will be included without change" + ], + [ + "25", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0690C20>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0690CE0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "Will be included without change" + ], + [ + "26", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0690980>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0690A40>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "Will be included without change" + ], + [ + "27", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0690230>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0690110>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "Will be included without change" + ], + [ + "28", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0690500>", + "<alyx_connector.files.parsing.File object at 0x000001A7C06901A0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "Will be included without change" + ], + [ + "29", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067BFB0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C067B8F0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "Will be included without change" + ], + [ + "30", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067BE60>", + "<alyx_connector.files.parsing.File object at 0x000001A7C067BEC0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "Will be included without change" + ], + [ + "31", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067BBC0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C067BC20>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "Will be included without change" + ], + [ + "32", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067B950>", + "<alyx_connector.files.parsing.File object at 0x000001A7C067B770>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "Will be included without change" + ], + [ + "33", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067B6B0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C067B4D0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "Will be included without change" + ], + [ + "34", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067B410>", + "<alyx_connector.files.parsing.File object at 0x000001A7C067B230>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "Will be included without change" + ], + [ + "35", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067B170>", + "<alyx_connector.files.parsing.File object at 0x000001A7C067AF90>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "Will be included without change" + ], + [ + "36", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067AED0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C067ACF0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "Will be included without change" + ], + [ + "37", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067AC30>", + "<alyx_connector.files.parsing.File object at 0x000001A7C067AA50>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "Will be included without change" + ], + [ + "38", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067A990>", + "<alyx_connector.files.parsing.File object at 0x000001A7C067A7B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "Will be included without change" + ], + [ + "39", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067A6F0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C067A510>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "Will be included without change" + ], + [ + "40", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067A450>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0678170>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "Will be included without change" + ], + [ + "41", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C067A300>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0679D60>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "Will be included without change" + ], + [ + "42", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0679E20>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0679B80>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "Will be included without change" + ], + [ + "43", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06799A0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0679A60>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "Will be included without change" + ], + [ + "44", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0679880>", + "<alyx_connector.files.parsing.File object at 0x000001A7C06795E0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "Will be included without change" + ], + [ + "45", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0679400>", + "<alyx_connector.files.parsing.File object at 0x000001A7C06794C0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "Will be included without change" + ], + [ + "46", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06792E0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0679040>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "Will be included without change" + ], + [ + "47", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0678E60>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0678F20>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "Will be included without change" + ], + [ + "48", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C0678D40>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0678AA0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "Will be included without change" + ], + [ + "49", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001A7C06788C0>", + "<alyx_connector.files.parsing.File object at 0x000001A7C0678980>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "Will be included without change" + ] + ], + "shape": { + "columns": 16, + "rows": 1002 + } + }, + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>source_path</th>\n", + " <th>match</th>\n", + " <th>matching_rules</th>\n", + " <th>used_rule</th>\n", + " <th>valid_alf</th>\n", + " <th>path_conflicts</th>\n", + " <th>dataset_type_exists</th>\n", + " <th>rename</th>\n", + " <th>delete</th>\n", + " <th>include</th>\n", + " <th>abort</th>\n", + " <th>_source_file</th>\n", + " <th>_destination_file</th>\n", + " <th>_final_path</th>\n", + " <th>_final_pathstring</th>\n", + " <th>info</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_cam_sessings_include_rule]</td>\n", + " <td>behavior_cam_sessings_include_rule</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>...</th>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>997</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type n...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>998</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type n...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>999</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type n...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1000</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type n...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1001</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>1002 rows × 16 columns</p>\n", + "</div>" + ], + "text/plain": [ + " source_path match \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "... ... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "\n", + " matching_rules \\\n", + "0 [behavior_cam_sessings_include_rule] \n", + "1 [behavior_whiskers_rule1] \n", + "2 [behavior_whiskers_rule1] \n", + "3 [behavior_whiskers_rule1] \n", + "4 [behavior_whiskers_rule1] \n", + "... ... \n", + "997 [] \n", + "998 [] \n", + "999 [] \n", + "1000 [] \n", + "1001 [] \n", + "\n", + " used_rule valid_alf path_conflicts \\\n", + "0 behavior_cam_sessings_include_rule True False \n", + "1 behavior_whiskers_rule1 True False \n", + "2 behavior_whiskers_rule1 True False \n", + "3 behavior_whiskers_rule1 True False \n", + "4 behavior_whiskers_rule1 True False \n", + "... ... ... ... \n", + "997 True False \n", + "998 True False \n", + "999 True False \n", + "1000 True False \n", + "1001 False False \n", + "\n", + " dataset_type_exists rename delete include abort \\\n", + "0 True False False True [] \n", + "1 True False False True [] \n", + "2 True False False True [] \n", + "3 True False False True [] \n", + "4 True False False True [] \n", + "... ... ... ... ... ... \n", + "997 False False False False [] \n", + "998 False False False False [] \n", + "999 False False False False [] \n", + "1000 False False False False [] \n", + "1001 False False False False [] \n", + "\n", + " _source_file \\\n", + "0 <alyx_connector.files.parsing.File object at 0... \n", + "1 <alyx_connector.files.parsing.File object at 0... \n", + "2 <alyx_connector.files.parsing.File object at 0... \n", + "3 <alyx_connector.files.parsing.File object at 0... \n", + "4 <alyx_connector.files.parsing.File object at 0... \n", + "... ... \n", + "997 <alyx_connector.files.parsing.File object at 0... \n", + "998 <alyx_connector.files.parsing.File object at 0... \n", + "999 <alyx_connector.files.parsing.File object at 0... \n", + "1000 <alyx_connector.files.parsing.File object at 0... \n", + "1001 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _destination_file \\\n", + "0 <alyx_connector.files.parsing.File object at 0... \n", + "1 <alyx_connector.files.parsing.File object at 0... \n", + "2 <alyx_connector.files.parsing.File object at 0... \n", + "3 <alyx_connector.files.parsing.File object at 0... \n", + "4 <alyx_connector.files.parsing.File object at 0... \n", + "... ... \n", + "997 <alyx_connector.files.parsing.File object at 0... \n", + "998 <alyx_connector.files.parsing.File object at 0... \n", + "999 <alyx_connector.files.parsing.File object at 0... \n", + "1000 <alyx_connector.files.parsing.File object at 0... \n", + "1001 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _final_path \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "\n", + " _final_pathstring \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "\n", + " info \n", + "0 Will be included without change \n", + "1 Will be included without change \n", + "2 Will be included without change \n", + "3 Will be included without change \n", + "4 Will be included without change \n", + "... ... \n", + "997 Will be excluded without change dataset_type n... \n", + "998 Will be excluded without change dataset_type n... \n", + "999 Will be excluded without change dataset_type n... \n", + "1000 Will be excluded without change dataset_type n... \n", + "1001 Will be excluded without change dataset_type d... \n", + "\n", + "[1002 rows x 16 columns]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_records.to_dataframe()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "8870465e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "isinstance(file_records, list)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "4874e5dd", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.microsoft.datawrangler.viewer.v0+json": { + "columns": [ + { + "name": "index", + "rawType": "int64", + "type": "integer" + }, + { + "name": "source_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "match", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "matching_rules", + "rawType": "object", + "type": "unknown" + }, + { + "name": "used_rule", + "rawType": "object", + "type": "string" + }, + { + "name": "valid_alf", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "path_conflicts", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "dataset_type_exists", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "rename", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "delete", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "include", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "abort", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_source_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_destination_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_pathstring", + "rawType": "object", + "type": "string" + }, + { + "name": "info", + "rawType": "object", + "type": "string" + } + ], + "conversionMethod": "pd.DataFrame", + "ref": "1286bcdd-7b22-44ab-83a3-a7564f51ffe0", + "rows": [ + [ + "0", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "True", + "['behavior_cam_sessings_include_rule']", + "behavior_cam_sessings_include_rule ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3F04200>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3F04740>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "Will be included without change" + ], + [ + "1", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3F045C0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF7CE0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "Will be included without change" + ], + [ + "2", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF4080>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF7A70>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "Will be included without change" + ], + [ + "3", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF7530>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF7D70>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "Will be included without change" + ], + [ + "4", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF7E60>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF7AD0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "Will be included without change" + ], + [ + "5", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF7BC0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF6FF0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "Will be included without change" + ], + [ + "6", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF7920>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF6D50>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "Will be included without change" + ], + [ + "7", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF7680>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF6AB0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "Will be included without change" + ], + [ + "8", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF73E0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF6810>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "Will be included without change" + ], + [ + "9", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF7140>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF6570>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "Will be included without change" + ], + [ + "10", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF6EA0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF62D0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "Will be included without change" + ], + [ + "11", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF6C00>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF6030>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "Will be included without change" + ], + [ + "12", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF6960>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF5D90>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "Will be included without change" + ], + [ + "13", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF66C0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF5AF0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "Will be included without change" + ], + [ + "14", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF6420>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF5850>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "Will be included without change" + ], + [ + "15", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF6180>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF55B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "Will be included without change" + ], + [ + "16", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF5EE0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF5310>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "Will be included without change" + ], + [ + "17", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF5C40>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF5070>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "Will be included without change" + ], + [ + "18", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF59A0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF4DD0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "Will be included without change" + ], + [ + "19", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF5700>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF4B30>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "Will be included without change" + ], + [ + "20", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF5190>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF5040>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "Will be included without change" + ], + [ + "21", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF4EF0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF4DA0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "Will be included without change" + ], + [ + "22", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF4C50>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF4B00>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "Will be included without change" + ], + [ + "23", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF49B0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF4860>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "Will be included without change" + ], + [ + "24", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF4470>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF41A0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "Will be included without change" + ], + [ + "25", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF4740>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF43B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "Will be included without change" + ], + [ + "26", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF4800>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EF4200>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "Will be included without change" + ], + [ + "27", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDF890>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDFDA0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "Will be included without change" + ], + [ + "28", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDFE30>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDFC50>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "Will be included without change" + ], + [ + "29", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDFBC0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDFC80>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "Will be included without change" + ], + [ + "30", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDF920>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDF9E0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "Will be included without change" + ], + [ + "31", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDF680>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDF740>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "Will be included without change" + ], + [ + "32", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDF3E0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDF4A0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "Will be included without change" + ], + [ + "33", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDF140>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDF200>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "Will be included without change" + ], + [ + "34", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDEEA0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDEF60>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "Will be included without change" + ], + [ + "35", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDEC00>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDECC0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "Will be included without change" + ], + [ + "36", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDE960>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDEA20>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "Will be included without change" + ], + [ + "37", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDE6C0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDE780>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "Will be included without change" + ], + [ + "38", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDE420>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDE4E0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "Will be included without change" + ], + [ + "39", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDE180>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDE240>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "Will be included without change" + ], + [ + "40", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDDEE0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDDFA0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "Will be included without change" + ], + [ + "41", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDDC40>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDDD00>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "Will be included without change" + ], + [ + "42", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDD9A0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDDA60>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "Will be included without change" + ], + [ + "43", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDD7F0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDD850>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "Will be included without change" + ], + [ + "44", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDD0D0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDD130>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "Will be included without change" + ], + [ + "45", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDCF50>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDCD10>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "Will be included without change" + ], + [ + "46", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDCB30>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDCB90>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "Will be included without change" + ], + [ + "47", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDC9B0>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDC770>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "Will be included without change" + ], + [ + "48", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDC590>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDC5F0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "Will be included without change" + ], + [ + "49", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDC440>", + "<alyx_connector.files.parsing.File object at 0x000002A5B3EDC1D0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "Will be included without change" + ] + ], + "shape": { + "columns": 16, + "rows": 1002 + } + }, + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>source_path</th>\n", + " <th>match</th>\n", + " <th>matching_rules</th>\n", + " <th>used_rule</th>\n", + " <th>valid_alf</th>\n", + " <th>path_conflicts</th>\n", + " <th>dataset_type_exists</th>\n", + " <th>rename</th>\n", + " <th>delete</th>\n", + " <th>include</th>\n", + " <th>abort</th>\n", + " <th>_source_file</th>\n", + " <th>_destination_file</th>\n", + " <th>_final_path</th>\n", + " <th>_final_pathstring</th>\n", + " <th>info</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_cam_sessings_include_rule]</td>\n", + " <td>behavior_cam_sessings_include_rule</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>...</th>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>997</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type n...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>998</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type n...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>999</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type n...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1000</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type n...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1001</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>1002 rows × 16 columns</p>\n", + "</div>" + ], + "text/plain": [ + " source_path match \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "... ... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "\n", + " matching_rules \\\n", + "0 [behavior_cam_sessings_include_rule] \n", + "1 [behavior_whiskers_rule1] \n", + "2 [behavior_whiskers_rule1] \n", + "3 [behavior_whiskers_rule1] \n", + "4 [behavior_whiskers_rule1] \n", + "... ... \n", + "997 [] \n", + "998 [] \n", + "999 [] \n", + "1000 [] \n", + "1001 [] \n", + "\n", + " used_rule valid_alf path_conflicts \\\n", + "0 behavior_cam_sessings_include_rule True False \n", + "1 behavior_whiskers_rule1 True False \n", + "2 behavior_whiskers_rule1 True False \n", + "3 behavior_whiskers_rule1 True False \n", + "4 behavior_whiskers_rule1 True False \n", + "... ... ... ... \n", + "997 True False \n", + "998 True False \n", + "999 True False \n", + "1000 True False \n", + "1001 False False \n", + "\n", + " dataset_type_exists rename delete include abort \\\n", + "0 True False False True [] \n", + "1 True False False True [] \n", + "2 True False False True [] \n", + "3 True False False True [] \n", + "4 True False False True [] \n", + "... ... ... ... ... ... \n", + "997 False False False False [] \n", + "998 False False False False [] \n", + "999 False False False False [] \n", + "1000 False False False False [] \n", + "1001 False False False False [] \n", + "\n", + " _source_file \\\n", + "0 <alyx_connector.files.parsing.File object at 0... \n", + "1 <alyx_connector.files.parsing.File object at 0... \n", + "2 <alyx_connector.files.parsing.File object at 0... \n", + "3 <alyx_connector.files.parsing.File object at 0... \n", + "4 <alyx_connector.files.parsing.File object at 0... \n", + "... ... \n", + "997 <alyx_connector.files.parsing.File object at 0... \n", + "998 <alyx_connector.files.parsing.File object at 0... \n", + "999 <alyx_connector.files.parsing.File object at 0... \n", + "1000 <alyx_connector.files.parsing.File object at 0... \n", + "1001 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _destination_file \\\n", + "0 <alyx_connector.files.parsing.File object at 0... \n", + "1 <alyx_connector.files.parsing.File object at 0... \n", + "2 <alyx_connector.files.parsing.File object at 0... \n", + "3 <alyx_connector.files.parsing.File object at 0... \n", + "4 <alyx_connector.files.parsing.File object at 0... \n", + "... ... \n", + "997 <alyx_connector.files.parsing.File object at 0... \n", + "998 <alyx_connector.files.parsing.File object at 0... \n", + "999 <alyx_connector.files.parsing.File object at 0... \n", + "1000 <alyx_connector.files.parsing.File object at 0... \n", + "1001 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _final_path \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "\n", + " _final_pathstring \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "\n", + " info \n", + "0 Will be included without change \n", + "1 Will be included without change \n", + "2 Will be included without change \n", + "3 Will be included without change \n", + "4 Will be included without change \n", + "... ... \n", + "997 Will be excluded without change dataset_type n... \n", + "998 Will be excluded without change dataset_type n... \n", + "999 Will be excluded without change dataset_type n... \n", + "1000 Will be excluded without change dataset_type n... \n", + "1001 Will be excluded without change dataset_type d... \n", + "\n", + "[1002 rows x 16 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(file_records.to_dataframe())" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "196dbe35", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.microsoft.datawrangler.viewer.v0+json": { + "columns": [ + { + "name": "index", + "rawType": "int64", + "type": "integer" + }, + { + "name": "source_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "match", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "matching_rules", + "rawType": "object", + "type": "unknown" + }, + { + "name": "used_rule", + "rawType": "object", + "type": "string" + }, + { + "name": "valid_alf", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "path_conflicts", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "dataset_type_exists", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "rename", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "delete", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "include", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "abort", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_source_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_destination_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_final_pathstring", + "rawType": "object", + "type": "string" + }, + { + "name": "info", + "rawType": "object", + "type": "string" + } + ], + "conversionMethod": "pd.DataFrame", + "ref": "536f656b-f570-4419-ad19-96f734742b61", + "rows": [ + [ + "0", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "True", + "['behavior_cam_sessings_include_rule']", + "behavior_cam_sessings_include_rule ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA007EF0>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA007C50>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "Will be included without change" + ], + [ + "1", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA007F20>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA007F80>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "Will be included without change" + ], + [ + "2", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA007470>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA007CB0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "Will be included without change" + ], + [ + "3", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA007DA0>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA007A10>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "Will be included without change" + ], + [ + "4", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA0076E0>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA007770>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "Will be included without change" + ], + [ + "5", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA007440>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA0074D0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "Will be included without change" + ], + [ + "6", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA0071A0>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA007230>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "Will be included without change" + ], + [ + "7", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA006F00>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA006F90>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "Will be included without change" + ], + [ + "8", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA006C60>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA006CF0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "Will be included without change" + ], + [ + "9", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA0069C0>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA006A50>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "Will be included without change" + ], + [ + "10", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA006720>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA0067B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "Will be included without change" + ], + [ + "11", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA006480>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA006510>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "Will be included without change" + ], + [ + "12", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA0061E0>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA006270>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "Will be included without change" + ], + [ + "13", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA005F40>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA005FD0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "Will be included without change" + ], + [ + "14", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA005CA0>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA005D30>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "Will be included without change" + ], + [ + "15", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA005A00>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA005A90>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "Will be included without change" + ], + [ + "16", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA005760>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA0057F0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "Will be included without change" + ], + [ + "17", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA0054C0>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA005550>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "Will be included without change" + ], + [ + "18", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA005220>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA0052B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "Will be included without change" + ], + [ + "19", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA004F80>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA005010>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "Will be included without change" + ], + [ + "20", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA004CE0>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA004D70>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "Will be included without change" + ], + [ + "21", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA004A40>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA004AD0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "Will be included without change" + ], + [ + "22", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA004BC0>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA004830>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "Will be included without change" + ], + [ + "23", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA004170>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA004590>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "Will be included without change" + ], + [ + "24", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADAA004320>", + "<alyx_connector.files.parsing.File object at 0x000001ADAA0043E0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "Will be included without change" + ], + [ + "25", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEFCE0>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEFA70>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "Will be included without change" + ], + [ + "26", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEF500>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEF260>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "Will be included without change" + ], + [ + "27", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEFDA0>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEFE60>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "Will be included without change" + ], + [ + "28", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEF8F0>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEF530>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "Will be included without change" + ], + [ + "29", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEF650>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEF290>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "Will be included without change" + ], + [ + "30", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEF3B0>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEEFF0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "Will be included without change" + ], + [ + "31", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEF110>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEED50>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "Will be included without change" + ], + [ + "32", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEEE70>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEEAB0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "Will be included without change" + ], + [ + "33", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEEBD0>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEE810>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "Will be included without change" + ], + [ + "34", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEE930>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEE570>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "Will be included without change" + ], + [ + "35", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEE690>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEE2D0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "Will be included without change" + ], + [ + "36", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEE3F0>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEE030>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "Will be included without change" + ], + [ + "37", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEE150>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEDD90>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "Will be included without change" + ], + [ + "38", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEDEB0>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEDAF0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "Will be included without change" + ], + [ + "39", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEDC10>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FED850>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "Will be included without change" + ], + [ + "40", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FED970>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FED5B0>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "Will be included without change" + ], + [ + "41", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FED6D0>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FED340>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "Will be included without change" + ], + [ + "42", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEC110>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FED430>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "Will be included without change" + ], + [ + "43", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FECF20>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FED400>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "Will be included without change" + ], + [ + "44", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FECD40>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FECE00>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "Will be included without change" + ], + [ + "45", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FECC20>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEC980>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "Will be included without change" + ], + [ + "46", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEC7A0>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEC860>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "Will be included without change" + ], + [ + "47", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEC680>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FEC350>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "Will be included without change" + ], + [ + "48", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FDBEF0>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FDBD10>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "Will be included without change" + ], + [ + "49", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "True", + "['behavior_whiskers_rule1']", + "behavior_whiskers_rule1 ", + "True", + "False", + "True", + "False", + "False", + "True", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FDBDD0>", + "<alyx_connector.files.parsing.File object at 0x000001ADA9FDBE00>", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "Will be included without change" + ] + ], + "shape": { + "columns": 16, + "rows": 1002 + } + }, + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>source_path</th>\n", + " <th>match</th>\n", + " <th>matching_rules</th>\n", + " <th>used_rule</th>\n", + " <th>valid_alf</th>\n", + " <th>path_conflicts</th>\n", + " <th>dataset_type_exists</th>\n", + " <th>rename</th>\n", + " <th>delete</th>\n", + " <th>include</th>\n", + " <th>abort</th>\n", + " <th>_source_file</th>\n", + " <th>_destination_file</th>\n", + " <th>_final_path</th>\n", + " <th>_final_pathstring</th>\n", + " <th>info</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_cam_sessings_include_rule]</td>\n", + " <td>behavior_cam_sessings_include_rule</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td>behavior_whiskers_rule1</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>True</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be included without change</td>\n", + " </tr>\n", + " <tr>\n", + " <th>...</th>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>997</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type n...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>998</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type n...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>999</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type n...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1000</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>True</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type n...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1001</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>1002 rows × 16 columns</p>\n", + "</div>" + ], + "text/plain": [ + " source_path match \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "... ... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "\n", + " matching_rules \\\n", + "0 [behavior_cam_sessings_include_rule] \n", + "1 [behavior_whiskers_rule1] \n", + "2 [behavior_whiskers_rule1] \n", + "3 [behavior_whiskers_rule1] \n", + "4 [behavior_whiskers_rule1] \n", + "... ... \n", + "997 [] \n", + "998 [] \n", + "999 [] \n", + "1000 [] \n", + "1001 [] \n", + "\n", + " used_rule valid_alf path_conflicts \\\n", + "0 behavior_cam_sessings_include_rule True False \n", + "1 behavior_whiskers_rule1 True False \n", + "2 behavior_whiskers_rule1 True False \n", + "3 behavior_whiskers_rule1 True False \n", + "4 behavior_whiskers_rule1 True False \n", + "... ... ... ... \n", + "997 True False \n", + "998 True False \n", + "999 True False \n", + "1000 True False \n", + "1001 False False \n", + "\n", + " dataset_type_exists rename delete include abort \\\n", + "0 True False False True [] \n", + "1 True False False True [] \n", + "2 True False False True [] \n", + "3 True False False True [] \n", + "4 True False False True [] \n", + "... ... ... ... ... ... \n", + "997 False False False False [] \n", + "998 False False False False [] \n", + "999 False False False False [] \n", + "1000 False False False False [] \n", + "1001 False False False False [] \n", + "\n", + " _source_file \\\n", + "0 <alyx_connector.files.parsing.File object at 0... \n", + "1 <alyx_connector.files.parsing.File object at 0... \n", + "2 <alyx_connector.files.parsing.File object at 0... \n", + "3 <alyx_connector.files.parsing.File object at 0... \n", + "4 <alyx_connector.files.parsing.File object at 0... \n", + "... ... \n", + "997 <alyx_connector.files.parsing.File object at 0... \n", + "998 <alyx_connector.files.parsing.File object at 0... \n", + "999 <alyx_connector.files.parsing.File object at 0... \n", + "1000 <alyx_connector.files.parsing.File object at 0... \n", + "1001 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _destination_file \\\n", + "0 <alyx_connector.files.parsing.File object at 0... \n", + "1 <alyx_connector.files.parsing.File object at 0... \n", + "2 <alyx_connector.files.parsing.File object at 0... \n", + "3 <alyx_connector.files.parsing.File object at 0... \n", + "4 <alyx_connector.files.parsing.File object at 0... \n", + "... ... \n", + "997 <alyx_connector.files.parsing.File object at 0... \n", + "998 <alyx_connector.files.parsing.File object at 0... \n", + "999 <alyx_connector.files.parsing.File object at 0... \n", + "1000 <alyx_connector.files.parsing.File object at 0... \n", + "1001 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _final_path \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "\n", + " _final_pathstring \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... \n", + "\n", + " info \n", + "0 Will be included without change \n", + "1 Will be included without change \n", + "2 Will be included without change \n", + "3 Will be included without change \n", + "4 Will be included without change \n", + "... ... \n", + "997 Will be excluded without change dataset_type n... \n", + "998 Will be excluded without change dataset_type n... \n", + "999 Will be excluded without change dataset_type n... \n", + "1000 Will be excluded without change dataset_type n... \n", + "1001 Will be excluded without change dataset_type d... \n", + "\n", + "[1002 rows x 16 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_records_to_df(file_records, details = True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0b42a8be", + "metadata": {}, + "outputs": [], + "source": [ + "sessions = connector.search(subject=\"wm32\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9fcc38e7", + "metadata": {}, + "outputs": [], + "source": [ + "from alyx_connector.files.transfers.transfers import FileTransferManager" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "1dd01e13", + "metadata": {}, + "outputs": [], + "source": [ + "from alyx_connector.files.parsing import File, Matcher\n", + "from alyx_connector.files.expressions import Expressions\n", + "\n", + "from alyx_registrator import Config, file_records_to_df\n", + "config = Config()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "5713ac7c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Ordered by: internal time\n", + " List reduced from 219 to 1 due to restriction <'{built-in method builtins.isinstance}'>\n", + "\n", + "Function was called by...\n", + " ncalls tottime cumtime\n", + "{built-in method builtins.isinstance} <- 3 0.000 0.000 <frozen importlib._bootstrap>:1384(_handle_fromlist)\n", + " 1013 0.000 0.000 <frozen ntpath>:107(join)\n", + " 54242 0.008 0.008 <frozen ntpath>:179(splitroot)\n", + " 1002 0.000 0.000 <frozen ntpath>:564(normpath)\n", + " 2003 0.000 0.000 C:\\Python312\\Lib\\copy.py:61(copy)\n", + " 2003 0.000 0.000 C:\\Python312\\Lib\\copy.py:247(_reconstruct)\n", + " 16 0.000 0.000 C:\\Python312\\Lib\\enum.py:1528(__or__)\n", + " 10 0.000 0.000 C:\\Python312\\Lib\\enum.py:1538(__and__)\n", + " 194820 0.031 0.031 C:\\Python312\\Lib\\pathlib.py:358(__init__)\n", + " 4 0.000 0.000 C:\\Python312\\Lib\\typing.py:1439(__subclasscheck__)\n", + " 11457 0.003 0.003 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:381(evaluate)\n", + " 128612 0.019 0.019 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\expressions.py:228(search)\n", + " 32153 0.005 0.005 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:146(date)\n", + " 32153 0.007 0.007 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:228(extra)\n", + " 1 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\IPython\\core\\interactiveshell.py:3513(run_code)\n", + " 64 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\ipykernel\\ipkernel.py:775(_clean_thread_parent_frames)\n", + " 1 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\pandas\\core\\dtypes\\common.py:1040(needs_i8_conversion)\n", + " 1 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\pandas\\core\\dtypes\\common.py:1434(_is_dtype_type)\n", + " 2 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\pandas\\core\\indexes\\base.py:842(_engine)\n", + " 3 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\pandas\\core\\indexes\\base.py:5170(_get_engine_target)\n", + " 4 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\pandas\\core\\indexing.py:2765(check_dict_or_set_indexers)\n", + " 1 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\pandas\\core\\series.py:1095(__getitem__)\n", + " 1 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\traitlets\\traitlets.py:1527(_notify_observers)\n", + " 2 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\traitlets\\traitlets.py:2304(validate)\n", + " 2 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\traitlets\\traitlets.py:3474(validate)\n", + " 2 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\traitlets\\traitlets.py:3631(set)\n", + " 1 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\zmq\\eventloop\\zmqstream.py:546(_run_callback)\n", + " 7 0.000 0.000 c:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\.venv\\Lib\\site-packages\\zmq\\sugar\\socket.py:712(send_multipart)\n", + "\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "<pstats.Stats at 0x17bdfe13b60>" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stats.print_callers('{built-in method builtins.isinstance}')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "562c659a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 4955759 function calls (4925591 primitive calls) in 3.411 seconds\n", + "\n", + " Ordered by: internal time\n", + " List reduced from 219 to 50 due to restriction <50>\n", + "\n", + " ncalls tottime percall cumtime percall filename:lineno(function)\n", + " 1014 0.404 0.000 0.404 0.000 {built-in method nt._path_isfile}\n", + " 352385 0.298 0.000 0.298 0.000 {method 'search' of 're.Pattern' objects}\n", + " 32153 0.186 0.000 2.097 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:77(from_parts)\n", + " 321530 0.176 0.000 0.279 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:60(_check_unallowed_chars)\n", + " 321530 0.154 0.000 1.800 0.000 {built-in method builtins.setattr}\n", + " 97410 0.154 0.000 0.223 0.000 C:\\Python312\\Lib\\pathlib.py:358(__init__)\n", + " 64306 0.145 0.000 0.601 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\expressions.py:228(search)\n", + " 32153 0.111 0.000 0.953 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:108(root)\n", + " 54242 0.103 0.000 0.161 0.000 <frozen ntpath>:179(splitroot)\n", + " 43186 0.102 0.000 0.291 0.000 C:\\Python312\\Lib\\pathlib.py:387(_parse_path)\n", + " 105489 0.086 0.000 0.242 0.000 C:\\Python312\\Lib\\pathlib.py:437(__str__)\n", + " 351680 0.081 0.000 0.081 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:100(_raise_if_not_partname)\n", + "459583/459579 0.073 0.000 0.073 0.000 {built-in method builtins.isinstance}\n", + " 32153 0.070 0.000 0.099 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:179(revision)\n", + " 97410 0.065 0.000 0.288 0.000 C:\\Python312\\Lib\\pathlib.py:1158(__init__)\n", + " 12 0.062 0.005 0.062 0.005 {built-in method nt.listdir}\n", + " 75339 0.059 0.000 0.410 0.000 C:\\Python312\\Lib\\pathlib.py:551(drive)\n", + " 32153 0.059 0.000 0.203 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:166(collection)\n", + " 32153 0.057 0.000 2.507 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:87(from_path)\n", + " 128612 0.049 0.000 0.067 0.000 C:\\Python312\\Lib\\enum.py:197(__get__)\n", + " 64306 0.048 0.000 0.048 0.000 {method 'groupdict' of 're.Match' objects}\n", + " 43186 0.046 0.000 0.350 0.000 C:\\Python312\\Lib\\pathlib.py:407(_load_parts)\n", + " 97410 0.043 0.000 0.063 0.000 C:\\Python312\\Lib\\pathlib.py:1165(__new__)\n", + " 32153 0.042 0.000 2.554 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:87(source_file)\n", + " 30150 0.039 0.000 2.597 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:308(evaluate)\n", + "164780/134629 0.036 0.000 0.046 0.000 {built-in method builtins.getattr}\n", + " 32153 0.036 0.000 0.072 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:157(number)\n", + " 11457 0.032 0.000 2.640 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:381(evaluate)\n", + " 32153 0.031 0.000 0.066 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:248(extension)\n", + " 131566 0.030 0.000 0.030 0.000 {built-in method __new__ of type object at 0x00007FFDAF9F13D0}\n", + " 106490 0.028 0.000 0.028 0.000 {method 'startswith' of 'str' objects}\n", + " 129463 0.027 0.000 0.027 0.000 {method 'append' of 'list' objects}\n", + " 153667 0.025 0.000 0.025 0.000 {built-in method nt.fspath}\n", + " 32153 0.025 0.000 0.344 0.000 C:\\Python312\\Lib\\pathlib.py:749(is_absolute)\n", + " 42185 0.025 0.000 0.057 0.000 C:\\Python312\\Lib\\pathlib.py:429(_format_parsed_parts)\n", + " 68336 0.023 0.000 0.023 0.000 {method 'find' of 'str' objects}\n", + " 97428 0.022 0.000 0.022 0.000 {method 'replace' of 'str' objects}\n", + " 34156 0.022 0.000 0.031 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:69(__new__)\n", + " 32153 0.021 0.000 0.057 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:228(extra)\n", + " 87638 0.021 0.000 0.021 0.000 {built-in method sys.intern}\n", + " 32153 0.020 0.000 0.055 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:146(date)\n", + " 32153 0.018 0.000 0.050 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:194(object)\n", + " 32153 0.017 0.000 0.045 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:205(attribute)\n", + " 64306 0.016 0.000 0.016 0.000 {method 'endswith' of 'str' objects}\n", + " 30150 0.016 0.000 0.051 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:96(__getitem__)\n", + " 43186 0.015 0.000 0.015 0.000 {method 'split' of 'str' objects}\n", + " 86380 0.013 0.000 0.013 0.000 {built-in method builtins.len}\n", + " 32153 0.013 0.000 0.044 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:137(subject)\n", + " 42185 0.011 0.000 0.011 0.000 {method 'join' of 'str' objects}\n", + " 75339 0.011 0.000 0.011 0.000 C:\\Python312\\Lib\\pathlib.py:560(root)\n", + "\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "<pstats.Stats at 0x17bdfe13b60>" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import cProfile\n", + "import pstats\n", + "\n", + "profiler = cProfile.Profile()\n", + "profiler.enable()\n", + "\n", + "file_records = config.evaluate_session(session)\n", + "\n", + "profiler.disable()\n", + "stats = pstats.Stats(profiler).sort_stats('tottime')\n", + "stats.print_stats(50) # print top 10 functions by cumulative time" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "27308329", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.microsoft.datawrangler.viewer.v0+json": { + "columns": [ + { + "name": "index", + "rawType": "int64", + "type": "integer" + }, + { + "name": "source_path", + "rawType": "object", + "type": "unknown" + }, + { + "name": "match", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "matching_rules", + "rawType": "object", + "type": "unknown" + }, + { + "name": "used_rule", + "rawType": "object", + "type": "string" + }, + { + "name": "valid_alf", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "path_conflicts", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "dataset_type_exists", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "rename", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "delete", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "include", + "rawType": "bool", + "type": "boolean" + }, + { + "name": "abort", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_source_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "_destination_file", + "rawType": "object", + "type": "unknown" + }, + { + "name": "info", + "rawType": "object", + "type": "string" + } + ], + "conversionMethod": "pd.DataFrame", + "ref": "be605038-92d9-43b1-b299-0a6afce0e54b", + "rows": [ + [ + "0", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.camera_settings.whiskers.txt", + "True", + "['behavior_cam_sessings_include_rule']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE594F800>", + "<alyx_connector.files.parsing.File object at 0x000001EEE594F7D0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "1", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00000.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE594F950>", + "<alyx_connector.files.parsing.File object at 0x000001EEE594F9B0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "2", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00001.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE594FC20>", + "<alyx_connector.files.parsing.File object at 0x000001EEE594FB90>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "3", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00002.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE594FE00>", + "<alyx_connector.files.parsing.File object at 0x000001EEE594FD70>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "4", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00003.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE594F7A0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE594FF50>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "5", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00004.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598C200>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598C170>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "6", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00005.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598C3E0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598C350>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "7", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00006.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598C5C0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598C530>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "8", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00007.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598C7A0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598C710>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "9", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00008.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598C980>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598C8F0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "10", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00009.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598CB60>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598CAD0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "11", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00010.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598CD40>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598CCB0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "12", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00011.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598CF20>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598CE90>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "13", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00012.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598D0D0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598D040>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "14", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00013.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598D2B0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598D220>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "15", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00014.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598D490>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598D400>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "16", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00015.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598D6A0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598D610>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "17", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00016.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598D880>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598D7F0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "18", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00017.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598DA60>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598D9D0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "19", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00018.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598DC40>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598DBB0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "20", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00019.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598DE20>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598DD90>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "21", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00020.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598E000>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598DF70>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "22", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00021.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598E1E0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598E150>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "23", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00022.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598E3C0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598E330>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "24", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00023.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598E5A0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598E510>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "25", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00024.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598E780>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598E6F0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "26", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00025.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598E960>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598E8D0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "27", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00026.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598EB40>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598EAB0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "28", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00027.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598ED20>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598EC90>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "29", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00028.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598EF00>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598EE70>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "30", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00029.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598F0E0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598F050>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "31", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00030.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598F2F0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598F230>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "32", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00031.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598F4D0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598F440>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "33", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00032.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598F6B0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598F620>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "34", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00033.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598F890>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598F800>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "35", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00034.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598FA70>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598F9E0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "36", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00035.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598FC80>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598FBC0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "37", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00036.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE598FE60>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598FDD0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "38", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00037.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE597C080>", + "<alyx_connector.files.parsing.File object at 0x000001EEE598FFB0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "39", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00038.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE597C260>", + "<alyx_connector.files.parsing.File object at 0x000001EEE597C1D0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "40", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00039.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE597C350>", + "<alyx_connector.files.parsing.File object at 0x000001EEE597C3B0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "41", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00040.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE597C620>", + "<alyx_connector.files.parsing.File object at 0x000001EEE597C590>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "42", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00041.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE597C800>", + "<alyx_connector.files.parsing.File object at 0x000001EEE597C770>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "43", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00042.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE597C9E0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE597C950>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "44", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00043.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE597CBC0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE597CB30>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "45", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00044.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE597CDA0>", + "<alyx_connector.files.parsing.File object at 0x000001EEE597CD10>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "46", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00045.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE597CF80>", + "<alyx_connector.files.parsing.File object at 0x000001EEE597CEF0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "47", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00046.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE597D160>", + "<alyx_connector.files.parsing.File object at 0x000001EEE597D0D0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "48", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00047.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE597D340>", + "<alyx_connector.files.parsing.File object at 0x000001EEE597D2B0>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ], + [ + "49", + "\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem05\\2024-11-06\\002\\behaviour_imaging\\whiskers\\behaviour.video.whiskers.00048.tdms", + "True", + "['behavior_whiskers_rule1']", + "", + "False", + "False", + "False", + "False", + "False", + "False", + "[]", + "<alyx_connector.files.parsing.File object at 0x000001EEE597D520>", + "<alyx_connector.files.parsing.File object at 0x000001EEE597D490>", + "Will be excluded without change dataset_type doesn't follow alyx format dataset_type not existing " + ] + ], + "shape": { + "columns": 14, + "rows": 1002 + } + }, + "text/html": [ + "<div>\n", + "<style scoped>\n", + " .dataframe tbody tr th:only-of-type {\n", + " vertical-align: middle;\n", + " }\n", + "\n", + " .dataframe tbody tr th {\n", + " vertical-align: top;\n", + " }\n", + "\n", + " .dataframe thead th {\n", + " text-align: right;\n", + " }\n", + "</style>\n", + "<table border=\"1\" class=\"dataframe\">\n", + " <thead>\n", + " <tr style=\"text-align: right;\">\n", + " <th></th>\n", + " <th>source_path</th>\n", + " <th>match</th>\n", + " <th>matching_rules</th>\n", + " <th>used_rule</th>\n", + " <th>valid_alf</th>\n", + " <th>path_conflicts</th>\n", + " <th>dataset_type_exists</th>\n", + " <th>rename</th>\n", + " <th>delete</th>\n", + " <th>include</th>\n", + " <th>abort</th>\n", + " <th>_source_file</th>\n", + " <th>_destination_file</th>\n", + " <th>info</th>\n", + " </tr>\n", + " </thead>\n", + " <tbody>\n", + " <tr>\n", + " <th>0</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_cam_sessings_include_rule]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>2</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>3</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>4</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>True</td>\n", + " <td>[behavior_whiskers_rule1]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>...</th>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " <td>...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>997</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>998</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>999</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1000</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " <tr>\n", + " <th>1001</th>\n", + " <td>\\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem...</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td></td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>False</td>\n", + " <td>[]</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td><alyx_connector.files.parsing.File object at 0...</td>\n", + " <td>Will be excluded without change dataset_type d...</td>\n", + " </tr>\n", + " </tbody>\n", + "</table>\n", + "<p>1002 rows × 14 columns</p>\n", + "</div>" + ], + "text/plain": [ + " source_path match \\\n", + "0 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "1 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "2 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "3 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "4 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... True \n", + "... ... ... \n", + "997 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "998 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "999 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "1000 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "1001 \\\\157.99.138.167\\cajal_data2\\ONE\\Interhem\\ihem... False \n", + "\n", + " matching_rules used_rule valid_alf \\\n", + "0 [behavior_cam_sessings_include_rule] False \n", + "1 [behavior_whiskers_rule1] False \n", + "2 [behavior_whiskers_rule1] False \n", + "3 [behavior_whiskers_rule1] False \n", + "4 [behavior_whiskers_rule1] False \n", + "... ... ... ... \n", + "997 [] False \n", + "998 [] False \n", + "999 [] False \n", + "1000 [] False \n", + "1001 [] False \n", + "\n", + " path_conflicts dataset_type_exists rename delete include abort \\\n", + "0 False False False False False [] \n", + "1 False False False False False [] \n", + "2 False False False False False [] \n", + "3 False False False False False [] \n", + "4 False False False False False [] \n", + "... ... ... ... ... ... ... \n", + "997 False False False False False [] \n", + "998 False False False False False [] \n", + "999 False False False False False [] \n", + "1000 False False False False False [] \n", + "1001 False False False False False [] \n", + "\n", + " _source_file \\\n", + "0 <alyx_connector.files.parsing.File object at 0... \n", + "1 <alyx_connector.files.parsing.File object at 0... \n", + "2 <alyx_connector.files.parsing.File object at 0... \n", + "3 <alyx_connector.files.parsing.File object at 0... \n", + "4 <alyx_connector.files.parsing.File object at 0... \n", + "... ... \n", + "997 <alyx_connector.files.parsing.File object at 0... \n", + "998 <alyx_connector.files.parsing.File object at 0... \n", + "999 <alyx_connector.files.parsing.File object at 0... \n", + "1000 <alyx_connector.files.parsing.File object at 0... \n", + "1001 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " _destination_file \\\n", + "0 <alyx_connector.files.parsing.File object at 0... \n", + "1 <alyx_connector.files.parsing.File object at 0... \n", + "2 <alyx_connector.files.parsing.File object at 0... \n", + "3 <alyx_connector.files.parsing.File object at 0... \n", + "4 <alyx_connector.files.parsing.File object at 0... \n", + "... ... \n", + "997 <alyx_connector.files.parsing.File object at 0... \n", + "998 <alyx_connector.files.parsing.File object at 0... \n", + "999 <alyx_connector.files.parsing.File object at 0... \n", + "1000 <alyx_connector.files.parsing.File object at 0... \n", + "1001 <alyx_connector.files.parsing.File object at 0... \n", + "\n", + " info \n", + "0 Will be excluded without change dataset_type d... \n", + "1 Will be excluded without change dataset_type d... \n", + "2 Will be excluded without change dataset_type d... \n", + "3 Will be excluded without change dataset_type d... \n", + "4 Will be excluded without change dataset_type d... \n", + "... ... \n", + "997 Will be excluded without change dataset_type d... \n", + "998 Will be excluded without change dataset_type d... \n", + "999 Will be excluded without change dataset_type d... \n", + "1000 Will be excluded without change dataset_type d... \n", + "1001 Will be excluded without change dataset_type d... \n", + "\n", + "[1002 rows x 14 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_records_to_df(file_records, details = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "7b7cc42a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1002" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(file_records)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "55c3a86a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 939748 function calls (939733 primitive calls) in 0.571 seconds\n", + "\n", + " Ordered by: internal time\n", + " List reduced from 332 to 50 due to restriction <50>\n", + "\n", + " ncalls tottime percall cumtime percall filename:lineno(function)\n", + " 53195 0.051 0.000 0.051 0.000 {method 'search' of 're.Pattern' objects}\n", + " 4809 0.029 0.000 0.328 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:63(from_parts)\n", + " 49290 0.027 0.000 0.043 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:46(_check_unallowed_chars)\n", + " 49290 0.025 0.000 0.286 0.000 {built-in method builtins.setattr}\n", + " 9618 0.023 0.000 0.095 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\expressions.py:228(search)\n", + " 17724 0.021 0.000 0.035 0.000 C:\\Python312\\Lib\\pathlib.py:358(__init__)\n", + " 4809 0.018 0.000 0.153 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:94(root)\n", + " 11419 0.016 0.000 0.023 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:485(is_matching_rule)\n", + " 8109 0.016 0.000 0.025 0.000 <frozen ntpath>:179(splitroot)\n", + " 5409 0.014 0.000 0.042 0.000 C:\\Python312\\Lib\\pathlib.py:387(_parse_path)\n", + " 17724 0.013 0.000 0.048 0.000 C:\\Python312\\Lib\\pathlib.py:1158(__init__)\n", + "78103/78097 0.013 0.000 0.013 0.000 {built-in method builtins.isinstance}\n", + " 49290 0.012 0.000 0.012 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:86(_raise_if_not_partname)\n", + " 17331 0.012 0.000 0.033 0.000 C:\\Python312\\Lib\\pathlib.py:437(__str__)\n", + " 3807 0.012 0.000 0.035 0.000 C:\\Python312\\Lib\\copy.py:61(copy)\n", + " 4809 0.011 0.000 0.016 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:165(revision)\n", + " 19038 0.010 0.000 0.312 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:465(actions_cascade)\n", + " 1 0.010 0.010 0.503 0.503 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:755(actions_cascade)\n", + " 5109 0.010 0.000 0.034 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:152(collection)\n", + " 4809 0.009 0.000 0.393 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:73(from_path)\n", + " 10218 0.009 0.000 0.066 0.000 C:\\Python312\\Lib\\pathlib.py:551(drive)\n", + " 17724 0.008 0.000 0.012 0.000 C:\\Python312\\Lib\\pathlib.py:1165(__new__)\n", + " 19236 0.008 0.000 0.010 0.000 C:\\Python312\\Lib\\enum.py:197(__get__)\n", + " 300 0.007 0.000 0.008 0.000 {built-in method builtins.eval}\n", + " 5409 0.007 0.000 0.057 0.000 C:\\Python312\\Lib\\pathlib.py:407(_load_parts)\n", + " 9618 0.007 0.000 0.007 0.000 {method 'groupdict' of 're.Match' objects}\n", + " 19038 0.007 0.000 0.340 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:665(actions_cascade)\n", + " 40611 0.007 0.000 0.007 0.000 {built-in method builtins.getattr}\n", + " 3807 0.006 0.000 0.359 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:96(destination_file)\n", + " 26343 0.006 0.000 0.006 0.000 {built-in method __new__ of type object at 0x00007FFDAF9F13D0}\n", + " 4809 0.006 0.000 0.401 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:87(source_file)\n", + " 4809 0.006 0.000 0.011 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:143(number)\n", + " 3807 0.006 0.000 0.015 0.000 C:\\Python312\\Lib\\copy.py:247(_reconstruct)\n", + " 8616 0.006 0.000 0.008 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:55(__new__)\n", + "33678/33670 0.005 0.000 0.005 0.000 {built-in method builtins.len}\n", + " 4809 0.005 0.000 0.010 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:231(extension)\n", + " 25233 0.004 0.000 0.004 0.000 {built-in method nt.fspath}\n", + " 20838 0.004 0.000 0.004 0.000 {method 'get' of 'dict' objects}\n", + " 17425 0.004 0.000 0.004 0.000 {method 'append' of 'list' objects}\n", + " 15027 0.004 0.000 0.004 0.000 {method 'startswith' of 'str' objects}\n", + " 4809 0.004 0.000 0.056 0.000 C:\\Python312\\Lib\\pathlib.py:749(is_absolute)\n", + " 10818 0.004 0.000 0.004 0.000 {method 'find' of 'str' objects}\n", + " 3807 0.004 0.000 0.004 0.000 {method '__reduce_ex__' of 'object' objects}\n", + " 5409 0.003 0.000 0.006 0.000 C:\\Python312\\Lib\\pathlib.py:429(_format_parsed_parts)\n", + " 12918 0.003 0.000 0.003 0.000 {built-in method sys.intern}\n", + " 4809 0.003 0.000 0.009 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:132(date)\n", + " 13518 0.003 0.000 0.003 0.000 {method 'replace' of 'str' objects}\n", + " 5109 0.003 0.000 0.008 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:180(object)\n", + " 5109 0.003 0.000 0.007 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:191(attribute)\n", + " 300 0.003 0.000 0.205 0.001 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:592(rename)\n", + "\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "<pstats.Stats at 0x19eb2a892b0>" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import cProfile\n", + "import pstats\n", + "\n", + "profiler = cProfile.Profile()\n", + "profiler.enable()\n", + "\n", + "file_records = config.actions_cascade(file_records)\n", + "\n", + "profiler.disable()\n", + "stats = pstats.Stats(profiler).sort_stats('tottime')\n", + "stats.print_stats(50) # print top 10 functions by cumulative time" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f4d50053", + "metadata": {}, + "outputs": [], + "source": [ + "FileTransferManager(sessions).push_request(policies={\"destination_older\":\"ignore\"}).transfer()" + ] + }, { "cell_type": "code", "execution_count": 15, @@ -112,12 +11387,12 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "d21b3e1e", + "execution_count": 4, + "id": "780cf946", "metadata": {}, "outputs": [], "source": [ - "connector." + "existing_dst = connector.search(\"dataset-types\", details = False)" ] }, { @@ -450,60 +11725,6 @@ "sessions" ] }, - { - "cell_type": "code", - "execution_count": 18, - "id": "0ce5699f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "subject wm32\n", - "users []\n", - "location None\n", - "procedures []\n", - "lab HaissLab\n", - "projects []\n", - "type None\n", - "task_protocol \n", - "number 1\n", - "start_time 2025-04-09T20:36:41.648138+02:00\n", - "end_time None\n", - "narrative \n", - "parent_session None\n", - "n_correct_trials None\n", - "n_trials None\n", - "url http://127.0.0.1/sessions/a977f70d-38f7-4da8-a...\n", - "extended_qc None\n", - "qc NOT_SET\n", - "wateradmin_session_related []\n", - "data_dataset_session_related []\n", - "auto_datetime 2025-04-09T20:36:41.656298+02:00\n", - "alias wm32/2025-04-09/001\n", - "u_alias wm32_2025-04-09_001\n", - "path //157.99.138.167/cajal_data2/ONE/Adaptation/wm...\n", - "json None\n", - "probe_insertion []\n", - "notes []\n", - "default_data_repository_path //157.99.138.167/cajal_data2/ONE/Adaptation\n", - "default_data_repository_name Cajal2Adaptation\n", - "default_data_repository_pk 05baa8e4-5eb5-4214-a008-c9e5331004b0\n", - "rel_path wm32/2025-04-09/001\n", - "admin_url /admin/actions/session/a977f70d-38f7-4da8-adfd...\n", - "Name: a977f70d-38f7-4da8-adfd-8884dd42b5b3, dtype: object" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sessions = connector.search(id = \"a977f70d-38f7-4da8-adfd-8884dd42b5b3\")\n", - "sessions" - ] - }, { "cell_type": "code", "execution_count": 19, @@ -559,23 +11780,262 @@ }, { "cell_type": "code", - "execution_count": 2, - "id": "2a732e40", + "execution_count": 9, + "id": "c1d6ee83", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'//157.99.138.167/cajal_data2/ONE/Interhem/ihem05/2024-11-06/002'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "from alyx_connector.files.parsing import File, Matcher\n", - "from alyx_connector.files.expressions import Expressions\n" + "session.path" ] }, { "cell_type": "code", - "execution_count": 7, - "id": "1dd01e13", + "execution_count": 17, + "id": "f1638466", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "79.7198255" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum([v[2] for k,v in stats.stats.items()])" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "ac88c9fd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Set: 2.646561099914834\n", + "Regexp: 0.3690903000533581\n" + ] + } + ], + "source": [ + "import re\n", + "import timeit\n", + "\n", + "_unallowed_chars_set = {\"?\", \"*\", \":\", '\"', \"<\", \">\"}\n", + "_unallowed_chars_re = re.compile(r'[?*:\"><]')\n", + "\n", + "def check_set(variable):\n", + " return any(char in _unallowed_chars_set for char in variable)\n", + "\n", + "def check_re(variable):\n", + " return bool(_unallowed_chars_re.search(variable))\n", + "\n", + "test_str = \"this_is_a_test_string_with_no_unallowed_chars\"\n", + "\n", + "print(\"Set:\", timeit.timeit(lambda: check_set(test_str), number=1000000))\n", + "print(\"Regexp:\", timeit.timeit(lambda: check_re(test_str), number=1000000))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "a19154bc", "metadata": {}, "outputs": [], "source": [ - "from alyx_registrator import Config" + "profiler.dump_stats(\"profile_results.prof\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "ac400b74", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 145726694 function calls (144967324 primitive calls) in 79.720 seconds\n", + "\n", + " Ordered by: internal time\n", + " List reduced from 228 to 50 due to restriction <50>\n", + "\n", + " ncalls tottime percall cumtime percall filename:lineno(function)\n", + " 4744322 5.847 0.000 9.579 0.000 C:\\Python312\\Lib\\pathlib.py:358(__init__)\n", + " 4373811 5.533 0.000 8.682 0.000 <frozen ntpath>:179(splitroot)\n", + " 1095930 3.514 0.000 8.529 0.000 C:\\Python312\\Lib\\pathlib.py:387(_parse_path)\n", + " 4744322 3.376 0.000 12.955 0.000 C:\\Python312\\Lib\\pathlib.py:1158(__init__)\n", + " 3676320 2.972 0.000 3.680 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:45(_check_unallowed_chars)\n", + "17528008/17528004 2.672 0.000 2.672 0.000 {built-in method builtins.isinstance}\n", + " 735324 2.518 0.000 2.518 0.000 {method 'search' of 're.Pattern' objects}\n", + " 728418 2.467 0.000 7.767 0.000 <frozen ntpath>:107(join)\n", + " 367512 2.310 0.000 25.677 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:63(from_parts)\n", + " 1463442 2.199 0.000 20.365 0.000 C:\\Python312\\Lib\\pathlib.py:437(__str__)\n", + " 2185254 1.973 0.000 9.861 0.000 C:\\Python312\\Lib\\pathlib.py:380(with_segments)\n", + " 3676320 1.883 0.000 21.958 0.000 {built-in method builtins.setattr}\n", + " 4744322 1.878 0.000 2.874 0.000 C:\\Python312\\Lib\\pathlib.py:1165(__new__)\n", + " 735024 1.691 0.000 7.130 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\expressions.py:228(search)\n", + " 1095930 1.557 0.000 18.186 0.000 C:\\Python312\\Lib\\pathlib.py:407(_load_parts)\n", + " 10218550 1.472 0.000 1.472 0.000 {built-in method builtins.getattr}\n", + " 1463442 1.409 0.000 19.595 0.000 C:\\Python312\\Lib\\pathlib.py:551(drive)\n", + " 367512 1.379 0.000 11.507 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:94(root)\n", + " 2185254 1.342 0.000 11.202 0.000 C:\\Python312\\Lib\\pathlib.py:712(joinpath)\n", + " 8390318 1.305 0.000 1.305 0.000 {built-in method nt.fspath}\n", + " 364209 1.300 0.000 15.796 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:244(session_name)\n", + " 364209 1.259 0.000 4.625 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:274(filename)\n", + " 5469741 1.221 0.000 1.221 0.000 {method 'replace' of 'str' objects}\n", + " 4559217 1.146 0.000 1.146 0.000 {built-in method sys.intern}\n", + " 5114834 1.099 0.000 1.099 0.000 {built-in method __new__ of type object at 0x00007FFDAF9F13D0}\n", + " 3676320 0.951 0.000 0.951 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:86(_raise_if_not_partname)\n", + " 1092627 0.932 0.000 2.061 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:219(extras)\n", + " 367512 0.866 0.000 1.203 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:165(revision)\n", + "367511/70 0.865 0.000 0.011 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:85(source_file)\n", + " 2185254 0.829 0.000 12.031 0.000 C:\\Python312\\Lib\\pathlib.py:720(__truediv__)\n", + " 726612 0.821 0.000 11.932 0.000 C:\\Python312\\Lib\\pathlib.py:484(_str_normcase)\n", + " 3675112 0.802 0.000 0.802 0.000 {built-in method builtins.any}\n", + " 3641489 0.787 0.000 0.787 0.000 {method 'extend' of 'list' objects}\n", + " 3289592 0.786 0.000 0.786 0.000 {method 'append' of 'list' objects}\n", + " 2186748 0.758 0.000 0.758 0.000 {method 'split' of 'str' objects}\n", + "367511/70 0.734 0.000 0.011 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:73(from_path)\n", + " 1095930 0.728 0.000 1.898 0.000 C:\\Python312\\Lib\\pathlib.py:429(_format_parsed_parts)\n", + " 364209 0.724 0.000 21.270 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:315(session_path)\n", + " 367812 0.722 0.000 2.583 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:152(collection)\n", + " 2191860 0.713 0.000 0.713 0.000 {method 'find' of 'str' objects}\n", + " 364209 0.708 0.000 4.167 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:297(collection_subpath)\n", + " 735024 0.610 0.000 0.610 0.000 {method 'groupdict' of 're.Match' objects}\n", + " 1470048 0.600 0.000 0.823 0.000 C:\\Python312\\Lib\\enum.py:197(__get__)\n", + " 2183445 0.570 0.000 0.856 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:210(extra)\n", + " 603 0.549 0.001 79.129 0.131 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\ONE-registrator\\alyx_registrator\\registration.py:134(check_path_conflicts)\n", + " 1460139 0.513 0.000 0.513 0.000 {method 'join' of 'str' objects}\n", + " 367512 0.465 0.000 0.948 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:143(number)\n", + " 1467045 0.409 0.000 0.409 0.000 {method 'startswith' of 'str' objects}\n", + " 364209 0.406 0.000 17.381 0.000 C:\\Users\\tjostmou\\Documents\\Python\\__packages__\\alyx-connector\\src\\alyx_connector\\files\\parsing.py:240(session_name_as_path)\n", + " 363609 0.405 0.000 0.405 0.000 <string>:2(__eq__)\n", + "\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "<pstats.Stats at 0x13b62e3e0c0>" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stats = pstats.Stats(profiler).sort_stats('tottime')\n", + "stats.print_stats(50) # print top 10 functions by cumulative time" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "82ac9520", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['behaviour.camera_settings',\n", + " 'behaviour.video',\n", + " 'behaviour.video_compressed',\n", + " 'behaviour.video_compressed_meta']" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[name for name in config.dataset_types if \"behaviour\" in name]" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "d7f4ab2a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_records[0].destination_file.dataset_type in config.dataset_types" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "7d20d10b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_records[0].destination_file.is_dataset_type_valid" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "4bf7852a", + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'file_records' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mNameError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m file_records_to_df(\u001b[43mfile_records\u001b[49m, details = \u001b[38;5;28;01mTrue\u001b[39;00m)\n", + "\u001b[31mNameError\u001b[39m: name 'file_records' is not defined" + ] + } + ], + "source": [ + "file_records_to_df(file_records, details = True)" ] }, { diff --git a/src/alyx_connector/__init__.py b/src/alyx_connector/__init__.py index d779abe4871623ba0c2296b27a03028790e964ba..b50460a23500b536163b92af22a5d79d57156ad4 100644 --- a/src/alyx_connector/__init__.py +++ b/src/alyx_connector/__init__.py @@ -1,3 +1,3 @@ -__version__ = "2.1.30" +__version__ = "2.1.31" from .connector.core import Connector diff --git a/src/alyx_connector/connector/core.py b/src/alyx_connector/connector/core.py index f6ae37ead99e4bf5589d682965c883c7b4b89359..ec25aeebe58e397e3237600334da6e2ddef47e46 100644 --- a/src/alyx_connector/connector/core.py +++ b/src/alyx_connector/connector/core.py @@ -5,6 +5,7 @@ from tqdm import tqdm from ..utils import Singleton from ..web.clients import WebClient +from ..files.registration.rules_config import Config from typing import overload, Optional, NoReturn @@ -12,6 +13,36 @@ logger = getLogger(__name__) class Connector(metaclass=Singleton): + """Connector class for managing a singleton web client connection. + + This class provides methods to interact with a web client, including searching for sessions, registering sessions, + and converting results to pandas DataFrames or Series. It ensures that only one instance + of the Connector exists at any time. + + Attributes: + username (str): The username associated with the web client. + url (str): The URL of the web client. + + Methods: + setup(*args, **kwargs): + Sets up the web client and returns a Connector instance. + + search(endpoint="sessions", details=True, raises=True, **kwargs): + Searches for sessions or other resources at the specified endpoint. + + register(session_or_sessions): + Registers a session or multiple sessions with the connector. + + raise_if_search_empty(search_result): + Raises a ValueError if the search result is empty. + + results_to_pandas(request_result): + Converts the results from a request into a pandas DataFrame or Series. + + details_aggregation(search_result, endpoint): + Aggregates detailed results from a list of search results by retrieving additional + information from a specified endpoint. + """ _singleton_no_argument_only = True @@ -41,6 +72,12 @@ class Connector(metaclass=Singleton): search_result = self.raise_if_search_empty(search_result) return self.results_to_pandas(search_result) + def register(self, session_or_sessions=DataFrame | Series): + if isinstance(session_or_sessions, Series): + return Config(connector=self, session=session_or_sessions) + for _, session in session_or_sessions.iterrows(): + return Config(connector=self, session=session).registration_pipeline(session) + # @overload # def search(self, endpoint=..., id: str = ..., **kwargs) -> Series: ... @@ -158,1498 +195,1497 @@ class Connector(metaclass=Singleton): return detailed_results -if __name__ == "__main__": - - class WebConnector(metaclass=Singleton): - """An API for searching and loading data through the Alyx database""" - - def __init__( - self, - username=None, - password=None, - base_url=None, - cache_dir=None, - mode="auto", - data_access_mode="local", - wildcards=True, - **kwargs, - ): - """An API for searching and loading data through the Alyx database - - Parameters - ---------- - mode : str - Query mode, options include 'auto', 'local' (offline) and 'remote' (online only). Most - methods have a `query_type` parameter that can override the class mode. - wildcards : bool - If true, methods allow unix shell style pattern matching, otherwise regular - expressions are supported - cache_dir : str, Path - Path to the data files. If Alyx parameters have been set up for this location, - an OneAlyx instance is returned. If data_dir and base_url are None, the default - location is used. - base_url : str - An Alyx database URL. The URL must start with 'http'. - username : str - An Alyx database login username. - password : str - An Alyx database password. - cache_rest : str - If not in 'local' mode, this determines which http request types to cache. Default is - 'GET'. Use None to deactivate cache (not recommended). - """ - - # Load Alyx Web client - self.web_client = AlyxClient( - username=username, - password=password, - base_url=base_url, - cache_dir=cache_dir, - **kwargs, - ) - - self._registration_client = RegistrationClient(self) - - self.data_access_mode = data_access_mode - - self._search_endpoint = "sessions" - - # get parameters override if inputs provided - super().__init__(mode=mode, wildcards=wildcards, cache_dir=cache_dir) - - def set_data_access_mode(self, mode): - available_modes = [ - "local", - "remote", - ] # TODO : add ability to go auto mode later. (if possible, still have to think about it) - if mode in available_modes: - self.data_access_mode = mode - self.alyx.delete_cache() # delete rest cache in case there is local / remote path stored inside - else: - raise ValueError(f"data_access_mode must be one of : {available_modes}") - - def __repr__(self): - return f'One ({"off" if self.offline else "on"}line, {self.alyx.base_url})' - - def load_cache(self, cache_dir=None, clobber=False, tag=None): - """ - Load parquet cache files. If the local cache is sufficiently old, this method will query - the database for the location and creation date of the remote cache. If newer, it will be - download and loaded. - - Note: Unlike refresh_cache, this will always reload the local files at least once. - - Parameters - ---------- - cache_dir : str, pathlib.Path - An optional directory location of the parquet files, defaults to One.cache_dir. - clobber : bool - If True, query Alyx for a newer cache even if current (local) cache is recent. - tag : str - An optional Alyx dataset tag for loading cache tables containing a subset of datasets. - """ - _logger = logging.getLogger("load_cache") - cache_meta = self._cache.get("_meta", {}) - cache_dir = cache_dir or self.cache_dir - # If user provides tag that doesn't match current cache's tag, always download. - # NB: In the future 'database_tags' may become a list. - current_tags = [x.get("database_tags") for x in cache_meta.get("raw", {}).values() or [{}]] - tag = tag or current_tags[0] # For refreshes take the current tag as default - different_tag = any(x != tag for x in current_tags) - if not clobber or different_tag: - super().load_cache(cache_dir) # Load any present cache - cache_meta = self._cache.get("_meta", {}) # TODO Make walrus when we drop 3.7 support - expired = self._cache and cache_meta["expired"] - if not expired or self.mode in ("local", "remote"): - return - - # Warn user if expired - if cache_meta["expired"] and cache_meta.get("created_time", False) and not self.alyx.silent: - age = datetime.now() - cache_meta["created_time"] - t_str = f"{age.days} day(s)" if age.days >= 1 else f"{np.floor(age.seconds / (60 * 2))} hour(s)" - _logger.info(f"cache over {t_str} old") - - try: - # Determine whether a newer cache is available - cache_info = self.alyx.get(f'cache/info/{tag or ""}'.strip("/"), expires=True) - assert tag == cache_info.get("database_tags") - - # Check version compatibility - min_version = packaging.version.parse(cache_info.get("min_api_version", "0.0.0")) - if packaging.version.parse(alyx_connector.__version__) < min_version: - warnings.warn(f"Newer cache tables require ONE version {min_version} or greater") - return - - # Check whether remote cache more recent - remote_created = datetime.fromisoformat(cache_info["date_created"]) - local_created = cache_meta.get("created_time", None) - if local_created and (remote_created - local_created) < timedelta(minutes=1): - _logger.info("No newer cache available") - return - - # Download the remote cache files - _logger.info("Downloading remote caches...") - files = self.alyx.download_cache_tables(cache_info.get("location"), cache_dir) - assert any(files) - super().load_cache(cache_dir) # Reload cache after download - except (requests.exceptions.HTTPError, HTTPError) as ex: - _logger.debug(ex) - ## REMOVED THIS WARNING FOR NOW AS I CAN'T FIND IF IT IS ACTUALLY USEFULL TO HAVE A REMOTE CACHE WHEN - # SETUPING A LOCAL USE OF ALYX LIKE WE DO - # _logger.error('Failed to load the remote cache file') - self.mode = "remote" - except (ConnectionError, requests.exceptions.ConnectionError) as ex: - _logger.debug(ex) - _logger.error("Failed to connect to Alyx") - self.mode = "local" - - @property - def alyx(self): - """one.webclient.AlyxClient: The Alyx Web client""" - return self.web_client - - @property - def register(self): - return self._registration_client - - @property - def cache_dir(self): - """pathlib.Path: The location of the downloaded file cache""" - return self.web_client.cache_dir - - @util.refresh - def search_terms(self, query_type=None): - """ - Returns a list of search terms to be passed as kwargs to the search method - - Parameters - ---------- - query_type : str - If 'remote', the search terms are largely determined by the REST endpoint used - - Returns - ------- - tuple - Tuple of search strings - """ - if (query_type or self.mode) != "remote": - # Return search terms from REST schema - return self._search_terms - fields = self.alyx.rest_schemes[self._search_endpoint]["list"]["fields"] - # 'laboratory' already in search terms - excl = ("lab",) - return tuple({*self._search_terms, *(x["name"] for x in fields if x["name"] not in excl)}) - - def describe_dataset(self, dataset_type=None): - """Print a dataset type description. - - NB: This requires an Alyx database connection. - - Parameters - ---------- - dataset_type : str - A dataset type or dataset name - - Returns - ------- - dict - The Alyx dataset type record - """ - _logger = logging.getLogger("describe_dataset") - assert self.mode != "local" and not self.offline, "Unable to connect to Alyx in local mode" - if not dataset_type: - return self.alyx.rest("dataset-types", "list") - try: - assert isinstance(dataset_type, str) and not is_uuid_string(dataset_type) - _logger.disabled = True - out = self.alyx.rest("dataset-types", "read", dataset_type) - except (AssertionError, requests.exceptions.HTTPError): - # Try to get dataset type from dataset name - out = self.alyx.rest("dataset-types", "read", self.dataset2type(dataset_type)) - finally: - _logger.disabled = False - print(out["description"]) - return out - - def change_session_data_mode(self, session_details, mode): - session_details["full_path"] = session_details[mode + "_full_path"] - return session_details - - #### LIST DATASETS - @util.refresh - def list_datasets( - self, - eid=None, - details=False, - query_type=None, - as_mode=None, - no_cache=False, - **filters, - ) -> np.ndarray | pd.DataFrame | List[str]: - """_summary_ - - Args: - eid (str, optional): Session id (alias or pk). Does not need to be supplied only if - using session_details. Defaults to None. - details (bool, optional): If False, will only return a list of absolute file paths - (obtained from the column full_path of the dataset dataframe). - Otherwise will return a full dataframe of all datasets found for this session - Defaults to False. - query_type (str or None, optional): Wether to perform the metadata fetch - (only if using eid) from local cache or on alyx. If None, uses the current mode of - the connector instance. Defaults to None. - as_mode (str or None, optional): Wether to perform the full_path construction using - default current (None), 'local' or 'remote' mode. Defaults to None. - session_details (pd.Series, optional): The pandas series containing - data_dataset_session_related information. - If not supplied, the function must be supplied a session id (eid, first argument) - to get this session_details variable internally. Defaults to None. - - Other filtering keys are accepted : - (the value on wich you search must match perfectly. Key must also match any of the - below. key and values are case sensitive) - - extra - - object - - attribute - - subject - - date - - number - - revision - - collection - - extension - - - dataset_type - - name (from dataset, ex trials.eventTimelines) - - file_name - - - relative_path - - exists - - created_by - - created_datetime - - data_repository - - hash - - file_size - - tags - - Raises: - NotImplementedError: For now, using mode (metadata) local will not work as the cache system to retrive data - has not been tested for. - - Returns: - Union[list, pd.DataFrame]: A list of matching files full_paths (if details = False) or a dataframe of all - matching file records components and metadata. - """ - - import natsort - - _logger = logging.getLogger("list_datasets") - - def flatten_pathlist(x): - if isinstance(x, (list, tuple)): - return natsort.natsorted([a for i in x for a in flatten(i)]) - else: - return natsort.natsorted([x]) - - # OBTAINING A SESSION_DETAILS (IN WHICH RESIDES FILES INFO) - - data_access_mode = as_mode or self.data_access_mode - if hasattr(eid, "keys") and "data_dataset_session_related" in eid.keys(): - session_details = ( - eid.copy() - ) # either a pd.series of dict, copy and key getters/setters works both cases - try: - eid = session_details["id"] - except KeyError: - eid = session_details.name - session_details["id"] = eid - else: - _eid = eid - # Ensure we have a UUID str - eid = self.to_eid(eid) - if eid is None: - raise ValueError( - f"The session id {_eid} supplied seem to not be existing. Check that you are in 'remote' mode " - "(not data_access_mode) and check that the session exists on a webpage." - ) - if (query_type or self.mode) != "remote": - raise NotImplementedError - ## TODO : GET BACK THE DATA FROM THE CACHE AFTER CHANGE IN DATA MANAGEMENT METHODOLOGY - # return super().list_datasets(eid, details=details, query_type=query_type, **filters) - - session_details = self.to_session_details( - self.alyx.rest("sessions", "read", id=eid, query_type=query_type, no_cache=no_cache) - ) - # session, datasets = util.ses2records(self.alyx.rest('sessions', 'read', id=eid)) - # self._update_cache_from_records(sessions=session, datasets=datasets.copy() - # if datasets is not None else datasets) - # Add to cache tables # TODO : DO ADD THAT FUNCTIONNALITY AGAIN - - datasets = copy.deepcopy(session_details["data_dataset_session_related"]) - # copy to not change the session_details in case they are suplied by user as input - - file_records = [] - for dataset in datasets: - files = dataset.pop("file_records") - dataset["session#"] = dataset.pop("session") - dataset["dataset#"] = dataset.pop("id") - dataset["dataset_url"] = dataset.pop("url") - dataset["dataset_admin_url"] = dataset.pop("admin_url") - dataset["local_root"] = alyx_connector.params.get().LOCAL_ROOT - for file in files: - # file["file_url"] = file.pop("url") - # file["file_admin_url"] = file.pop("admin_url") - file["file#"] = file.pop("id") - file.update( - { - "remote_full_path": os.path.normpath( - os.path.join(dataset["remote_root"], file["relative_path"]) - ), - "local_full_path": os.path.normpath( - os.path.join(dataset["local_root"], file["relative_path"]) - ), - } - ) - # remote or local depending on current mode - file["full_path"] = file[data_access_mode + "_full_path"] - file.update(dataset) - file_records.append(file) - - dataframe = pd.DataFrame(file_records) - if dataframe.empty: - _logger.warning( - "No dataset found for this session. Are you sure you ran the file registration routine ?" - ) - return dataframe if details else [] - - dataframe.set_index(["session#", "dataset#", "file#"]) - - # FILTERING THE ROWS BASED ON USER INPUT - # query_string = ' & '.join([f'{k} == {repr(v)}' for k, v in filters.items()]) - if filters: - if "filename" in filters.keys(): - # allowing filename for retrocompatibility - filters["file_name"] = filters.pop("filename") - queries = [] - for key, value in filters.items(): - # if the columns correspunding to filter is object or string, we try to match using wildcard type - # syntax as input - # to do that we convert * wildcards to .* in regex and add a ^ and $ at start and end of pattern - # to force a complete string length match. - - if dataframe[key].dtype is npdtype("O") or dataframe[key].dtype is npdtype(str): - queries.append(f"{key}.str.match('^' + {repr(value).replace('*', '.*')} + '$') ") # - # if the columns is not a sting, we match it directly. - else: - queries.append(f"{key} == {value}") - - # example of a query string : query_string = "exists == True & subject.str.match('wm.*$')" - query_string = " & ".join(queries) - - try: - dataframe = dataframe.query(query_string, engine="python") - except (KeyError, pd.errors.UndefinedVariableError) as e: - raise KeyError(f"Cannot use the key {str(e)} to filter for datasets") - - return dataframe if details else list(dataframe["full_path"]) - - @util.refresh - def pid2eid(self, pid: str, query_type=None) -> Tuple[str, str]: - """ - Given an Alyx probe UUID string, returns the session id string and the probe label - (i.e. the ALF collection). - - NB: Requires a connection to the Alyx database. - - Parameters - ---------- - pid : str, uuid.UUID - A probe UUID - query_type : str - Query mode - options include 'remote', and 'refresh' - - Returns - ------- - str - Experiment ID (eid) - str - Probe label - """ - query_type = query_type or self.mode - if query_type != "remote": - self.refresh_cache(query_type) - if query_type == "local" and "insertions" not in self._cache.keys(): - raise NotImplementedError("Converting probe IDs required remote connection") - rec = self.alyx.rest("insertions", "read", id=str(pid)) - return rec["session"], rec["name"] - - #### SEARCH - def search( - self, - id=None, - *, - details=False, - query_type=None, - as_mode=None, - no_cache=False, - **kwargs, - ): - """ - Searches sessions matching the given criteria and returns a list of matching eids - - For a list of search terms, use the method - - one.search_terms(query_type='remote') - - For all of the search parameters, a single value or list may be provided. For dataset, - the sessions returned will contain all listed datasets. For the other parameters, - the session must contain at least one of the entries. NB: Wildcards are not permitted, - however if wildcards property is False, regular expressions may be used for all but - number and date_range. - - Parameters - ---------- - dataset : str, list - List of dataset names. Returns sessions containing all these datasets. - A dataset matches if it contains the search string e.g. 'wheel.position' matches - '_ibl_wheel.position.npy' - date_range : str, list, datetime.datetime, datetime.date, pandas.timestamp - A single date to search or a list of 2 dates that define the range (inclusive). To - define only the upper or lower date bound, set the other element to None. - lab : str, list - A str or list of lab names, returns sessions from any of these labs - number : str, int - Number of session to be returned, i.e. number in sequence for a given date - subject : str, list - A list of subject nicknames, returns sessions for any of these subjects - task_protocol : str, list - The task protocol name (can be partial, i.e. any task protocol containing that str - will be found) - project(s) : str, list - The project name (can be partial, i.e. any task protocol containing that str - will be found) - performance_lte / performance_gte : float - Search only for sessions whose performance is less equal or greater equal than a - pre-defined threshold as a percentage (0-100) - users : str, list - A list of users - location : str, list - A str or list of lab location (as per Alyx definition) name - Note: this corresponds to the specific rig, not the lab geographical location per se - json : dict - example : - ```python - json = { - "whisker_stims": { - "amplitudes": { - "abstract__contains": ['10-0','10-10','10_90-0'] - } - } - } - ``` - allowed filter looups are listed here : - https://docs.djangoproject.com/en/5.0/ref/models/querysets/#field-lookups - - - dataset_types : str, list - One or more of dataset_types - details : bool - If true also returns a dict of dataset details - query_type : str, None - Query cache ('local') or Alyx database ('remote') - limit : int - The number of results to fetch in one go (if pagination enabled on server) - - - - - Returns - ------- - list - List of eids - (list of dicts) - If details is True, also returns a list of dictionaries, each entry corresponding to a - matching session - """ - _logger = logging.getLogger("search") - query_type = query_type or self.mode # we set query_type = self.mode if query_type is None - if query_type != "remote": - return super().search(details=details, query_type=query_type, **kwargs) - - # loop over input arguments and build the url - search_terms = self.search_terms(query_type=query_type) - params = {} # {"django": kwargs.pop("django", "")} - - if isinstance(id, (list, tuple)): - sessions = [] - for i in id: - sessions.append( - self.search( - id=i, details=details, as_mode=as_mode, no_cache=no_cache, query_type=query_type, **kwargs - ) - ) - return pd.DataFrame(sessions) - - if id is not None: - params["id"] = self.to_eid(id) - if params["id"] is None: # this means the id we supplied is not a valid eid - raise ValueError(f"{id} is not a valid identifier, could not convert it to session uuid.") - _logger.debug(f"kwargs : {kwargs}") - for key, value in sorted(kwargs.items()): - field = util.autocomplete(key, search_terms) # Validate and get full name - _logger.debug(f"field : {field}") - # check that the input matches one of the defined filters - if field == "date_range": - params[field] = [x.date().isoformat() for x in util.validate_date_range(value)] - elif field == "laboratory": - params["lab"] = value - else: - params[field] = value - _logger.debug(f"params : {params}") - # Make GET request - ses = self.alyx.rest( - self._search_endpoint, - "list", - no_cache=no_cache, - query_type=query_type, - **params, - ) - if len(ses) > 1: - _logger.info(f"Found {len(ses)} sessions.") - - if not details: - return [item["id"] for item in ses] - # list(util.LazyId(ses)) - - sess_df = [] - for session_short_info in tqdm(ses, total=len(ses), delay=2, desc="Loading session details", file=stdout): - session_detailed_info = self.alyx.rest( - "sessions", - "read", - id=session_short_info["id"], - no_cache=no_cache, - query_type=query_type, - ) - formated_session = self.to_session_details(session_detailed_info, as_mode=as_mode) - sess_df.append(formated_session) - - try: - sess_df = pd.DataFrame(sess_df) - sess_df.index = sess_df.index.set_names("id") - sess_df["start_datetime"] = pd.to_datetime(sess_df["start_datetime"], utc=True) - except (ValueError, KeyError): - warnings.warn("search result contained no entry") - pass # could not create a dataframe form session details. Returning dict instead - if id is not None: - return sess_df.iloc[0] - return sess_df - - def to_session_details(self, session_dict, as_mode=None): - data_access_mode = ( - as_mode or self.data_access_mode - ) # we set data_access_mode = self.data_access_mode if as_mode is None - - session_dict["date"] = str(datetime.fromisoformat(session_dict["start_time"]).date()) - session_dict["extended_qc"] = session_dict["extended_qc"] if session_dict["extended_qc"] is not None else {} - session_dict["local_path"] = os.path.normpath( - os.path.join(alyx_connector.params.get().LOCAL_ROOT, session_dict["rel_path"]) - ) - session_dict["remote_path"] = os.path.normpath( - session_dict["path"] - ) # path is the remote path initially (out from the database) - # we set path depending on the data_access_mode - session_dict["path"] = session_dict[data_access_mode + "_path"] - session_dict["rel_path"] = Path(session_dict["rel_path"]) - - session_dict["start_datetime"] = datetime.strptime(session_dict["start_time"], "%Y-%m-%dT%H:%M:%S%z") - - id = session_dict.pop("id") - - session_details = pd.Series(session_dict, name=id) - return session_details - - def _download_datasets(self, dsets, **kwargs) -> List[Path]: - """ - Download a single or multitude of datasets if stored on AWS, otherwise calls - OneAlyx._download_dataset. - - NB: This will not skip files that are already present. Use check_filesystem instead. - - Parameters - ---------- - dset : dict, str, pd.Series - A single or multitude of dataset dictionaries - - Returns - ------- - pathlib.Path - A local file path or list of paths - """ - # If all datasets exist on AWS, download from there. - _logger = logging.getLogger("_download_datasets") - try: - if "exists_aws" in dsets and np.all(np.equal(dsets["exists_aws"].values, True)): - _logger.info("Downloading from AWS") - return self._download_aws(map(lambda x: x[1], dsets.iterrows()), **kwargs) - except Exception as ex: - _logger.debug(ex) - return self._download_dataset(dsets, **kwargs) - - def _dset2url(self, dset, update_cache=True): - """ - Converts a dataset into a remote HTTP server URL. The dataset may be one or more of the - following: a dict from returned by the sessions endpoint or dataset endpoint, a record - from the datasets cache table, or a file path. Unlike record2url, this method can convert - dicts and paths to URLs. - - Parameters - ---------- - dset : dict, str, pd.Series, pd.DataFrame, list - A single or multitude of dataset dictionary from an Alyx REST query OR URL string - update_cache : bool - If True (default) and the dataset is from Alyx and cannot be converted to a URL, - 'exists' will be set to False in the corresponding entry in the cache table. - - Returns - ------- - str - The remote URL of the dataset - """ - _logger = logging.getLogger("_dset2url") - did = None - if isinstance(dset, str) and dset.startswith("http"): - url = dset - elif isinstance(dset, (str, Path)): - url = self.path2url(dset) - if not url: - _logger.warning(f"Dataset {dset} not found in cache") - return - elif isinstance(dset, (list, tuple)): - dset2url = partial(self._dset2url, update_cache=update_cache) - return list(flatten(map(dset2url, dset))) - else: - # check if dset is dataframe, iterate over rows - if hasattr(dset, "iterrows"): - dset2url = partial(self._dset2url, update_cache=update_cache) - url = list(map(lambda x: dset2url(x[1]), dset.iterrows())) - elif "data_url" in dset: # data_dataset_session_related dict - url = dset["data_url"] - did = dset["id"] - elif "file_records" not in dset: # Convert dataset Series to alyx dataset dict - url = self.record2url(dset) # NB: URL will always be returned but may not exist - is_int = all(isinstance(x, (int, np.int64)) for x in util.ensure_list(dset.name)) - did = np.array(dset.name)[-2:] if is_int else util.ensure_list(dset.name)[-1] - else: # from datasets endpoint - repo = getattr(getattr(self.web_client, "_par", None), "HTTP_DATA_SERVER", None) - url = next( - ( - fr["data_url"] - for fr in dset["file_records"] - if fr["data_url"] and fr["exists"] and fr["data_url"].startswith(repo or fr["data_url"]) - ), - None, - ) - did = dset["url"][-36:] - - # Update cache if url not found - if did is not None and not url and update_cache: - _logger.debug("Updating cache") - if isinstance(did, str) and self._index_type("datasets") is int: - (did,) = parquet.str2np(did).tolist() - elif self._index_type("datasets") is str and not isinstance(did, str): - did = parquet.np2str(did) - # NB: This will be considerably easier when IndexSlice supports Ellipsis - idx = [slice(None)] * int(self._cache["datasets"].index.nlevels / 2) - self._cache["datasets"].loc[(*idx, *util.ensure_list(did)), "exists"] = False - self._cache["_meta"]["modified_time"] = datetime.now() - - return url - - def _download_dataset(self, dset, cache_dir=None, update_cache=True, **kwargs) -> List[Path | None]: - """ - Download a single or multitude of dataset from an Alyx REST dictionary. - - NB: This will not skip files that are already present. Use check_filesystem instead. - - Parameters - ---------- - dset : dict, str, pd.Series, pd.DataFrame, list - A single or multitude of dataset dictionary from an Alyx REST query OR URL string - cache_dir : str, pathlib.Path - The root directory to save the data to (default taken from ONE parameters) - update_cache : bool - If true, the cache is updated when filesystem discrepancies are encountered - - Returns - ------- - pathlib.Path, list - A local file path or list of paths - """ - cache_dir = cache_dir or self.cache_dir - url = self._dset2url(dset, update_cache=update_cache) - if not url: - return - if isinstance(url, str): - target_dir = str(Path(cache_dir, get_alf_path(url)).parent) - return self._download_file(url, target_dir, **kwargs) - # must be list of URLs - valid_urls = list(filter(None, url)) - if not valid_urls: - return [None] * len(url) - target_dir = [str(Path(cache_dir, get_alf_path(x)).parent) for x in valid_urls] - files = self._download_file(valid_urls, target_dir, **kwargs) - # Return list of file paths or None if we failed to extract URL from dataset - return [None if not x else files.pop(0) for x in url] - - def _tag_mismatched_file_record(self, url): - fr = self.alyx.rest( - "files", - "list", - django=f'dataset,{Path(url).name.split(".")[-2]},data_repository__globus_is_personal,False', - no_cache=True, - ) - if len(fr) > 0: - json_field = fr[0]["json"] - if json_field is None: - json_field = {"mismatch_hash": True} - else: - json_field.update({"mismatch_hash": True}) - try: - self.alyx.rest( - "files", - "partial_update", - id=fr[0]["url"][-36:], - data={"json": json_field}, - ) - except requests.exceptions.HTTPError as ex: - warnings.warn( - f"Failed to tag remote file record mismatch: {ex}\nPlease contact the database administrator." - ) - - def _download_file(self, url, target_dir, keep_uuid=False, file_size=None, hash=None) -> Path | List[Path]: - """ - Downloads a single file or multitude of files from an HTTP webserver. - The webserver in question is set by the AlyxClient object. - - Parameters - ---------- - url : str, list - An absolute or relative URL for a remote dataset - target_dir : str, list - Absolute path of directory to download file to (including alf path) - keep_uuid : bool - If true, the UUID is not removed from the file name (default is False) - file_size : int, list - The expected file size or list of file sizes to compare with downloaded file - hash : str, list - The expected file hash or list of file hashes to compare with downloaded file - - Returns - ------- - pathlib.Path - The file path of the downloaded file or files. - - Example - ------- - >>> file_path = OneAlyx._download_file( - ... 'https://example.com/data.file.npy', '/home/Downloads/subj/1900-01-01/001/alf') - """ - assert not self.offline - # Ensure all target directories exist - [Path(x).mkdir(parents=True, exist_ok=True) for x in set(util.ensure_list(target_dir))] - - # download file(s) from url(s), returns file path(s) with UUID - local_path, md5 = self.alyx.download_file(url, target_dir=target_dir, return_md5=True) - - # check if url, hash, and file_size are lists - if isinstance(url, (tuple, list)): - assert (file_size is None) or len(file_size) == len(url) - assert (hash is None) or len(hash) == len(url) - for args in zip(*map(util.ensure_list, (file_size, md5, hash, local_path, url))): - self._check_hash_and_file_size_mismatch(*args) - - # check if we are keeping the uuid on the list of file names - if keep_uuid: - return local_path - - # remove uuids from list of file names - if isinstance(local_path, (list, tuple)): - return [alfio.remove_uuid_file(x) for x in local_path] - else: - return alfio.remove_uuid_file(local_path) - - def _check_hash_and_file_size_mismatch(self, file_size, hash, expected_hash, local_path, url): - """ - Check to ensure the hash and file size of a downloaded file matches what is on disk - - Parameters - ---------- - file_size : int - The expected file size to compare with downloaded file - hash : str - The expected file hash to compare with downloaded file - local_path: str - The path of the downloaded file - url : str - An absolute or relative URL for a remote dataset - """ - _logger = logging.getLogger("_check_hash_and_file_size_mismatch") - # verify hash size - hash = hash or hashfile.md5(local_path) - hash_mismatch = hash and hash != expected_hash - # verify file size - file_size_mismatch = file_size and Path(local_path).stat().st_size != file_size - # check if there is a mismatch in hash or file_size - if hash_mismatch or file_size_mismatch: - # post download, if there is a mismatch between Alyx and the newly downloaded file size - # or hash, flag the offending file record in Alyx for database for maintenance - hash_mismatch = expected_hash and expected_hash != hash - file_size_mismatch = file_size and Path(local_path).stat().st_size != file_size - if hash_mismatch or file_size_mismatch: - url = url or self.path2url(local_path) - _logger.debug(f"Tagging mismatch for {url}") - # tag the mismatched file records - self._tag_mismatched_file_record(url) - - @staticmethod - def setup(base_url=None, **kwargs): - """ - Set up OneAlyx for a given database - - Parameters - ---------- - base_url : str - An Alyx database URL. If None, the current default database is used. - **kwargs - Optional arguments to pass to one.params.setup. - - Returns - ------- - OneAlyx - An instance of OneAlyx for the newly set up database URL - """ - base_url = base_url or alyx_connector.params.get_default_client() - cache_map = alyx_connector.params.setup(client=base_url, **kwargs) - return OneAlyx(base_url=base_url or alyx_connector.params.get(cache_map.DEFAULT).ALYX_URL) - - @util.refresh - @util.parse_id - def eid2path(self, eid, query_type=None) -> util.Listable(Path): - """ - From an experiment ID gets the local session path - - Parameters - ---------- - eid : str, UUID, pathlib.Path, dict, list - Experiment session identifier; may be a UUID, URL, experiment reference string - details dict or Path. - query_type : str - If set to 'remote', will force database connection - - Returns - ------- - pathlib.Path, list - A session path or list of session paths - """ - - # first try avoid hitting the database - mode = query_type or self.mode - if mode != "remote": - cache_path = super().eid2path(eid) - if cache_path or mode == "local": - return cache_path - - # If eid is a list recurse through it and return a list - if isinstance(eid, list): - unwrapped = unwrap(self.path2eid) - return [unwrapped(self, e, query_type="remote") for e in eid] - - # if it wasn't successful, query Alyx - ses = self.alyx.rest("sessions", "list", django=f"pk,{eid}") - - if len(ses) == 0: - return None - - data_repository = ses[0]["default_data_repository"] - if data_repository is None: - data_repository = "" - - return os.path.join( - data_repository, - ses[0]["subject"], - ses[0]["start_time"][:10], - str(ses[0]["number"]).zfill(3), - ) - - @util.refresh - def path2eid(self, path_obj: Union[str, Path], query_type=None) -> util.Listable(Path): - import re - - """ - From a local path, gets the experiment ID - - Parameters - ---------- - path_obj : str, pathlib.Path, list - Local path or list of local paths - query_type : str - If set to 'remote', will force database connection - - Returns - ------- - str, list - An eid or list of eids - """ - # If path_obj is a list recurse through it and return a list - if isinstance(path_obj, list): - path_obj = [Path(x) for x in path_obj] - eid_list = [] - unwrapped = unwrap(self.path2eid) - for p in path_obj: - eid_list.append(unwrapped(self, p)) - return eid_list - # else ensure the path ends with mouse,date, number - try: - path_obj = re.findall(r"(\w+(?:\\|\/)\d{4}-\d{2}-\d{2}(?:\\|\/)\d+)", path_obj)[0] - except IndexError: # could not match anything - pass - - path_obj = Path(path_obj) - - # try the cached info to possibly avoid hitting database - mode = query_type or self.mode - if mode != "remote": - cache_eid = super().path2eid(path_obj) - if cache_eid or mode == "local": - return cache_eid - - session_path = get_session_path(path_obj) - # if path does not have a date and a number return None - if session_path is None: - return None - - # if not search for subj, date, number XXX: hits the DB - search = unwrap(self.search) - uuid = search( - subject=session_path.parts[-3], - date_range=session_path.parts[-2], - number=session_path.parts[-1], - query_type="remote", - ) - - # Return the uuid if any - return uuid[0] if uuid else None - - @util.refresh - def path2url(self, filepath, query_type=None) -> str: - """ - Given a local file path, returns the URL of the remote file. - - Parameters - ---------- - filepath : str, pathlib.Path - A local file path - query_type : str - If set to 'remote', will force database connection - - Returns - ------- - str - A URL string - """ - query_type = query_type or self.mode - if query_type != "remote": - return super().path2url(filepath) - eid = self.path2eid(filepath) - try: - (dataset,) = self.alyx.rest("datasets", "list", session=eid, name=Path(filepath).name) - return next(r["data_url"] for r in dataset["file_records"] if r["data_url"] and r["exists"]) - except (ValueError, StopIteration): - raise alferr.ALFObjectNotFound(f"File record for {filepath} not found on Alyx") - - @util.parse_id - def type2datasets(self, eid, dataset_type, details=False): - """ - Get list of datasets belonging to a given dataset type for a given session - - Parameters - ---------- - eid : str, UUID, pathlib.Path, dict - Experiment session identifier; may be a UUID, URL, experiment reference string - details dict or Path. - dataset_type : str, list - An Alyx dataset type, e.g. camera.times or a list of dtypes - details : bool - If True, a datasets DataFrame is returned - - Returns - ------- - np.ndarray, dict - A numpy array of data, or DataFrame if details is true - """ - assert self.mode != "local" and not self.offline, "Unable to connect to Alyx in local mode" - if isinstance(dataset_type, str): - restriction = f"session__id,{eid},dataset_type__name,{dataset_type}" - elif isinstance(dataset_type, collections.abc.Sequence): - restriction = f"session__id,{eid},dataset_type__name__in,{dataset_type}" - else: - raise TypeError("dataset_type must be a str or str list") - datasets = util.datasets2records(self.alyx.rest("datasets", "list", django=restriction)) - return datasets if details else datasets["rel_path"].sort_values().values - - def dataset2type(self, dset) -> str: - """Return dataset type from dataset. - - NB: Requires an Alyx database connection - - Parameters - ---------- - dset : str, np.ndarray, tuple - A dataset name, dataset uuid or dataset integer id - - Returns - ------- - str - The dataset type - """ - assert self.mode != "local" and not self.offline, "Unable to connect to Alyx in local mode" - # Ensure dset is a str uuid - if isinstance(dset, str) and not is_uuid_string(dset): - dset = self._dataset_name2id(dset) - if isinstance(dset, np.ndarray): - dset = parquet.np2str(dset)[0] - if isinstance(dset, tuple) and all(isinstance(x, int) for x in dset): - dset = parquet.np2str(np.array(dset)) - if not is_uuid_string(dset): - raise ValueError("Unrecognized name or UUID") - return self.alyx.rest("datasets", "read", id=dset)["dataset_type"] - - def describe_revision(self, revision, full=False): - """Print description of a revision - - Parameters - ---------- - revision : str - The name of the revision (without '#') - full : bool - If true, returns the matching record - - Returns - ------- - None, dict - None if full is false or no record found, otherwise returns record as dict - """ - assert self.mode != "local" and not self.offline, "Unable to connect to Alyx in local mode" - try: - rec = self.alyx.rest("revisions", "read", id=revision) - print(rec["description"]) - if full: - return rec - except requests.exceptions.HTTPError as ex: - if ex.response.status_code != 404: - raise ex - print(f'revision "{revision}" not found') - - def _dataset_name2id(self, dset_name, eid=None): - # TODO finish function - datasets = self.list_datasets(eid) if eid else self._cache["datasets"] - # Get ID of fist matching dset - for idx, rel_path in datasets["rel_path"].items(): - if rel_path.endswith(dset_name): - return idx[-1] # (eid, did) - raise ValueError(f"Dataset {dset_name} not found in cache") - - @util.refresh - @util.parse_id - def get_details(self, eid: str, full: bool = False, query_type=None): - """Return session details for a given session - - Parameters - ---------- - eid : str, UUID, pathlib.Path, dict, list - Experiment session identifier; may be a UUID, URL, experiment reference string - details dict or Path. - full : bool - If True, returns a DataFrame of session and dataset info - query_type : {'local', 'refresh', 'auto', 'remote'} - The query mode - if 'local' the details are taken from the cache tables; if 'remote' - the details are returned from the sessions REST endpoint; if 'auto' uses whichever - mode ONE is in; if 'refresh' reloads the cache before querying. - - Returns - ------- - pd.Series, pd.DataFrame, dict - in local mode - a session record or full DataFrame with dataset information if full is - True; in remote mode - a full or partial session dict - - Raises - ------ - ValueError - Invalid experiment ID (failed to parse into eid string) - requests.exceptions.HTTPError - [Errno 404] Remote session not found on Alyx - """ - if (query_type or self.mode) == "local": - return super().get_details(eid, full=full) - # If eid is a list of eIDs recurse through list and return the results - if isinstance(eid, list): - details_list = [] - for p in eid: - details_list.append(self.get_details(p, full=full)) - return details_list - # load all details - dets = self.alyx.rest("sessions", "read", eid) - if full: - return dets - # If it's not full return the normal output like from a one.search - det_fields = [ - "subject", - "start_time", - "number", - "lab", - "projects", - "url", - "task_protocol", - "local_path", - ] - out = {k: v for k, v in dets.items() if k in det_fields} - out["projects"] = ",".join(out["projects"]) - out.update( - { - "local_path": self.eid2path(eid), - "date": datetime.fromisoformat(out["start_time"]).date(), - } - ) - return out - - ### METHODS ADDED BY TIMOTHE TO EXTEND THE USE OF THE API - - def get_data_repository_path(self, repository_name): - repo_data = self.alyx.rest("data-repository", "read", repository_name) - repo_path = r"\\" + os.path.join(repo_data["hostname"], repo_data["globus_path"].lstrip("/")) - return os.path.normpath(repo_path) - - def read_sql(self, query): - raise NotImplementedError - - def create_session(self, data_dict): - import re - - data_dict = data_dict.copy() - data_dict["number"] = str(int(data_dict["number"])) # remove leading zeros if any - try: # a session have been found with same 3 parameters, don't allow to process to registering. - _searched_session = self.search( - subject=data_dict["subject"], - number=data_dict["number"], - date_range=data_dict["start_time"][:10], - users=data_dict["users"], - details=True, - ) - url = re.sub(r"\/sessions", r"/actions/session", _searched_session["url"].item()) - raise ValueError( - f"This session path is already registered ! See here : {url}\n You probably need to change the number " - "of the session for this animald/date combo" - ) - except KeyError: # no session have benn found, all is well, can proceed - pass - - self.alyx.rest("sessions", "create", data=data_dict) - - def default_session_data(self): - return {"lab": "HaissLab", "task_protocol": ""} - - @staticmethod - def explorer(path): - import subprocess - - path = os.path.normpath(path) - if not os.path.exists(path): - raise IOError(f"Path {path} does not exist") - if os.path.isfile(path): - path = os.path.dirname(path) - - pre_cmd = f"explorer.exe {path}" - subprocess.call(pre_cmd) - return - # this part is to open in atab instead of window. Buggy for now. - if path[:2] == r"\\": - pre_cmd = f"pushd {path}; " - # path = os.path.join(*[item for item in selected_folder.split(os.sep) if item != ''][1:]) - # #this removes the first object of the path - else: - pre_cmd = 'cd "{pateh}; "' - subprocess.call(pre_cmd + r"start .") - # subprocess.Popen(r'explorer '+f'{os.path.dirname(path)},select,{os.path.basename(path)}') - - def collection_path(self, eid, collections): - return os.path.join(self.current_remote_repository_path, self.eid2path(eid), collections) - - def set_current_remote_repository(self, repo_name): - self.current_remote_repository_path = self.get_data_repository_path(repo_name) - - def get_parts_from_path(self, input_path): - import re - - subject, date, number = re.findall(r"(\w+)(?:\\|\/)(\d{4}-\d{2}-\d{2})(?:\\|\/)(\d+)", input_path)[0] - return {"subject": subject, "date": date, "number": number} - - def get_json_params(self, eid): - return self.alyx.rest("sessions", "read", eid)["json"] - - def get_extended_qc(self, eid): - return self.alyx.rest("sessions", "read", eid)["extended_qc"] - - def display_session_info(self, session_details): - from IPython.display import Markdown, display - - session_data_link = f"[Data pathes](file:{os.path.normpath(session_details.path)}) pointing in {self.data_access_mode} mode." - metadatas_link = f"[Metadatas]({session_details.url}) obtained in {self.mode} mode." - uuid = f"(uuid is '{session_details.name}')" - display(Markdown(f"Session {session_details.rel_path}. {session_data_link} {metadatas_link} {uuid}")) - - @wraps(MultiSessionPlaceholder) - def multisession(*args, **kwargs): - return MultiSessionPlaceholder(*args, **kwargs) - - def update_session_info(self, session_details, json={}, extended_qc={}, **kwargs): - _logger = logging.getLogger("update_session_info") - - data = {} - if len(json): - base_json = session_details.json - if base_json is None: - base_json = {} - base_json.update(json) - data["json"] = base_json - - if len(extended_qc): - base_ext_qc = session_details.extended_qc - if base_ext_qc is None: - base_ext_qc = {} - base_ext_qc.update(extended_qc) - data["extended_qc"] = base_ext_qc - - data.update(kwargs) - - _logger.info(f"Updating session {session_details.rel_path}") - ans = input(f"Data OK ? (OK or Cancel) : {data}") - if ans != "OK": - _logger.info("Aborting") - return - _logger.info("Applying changes") - self.alyx.rest("sessions", "partial_update", id=session_details.name, data=data) - self.alyx.delete_cache() - - def push_files(self, file_list, *, session_details, relative=False, overwrite_policy="raise"): - """ - The function push_processed_files copies a list of files to a remote session directory, - and handles various overwrite policies. - - Args: - - - file_list (list of str): a list of local file paths to be copied to the remote session directory. - - session_details (SessionDetails): an object containing the session details. - - relative: If the string representing the path of the files are absolute or relative from - INSIDE the session folder (ex : 'D:\\LOCAL_DATA\\wm25\\2022-08-05\\001\\a_folder\\test.file' - is an absolute path and 'a_folder\test.file' is a relative path) - - overwrite_policy (str, optional): the overwrite policy. Possibilities are: - - "raise" (raise an exception if a file with the same name already exists in the remote directory), - - "skip" (skip copying the file if a file with the same name already exists in the remote directory), - - "overwrite" (overwrite the file with the same name in the remote directory), - - "most_recent" (copy the file only if it is more recent than the file - with the same name in the remote directory), - - "erase" (erase the existing file in the remote directory if a file with the same name already exists, - then copy a new one in place.) Prefer choosing overwrite in most situations). - - Default is "raise". - - Returns: - - a dictionary with two keys: - - "copied" : a list of file paths that have been copied to the remote session directory. - - "ignored" : a list of file paths that could not be copied (either because they were not found or - because they were excluded by the overwrite policy). - """ - - import shutil - - def get_relative_path(absolute_path, common_root_path): - """Compare an input path and a path with a common root with the input path, and returns only the part of - the input path that is not shared with the _common_root_path. - - Args: - input_path (TYPE): DESCRIPTION. - common_root_base (TYPE): DESCRIPTION. - - Returns: - TYPE: DESCRIPTION. - - """ - absolute_path = os.path.normpath(absolute_path) - common_root_path = os.path.normpath(common_root_path) - - commonprefix = os.path.commonprefix([common_root_path, absolute_path]) - if commonprefix == "": - raise IOError(f"These two pathes have no common root path : {absolute_path} and {common_root_path}") - return os.path.relpath(absolute_path, start=commonprefix) - - overwrite_policies = ["raise", "skip", "erase", "most_recent", "overwrite"] - if overwrite_policy not in overwrite_policies: - raise NotImplementedError( - f"Value {overwrite_policy} for overwrite_policy is not supported. " - f"Possibilities are : {overwrite_policies}" - ) - - session_local_root = session_details["local_path"] - session_remote_root = session_details["remote_path"] - - if not isinstance(file_list, (list, tuple, np.ndarray)): - file_list = [file_list] - - if relative: - file_list = [os.path.join(session_local_root, session_details.rel_path, file) for file in file_list] - - source_files = [] # file paths that have been copied - # files paths of the copies of the one in the list above (ordered similarly) - dest_files = [] - - overwrite_raise_list = ( - [] - ) # stores files that already exist in remote folder in case we have 'raise' overwrite_policy, to print to user - file_not_found_warning = [] - - # MAKE THE LIST OF FILES THAT WILL BE COPIED - for local_path in file_list: - if not os.path.isfile(local_path): - file_not_found_warning.append(local_path) - continue - - try: - relative_path = get_relative_path(local_path, session_local_root) - except IOError: - file_not_found_warning.append(local_path) - continue - - remote_path = os.path.join(session_remote_root, relative_path) - - if os.path.isfile(remote_path): - if overwrite_policy == "raise": - overwrite_raise_list.append(local_path) - elif overwrite_policy == "skip": - logging.getLogger().info(f"Skipping file {remote_path}") - continue - elif overwrite_policy == "erase": - os.remove(remote_path) - elif overwrite_policy == "most_recent": - if ( - os.stat(remote_path).st_mtime > os.stat(local_path).st_mtime - ): # remote_path is more recent (higher time value) - continue - elif overwrite_policy == "overwrite": - pass - # else if overwrite, we just do nothing and files will be overwritten during shutil.copy operation - - source_files.append(local_path) - dest_files.append(remote_path) - - if len(file_not_found_warning): - logging.getLogger().warning( - "These files were not found or are not inside the session local folder, " - f"and therefore cannot be copied :\nFiles:\n{file_not_found_warning}" - ) - - if len(overwrite_raise_list): - raise IOError( - f"The files listed below already exist in the destination : {session_remote_root}\n" - "No file have been copied to avoid mistakes. " - "You can check the content of the destination folder manually, " - "or change the 'overwrite_policy' argument of this function (beware of data losses !).\n" - f"Files :\n {overwrite_raise_list}" - ) - - # APPLY THE COPY - for local_path, remote_path in zip(source_files, dest_files): - container_dir = os.path.dirname(remote_path) - # make destination dir if it doesn't exist already - os.makedirs(container_dir, exist_ok=True) - shutil.copy(local_path, remote_path) - - return { - "copied": source_files, - "ignored": list(set(file_list).difference(set(source_files))), - } - - def copy_files(self, source_file_list, source_root, destination_root, overwrite_policy="raise"): - def get_relative_path(absolute_path, common_root_path): - """ - Compare an input path and a path with a common root with the input path, and returns only the part of the - input path that is not shared with the _common_root_path. - - Args: - input_path (TYPE): DESCRIPTION. - common_root_base (TYPE): DESCRIPTION. - - Returns: - TYPE: DESCRIPTION. - - """ - absolute_path = os.path.normpath(absolute_path) - common_root_path = os.path.normpath(common_root_path) - - commonprefix = os.path.commonprefix([common_root_path, absolute_path]) - if commonprefix == "": - raise IOError(f"These two pathes have no common root path : {absolute_path} and {common_root_path}") - return os.path.relpath(absolute_path, start=commonprefix) - - # Check if the overwrite_policy is supported - overwrite_policies = ["raise", "skip", "erase", "most_recent", "overwrite"] - if overwrite_policy not in overwrite_policies: - raise ValueError( - f"Unsupported value for overwrite_policy: {overwrite_policy}. Possibilities are: {overwrite_policies}" - ) - - # Iterate through the list of source files and copy them to the destination - copied_files = [] - ignored_files = [] - - for source_file_path in source_file_list: - # Get the relative path of the source file with respect to the source root - relative_path = get_relative_path(source_file_path, source_root) - - # Create the destination path by joining the destination root and the relative path - destination_path = os.path.join(destination_root, relative_path) - - # Check if the file exists at the source location and is a file - if not os.path.isfile(source_file_path): - ignored_files.append(source_file_path) - continue - - # Check if the file exists at the destination location and apply the overwrite policy accordingly - if os.path.isfile(destination_path): - if overwrite_policy == "raise": - raise ValueError(f"File already exists at the destination: {destination_path}") - elif overwrite_policy == "skip": - ignored_files.append(source_file_path) - continue - elif overwrite_policy == "erase": - os.remove(destination_path) - elif overwrite_policy == "most_recent": - if os.stat(destination_path).st_mtime > os.stat(source_file_path).st_mtime: - ignored_files.append(source_file_path) - continue - elif overwrite_policy == "overwrite": - pass - - # Create the directory structure at the destination if it does not exist already - os.makedirs(os.path.dirname(destination_path), exist_ok=True) - - # Copy the file from source to destination - shutil.copy(source_file_path, destination_path) - - # Append the copied file to the list of copied files - copied_files.append(source_file_path) - - # Return a dictionary with the list of copied and ignored files - return {"copied": copied_files, "ignored": ignored_files} - - def pull_files(self, file_list, *, session_details, relative=False, overwrite_policy="raise"): - pass +# if __name__ == "__main__": + +# class WebConnector(metaclass=Singleton): +# """An API for searching and loading data through the Alyx database""" + +# def __init__( +# self, +# username=None, +# password=None, +# base_url=None, +# cache_dir=None, +# mode="auto", +# data_access_mode="local", +# wildcards=True, +# **kwargs, +# ): +# """An API for searching and loading data through the Alyx database + +# Parameters +# ---------- +# mode : str +# Query mode, options include 'auto', 'local' (offline) and 'remote' (online only). Most +# methods have a `query_type` parameter that can override the class mode. +# wildcards : bool +# If true, methods allow unix shell style pattern matching, otherwise regular +# expressions are supported +# cache_dir : str, Path +# Path to the data files. If Alyx parameters have been set up for this location, +# an OneAlyx instance is returned. If data_dir and base_url are None, the default +# location is used. +# base_url : str +# An Alyx database URL. The URL must start with 'http'. +# username : str +# An Alyx database login username. +# password : str +# An Alyx database password. +# cache_rest : str +# If not in 'local' mode, this determines which http request types to cache. Default is +# 'GET'. Use None to deactivate cache (not recommended). +# """ + +# # Load Alyx Web client +# self.web_client = AlyxClient( +# username=username, +# password=password, +# base_url=base_url, +# cache_dir=cache_dir, +# **kwargs, +# ) + +# self._registration_client = RegistrationClient(self) + +# self.data_access_mode = data_access_mode + +# self._search_endpoint = "sessions" + +# # get parameters override if inputs provided +# super().__init__(mode=mode, wildcards=wildcards, cache_dir=cache_dir) + +# def set_data_access_mode(self, mode): +# available_modes = [ +# "local", +# "remote", +# ] # TODO : add ability to go auto mode later. (if possible, still have to think about it) +# if mode in available_modes: +# self.data_access_mode = mode +# self.alyx.delete_cache() # delete rest cache in case there is local / remote path stored inside +# else: +# raise ValueError(f"data_access_mode must be one of : {available_modes}") + +# def __repr__(self): +# return f'One ({"off" if self.offline else "on"}line, {self.alyx.base_url})' + +# def load_cache(self, cache_dir=None, clobber=False, tag=None): +# """ +# Load parquet cache files. If the local cache is sufficiently old, this method will query +# the database for the location and creation date of the remote cache. If newer, it will be +# download and loaded. + +# Note: Unlike refresh_cache, this will always reload the local files at least once. + +# Parameters +# ---------- +# cache_dir : str, pathlib.Path +# An optional directory location of the parquet files, defaults to One.cache_dir. +# clobber : bool +# If True, query Alyx for a newer cache even if current (local) cache is recent. +# tag : str +# An optional Alyx dataset tag for loading cache tables containing a subset of datasets. +# """ +# _logger = logging.getLogger("load_cache") +# cache_meta = self._cache.get("_meta", {}) +# cache_dir = cache_dir or self.cache_dir +# # If user provides tag that doesn't match current cache's tag, always download. +# # NB: In the future 'database_tags' may become a list. +# current_tags = [x.get("database_tags") for x in cache_meta.get("raw", {}).values() or [{}]] +# tag = tag or current_tags[0] # For refreshes take the current tag as default +# different_tag = any(x != tag for x in current_tags) +# if not clobber or different_tag: +# super().load_cache(cache_dir) # Load any present cache +# cache_meta = self._cache.get("_meta", {}) # TODO Make walrus when we drop 3.7 support +# expired = self._cache and cache_meta["expired"] +# if not expired or self.mode in ("local", "remote"): +# return + +# # Warn user if expired +# if cache_meta["expired"] and cache_meta.get("created_time", False) and not self.alyx.silent: +# age = datetime.now() - cache_meta["created_time"] +# t_str = f"{age.days} day(s)" if age.days >= 1 else f"{np.floor(age.seconds / (60 * 2))} hour(s)" +# _logger.info(f"cache over {t_str} old") + +# try: +# # Determine whether a newer cache is available +# cache_info = self.alyx.get(f'cache/info/{tag or ""}'.strip("/"), expires=True) +# assert tag == cache_info.get("database_tags") + +# # Check version compatibility +# min_version = packaging.version.parse(cache_info.get("min_api_version", "0.0.0")) +# if packaging.version.parse(alyx_connector.__version__) < min_version: +# warnings.warn(f"Newer cache tables require ONE version {min_version} or greater") +# return + +# # Check whether remote cache more recent +# remote_created = datetime.fromisoformat(cache_info["date_created"]) +# local_created = cache_meta.get("created_time", None) +# if local_created and (remote_created - local_created) < timedelta(minutes=1): +# _logger.info("No newer cache available") +# return + +# # Download the remote cache files +# _logger.info("Downloading remote caches...") +# files = self.alyx.download_cache_tables(cache_info.get("location"), cache_dir) +# assert any(files) +# super().load_cache(cache_dir) # Reload cache after download +# except (requests.exceptions.HTTPError, HTTPError) as ex: +# _logger.debug(ex) +# ## REMOVED THIS WARNING FOR NOW AS I CAN'T FIND IF IT IS ACTUALLY USEFULL TO HAVE A REMOTE CACHE WHEN +# # SETUPING A LOCAL USE OF ALYX LIKE WE DO +# # _logger.error('Failed to load the remote cache file') +# self.mode = "remote" +# except (ConnectionError, requests.exceptions.ConnectionError) as ex: +# _logger.debug(ex) +# _logger.error("Failed to connect to Alyx") +# self.mode = "local" + +# @property +# def alyx(self): +# """one.webclient.AlyxClient: The Alyx Web client""" +# return self.web_client + +# @property +# def register(self): +# return self._registration_client + +# @property +# def cache_dir(self): +# """pathlib.Path: The location of the downloaded file cache""" +# return self.web_client.cache_dir + +# @util.refresh +# def search_terms(self, query_type=None): +# """ +# Returns a list of search terms to be passed as kwargs to the search method + +# Parameters +# ---------- +# query_type : str +# If 'remote', the search terms are largely determined by the REST endpoint used + +# Returns +# ------- +# tuple +# Tuple of search strings +# """ +# if (query_type or self.mode) != "remote": +# # Return search terms from REST schema +# return self._search_terms +# fields = self.alyx.rest_schemes[self._search_endpoint]["list"]["fields"] +# # 'laboratory' already in search terms +# excl = ("lab",) +# return tuple({*self._search_terms, *(x["name"] for x in fields if x["name"] not in excl)}) + +# def describe_dataset(self, dataset_type=None): +# """Print a dataset type description. + +# NB: This requires an Alyx database connection. + +# Parameters +# ---------- +# dataset_type : str +# A dataset type or dataset name + +# Returns +# ------- +# dict +# The Alyx dataset type record +# """ +# _logger = logging.getLogger("describe_dataset") +# assert self.mode != "local" and not self.offline, "Unable to connect to Alyx in local mode" +# if not dataset_type: +# return self.alyx.rest("dataset-types", "list") +# try: +# assert isinstance(dataset_type, str) and not is_uuid_string(dataset_type) +# _logger.disabled = True +# out = self.alyx.rest("dataset-types", "read", dataset_type) +# except (AssertionError, requests.exceptions.HTTPError): +# # Try to get dataset type from dataset name +# out = self.alyx.rest("dataset-types", "read", self.dataset2type(dataset_type)) +# finally: +# _logger.disabled = False +# print(out["description"]) +# return out + +# def change_session_data_mode(self, session_details, mode): +# session_details["full_path"] = session_details[mode + "_full_path"] +# return session_details + +# #### LIST DATASETS +# @util.refresh +# def list_datasets( +# self, +# eid=None, +# details=False, +# query_type=None, +# as_mode=None, +# no_cache=False, +# **filters, +# ) -> np.ndarray | pd.DataFrame | List[str]: +# """_summary_ + +# Args: +# eid (str, optional): Session id (alias or pk). Does not need to be supplied only if +# using session_details. Defaults to None. +# details (bool, optional): If False, will only return a list of absolute file paths +# (obtained from the column full_path of the dataset dataframe). +# Otherwise will return a full dataframe of all datasets found for this session +# Defaults to False. +# query_type (str or None, optional): Wether to perform the metadata fetch +# (only if using eid) from local cache or on alyx. If None, uses the current mode of +# the connector instance. Defaults to None. +# as_mode (str or None, optional): Wether to perform the full_path construction using +# default current (None), 'local' or 'remote' mode. Defaults to None. +# session_details (pd.Series, optional): The pandas series containing +# data_dataset_session_related information. +# If not supplied, the function must be supplied a session id (eid, first argument) +# to get this session_details variable internally. Defaults to None. + +# Other filtering keys are accepted : +# (the value on wich you search must match perfectly. Key must also match any of the +# below. key and values are case sensitive) +# - extra +# - object +# - attribute +# - subject +# - date +# - number +# - revision +# - collection +# - extension + +# - dataset_type +# - name (from dataset, ex trials.eventTimelines) +# - file_name + +# - relative_path +# - exists +# - created_by +# - created_datetime +# - data_repository +# - hash +# - file_size +# - tags + +# Raises: +# NotImplementedError: For now, using mode (metadata) local will not work as the cache system to retrive data +# has not been tested for. + +# Returns: +# Union[list, pd.DataFrame]: A list of matching files full_paths (if details = False) or a dataframe of all +# matching file records components and metadata. +# """ + +# import natsort + +# _logger = logging.getLogger("list_datasets") + +# def flatten_pathlist(x): +# if isinstance(x, (list, tuple)): +# return natsort.natsorted([a for i in x for a in flatten(i)]) +# else: +# return natsort.natsorted([x]) + +# # OBTAINING A SESSION_DETAILS (IN WHICH RESIDES FILES INFO) + +# data_access_mode = as_mode or self.data_access_mode +# if hasattr(eid, "keys") and "data_dataset_session_related" in eid.keys(): +# session_details = ( +# eid.copy() +# ) # either a pd.series of dict, copy and key getters/setters works both cases +# try: +# eid = session_details["id"] +# except KeyError: +# eid = session_details.name +# session_details["id"] = eid +# else: +# _eid = eid +# # Ensure we have a UUID str +# eid = self.to_eid(eid) +# if eid is None: +# raise ValueError( +# f"The session id {_eid} supplied seem to not be existing. Check that you are in 'remote' mode " +# "(not data_access_mode) and check that the session exists on a webpage." +# ) +# if (query_type or self.mode) != "remote": +# raise NotImplementedError +# ## TODO : GET BACK THE DATA FROM THE CACHE AFTER CHANGE IN DATA MANAGEMENT METHODOLOGY +# # return super().list_datasets(eid, details=details, query_type=query_type, **filters) + +# session_details = self.to_session_details( +# self.alyx.rest("sessions", "read", id=eid, query_type=query_type, no_cache=no_cache) +# ) +# # session, datasets = util.ses2records(self.alyx.rest('sessions', 'read', id=eid)) +# # self._update_cache_from_records(sessions=session, datasets=datasets.copy() +# # if datasets is not None else datasets) +# # Add to cache tables # TODO : DO ADD THAT FUNCTIONNALITY AGAIN + +# datasets = copy.deepcopy(session_details["data_dataset_session_related"]) +# # copy to not change the session_details in case they are suplied by user as input + +# file_records = [] +# for dataset in datasets: +# files = dataset.pop("file_records") +# dataset["session#"] = dataset.pop("session") +# dataset["dataset#"] = dataset.pop("id") +# dataset["dataset_url"] = dataset.pop("url") +# dataset["dataset_admin_url"] = dataset.pop("admin_url") +# dataset["local_root"] = alyx_connector.params.get().LOCAL_ROOT +# for file in files: +# # file["file_url"] = file.pop("url") +# # file["file_admin_url"] = file.pop("admin_url") +# file["file#"] = file.pop("id") +# file.update( +# { +# "remote_full_path": os.path.normpath( +# os.path.join(dataset["remote_root"], file["relative_path"]) +# ), +# "local_full_path": os.path.normpath( +# os.path.join(dataset["local_root"], file["relative_path"]) +# ), +# } +# ) +# # remote or local depending on current mode +# file["full_path"] = file[data_access_mode + "_full_path"] +# file.update(dataset) +# file_records.append(file) + +# dataframe = pd.DataFrame(file_records) +# if dataframe.empty: +# _logger.warning( +# "No dataset found for this session. Are you sure you ran the file registration routine ?" +# ) +# return dataframe if details else [] + +# dataframe.set_index(["session#", "dataset#", "file#"]) + +# # FILTERING THE ROWS BASED ON USER INPUT +# # query_string = ' & '.join([f'{k} == {repr(v)}' for k, v in filters.items()]) +# if filters: +# if "filename" in filters.keys(): +# # allowing filename for retrocompatibility +# filters["file_name"] = filters.pop("filename") +# queries = [] +# for key, value in filters.items(): +# # if the columns correspunding to filter is object or string, we try to match using wildcard type +# # syntax as input +# # to do that we convert * wildcards to .* in regex and add a ^ and $ at start and end of pattern +# # to force a complete string length match. + +# if dataframe[key].dtype is npdtype("O") or dataframe[key].dtype is npdtype(str): +# queries.append(f"{key}.str.match('^' + {repr(value).replace('*', '.*')} + '$') ") # +# # if the columns is not a sting, we match it directly. +# else: +# queries.append(f"{key} == {value}") + +# # example of a query string : query_string = "exists == True & subject.str.match('wm.*$')" +# query_string = " & ".join(queries) + +# try: +# dataframe = dataframe.query(query_string, engine="python") +# except (KeyError, pd.errors.UndefinedVariableError) as e: +# raise KeyError(f"Cannot use the key {str(e)} to filter for datasets") + +# return dataframe if details else list(dataframe["full_path"]) + +# @util.refresh +# def pid2eid(self, pid: str, query_type=None) -> Tuple[str, str]: +# """ +# Given an Alyx probe UUID string, returns the session id string and the probe label +# (i.e. the ALF collection). + +# NB: Requires a connection to the Alyx database. + +# Parameters +# ---------- +# pid : str, uuid.UUID +# A probe UUID +# query_type : str +# Query mode - options include 'remote', and 'refresh' + +# Returns +# ------- +# str +# Experiment ID (eid) +# str +# Probe label +# """ +# query_type = query_type or self.mode +# if query_type != "remote": +# self.refresh_cache(query_type) +# if query_type == "local" and "insertions" not in self._cache.keys(): +# raise NotImplementedError("Converting probe IDs required remote connection") +# rec = self.alyx.rest("insertions", "read", id=str(pid)) +# return rec["session"], rec["name"] + +# #### SEARCH +# def search( +# self, +# id=None, +# *, +# details=False, +# query_type=None, +# as_mode=None, +# no_cache=False, +# **kwargs, +# ): +# """ +# Searches sessions matching the given criteria and returns a list of matching eids + +# For a list of search terms, use the method + +# one.search_terms(query_type='remote') + +# For all of the search parameters, a single value or list may be provided. For dataset, +# the sessions returned will contain all listed datasets. For the other parameters, +# the session must contain at least one of the entries. NB: Wildcards are not permitted, +# however if wildcards property is False, regular expressions may be used for all but +# number and date_range. + +# Parameters +# ---------- +# dataset : str, list +# List of dataset names. Returns sessions containing all these datasets. +# A dataset matches if it contains the search string e.g. 'wheel.position' matches +# '_ibl_wheel.position.npy' +# date_range : str, list, datetime.datetime, datetime.date, pandas.timestamp +# A single date to search or a list of 2 dates that define the range (inclusive). To +# define only the upper or lower date bound, set the other element to None. +# lab : str, list +# A str or list of lab names, returns sessions from any of these labs +# number : str, int +# Number of session to be returned, i.e. number in sequence for a given date +# subject : str, list +# A list of subject nicknames, returns sessions for any of these subjects +# task_protocol : str, list +# The task protocol name (can be partial, i.e. any task protocol containing that str +# will be found) +# project(s) : str, list +# The project name (can be partial, i.e. any task protocol containing that str +# will be found) +# performance_lte / performance_gte : float +# Search only for sessions whose performance is less equal or greater equal than a +# pre-defined threshold as a percentage (0-100) +# users : str, list +# A list of users +# location : str, list +# A str or list of lab location (as per Alyx definition) name +# Note: this corresponds to the specific rig, not the lab geographical location per se +# json : dict +# example : +# ```python +# json = { +# "whisker_stims": { +# "amplitudes": { +# "abstract__contains": ['10-0','10-10','10_90-0'] +# } +# } +# } +# ``` +# allowed filter looups are listed here : +# https://docs.djangoproject.com/en/5.0/ref/models/querysets/#field-lookups + + +# dataset_types : str, list +# One or more of dataset_types +# details : bool +# If true also returns a dict of dataset details +# query_type : str, None +# Query cache ('local') or Alyx database ('remote') +# limit : int +# The number of results to fetch in one go (if pagination enabled on server) + + +# Returns +# ------- +# list +# List of eids +# (list of dicts) +# If details is True, also returns a list of dictionaries, each entry corresponding to a +# matching session +# """ +# _logger = logging.getLogger("search") +# query_type = query_type or self.mode # we set query_type = self.mode if query_type is None +# if query_type != "remote": +# return super().search(details=details, query_type=query_type, **kwargs) + +# # loop over input arguments and build the url +# search_terms = self.search_terms(query_type=query_type) +# params = {} # {"django": kwargs.pop("django", "")} + +# if isinstance(id, (list, tuple)): +# sessions = [] +# for i in id: +# sessions.append( +# self.search( +# id=i, details=details, as_mode=as_mode, no_cache=no_cache, query_type=query_type, **kwargs +# ) +# ) +# return pd.DataFrame(sessions) + +# if id is not None: +# params["id"] = self.to_eid(id) +# if params["id"] is None: # this means the id we supplied is not a valid eid +# raise ValueError(f"{id} is not a valid identifier, could not convert it to session uuid.") +# _logger.debug(f"kwargs : {kwargs}") +# for key, value in sorted(kwargs.items()): +# field = util.autocomplete(key, search_terms) # Validate and get full name +# _logger.debug(f"field : {field}") +# # check that the input matches one of the defined filters +# if field == "date_range": +# params[field] = [x.date().isoformat() for x in util.validate_date_range(value)] +# elif field == "laboratory": +# params["lab"] = value +# else: +# params[field] = value +# _logger.debug(f"params : {params}") +# # Make GET request +# ses = self.alyx.rest( +# self._search_endpoint, +# "list", +# no_cache=no_cache, +# query_type=query_type, +# **params, +# ) +# if len(ses) > 1: +# _logger.info(f"Found {len(ses)} sessions.") + +# if not details: +# return [item["id"] for item in ses] +# # list(util.LazyId(ses)) + +# sess_df = [] +# for session_short_info in tqdm(ses, total=len(ses), delay=2, desc="Loading session details", file=stdout): +# session_detailed_info = self.alyx.rest( +# "sessions", +# "read", +# id=session_short_info["id"], +# no_cache=no_cache, +# query_type=query_type, +# ) +# formated_session = self.to_session_details(session_detailed_info, as_mode=as_mode) +# sess_df.append(formated_session) + +# try: +# sess_df = pd.DataFrame(sess_df) +# sess_df.index = sess_df.index.set_names("id") +# sess_df["start_datetime"] = pd.to_datetime(sess_df["start_datetime"], utc=True) +# except (ValueError, KeyError): +# warnings.warn("search result contained no entry") +# pass # could not create a dataframe form session details. Returning dict instead +# if id is not None: +# return sess_df.iloc[0] +# return sess_df + +# def to_session_details(self, session_dict, as_mode=None): +# data_access_mode = ( +# as_mode or self.data_access_mode +# ) # we set data_access_mode = self.data_access_mode if as_mode is None + +# session_dict["date"] = str(datetime.fromisoformat(session_dict["start_time"]).date()) +# session_dict["extended_qc"] = session_dict["extended_qc"] if session_dict["extended_qc"] is not None else {} +# session_dict["local_path"] = os.path.normpath( +# os.path.join(alyx_connector.params.get().LOCAL_ROOT, session_dict["rel_path"]) +# ) +# session_dict["remote_path"] = os.path.normpath( +# session_dict["path"] +# ) # path is the remote path initially (out from the database) +# # we set path depending on the data_access_mode +# session_dict["path"] = session_dict[data_access_mode + "_path"] +# session_dict["rel_path"] = Path(session_dict["rel_path"]) + +# session_dict["start_datetime"] = datetime.strptime(session_dict["start_time"], "%Y-%m-%dT%H:%M:%S%z") + +# id = session_dict.pop("id") + +# session_details = pd.Series(session_dict, name=id) +# return session_details + +# def _download_datasets(self, dsets, **kwargs) -> List[Path]: +# """ +# Download a single or multitude of datasets if stored on AWS, otherwise calls +# OneAlyx._download_dataset. + +# NB: This will not skip files that are already present. Use check_filesystem instead. + +# Parameters +# ---------- +# dset : dict, str, pd.Series +# A single or multitude of dataset dictionaries + +# Returns +# ------- +# pathlib.Path +# A local file path or list of paths +# """ +# # If all datasets exist on AWS, download from there. +# _logger = logging.getLogger("_download_datasets") +# try: +# if "exists_aws" in dsets and np.all(np.equal(dsets["exists_aws"].values, True)): +# _logger.info("Downloading from AWS") +# return self._download_aws(map(lambda x: x[1], dsets.iterrows()), **kwargs) +# except Exception as ex: +# _logger.debug(ex) +# return self._download_dataset(dsets, **kwargs) + +# def _dset2url(self, dset, update_cache=True): +# """ +# Converts a dataset into a remote HTTP server URL. The dataset may be one or more of the +# following: a dict from returned by the sessions endpoint or dataset endpoint, a record +# from the datasets cache table, or a file path. Unlike record2url, this method can convert +# dicts and paths to URLs. + +# Parameters +# ---------- +# dset : dict, str, pd.Series, pd.DataFrame, list +# A single or multitude of dataset dictionary from an Alyx REST query OR URL string +# update_cache : bool +# If True (default) and the dataset is from Alyx and cannot be converted to a URL, +# 'exists' will be set to False in the corresponding entry in the cache table. + +# Returns +# ------- +# str +# The remote URL of the dataset +# """ +# _logger = logging.getLogger("_dset2url") +# did = None +# if isinstance(dset, str) and dset.startswith("http"): +# url = dset +# elif isinstance(dset, (str, Path)): +# url = self.path2url(dset) +# if not url: +# _logger.warning(f"Dataset {dset} not found in cache") +# return +# elif isinstance(dset, (list, tuple)): +# dset2url = partial(self._dset2url, update_cache=update_cache) +# return list(flatten(map(dset2url, dset))) +# else: +# # check if dset is dataframe, iterate over rows +# if hasattr(dset, "iterrows"): +# dset2url = partial(self._dset2url, update_cache=update_cache) +# url = list(map(lambda x: dset2url(x[1]), dset.iterrows())) +# elif "data_url" in dset: # data_dataset_session_related dict +# url = dset["data_url"] +# did = dset["id"] +# elif "file_records" not in dset: # Convert dataset Series to alyx dataset dict +# url = self.record2url(dset) # NB: URL will always be returned but may not exist +# is_int = all(isinstance(x, (int, np.int64)) for x in util.ensure_list(dset.name)) +# did = np.array(dset.name)[-2:] if is_int else util.ensure_list(dset.name)[-1] +# else: # from datasets endpoint +# repo = getattr(getattr(self.web_client, "_par", None), "HTTP_DATA_SERVER", None) +# url = next( +# ( +# fr["data_url"] +# for fr in dset["file_records"] +# if fr["data_url"] and fr["exists"] and fr["data_url"].startswith(repo or fr["data_url"]) +# ), +# None, +# ) +# did = dset["url"][-36:] + +# # Update cache if url not found +# if did is not None and not url and update_cache: +# _logger.debug("Updating cache") +# if isinstance(did, str) and self._index_type("datasets") is int: +# (did,) = parquet.str2np(did).tolist() +# elif self._index_type("datasets") is str and not isinstance(did, str): +# did = parquet.np2str(did) +# # NB: This will be considerably easier when IndexSlice supports Ellipsis +# idx = [slice(None)] * int(self._cache["datasets"].index.nlevels / 2) +# self._cache["datasets"].loc[(*idx, *util.ensure_list(did)), "exists"] = False +# self._cache["_meta"]["modified_time"] = datetime.now() + +# return url + +# def _download_dataset(self, dset, cache_dir=None, update_cache=True, **kwargs) -> List[Path | None]: +# """ +# Download a single or multitude of dataset from an Alyx REST dictionary. + +# NB: This will not skip files that are already present. Use check_filesystem instead. + +# Parameters +# ---------- +# dset : dict, str, pd.Series, pd.DataFrame, list +# A single or multitude of dataset dictionary from an Alyx REST query OR URL string +# cache_dir : str, pathlib.Path +# The root directory to save the data to (default taken from ONE parameters) +# update_cache : bool +# If true, the cache is updated when filesystem discrepancies are encountered + +# Returns +# ------- +# pathlib.Path, list +# A local file path or list of paths +# """ +# cache_dir = cache_dir or self.cache_dir +# url = self._dset2url(dset, update_cache=update_cache) +# if not url: +# return +# if isinstance(url, str): +# target_dir = str(Path(cache_dir, get_alf_path(url)).parent) +# return self._download_file(url, target_dir, **kwargs) +# # must be list of URLs +# valid_urls = list(filter(None, url)) +# if not valid_urls: +# return [None] * len(url) +# target_dir = [str(Path(cache_dir, get_alf_path(x)).parent) for x in valid_urls] +# files = self._download_file(valid_urls, target_dir, **kwargs) +# # Return list of file paths or None if we failed to extract URL from dataset +# return [None if not x else files.pop(0) for x in url] + +# def _tag_mismatched_file_record(self, url): +# fr = self.alyx.rest( +# "files", +# "list", +# django=f'dataset,{Path(url).name.split(".")[-2]},data_repository__globus_is_personal,False', +# no_cache=True, +# ) +# if len(fr) > 0: +# json_field = fr[0]["json"] +# if json_field is None: +# json_field = {"mismatch_hash": True} +# else: +# json_field.update({"mismatch_hash": True}) +# try: +# self.alyx.rest( +# "files", +# "partial_update", +# id=fr[0]["url"][-36:], +# data={"json": json_field}, +# ) +# except requests.exceptions.HTTPError as ex: +# warnings.warn( +# f"Failed to tag remote file record mismatch: {ex}\nPlease contact the database administrator." +# ) + +# def _download_file(self, url, target_dir, keep_uuid=False, file_size=None, hash=None) -> Path | List[Path]: +# """ +# Downloads a single file or multitude of files from an HTTP webserver. +# The webserver in question is set by the AlyxClient object. + +# Parameters +# ---------- +# url : str, list +# An absolute or relative URL for a remote dataset +# target_dir : str, list +# Absolute path of directory to download file to (including alf path) +# keep_uuid : bool +# If true, the UUID is not removed from the file name (default is False) +# file_size : int, list +# The expected file size or list of file sizes to compare with downloaded file +# hash : str, list +# The expected file hash or list of file hashes to compare with downloaded file + +# Returns +# ------- +# pathlib.Path +# The file path of the downloaded file or files. + +# Example +# ------- +# >>> file_path = OneAlyx._download_file( +# ... 'https://example.com/data.file.npy', '/home/Downloads/subj/1900-01-01/001/alf') +# """ +# assert not self.offline +# # Ensure all target directories exist +# [Path(x).mkdir(parents=True, exist_ok=True) for x in set(util.ensure_list(target_dir))] + +# # download file(s) from url(s), returns file path(s) with UUID +# local_path, md5 = self.alyx.download_file(url, target_dir=target_dir, return_md5=True) + +# # check if url, hash, and file_size are lists +# if isinstance(url, (tuple, list)): +# assert (file_size is None) or len(file_size) == len(url) +# assert (hash is None) or len(hash) == len(url) +# for args in zip(*map(util.ensure_list, (file_size, md5, hash, local_path, url))): +# self._check_hash_and_file_size_mismatch(*args) + +# # check if we are keeping the uuid on the list of file names +# if keep_uuid: +# return local_path + +# # remove uuids from list of file names +# if isinstance(local_path, (list, tuple)): +# return [alfio.remove_uuid_file(x) for x in local_path] +# else: +# return alfio.remove_uuid_file(local_path) + +# def _check_hash_and_file_size_mismatch(self, file_size, hash, expected_hash, local_path, url): +# """ +# Check to ensure the hash and file size of a downloaded file matches what is on disk + +# Parameters +# ---------- +# file_size : int +# The expected file size to compare with downloaded file +# hash : str +# The expected file hash to compare with downloaded file +# local_path: str +# The path of the downloaded file +# url : str +# An absolute or relative URL for a remote dataset +# """ +# _logger = logging.getLogger("_check_hash_and_file_size_mismatch") +# # verify hash size +# hash = hash or hashfile.md5(local_path) +# hash_mismatch = hash and hash != expected_hash +# # verify file size +# file_size_mismatch = file_size and Path(local_path).stat().st_size != file_size +# # check if there is a mismatch in hash or file_size +# if hash_mismatch or file_size_mismatch: +# # post download, if there is a mismatch between Alyx and the newly downloaded file size +# # or hash, flag the offending file record in Alyx for database for maintenance +# hash_mismatch = expected_hash and expected_hash != hash +# file_size_mismatch = file_size and Path(local_path).stat().st_size != file_size +# if hash_mismatch or file_size_mismatch: +# url = url or self.path2url(local_path) +# _logger.debug(f"Tagging mismatch for {url}") +# # tag the mismatched file records +# self._tag_mismatched_file_record(url) + +# @staticmethod +# def setup(base_url=None, **kwargs): +# """ +# Set up OneAlyx for a given database + +# Parameters +# ---------- +# base_url : str +# An Alyx database URL. If None, the current default database is used. +# **kwargs +# Optional arguments to pass to one.params.setup. + +# Returns +# ------- +# OneAlyx +# An instance of OneAlyx for the newly set up database URL +# """ +# base_url = base_url or alyx_connector.params.get_default_client() +# cache_map = alyx_connector.params.setup(client=base_url, **kwargs) +# return OneAlyx(base_url=base_url or alyx_connector.params.get(cache_map.DEFAULT).ALYX_URL) + +# @util.refresh +# @util.parse_id +# def eid2path(self, eid, query_type=None) -> util.Listable(Path): +# """ +# From an experiment ID gets the local session path + +# Parameters +# ---------- +# eid : str, UUID, pathlib.Path, dict, list +# Experiment session identifier; may be a UUID, URL, experiment reference string +# details dict or Path. +# query_type : str +# If set to 'remote', will force database connection + +# Returns +# ------- +# pathlib.Path, list +# A session path or list of session paths +# """ + +# # first try avoid hitting the database +# mode = query_type or self.mode +# if mode != "remote": +# cache_path = super().eid2path(eid) +# if cache_path or mode == "local": +# return cache_path + +# # If eid is a list recurse through it and return a list +# if isinstance(eid, list): +# unwrapped = unwrap(self.path2eid) +# return [unwrapped(self, e, query_type="remote") for e in eid] + +# # if it wasn't successful, query Alyx +# ses = self.alyx.rest("sessions", "list", django=f"pk,{eid}") + +# if len(ses) == 0: +# return None + +# data_repository = ses[0]["default_data_repository"] +# if data_repository is None: +# data_repository = "" + +# return os.path.join( +# data_repository, +# ses[0]["subject"], +# ses[0]["start_time"][:10], +# str(ses[0]["number"]).zfill(3), +# ) + +# @util.refresh +# def path2eid(self, path_obj: Union[str, Path], query_type=None) -> util.Listable(Path): +# import re + +# """ +# From a local path, gets the experiment ID + +# Parameters +# ---------- +# path_obj : str, pathlib.Path, list +# Local path or list of local paths +# query_type : str +# If set to 'remote', will force database connection + +# Returns +# ------- +# str, list +# An eid or list of eids +# """ +# # If path_obj is a list recurse through it and return a list +# if isinstance(path_obj, list): +# path_obj = [Path(x) for x in path_obj] +# eid_list = [] +# unwrapped = unwrap(self.path2eid) +# for p in path_obj: +# eid_list.append(unwrapped(self, p)) +# return eid_list +# # else ensure the path ends with mouse,date, number +# try: +# path_obj = re.findall(r"(\w+(?:\\|\/)\d{4}-\d{2}-\d{2}(?:\\|\/)\d+)", path_obj)[0] +# except IndexError: # could not match anything +# pass + +# path_obj = Path(path_obj) + +# # try the cached info to possibly avoid hitting database +# mode = query_type or self.mode +# if mode != "remote": +# cache_eid = super().path2eid(path_obj) +# if cache_eid or mode == "local": +# return cache_eid + +# session_path = get_session_path(path_obj) +# # if path does not have a date and a number return None +# if session_path is None: +# return None + +# # if not search for subj, date, number XXX: hits the DB +# search = unwrap(self.search) +# uuid = search( +# subject=session_path.parts[-3], +# date_range=session_path.parts[-2], +# number=session_path.parts[-1], +# query_type="remote", +# ) + +# # Return the uuid if any +# return uuid[0] if uuid else None + +# @util.refresh +# def path2url(self, filepath, query_type=None) -> str: +# """ +# Given a local file path, returns the URL of the remote file. + +# Parameters +# ---------- +# filepath : str, pathlib.Path +# A local file path +# query_type : str +# If set to 'remote', will force database connection + +# Returns +# ------- +# str +# A URL string +# """ +# query_type = query_type or self.mode +# if query_type != "remote": +# return super().path2url(filepath) +# eid = self.path2eid(filepath) +# try: +# (dataset,) = self.alyx.rest("datasets", "list", session=eid, name=Path(filepath).name) +# return next(r["data_url"] for r in dataset["file_records"] if r["data_url"] and r["exists"]) +# except (ValueError, StopIteration): +# raise alferr.ALFObjectNotFound(f"File record for {filepath} not found on Alyx") + +# @util.parse_id +# def type2datasets(self, eid, dataset_type, details=False): +# """ +# Get list of datasets belonging to a given dataset type for a given session + +# Parameters +# ---------- +# eid : str, UUID, pathlib.Path, dict +# Experiment session identifier; may be a UUID, URL, experiment reference string +# details dict or Path. +# dataset_type : str, list +# An Alyx dataset type, e.g. camera.times or a list of dtypes +# details : bool +# If True, a datasets DataFrame is returned + +# Returns +# ------- +# np.ndarray, dict +# A numpy array of data, or DataFrame if details is true +# """ +# assert self.mode != "local" and not self.offline, "Unable to connect to Alyx in local mode" +# if isinstance(dataset_type, str): +# restriction = f"session__id,{eid},dataset_type__name,{dataset_type}" +# elif isinstance(dataset_type, collections.abc.Sequence): +# restriction = f"session__id,{eid},dataset_type__name__in,{dataset_type}" +# else: +# raise TypeError("dataset_type must be a str or str list") +# datasets = util.datasets2records(self.alyx.rest("datasets", "list", django=restriction)) +# return datasets if details else datasets["rel_path"].sort_values().values + +# def dataset2type(self, dset) -> str: +# """Return dataset type from dataset. + +# NB: Requires an Alyx database connection + +# Parameters +# ---------- +# dset : str, np.ndarray, tuple +# A dataset name, dataset uuid or dataset integer id + +# Returns +# ------- +# str +# The dataset type +# """ +# assert self.mode != "local" and not self.offline, "Unable to connect to Alyx in local mode" +# # Ensure dset is a str uuid +# if isinstance(dset, str) and not is_uuid_string(dset): +# dset = self._dataset_name2id(dset) +# if isinstance(dset, np.ndarray): +# dset = parquet.np2str(dset)[0] +# if isinstance(dset, tuple) and all(isinstance(x, int) for x in dset): +# dset = parquet.np2str(np.array(dset)) +# if not is_uuid_string(dset): +# raise ValueError("Unrecognized name or UUID") +# return self.alyx.rest("datasets", "read", id=dset)["dataset_type"] + +# def describe_revision(self, revision, full=False): +# """Print description of a revision + +# Parameters +# ---------- +# revision : str +# The name of the revision (without '#') +# full : bool +# If true, returns the matching record + +# Returns +# ------- +# None, dict +# None if full is false or no record found, otherwise returns record as dict +# """ +# assert self.mode != "local" and not self.offline, "Unable to connect to Alyx in local mode" +# try: +# rec = self.alyx.rest("revisions", "read", id=revision) +# print(rec["description"]) +# if full: +# return rec +# except requests.exceptions.HTTPError as ex: +# if ex.response.status_code != 404: +# raise ex +# print(f'revision "{revision}" not found') + +# def _dataset_name2id(self, dset_name, eid=None): +# # TODO finish function +# datasets = self.list_datasets(eid) if eid else self._cache["datasets"] +# # Get ID of fist matching dset +# for idx, rel_path in datasets["rel_path"].items(): +# if rel_path.endswith(dset_name): +# return idx[-1] # (eid, did) +# raise ValueError(f"Dataset {dset_name} not found in cache") + +# @util.refresh +# @util.parse_id +# def get_details(self, eid: str, full: bool = False, query_type=None): +# """Return session details for a given session + +# Parameters +# ---------- +# eid : str, UUID, pathlib.Path, dict, list +# Experiment session identifier; may be a UUID, URL, experiment reference string +# details dict or Path. +# full : bool +# If True, returns a DataFrame of session and dataset info +# query_type : {'local', 'refresh', 'auto', 'remote'} +# The query mode - if 'local' the details are taken from the cache tables; if 'remote' +# the details are returned from the sessions REST endpoint; if 'auto' uses whichever +# mode ONE is in; if 'refresh' reloads the cache before querying. + +# Returns +# ------- +# pd.Series, pd.DataFrame, dict +# in local mode - a session record or full DataFrame with dataset information if full is +# True; in remote mode - a full or partial session dict + +# Raises +# ------ +# ValueError +# Invalid experiment ID (failed to parse into eid string) +# requests.exceptions.HTTPError +# [Errno 404] Remote session not found on Alyx +# """ +# if (query_type or self.mode) == "local": +# return super().get_details(eid, full=full) +# # If eid is a list of eIDs recurse through list and return the results +# if isinstance(eid, list): +# details_list = [] +# for p in eid: +# details_list.append(self.get_details(p, full=full)) +# return details_list +# # load all details +# dets = self.alyx.rest("sessions", "read", eid) +# if full: +# return dets +# # If it's not full return the normal output like from a one.search +# det_fields = [ +# "subject", +# "start_time", +# "number", +# "lab", +# "projects", +# "url", +# "task_protocol", +# "local_path", +# ] +# out = {k: v for k, v in dets.items() if k in det_fields} +# out["projects"] = ",".join(out["projects"]) +# out.update( +# { +# "local_path": self.eid2path(eid), +# "date": datetime.fromisoformat(out["start_time"]).date(), +# } +# ) +# return out + +# ### METHODS ADDED BY TIMOTHE TO EXTEND THE USE OF THE API + +# def get_data_repository_path(self, repository_name): +# repo_data = self.alyx.rest("data-repository", "read", repository_name) +# repo_path = r"\\" + os.path.join(repo_data["hostname"], repo_data["globus_path"].lstrip("/")) +# return os.path.normpath(repo_path) + +# def read_sql(self, query): +# raise NotImplementedError + +# def create_session(self, data_dict): +# import re + +# data_dict = data_dict.copy() +# data_dict["number"] = str(int(data_dict["number"])) # remove leading zeros if any +# try: # a session have been found with same 3 parameters, don't allow to process to registering. +# _searched_session = self.search( +# subject=data_dict["subject"], +# number=data_dict["number"], +# date_range=data_dict["start_time"][:10], +# users=data_dict["users"], +# details=True, +# ) +# url = re.sub(r"\/sessions", r"/actions/session", _searched_session["url"].item()) +# raise ValueError( +# f"This session path is already registered ! See here : {url}\n You probably need to change the number " +# "of the session for this animald/date combo" +# ) +# except KeyError: # no session have benn found, all is well, can proceed +# pass + +# self.alyx.rest("sessions", "create", data=data_dict) + +# def default_session_data(self): +# return {"lab": "HaissLab", "task_protocol": ""} + +# @staticmethod +# def explorer(path): +# import subprocess + +# path = os.path.normpath(path) +# if not os.path.exists(path): +# raise IOError(f"Path {path} does not exist") +# if os.path.isfile(path): +# path = os.path.dirname(path) + +# pre_cmd = f"explorer.exe {path}" +# subprocess.call(pre_cmd) +# return +# # this part is to open in atab instead of window. Buggy for now. +# if path[:2] == r"\\": +# pre_cmd = f"pushd {path}; " +# # path = os.path.join(*[item for item in selected_folder.split(os.sep) if item != ''][1:]) +# # #this removes the first object of the path +# else: +# pre_cmd = 'cd "{pateh}; "' +# subprocess.call(pre_cmd + r"start .") +# # subprocess.Popen(r'explorer '+f'{os.path.dirname(path)},select,{os.path.basename(path)}') + +# def collection_path(self, eid, collections): +# return os.path.join(self.current_remote_repository_path, self.eid2path(eid), collections) + +# def set_current_remote_repository(self, repo_name): +# self.current_remote_repository_path = self.get_data_repository_path(repo_name) + +# def get_parts_from_path(self, input_path): +# import re + +# subject, date, number = re.findall(r"(\w+)(?:\\|\/)(\d{4}-\d{2}-\d{2})(?:\\|\/)(\d+)", input_path)[0] +# return {"subject": subject, "date": date, "number": number} + +# def get_json_params(self, eid): +# return self.alyx.rest("sessions", "read", eid)["json"] + +# def get_extended_qc(self, eid): +# return self.alyx.rest("sessions", "read", eid)["extended_qc"] + +# def display_session_info(self, session_details): +# from IPython.display import Markdown, display + +# session_data_link = f"[Data pathes](file:{os.path.normpath(session_details.path)}) pointing in {self.data_access_mode} mode." +# metadatas_link = f"[Metadatas]({session_details.url}) obtained in {self.mode} mode." +# uuid = f"(uuid is '{session_details.name}')" +# display(Markdown(f"Session {session_details.rel_path}. {session_data_link} {metadatas_link} {uuid}")) + +# @wraps(MultiSessionPlaceholder) +# def multisession(*args, **kwargs): +# return MultiSessionPlaceholder(*args, **kwargs) + +# def update_session_info(self, session_details, json={}, extended_qc={}, **kwargs): +# _logger = logging.getLogger("update_session_info") + +# data = {} +# if len(json): +# base_json = session_details.json +# if base_json is None: +# base_json = {} +# base_json.update(json) +# data["json"] = base_json + +# if len(extended_qc): +# base_ext_qc = session_details.extended_qc +# if base_ext_qc is None: +# base_ext_qc = {} +# base_ext_qc.update(extended_qc) +# data["extended_qc"] = base_ext_qc + +# data.update(kwargs) + +# _logger.info(f"Updating session {session_details.rel_path}") +# ans = input(f"Data OK ? (OK or Cancel) : {data}") +# if ans != "OK": +# _logger.info("Aborting") +# return +# _logger.info("Applying changes") +# self.alyx.rest("sessions", "partial_update", id=session_details.name, data=data) +# self.alyx.delete_cache() + +# def push_files(self, file_list, *, session_details, relative=False, overwrite_policy="raise"): +# """ +# The function push_processed_files copies a list of files to a remote session directory, +# and handles various overwrite policies. + +# Args: + +# - file_list (list of str): a list of local file paths to be copied to the remote session directory. +# - session_details (SessionDetails): an object containing the session details. +# - relative: If the string representing the path of the files are absolute or relative from +# INSIDE the session folder (ex : 'D:\\LOCAL_DATA\\wm25\\2022-08-05\\001\\a_folder\\test.file' +# is an absolute path and 'a_folder\test.file' is a relative path) +# - overwrite_policy (str, optional): the overwrite policy. Possibilities are: +# - "raise" (raise an exception if a file with the same name already exists in the remote directory), +# - "skip" (skip copying the file if a file with the same name already exists in the remote directory), +# - "overwrite" (overwrite the file with the same name in the remote directory), +# - "most_recent" (copy the file only if it is more recent than the file +# with the same name in the remote directory), +# - "erase" (erase the existing file in the remote directory if a file with the same name already exists, +# then copy a new one in place.) Prefer choosing overwrite in most situations). + +# Default is "raise". + +# Returns: + +# a dictionary with two keys: +# - "copied" : a list of file paths that have been copied to the remote session directory. +# - "ignored" : a list of file paths that could not be copied (either because they were not found or +# because they were excluded by the overwrite policy). +# """ + +# import shutil + +# def get_relative_path(absolute_path, common_root_path): +# """Compare an input path and a path with a common root with the input path, and returns only the part of +# the input path that is not shared with the _common_root_path. + +# Args: +# input_path (TYPE): DESCRIPTION. +# common_root_base (TYPE): DESCRIPTION. + +# Returns: +# TYPE: DESCRIPTION. + +# """ +# absolute_path = os.path.normpath(absolute_path) +# common_root_path = os.path.normpath(common_root_path) + +# commonprefix = os.path.commonprefix([common_root_path, absolute_path]) +# if commonprefix == "": +# raise IOError(f"These two pathes have no common root path : {absolute_path} and {common_root_path}") +# return os.path.relpath(absolute_path, start=commonprefix) + +# overwrite_policies = ["raise", "skip", "erase", "most_recent", "overwrite"] +# if overwrite_policy not in overwrite_policies: +# raise NotImplementedError( +# f"Value {overwrite_policy} for overwrite_policy is not supported. " +# f"Possibilities are : {overwrite_policies}" +# ) + +# session_local_root = session_details["local_path"] +# session_remote_root = session_details["remote_path"] + +# if not isinstance(file_list, (list, tuple, np.ndarray)): +# file_list = [file_list] + +# if relative: +# file_list = [os.path.join(session_local_root, session_details.rel_path, file) for file in file_list] + +# source_files = [] # file paths that have been copied +# # files paths of the copies of the one in the list above (ordered similarly) +# dest_files = [] + +# overwrite_raise_list = ( +# [] +# ) # stores files that already exist in remote folder in case we have 'raise' overwrite_policy, to print to user +# file_not_found_warning = [] + +# # MAKE THE LIST OF FILES THAT WILL BE COPIED +# for local_path in file_list: +# if not os.path.isfile(local_path): +# file_not_found_warning.append(local_path) +# continue + +# try: +# relative_path = get_relative_path(local_path, session_local_root) +# except IOError: +# file_not_found_warning.append(local_path) +# continue + +# remote_path = os.path.join(session_remote_root, relative_path) + +# if os.path.isfile(remote_path): +# if overwrite_policy == "raise": +# overwrite_raise_list.append(local_path) +# elif overwrite_policy == "skip": +# logging.getLogger().info(f"Skipping file {remote_path}") +# continue +# elif overwrite_policy == "erase": +# os.remove(remote_path) +# elif overwrite_policy == "most_recent": +# if ( +# os.stat(remote_path).st_mtime > os.stat(local_path).st_mtime +# ): # remote_path is more recent (higher time value) +# continue +# elif overwrite_policy == "overwrite": +# pass +# # else if overwrite, we just do nothing and files will be overwritten during shutil.copy operation + +# source_files.append(local_path) +# dest_files.append(remote_path) + +# if len(file_not_found_warning): +# logging.getLogger().warning( +# "These files were not found or are not inside the session local folder, " +# f"and therefore cannot be copied :\nFiles:\n{file_not_found_warning}" +# ) + +# if len(overwrite_raise_list): +# raise IOError( +# f"The files listed below already exist in the destination : {session_remote_root}\n" +# "No file have been copied to avoid mistakes. " +# "You can check the content of the destination folder manually, " +# "or change the 'overwrite_policy' argument of this function (beware of data losses !).\n" +# f"Files :\n {overwrite_raise_list}" +# ) + +# # APPLY THE COPY +# for local_path, remote_path in zip(source_files, dest_files): +# container_dir = os.path.dirname(remote_path) +# # make destination dir if it doesn't exist already +# os.makedirs(container_dir, exist_ok=True) +# shutil.copy(local_path, remote_path) + +# return { +# "copied": source_files, +# "ignored": list(set(file_list).difference(set(source_files))), +# } + +# def copy_files(self, source_file_list, source_root, destination_root, overwrite_policy="raise"): +# def get_relative_path(absolute_path, common_root_path): +# """ +# Compare an input path and a path with a common root with the input path, and returns only the part of the +# input path that is not shared with the _common_root_path. + +# Args: +# input_path (TYPE): DESCRIPTION. +# common_root_base (TYPE): DESCRIPTION. + +# Returns: +# TYPE: DESCRIPTION. + +# """ +# absolute_path = os.path.normpath(absolute_path) +# common_root_path = os.path.normpath(common_root_path) + +# commonprefix = os.path.commonprefix([common_root_path, absolute_path]) +# if commonprefix == "": +# raise IOError(f"These two pathes have no common root path : {absolute_path} and {common_root_path}") +# return os.path.relpath(absolute_path, start=commonprefix) + +# # Check if the overwrite_policy is supported +# overwrite_policies = ["raise", "skip", "erase", "most_recent", "overwrite"] +# if overwrite_policy not in overwrite_policies: +# raise ValueError( +# f"Unsupported value for overwrite_policy: {overwrite_policy}. Possibilities are: {overwrite_policies}" +# ) + +# # Iterate through the list of source files and copy them to the destination +# copied_files = [] +# ignored_files = [] + +# for source_file_path in source_file_list: +# # Get the relative path of the source file with respect to the source root +# relative_path = get_relative_path(source_file_path, source_root) + +# # Create the destination path by joining the destination root and the relative path +# destination_path = os.path.join(destination_root, relative_path) + +# # Check if the file exists at the source location and is a file +# if not os.path.isfile(source_file_path): +# ignored_files.append(source_file_path) +# continue + +# # Check if the file exists at the destination location and apply the overwrite policy accordingly +# if os.path.isfile(destination_path): +# if overwrite_policy == "raise": +# raise ValueError(f"File already exists at the destination: {destination_path}") +# elif overwrite_policy == "skip": +# ignored_files.append(source_file_path) +# continue +# elif overwrite_policy == "erase": +# os.remove(destination_path) +# elif overwrite_policy == "most_recent": +# if os.stat(destination_path).st_mtime > os.stat(source_file_path).st_mtime: +# ignored_files.append(source_file_path) +# continue +# elif overwrite_policy == "overwrite": +# pass + +# # Create the directory structure at the destination if it does not exist already +# os.makedirs(os.path.dirname(destination_path), exist_ok=True) + +# # Copy the file from source to destination +# shutil.copy(source_file_path, destination_path) + +# # Append the copied file to the list of copied files +# copied_files.append(source_file_path) + +# # Return a dictionary with the list of copied and ignored files +# return {"copied": copied_files, "ignored": ignored_files} + +# def pull_files(self, file_list, *, session_details, relative=False, overwrite_policy="raise"): +# pass +# diff --git a/src/alyx_connector/files/parsing/__init__.py b/src/alyx_connector/files/parsing/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..5887dae15e259662d08bbf7ac542b372f2b46032 --- /dev/null +++ b/src/alyx_connector/files/parsing/__init__.py @@ -0,0 +1 @@ +from .files import File, UUID diff --git a/src/alyx_connector/files/expressions.py b/src/alyx_connector/files/parsing/expressions.py similarity index 100% rename from src/alyx_connector/files/expressions.py rename to src/alyx_connector/files/parsing/expressions.py diff --git a/src/alyx_connector/files/parsing.py b/src/alyx_connector/files/parsing/files.py similarity index 92% rename from src/alyx_connector/files/parsing.py rename to src/alyx_connector/files/parsing/files.py index 2d0169b1580b18e70ff6f8b51a03fe80480bd4d3..e5871c93c1e4fefec0c92be1805aa0f36a94cdfc 100644 --- a/src/alyx_connector/files/parsing.py +++ b/src/alyx_connector/files/parsing/files.py @@ -1,5 +1,5 @@ from pathlib import Path -from re import split +from re import split, compile from uuid import UUID as OriginalUUID from datetime import datetime from pandas import Series @@ -7,7 +7,21 @@ from copy import copy from .expressions import Part, Matcher -from typing import Optional, Any +from typing import Optional, Any, TypedDict, List, Tuple, Unpack, Union, cast + + +class PartsDict(TypedDict, total=False): + root: Union[str, Path] + drive: Union[str, Path] + subject: str + date: Union[datetime, str] + number: Union[str, int] + collection: Union[str, Path] + revision: Union[str, Path] + object: str + attribute: str + extra: Union[str, List[str], Tuple[str, ...]] + extension: str class UUID(OriginalUUID): @@ -41,27 +55,27 @@ class File: partsnames = Part._member_names_ _unallowed_chars = ["?", "*", ":", '"', "<", ">"] + _unallowed_chars_pattern = compile(rf'[{"".join([char for char in _unallowed_chars])}]') def _check_unallowed_chars(self, variable: Any): if not variable: return - variable = str(variable) - if any([char in variable for char in self._unallowed_chars]): + if bool(self._unallowed_chars_pattern.search(str(variable))): raise ValueError(f"A path cannot contain any of these characters {self._unallowed_chars}") def copy(self) -> "File": return copy(self) - def __new__(cls, path: Optional[str | Path] = None, *args, **kwargs: Optional[str | Path]): + def __new__(cls, path: Optional[str | Path] = None, **kwargs: Unpack[PartsDict]): if path is None and not kwargs: return super().__new__(cls) if path is not None: obj = cls.from_path(path, pattern="fullpath") return obj - return cls.from_parts(*args, **kwargs) + return cls.from_parts(**kwargs) @classmethod - def from_parts(cls, **kwargs: Optional[str | Path]) -> "File": + def from_parts(cls, **kwargs: Unpack[PartsDict]) -> "File": obj = cls() for partname, partvalue in kwargs.items(): if partname == "drive": @@ -72,7 +86,7 @@ class File: @classmethod def from_path(cls, fullpath: str | Path, pattern="fullpath") -> "File": - parts = Matcher.search(pattern, fullpath) + parts = cast(PartsDict, Matcher.search(pattern, fullpath)) return cls.from_parts(**parts) def __setitem__(self, partname: str, value: Path | str | int | None): @@ -109,7 +123,7 @@ class File: self._root = rootpath @property - def drive(self): + def drive(self) -> Optional[Path]: return getattr(self, "_drive", None) @drive.setter @@ -121,7 +135,7 @@ class File: return getattr(self, "_subject", None) @subject.setter - def subject(self, subject: Optional[str | Path]): + def subject(self, subject: Optional[str]): self._check_unallowed_chars(subject) self._subject = subject if subject is not None else None @@ -212,7 +226,10 @@ class File: return getattr(self, "_extra", None) @extra.setter - def extra(self, extra: Optional[str]): + def extra(self, extra: Optional[str | List[str] | Tuple[str, ...]]): + if isinstance(extra, (list, tuple)): + self.extras = extra + return self._check_unallowed_chars(extra) self._extra = extra if extra else None @@ -221,7 +238,7 @@ class File: return str(self.extra).split(".") if self.extra else [] @extras.setter - def extras(self, extras: list[str] | tuple[str]): + def extras(self, extras: List[str] | Tuple[str, ...]): self.extra = ".".join(extras) @property @@ -414,6 +431,7 @@ class File: def to_dict(self) -> dict: return dict( root=self.root, + drive=self.drive, subject=self.subject, date=self.date, number=self.number, diff --git a/src/alyx_connector/files/parsing/rulesets.py b/src/alyx_connector/files/parsing/rulesets.py new file mode 100644 index 0000000000000000000000000000000000000000..0ea604f2a109f2b096e7ae4c8efd9d3e68ea685b --- /dev/null +++ b/src/alyx_connector/files/parsing/rulesets.py @@ -0,0 +1,623 @@ +from dataclasses import dataclass +from pathlib import Path +from typing import Literal, List, Dict, Tuple, Optional, Union, Callable, Protocol, Iterator, cast + + +class ActionFunction(Protocol): + def __call__(self, file_record: "FileRecord", source: str, *, message: str = "") -> "FileRecord": ... + + +class OperationFunction(Protocol): + def __call__( + self, + value: str, + ) -> bool: ... + + +@dataclass +class FileRecord: + # source_path is the original path from disk scan. will never change + source_path: Path + + match: bool = False + matching_rules: list = field(default_factory=list) + used_rule: str = "" + + valid_alf: bool = False + path_conflicts: bool = False + dataset_type_exists: bool = False + rename: bool = False + delete: bool = False + include: bool = False + abort: list = field(default_factory=list) + + frozen = False + + executed_actions = [] + + # source file + @property + def source_file(self) -> File: + source_file = getattr("self", "_source_file", None) + if source_file is None: + try: + source_file = File.from_path(self.source_path) + except Exception as e: + raise ValueError(f"File from {self.source_path} was not parseable ! {type(e)}:{e}") + self._source_file = source_file + return source_file + + # was alf_info + @property + def destination_file(self) -> File: + destination_file = getattr("self", "_destination_file", None) + if destination_file is None: + destination_file = self.source_file.copy() + self._destination_file = destination_file + return destination_file + + @property + def final_path(self) -> Path: + if not hasattr("self", "_final_path"): + self._final_path = self.destination_file.fullpath if self.rename else self.source_path + return self._final_path + + @property + def final_file(self) -> "File": + if not hasattr("self", "_final_file"): + self._final_file = self.destination_file if self.rename else self.source_file + return self._final_file + + @property + def final_pathstring(self): + if not hasattr("self", "_final_pathstring"): + self._final_pathstring = str(self.final_path) + return self._final_pathstring + + def actions_cascade(self, config: "Config"): + for rule in config.rules.values(): + rule.actions_cascade(self) + + def finish_cascade(self, config: "Config"): + # change the values of the filre record after all other actions have been resolved. + # finish actions include calculating , + + self.valid_alf = self.destination_file.is_dataset_type_valid + + if self.valid_alf and self.destination_file.dataset_type in config.dataset_types: + self.dataset_type_exists = True + + @property + def inclusion_accepted(self): + if ( + self.include + and self.valid_alf + and self.dataset_type_exists + and not self.path_conflicts + and not self.abort + and not self.delete + ): + return True + return False + + @property + def rename_accepted(self): + if self.rename and self.valid_alf and not self.path_conflicts and not self.abort and not self.delete: + return True + return False + + def apply_changes(self, do_deletes=True, do_renames=True): # apply changes to file_record + if self.delete and self.rename: + raise ValueError("Cannot rename AND delete the same entry.") + + if self.rename_accepted and do_renames: + file_directory = self.destination_file.fullpath.parent + file_directory.mkdir(parents=True, exist_ok=True) + self.source_file.fullpath.rename(self.destination_file.fullpath) + + elif self.delete and do_deletes: + self.source_file.fullpath.unlink() + self.include = False + + def to_user_dict(self): + return { + "source_path": self.source_path, + "dest_path": str(self.destination_file.fullpath) if self.rename_accepted else "", + "info": self.info_message, + } + + @property + def info_message( + self, + ): # message to make from action booleans to help the use understand what happened + message = "" + if self.inclusion_accepted and not self.rename_accepted: + message = " included without change" + + if self.inclusion_accepted and self.rename_accepted: + message = " renamed and included" + + if not self.inclusion_accepted and self.rename_accepted: + message = " renamed and excluded" + + if not self.inclusion_accepted and not self.rename_accepted: + message = " excluded without change" + + if not self.valid_alf: + message = message + " dataset_type doesn't follow alyx format" + + if not self.dataset_type_exists: + message = message + f" dataset_type:{self.destination_file.dataset_type} not existing" + + if self.delete: + message = " auto deleted" + + if self.abort: + message_prefix = " Aborting due to errors : " + abort_messages = [] + for ab_msg in self.abort: + if ab_msg == " filepath_conflicts": + ab_msg = " File name conflicts with a current file or another file that will be renamed identically" + abort_messages.append(ab_msg) + + message = ( + message_prefix + + ", ".join(abort_messages) + # + " --- Without Abort, would have been " + # + message + ) + else: + message = "Will be " + message + + return str(message) + + +class Statement: + allowed_operations: List[CheckOperation] = ["exact", "contain", "match"] + allowed_elements = [ + "source_path", + "subject", + "date", + "number", + "root", + "object", + "attribute", + "extension", + "extra", + "collection", + "revision", + ] + conditions: List[str] | List[Pattern] + operation: CheckOperation + operation_method: OperationFunction + + def __init__( + self, element: Element, operation_detail: str | List[str] | Dict[CheckFullOperation, str | list[str]], parent + ): + self.inverted = False + self.parent = parent + + for el in self.allowed_elements: + if element == el: + self.tested_element = element + break + else: + raise ValueError( + f"Tested element is {self.tested_element} wich is invalid value. " + f"If must be one of :({''.join(self.allowed_elements)})" + ) + + if isinstance(operation_detail, dict): + # if the operation detail is a dict, if should contain a single key, wich is the check operation type + if len(operation_detail) != 1: + raise ValueError( + f"Content of tested element {self.tested_element} is a dict. " + "Then it must contain only one key ({''.join(self.allowed_operations)})" + ) + + operation = list(operation_detail.keys())[0] + conditions = operation_detail[operation] + + for op in self.allowed_operations: + if op in operation: + self.inverted = True if "_not" in operation else False + self.operation = op + break + else: + raise ValueError( + f"Content of tested element {self.tested_element} is a dict and the key present was : {operation}. " + "It must contain one of : ({''.join(self.allowed_operations)}). " + ) + else: + # If the operation detail is not a dict, then we asume that the check operation + # is : "exact" matching of the string or strings + self.operation = "exact" + conditions = operation_detail + + if not isinstance(conditions, list): + conditions = [conditions] + + if self.operation == "match": + existing_patterns = self.patterns + patterns = [] + for pattern_name in conditions: + try: + patterns.append(existing_patterns[pattern_name]) + except KeyError: + raise ValueError( + f"Pattern {pattern_name} was asked in condition statement {self.tested_element} " + "but was not defined in re_patterns." + ) + conditions = patterns + + # self.operation is a string name of a method of the class that handles boolean matchong a condition. + # self.operation_method is the actual bound method object that corresponds to that string + self.operation_method = getattr(self, self.operation) + self.conditions = conditions + + @property + def patterns(self): + return self.parent.patterns + + def evaluate(self, file_record: FileRecord): + if self.tested_element == "source_path": + value = str(file_record.source_path) + else: + value = file_record.source_file[self.tested_element] + if value is None: + return False + value = str(value) + # we invert the result of the boolean check if Statement.inverted is True, or not if not inverted + return self.operation_method(value) != self.inverted + + def exact(self, value): + return value in self.conditions + + def contain(self, value): + for item in self.conditions: + if item in value: + return True + return False + + def match(self, value): + for pattern in self.conditions: + if pattern.search(value): + return True + return False + + def __str__(self): + return ( + f"{self.tested_element} {'~' if self.inverted else ''}{self.operation} -> " + f"{', '.join([str(value) for value in self.conditions])}" + ) + + +class RuleConditions: + def __init__( + self, + rule_dict: dict, + parent: "Rule | RuleConditions", + rule_name: Optional[str] = None, + rule_type: Literal["all", "any"] = "all", + inverted: bool = False, + ): + allowed_types: List[Literal["all", "any"]] = ["all", "any"] + rule_methods = [all, any] + if rule_type not in allowed_types: + raise ValueError(f"rule_type must be one of : {','. join(allowed_types)}") + + self.parent = parent + self.rule_name = rule_name + self.rule_type = rule_type + self.rule_method = rule_methods[ + allowed_types.index(self.rule_type) + ] # get the actual python object corresponding to the rule type + self.inverted = inverted + self.sub_rules: List[RuleConditions | Statement] = [] + + for key, value in rule_dict.items(): + allowed_types = ["all", "any"] + for ty in allowed_types: + if ty in key: + _rule_type = ty + _inverted = True if "_not" in key else False + sub_rule = RuleConditions(value, self, rule_type=_rule_type, inverted=_inverted) + break + else: + sub_rule = Statement(key, value, self) + + self.sub_rules.append(sub_rule) + + @property + def patterns(self): + return self.parent.patterns + + def evaluate(self, file_record: FileRecord | str | Path) -> FileRecord | bool: + if isinstance(file_record, (str, Path)): + file_record = FileRecord(Path(file_record)) + evaluations = [] + for condition in self.sub_rules: + boolean_return = condition.evaluate(file_record) + evaluations.append(boolean_return) + boolean_return = self.rule_method(evaluations) + + boolean_return = not boolean_return if self.inverted else boolean_return + if self.rule_name is None: + return boolean_return + + file_record.match |= boolean_return + if boolean_return: + file_record.matching_rules.append(self.rule_name) + return file_record + + def __str__(self): + spacer = "\n - " + line_return = "\n" + sub_rules_str = spacer + spacer.join(str(value) for value in self.sub_rules) + type_str = self.rule_type + type_str += "~" if self.inverted else "" + return f"{' Conditions :' if self.rule_name else ' ' + type_str}{sub_rules_str}" + + +class RuleActions: + allowed_actions = ["rename", "include", "delete", "exclude", "abort"] + allowed_triggers = ["match", "destination_exists", "rename_unchanged", "rename_error", "rename_successfull"] + triggers: Dict[Triggers, Actions] + + def __init__(self, rule_dict: dict, rule_name: str, parent: "Rule"): + self.rule_name = rule_name + self.parent = parent + if "on" not in rule_dict.keys(): + raise ValueError(f'The rule {rule_name} defined no "on" triggers !') + + self.triggers = rule_dict["on"] + + if "match" not in self.triggers.keys(): + raise ValueError( + f"match action was not defined in rule {rule_name}. Must be defined. " + "Set on : match to null if you wish to keep the rule but make it inactive." + ) + + if self.triggers["match"] is None: + self.parent.active = False + + for key, value in self.triggers.items(): + if value == "rename" and "rename" not in rule_dict.keys(): + raise ValueError( + f"Trigger {key} in rule {rule_name} was defined with action rename, " + "but rename rules are not defined" + ) + if key not in self.allowed_triggers: + raise ValueError( + f"Trigger {key} in rule {rule_name} is invalid. Valid keys are {','.join(self.allowed_triggers)}" + ) + if value not in self.allowed_actions: + raise ValueError( + f"Action {value} in trigger {key} in rule {rule_name} is invalid. Valid keys are" + f" {','.join(self.allowed_actions)}" + ) + + self.rename_rule: dict[Element, str | dict] = rule_dict.get("rename", {}) + for key, value in self.rename_rule.items(): + if isinstance(value, dict): + pattern_name = value.get("pattern", None) + if pattern_name and pattern_name not in self.patterns.keys(): + raise KeyError( + f"Pattern {pattern_name} was specified in rename action of rule : {self.rule_name} but that " + "pattern was not defined in re_patterns." + ) + elif not isinstance(value, str): + raise ValueError( + f"{rule_name} rule errror in 'rename' with {key}. The content of a renaming the rule must be either" + " a constant string or a dictionnary. See documentation for more details." + ) + + @property + def patterns(self): + return self.parent.patterns + + def actions_cascade(self, file_record: FileRecord): + if not file_record.match: + return file_record + + match_action = self.triggers.get("match", None) + if match_action is None: + return file_record + + if not self.is_matching_rule(file_record): + return file_record + + file_record.used_rule += self.rule_name + " " + + self.get_action_function_for("match", default="abort")(file_record, "match") + + if not file_record.destination_file.is_dataset_type_valid: + self.get_action_function_for("invalid_alf_format", default="abort")(file_record, "invalid_alf_format") + + return file_record + + def is_matching_rule(self, file_record: FileRecord): + matching_rules = file_record.matching_rules + + # no conflict between two matched rules, return the only matching rule + if len(matching_rules) == 1: + return self.rule_name == matching_rules[0] + + # get a dict of "rule" : "list of overriding rules" + overrides_dict = {rule_name: self.parent.parent.rules[rule_name].overrides for rule_name in matching_rules} + + overriden_rules = set() + for rule_name, overrides in overrides_dict.items(): + for overriden_name in overrides: + if overriden_name in matching_rules: + overriden_rules.add(overriden_name) + + remaining_rules = set(matching_rules).difference(overriden_rules) + if len(remaining_rules) == 0: + raise ValueError( + f"{','.join(set(matching_rules))} rules may be mutually overriding. Please double check your rules set." + ) + if len(remaining_rules) > 1: + raise ValueError( + f"{','.join(set(remaining_rules))} rules are matched together for one file and overridings are not" + " defined for such cases. Please double check." + ) + + if self.rule_name == list(remaining_rules)[0]: + return True + return False + + def rename_element( + self, file_record: FileRecord, element: Element, rule: RenameElementRule + ) -> Tuple[str | None, bool]: + """Return a renamed element of the source file based on the element name an content. + + Args: + file_record (FileRecord): The file to perform renaming on + element (str): the elemnt to rename (ocject, attribute, etc.) + rule (str | dict): _description_ + + Raises: + ValueError: _description_ + + Returns: + _type_: _description_ + """ + if isinstance(rule, str): # constant replacement + return rule, True + # then, it must be a dictionnary with pattern defined + pattern_name = rule["pattern"] + search_on = rule.get("search_on", "source_path") + if search_on == "source_path": + searched_string = str(file_record.source_path) + elif search_on == "source_filename": + searched_string = str(file_record.source_path.name) + else: + searched_string = file_record.source_file[search_on] # TODO make a list check in __init__ for that + + match = self.patterns[pattern_name].search(searched_string) + + # we make objects that we can use in case there is a matching or evaluation error. + # action_if_error is a bound method instance of the current class, + # that corresponds by name to what the user entered in "rename_error" : "" in rule in the json file. + # defaults to the abort method. + action_if_error = self.get_action_function_for("rename_error", default="abort") + message_error_prefix = ( + f"{element} matching error. Searched on {search_on}, with pattern {pattern_name}, matched {match}." + ) + + if eval_string := rule.get("eval", None): + try: + return eval(eval_string), True + # this occurs when there is most likely not match. + # Examples : NoneType is not supscriptable if match = None (TypeError) + # or match[3] does not exist because match contains only two elements (IndexError) + except (IndexError, TypeError) as e: + action_if_error( + file_record, + "no_match", + message=message_error_prefix + + f" Error : {e}. No match have been found. Test on https://regex101.com/", + ) + return "", False + + # this occurs when there is probably an error with the eval statement of the rule. + except Exception as e: + action_if_error( + file_record, + "evaluation_string_invalid", + message=message_error_prefix + f" Error : {e}. Evaluation string is probably invalid.", + ) + return "", False + else: # eval is not specified. We then expect to use the first element of match as rename + try: + return match[0], True + # this occurs when there is most likely not match. + except (IndexError, TypeError) as e: + action_if_error( + file_record, + "no_match_first_element", + message=message_error_prefix + + f" Error : {e}. No match have been found for first element. Test on https://regex101.com/", + ) + return "", False # we backtrack and don't change the element's value + + # actions : + def rename(self, file_record: FileRecord, source: str, *, message: str = "") -> FileRecord: + file_record.rename = True + file_record.executed_actions.append(f"{source} -> rename") + rename_status = True # will be set to false in the for loop after if any element renaming fails + for element, rule in self.rename_rule.items(): + file_record.destination_file[element], element_status = self.rename_element(file_record, element, rule) + rename_status = rename_status and element_status + + if not rename_status: # if we got a rename_error above, we skip the next steps + return file_record + + if file_record.destination_file.fullpath == file_record.source_path: + file_record.rename = False + self.get_action_function_for("rename_unchanged", default="include")(file_record, "rename_unchanged") + else: + self.get_action_function_for("rename_successfull", default="include")(file_record, "rename_successfull") + + return file_record + + def exclude(self, file_record: FileRecord, source: str, *, message: str = "") -> FileRecord: + file_record.include = False + file_record.executed_actions.append(f"{source} -> exclude") + return file_record + + def include(self, file_record: FileRecord, source: str, *, message: str = "") -> FileRecord: + file_record.include = True + file_record.executed_actions.append(f"{source} -> include") + return file_record + + def delete(self, file_record: FileRecord, source: str, *, message: str = "") -> FileRecord: + file_record.delete = True + file_record.executed_actions.append(f"{source} -> delete") + return file_record + + def abort(self, file_record: FileRecord, source: str, *, message: str = "") -> FileRecord: + file_record.abort.append(message) + file_record.executed_actions.append(f"{source} -> abort") + return file_record + + def get_action_function_for(self, trigger_name: Triggers, *, default: Actions) -> ActionFunction: + return getattr(self, self.triggers.get(trigger_name, default)) + + def __str__(self): + spacer = "\n - " + triggers_str = spacer + spacer.join([str(key) + " : " + str(value) for key, value in self.triggers.items()]) + rename_rule = spacer.join([str(key) + " : " + str(value) for key, value in self.rename_rule.items()]) + if rename_rule: + rename_rule = "\n Rename Rule :" + spacer + rename_rule + override_rule = spacer.join(self.parent.overrides) + if override_rule: + override_rule = "\n Overrides :" + spacer + override_rule + return f" Actions triggers :{triggers_str}{rename_rule}{override_rule}" + + +class Rule: + def __init__(self, rule_dict: dict, rule_name: str, parent: "Config"): + if "if" not in rule_dict.keys(): + raise ValueError(f"An if field must be defined in the rule {rule_name}") + self.rule_name = rule_name + self.parent = parent + self.rule_conditions = RuleConditions(rule_dict["if"], self, rule_name=rule_name) + self.rule_actions = RuleActions(rule_dict, rule_name, self) + overrides = rule_dict.get("overrides", []) + self.overrides = overrides if isinstance(overrides, list) else [overrides] + self.active = True + + @property + def patterns(self): + return self.parent.patterns + + def evaluate(self, file_record): + return self.rule_conditions.evaluate(file_record) if self.active else file_record + + def actions_cascade(self, file_record) -> FileRecord: + return self.rule_actions.actions_cascade(file_record) if self.active else file_record + + def __str__(self): + return f"Rule : {self.rule_name}" + "\n" + str(self.rule_actions) + "\n" + str(self.rule_conditions) diff --git a/src/alyx_connector/files/registration/__init__.py b/src/alyx_connector/files/registration/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/alyx_connector/files/registration/files.py b/src/alyx_connector/files/registration/files.py new file mode 100644 index 0000000000000000000000000000000000000000..f297d29baa3edc85086daafa84190dae6e665b94 --- /dev/null +++ b/src/alyx_connector/files/registration/files.py @@ -0,0 +1,198 @@ +from dataclasses import dataclass, field +from pathlib import Path +from pandas import Series, DataFrame +from ...files.parsing.files import File + + +@dataclass +class ActionRequests: + + rename = False + delete = False + include = False + abort = False + + +@dataclass +class Issues: + + path_conflicts = False + parseable = False + dataset_type_exists = False + + sources: list[str] = field(default_factory=list) + + +class FileStatus: + + def __init__(self): + self.issues = Issues() + self.requests = ActionRequests() + + +class FileRecordSeries(Series): + + def __init__(self, source_path: str | Path): + data = {} + data["source_path"] = Path(source_path) + data["matching_rules"] = [] + data["used_rule"] = None + super().__init__(data) + + +@dataclass +class FileRecord: + # source_path is the original path from disk scan. will never change + source_path: Path + + match: bool = False + matching_rules: list = field(default_factory=list) + used_rule: str = "" + + valid_alf: bool = False + path_conflicts: bool = False + dataset_type_exists: bool = False + rename: bool = False + delete: bool = False + include: bool = False + abort: list = field(default_factory=list) + + frozen = False + + executed_actions = [] + + # source file + @property + def source_file(self) -> File: + source_file = getattr("self", "_source_file", None) + if source_file is None: + try: + source_file = File.from_path(self.source_path) + except Exception as e: + raise ValueError(f"File from {self.source_path} was not parseable ! {type(e)}:{e}") + self._source_file = source_file + return source_file + + # was alf_info + @property + def destination_file(self) -> File: + destination_file = getattr("self", "_destination_file", None) + if destination_file is None: + destination_file = self.source_file.copy() + self._destination_file = destination_file + return destination_file + + @property + def final_path(self) -> Path: + if not hasattr("self", "_final_path"): + self._final_path = self.destination_file.fullpath if self.rename else self.source_path + return self._final_path + + @property + def final_file(self) -> "File": + if not hasattr("self", "_final_file"): + self._final_file = self.destination_file if self.rename else self.source_file + return self._final_file + + @property + def final_pathstring(self): + if not hasattr("self", "_final_pathstring"): + self._final_pathstring = str(self.final_path) + return self._final_pathstring + + def actions_cascade(self, config: "Config"): + for rule in config.rules.values(): + rule.actions_cascade(self) + + def finish_cascade(self, config: "Config"): + # change the values of the filre record after all other actions have been resolved. + # finish actions include calculating , + + self.valid_alf = self.destination_file.is_dataset_type_valid + + if self.valid_alf and self.destination_file.dataset_type in config.dataset_types: + self.dataset_type_exists = True + + @property + def inclusion_accepted(self): + if ( + self.include + and self.valid_alf + and self.dataset_type_exists + and not self.path_conflicts + and not self.abort + and not self.delete + ): + return True + return False + + @property + def rename_accepted(self): + if self.rename and self.valid_alf and not self.path_conflicts and not self.abort and not self.delete: + return True + return False + + def apply_changes(self, do_deletes=True, do_renames=True): # apply changes to file_record + if self.delete and self.rename: + raise ValueError("Cannot rename AND delete the same entry.") + + if self.rename_accepted and do_renames: + file_directory = self.destination_file.fullpath.parent + file_directory.mkdir(parents=True, exist_ok=True) + self.source_file.fullpath.rename(self.destination_file.fullpath) + + elif self.delete and do_deletes: + self.source_file.fullpath.unlink() + self.include = False + + def to_user_dict(self): + return { + "source_path": self.source_path, + "dest_path": str(self.destination_file.fullpath) if self.rename_accepted else "", + "info": self.info_message, + } + + @property + def info_message( + self, + ): # message to make from action booleans to help the use understand what happened + message = "" + if self.inclusion_accepted and not self.rename_accepted: + message = " included without change" + + if self.inclusion_accepted and self.rename_accepted: + message = " renamed and included" + + if not self.inclusion_accepted and self.rename_accepted: + message = " renamed and excluded" + + if not self.inclusion_accepted and not self.rename_accepted: + message = " excluded without change" + + if not self.valid_alf: + message = message + " dataset_type doesn't follow alyx format" + + if not self.dataset_type_exists: + message = message + f" dataset_type:{self.destination_file.dataset_type} not existing" + + if self.delete: + message = " auto deleted" + + if self.abort: + message_prefix = " Aborting due to errors : " + abort_messages = [] + for ab_msg in self.abort: + if ab_msg == " filepath_conflicts": + ab_msg = " File name conflicts with a current file or another file that will be renamed identically" + abort_messages.append(ab_msg) + + message = ( + message_prefix + + ", ".join(abort_messages) + # + " --- Without Abort, would have been " + # + message + ) + else: + message = "Will be " + message + + return str(message) diff --git a/src/alyx_connector/files/registration/manage.py b/src/alyx_connector/files/registration/manage.py new file mode 100644 index 0000000000000000000000000000000000000000..7105d2ad0149242e556ca2642eedd6961b5b1b1c --- /dev/null +++ b/src/alyx_connector/files/registration/manage.py @@ -0,0 +1,21 @@ + + + +class RegistrationClient: + + def add_files(self, files_list): + + connector.web_client.create( + endpoint="datasets", + data={ + "session_pk": "dc5a61db-cbb6-48dc-bcb9-310211c8512c", + "dataset_type": "trials.choice", + "collection": "DELETE_LATER_JUST_A_TEST", + "data_format": ".txt", + "set_file_records": [ + {"extra": "001", "exists": True}, + {"extra": "002", "exists": True}, + {"extra": "003", "exists": True}, + ], + }, + ) diff --git a/src/alyx_connector/files/registration/rules.json b/src/alyx_connector/files/registration/rules.json new file mode 100644 index 0000000000000000000000000000000000000000..8845409e3c3b858b4ba6ea6ff0b2ed1bd3c79d54 --- /dev/null +++ b/src/alyx_connector/files/registration/rules.json @@ -0,0 +1,466 @@ +{ + "re_patterns": { + "VGAT_MOUSE_NO": "Vgat.*?(\\d{1,3}).*jRGECO", + "TIFF_FRAME_NO": ".*(\\d{5})\\.tiff?$", + "TDMS_TRIALS_TABLE_TIME": "(\\d{4}_\\d{2}_\\d{2}_\\d{2}_\\d{2})\\.tdms$", + "TDMS_VIDEO_TRIAL_NO": ".*?(\\d+)\\.tdms$", + "FOV_NO": "^.*(?:(?:FOV)|(?:fieldOfView))[-_ \\.]*?(\\d+).*$", + "CONDENSED_DATE": ".*?(20\\d{4,6}).*?", + "SESSION_NO": ".*?20\\d{4,6}_(\\d).*?", + "ALYX_PATH_EID": "\\w+(?:\\|\/)\\d{4}\\-\\d{2}\\-\\d{2}(?:\\|\/)\\d{3}", + "IOI_WHISKER": "^([a-zA-Z0-9]+)", + "IOI_WITH_VERSIONS": "^(?:stim.*?_)?([a-zA-Z0-9]+)(?:(?:_|.)((?:[vV]\\d+)|(?:crash)))?(?:stim)?.*$" + }, + "rules": { + "imaging_data_rule1": { + "if": { + "extension": { + "exact": [ + "tif", + "tiff" + ] + }, + "collection": { + "contain": "imaging_data" + } + }, + "on": { + "match": "rename", + "destination_exists": "abort", + "rename_unchanged": "exclude" + }, + "rename": { + "object": "imaging", + "attribute": "frames", + "extra": { + "pattern": "TIFF_FRAME_NO", + "eval": "match[1].zfill(5)" + } + } + }, + "imaging_data_rule2": { + "if": { + "object": "imaging", + "attribute": "frames", + "extra": { + "exact_not": "" + } + }, + "on": { + "match": "include" + }, + "overrides": [ + "imaging_data_rule1" + ] + }, + "behavior_pupil_rule1": { + "if": { + "extension": "tdms", + "collection": { + "contain": [ + "pupil" + ] + } + }, + "on": { + "match": "rename" + }, + "rename": { + "object": "behaviour", + "attribute": "video", + "collection": "behaviour_imaging\\pupil", + "extra": { + "pattern": "TDMS_VIDEO_TRIAL_NO", + "eval": "'pupil.' + match[1].zfill(5)" + } + } + }, + "behavior_whiskers_rule1": { + "if": { + "extension": "tdms", + "collection": { + "contain": [ + "whiskers", + "whisker" + ] + } + }, + "on": { + "match": "rename" + }, + "rename": { + "object": "behaviour", + "attribute": "video", + "collection": "behaviour_imaging\\whiskers", + "extra": { + "pattern": "TDMS_VIDEO_TRIAL_NO", + "eval": "'whiskers.' + match[1].zfill(5)" + } + } + }, + "field_of_view_png_rule1": { + "if": { + "extension": [ + "png", + "PNG" + ], + "collection": [ + "", + "imaging_data" + ], + "object": { + "contain": [ + "FOV", + "imaging" + ] + } + }, + "on": { + "match": "rename" + }, + "rename": { + "object": "imaging", + "attribute": "fieldOfView", + "collection": "imaging_data", + "extra": { + "pattern": "FOV_NO", + "eval": "match[1].zfill(2) if match is not None and match.lastindex > 0 else ''" + } + } + }, + "behavior_timeline_tdms_rule1": { + "if": { + "extension": "tdms", + "collection": "" + }, + "on": { + "match": "rename" + }, + "rename": { + "object": "trials", + "attribute": "eventTimeline", + "extra": "" + } + }, + "behavior_timeline_tdms_rule2": { + "if": { + "extension": "tdms", + "collection": "imaging_data", + "object": { + "contain": [ + "VGAT", + "EGFP" + ] + } + }, + "on": { + "match": "rename" + }, + "rename": { + "object": "trials", + "attribute": "eventTimeline", + "collection": "", + "extra": "" + }, + "overrides": [ + "behavior_timeline_tdms_rule1" + ] + }, + "intrinsic_imaging_tdms_rule1": { + "if": { + "extension": "tdms", + "collection": { + "exact": [ + "intrinsic_optical_imaging", + "IOI" + ] + } + }, + "on": { + "match": "rename" + }, + "rename": { + "object": "imaging_intrinsic", + "attribute": "delta_stim_images", + "extra": { + "search_on": "source_filename", + "pattern": "IOI_WITH_VERSIONS", + "eval": "match[1] + ('.' + match[2] if match.lastindex > 1 else '')" + }, + "collection": "intrinsic_optical_imaging" + } + }, + "intrinsic_imaging_vessels_rule1": { + "if": { + "extension": [ + "", + "tiff" + ], + "collection": { + "exact": [ + "intrinsic_optical_imaging", + "IOI" + ] + }, + "object": { + "contain": [ + "reference", + "green", + "Green", + "FOV", + "fov" + ] + } + }, + "on": { + "match": "rename" + }, + "rename": { + "object": "imaging_intrinsic", + "attribute": "vessels_reference", + "extension": "tiff", + "collection": "intrinsic_optical_imaging" + } + }, + "intrinsic_imaging_binaries_rule1": { + "if": { + "extension": [ + "" + ], + "collection": { + "exact": [ + "intrinsic_optical_imaging", + "IOI" + ] + }, + "object": { + "contain_not": [ + "reference", + "green", + "Green" + ] + } + }, + "on": { + "match": "rename" + }, + "rename": { + "object": "imaging_intrinsic", + "attribute": "bin_delta_stim_images", + "extension": "binlv", + "collection": "intrinsic_optical_imaging", + "extra": { + "search_on": "source_filename", + "pattern": "IOI_WITH_VERSIONS", + "eval": "match[1] + ('.' + match[2] if match.lastindex > 1 else '')" + } + } + }, + "intrinsic_imaging_alredy_renamed_versions_rule1": { + "if": { + "collection": { + "exact": [ + "intrinsic_optical_imaging" + ] + }, + "object": { + "exact": "imaging_intrinsic" + }, + "attribute": { + "exact": [ + "delta_stim_images", + "bin_delta_stim_images", + "vessels_reference" + ] + }, + "extension": { + "exact": [ + "binlv", + "tdms", + "tiff" + ] + } + }, + "on": { + "match": "include" + }, + "overrides": [ + "intrinsic_imaging_binaries_rule1", + "intrinsic_imaging_vessels_rule1", + "intrinsic_imaging_tdms_rule1" + ] + }, + "behavior_trigger_text_pupil_rule1": { + "if": { + "extension": "txt", + "collection": { + "contain": [ + "pupil" + ] + }, + "object": "Trigger" + }, + "on": { + "match": "rename" + }, + "rename": { + "object": "behaviour", + "attribute": "video_triggers", + "collection": "behaviour_imaging\\pupil", + "extra": "pupil" + } + }, + "behavior_trigger_text_whiskers_rule1": { + "if": { + "extension": "txt", + "collection": { + "contain": [ + "whiskers", + "whisker" + ] + }, + "object": "Trigger" + }, + "on": { + "match": "rename" + }, + "rename": { + "object": "behaviour", + "attribute": "video_triggers", + "collection": "behaviour_imaging\\whiskers", + "extra": "whiskers" + } + }, + "behavior_cam_settings_text_pupil_rule1": { + "if": { + "extension": "txt", + "collection": { + "contain": [ + "pupil" + ] + }, + "object": "CameraSettings" + }, + "on": { + "match": "rename" + }, + "rename": { + "object": "behaviour", + "attribute": "camera_settings", + "collection": "behaviour_imaging\\pupil", + "extra": "pupil" + } + }, + "behavior_cam_settings_text_whiskers_rule1": { + "if": { + "extension": "txt", + "collection": { + "contain": [ + "whiskers", + "whisker" + ] + }, + "object": "CameraSettings" + }, + "on": { + "match": "rename" + }, + "rename": { + "object": "behaviour", + "attribute": "camera_settings", + "collection": "behaviour_imaging\\whiskers", + "extra": "whiskers" + } + }, + "behavior_cam_sessings_include_rule": { + "if": { + "extension": "txt", + "collection": { + "exact": [ + "behaviour_imaging\\whiskers", + "behaviour_imaging\\pupil" + ] + }, + "object": "behaviour", + "attribute": "camera_settings", + "extra": { + "exact": [ + "whiskers", + "pupil" + ] + } + }, + "on": { + "match": "include" + }, + "overrides": [ + "behavior_cam_settings_text_whiskers_rule1", + "behavior_cam_settings_text_pupil_rule1" + ] + }, + "delete_tdms_index_rule1": { + "if": { + "extension": "tdms_index" + }, + "on": { + "match": "delete" + }, + "overrides": [ + "intrinsic_imaging_exclude_versions_rule1" + ] + }, + "exclude_Thumbs_rule1": { + "if": { + "extension": "db", + "object": "Thumbs" + }, + "on": { + "match": "exclude" + } + }, + "exclude_svg_files_rule1": { + "if": { + "extension": [ + "svg", + "SVG" + ] + }, + "on": { + "match": "exclude" + } + }, + "include_test_data_rule": { + "if": { + "collection": "DELETE_LATER_JUST_A_TEST" + }, + "on": { + "match": "include" + } + } + }, + "excluded_folders": [ + "figures", + "preprocessing_saves", + "screen_captures", + "suite2p", + "screenshots", + "trash", + "draft", + "scratch", + "Fiji_analysis", + "fiji_analysis", + "fijianalysis", + "Fiji_Analysis", + "FijiAnalysis", + "fijiAnalysis" + ], + "excluded_filenames": [ + "session_meta.json", + "pipelines_arguments.json" + ], + "cleanup_folders": [ + "pupil", + "whiskers", + "whisker" + ] +} \ No newline at end of file diff --git a/src/alyx_connector/files/registration/rules_config.py b/src/alyx_connector/files/registration/rules_config.py new file mode 100644 index 0000000000000000000000000000000000000000..b8bde7fa30406290dc39c029d0d1fe7abb09b95a --- /dev/null +++ b/src/alyx_connector/files/registration/rules_config.py @@ -0,0 +1,900 @@ +from dataclasses import dataclass, field +from logging import getLogger +import os, shutil, re, json, pkgutil +from pandas import Series, DataFrame +from pathlib import Path +from re import Pattern + +from .utils import get_existing_datasets, find_files +from ...files.parsing.files import File + +from typing import Literal, List, Dict, Tuple, Optional, Union, Callable, Protocol, Iterator, cast, TYPE_CHECKING + +if TYPE_CHECKING: + from ...connector import Connector + +Element = Literal[ + "source_path", + "subject", + "date", + "number", + "root", + "object", + "attribute", + "extension", + "extra", + "collection", + "revision", +] + +Triggers = Literal[ + "match", + "destination_exists", + "invalid_alf_format", + "rename_unchanged", + "rename_error", + "rename_successfull", +] + + +Actions = Literal["rename", "include", "delete", "exclude", "abort"] + +CheckFullOperation = Literal["exact", "contain", "match", "exact_not", "contain_not", "match_not"] +CheckOperation = Literal["exact", "contain", "match"] + +RulesConfig = Dict[ + Literal["re_patterns", "rules", "excluded_folders", "excluded_filenames", "cleanup_folders"], str | dict +] + +Rules = Dict[Literal["if", "on", "overrides", Actions], dict | list] + +RenameElementRule = Union[str, Dict[Literal["pattern", "eval", "search_on"], str]] + +Patterns = Dict[str, str] + + +class FilesRecordList: + def __init__(self, records: List["FileRecord"], session: Optional[Series] = None): + self.records = records + self.session = session + + def to_dataframe(self, details=True) -> DataFrame: + dicts = [] + + if details: + for file_record in self.records: + dico = file_record.__dict__ + dico["info"] = file_record.info_message + dicts.append(dico) + else: + + for file_record in self.records: + dicts.append(file_record.to_user_dict()) + + return DataFrame(dicts) + + def actions_cascade(self, config: "Config"): + + for record in self.records: + record.source_file # verify we can pase the path as a valid file system compatible item + record.actions_cascade(config) + + def finish_cascade(self, config: "Config"): + for record in self.records: + record.finish_cascade(config) + + def check_duplicate_final_paths(self): + # checking if destination_file conflicts with a file already existing + # of other file's destination_file.fullpath. + paths = Series([fr.final_pathstring for fr in self.records if not fr.delete]) + duplicates = paths[paths.duplicated(keep=False)].unique() + + for file_record in self.records: + if file_record.final_pathstring in duplicates: + file_record.abort.append("filepath_conflicts") + file_record.path_conflicts = True + + def __repr__(self): + return repr(self.to_dataframe(details=True)) + + def _repr_mimebundle_(self, include=None, exclude=None): + from IPython.core.getipython import get_ipython + from IPython.core.formatters import DisplayFormatter + + df = self.to_dataframe(details=True) + ipython = get_ipython() + if ipython is None or ipython.display_formatter is None: + return None + formatter = cast(DisplayFormatter, ipython.display_formatter).format + return formatter(df, include=include, exclude=exclude) + + # Delegate list methods explicitly + def __getitem__(self, index: int) -> "FileRecord": + return self.records[index] + + def __len__(self): + return len(self.records) + + def __iter__(self) -> Iterator["FileRecord"]: + return iter(self.records) + + def append(self, item: "FileRecord"): + self.records.append(item) + + def extend(self, items: List["FileRecord"]): + self.records.extend(items) + + def stats(self): + return self.to_dataframe().groupby(["used_rule", "info"]).size() + + +class ActionFunction(Protocol): + def __call__(self, file_record: "FileRecord", source: str, *, message: str = "") -> "FileRecord": ... + + +class OperationFunction(Protocol): + def __call__( + self, + value: str, + ) -> bool: ... + + +@dataclass +class FileRecord: + # source_path is the original path from disk scan. will never change + source_path: Path + + match: bool = False + matching_rules: list = field(default_factory=list) + used_rule: str = "" + + valid_alf: bool = False + path_conflicts: bool = False + dataset_type_exists: bool = False + rename: bool = False + delete: bool = False + include: bool = False + abort: list = field(default_factory=list) + + executed_actions: list = field(default_factory=list) + + # source file + @property + def source_file(self) -> File: + source_file = getattr(self, "_source_file", None) + if source_file is None: + try: + source_file = File.from_path(self.source_path) + except Exception as e: + raise ValueError(f"File from {self.source_path} was not parseable ! {type(e)}:{e}") + self._source_file = source_file + return source_file + + # was alf_info + @property + def destination_file(self) -> File: + if not hasattr(self, "_destination_file"): + self._destination_file = self.source_file.copy() + return self._destination_file + + @property + def final_path(self) -> Path: + if not hasattr(self, "_final_path"): + self._final_path = self.destination_file.fullpath if self.rename else self.source_path + return self._final_path + + @property + def final_file(self) -> "File": + if not hasattr(self, "_final_file"): + self._final_file = self.destination_file if self.rename else self.source_file + return self._final_file + + @property + def final_pathstring(self): + if not hasattr(self, "_final_pathstring"): + self._final_pathstring = str(self.final_path) + return self._final_pathstring + + def actions_cascade(self, config: "Config"): + for rule in config.rules.values(): + rule.actions_cascade(self) + + def finish_cascade(self, config: "Config"): + # change the values of the file record after all other actions have been resolved. + # finish actions include calculating , + + self.valid_alf = self.destination_file.is_dataset_type_valid + + if self.valid_alf and self.destination_file.dataset_type in config.dataset_types: + self.dataset_type_exists = True + + @property + def inclusion_accepted(self): + if ( + self.include + and self.valid_alf + and self.dataset_type_exists + and not self.path_conflicts + and not self.abort + and not self.delete + ): + return True + return False + + @property + def rename_accepted(self): + if self.rename and self.valid_alf and not self.path_conflicts and not self.abort and not self.delete: + return True + return False + + def apply_changes(self, do_deletes=True, do_renames=True): # apply changes to file_record + if self.delete and self.rename: + raise ValueError("Cannot rename AND delete the same entry.") + + if self.rename_accepted and do_renames: + file_directory = self.destination_file.fullpath.parent + file_directory.mkdir(parents=True, exist_ok=True) + self.source_file.fullpath.rename(self.destination_file.fullpath) + + elif self.delete and do_deletes: + self.source_file.fullpath.unlink() + self.include = False + + def to_user_dict(self): + return { + "source_path": self.source_path, + "dest_path": str(self.destination_file.fullpath) if self.rename_accepted else "", + "info": self.info_message, + } + + @property + def info_message( + self, + ): # message to make from action booleans to help the use understand what happened + message = "" + if self.inclusion_accepted and not self.rename_accepted: + message = " included without change" + + if self.inclusion_accepted and self.rename_accepted: + message = " renamed and included" + + if not self.inclusion_accepted and self.rename_accepted: + message = " renamed and excluded" + + if not self.inclusion_accepted and not self.rename_accepted: + message = " excluded without change" + + if not self.valid_alf: + message = message + " dataset_type doesn't follow alyx format" + + if not self.dataset_type_exists: + message = message + f" dataset_type:{self.destination_file.dataset_type} not existing" + + if self.delete: + message = " auto deleted" + + if self.abort: + message_prefix = " Aborting due to errors : " + abort_messages = [] + for ab_msg in self.abort: + if ab_msg == " filepath_conflicts": + ab_msg = " File name conflicts with a current file or another file that will be renamed identically" + abort_messages.append(ab_msg) + + message = ( + message_prefix + + ", ".join(abort_messages) + # + " --- Without Abort, would have been " + # + message + ) + else: + message = "Will be " + message + + return str(message) + + +class Statement: + allowed_operations: List[CheckOperation] = ["exact", "contain", "match"] + allowed_elements = [ + "source_path", + "subject", + "date", + "number", + "root", + "object", + "attribute", + "extension", + "extra", + "collection", + "revision", + ] + conditions: List[str] | List[Pattern] + operation: CheckOperation + operation_method: OperationFunction + + def __init__( + self, element: Element, operation_detail: str | List[str] | Dict[CheckFullOperation, str | list[str]], parent + ): + self.inverted = False + self.parent = parent + + for el in self.allowed_elements: + if element == el: + self.tested_element = element + break + else: + raise ValueError( + f"Tested element is {self.tested_element} wich is invalid value. " + f"If must be one of :({''.join(self.allowed_elements)})" + ) + + if isinstance(operation_detail, dict): + # if the operation detail is a dict, if should contain a single key, wich is the check operation type + if len(operation_detail) != 1: + raise ValueError( + f"Content of tested element {self.tested_element} is a dict. " + "Then it must contain only one key ({''.join(self.allowed_operations)})" + ) + + operation = list(operation_detail.keys())[0] + conditions = operation_detail[operation] + + for op in self.allowed_operations: + if op in operation: + self.inverted = True if "_not" in operation else False + self.operation = op + break + else: + raise ValueError( + f"Content of tested element {self.tested_element} is a dict and the key present was : {operation}. " + "It must contain one of : ({''.join(self.allowed_operations)}). " + ) + else: + # If the operation detail is not a dict, then we asume that the check operation + # is : "exact" matching of the string or strings + self.operation = "exact" + conditions = operation_detail + + if not isinstance(conditions, list): + conditions = [conditions] + + if self.operation == "match": + existing_patterns = self.patterns + patterns = [] + for pattern_name in conditions: + try: + patterns.append(existing_patterns[pattern_name]) + except KeyError: + raise ValueError( + f"Pattern {pattern_name} was asked in condition statement {self.tested_element} " + "but was not defined in re_patterns." + ) + conditions = patterns + + # self.operation is a string name of a method of the class that handles boolean matchong a condition. + # self.operation_method is the actual bound method object that corresponds to that string + self.operation_method = getattr(self, self.operation) + self.conditions = conditions + + @property + def patterns(self): + return self.parent.patterns + + def evaluate(self, file_record: FileRecord): + if self.tested_element == "source_path": + value = str(file_record.source_path) + else: + value = file_record.source_file[self.tested_element] + if value is None: + return False + value = str(value) + # we invert the result of the boolean check if Statement.inverted is True, or not if not inverted + return self.operation_method(value) != self.inverted + + def exact(self, value): + return value in self.conditions + + def contain(self, value): + for item in self.conditions: + if item in value: + return True + return False + + def match(self, value): + for pattern in self.conditions: + if pattern.search(value): + return True + return False + + def __str__(self): + return ( + f"{self.tested_element} {'~' if self.inverted else ''}{self.operation} -> " + f"{', '.join([str(value) for value in self.conditions])}" + ) + + +class RuleConditions: + def __init__( + self, + rule_dict: dict, + parent: "Rule | RuleConditions", + rule_name: Optional[str] = None, + rule_type: Literal["all", "any"] = "all", + inverted: bool = False, + ): + allowed_types: List[Literal["all", "any"]] = ["all", "any"] + rule_methods = [all, any] + if rule_type not in allowed_types: + raise ValueError(f"rule_type must be one of : {','. join(allowed_types)}") + + self.parent = parent + self.rule_name = rule_name + self.rule_type = rule_type + self.rule_method = rule_methods[ + allowed_types.index(self.rule_type) + ] # get the actual python object corresponding to the rule type + self.inverted = inverted + self.sub_rules: List[RuleConditions | Statement] = [] + + for key, value in rule_dict.items(): + allowed_types = ["all", "any"] + for ty in allowed_types: + if ty in key: + _rule_type = ty + _inverted = True if "_not" in key else False + sub_rule = RuleConditions(value, self, rule_type=_rule_type, inverted=_inverted) + break + else: + sub_rule = Statement(key, value, self) + + self.sub_rules.append(sub_rule) + + @property + def patterns(self): + return self.parent.patterns + + def evaluate(self, file_record: FileRecord | str | Path) -> FileRecord | bool: + if isinstance(file_record, (str, Path)): + file_record = FileRecord(Path(file_record)) + evaluations = [] + for condition in self.sub_rules: + boolean_return = condition.evaluate(file_record) + evaluations.append(boolean_return) + boolean_return = self.rule_method(evaluations) + + boolean_return = not boolean_return if self.inverted else boolean_return + if self.rule_name is None: + return boolean_return + + file_record.match |= boolean_return + if boolean_return: + file_record.matching_rules.append(self.rule_name) + return file_record + + def __str__(self): + spacer = "\n - " + line_return = "\n" + sub_rules_str = spacer + spacer.join(str(value) for value in self.sub_rules) + type_str = self.rule_type + type_str += "~" if self.inverted else "" + return f"{' Conditions :' if self.rule_name else ' ' + type_str}{sub_rules_str}" + + +class RuleActions: + allowed_actions = ["rename", "include", "delete", "exclude", "abort"] + allowed_triggers = ["match", "destination_exists", "rename_unchanged", "rename_error", "rename_successfull"] + triggers: Dict[Triggers, Actions] + + def __init__(self, rule_dict: dict, rule_name: str, parent: "Rule"): + self.rule_name = rule_name + self.parent = parent + if "on" not in rule_dict.keys(): + raise ValueError(f'The rule {rule_name} defined no "on" triggers !') + + self.triggers = rule_dict["on"] + + if "match" not in self.triggers.keys(): + raise ValueError( + f"match action was not defined in rule {rule_name}. Must be defined. " + "Set on : match to null if you wish to keep the rule but make it inactive." + ) + + if self.triggers["match"] is None: + self.parent.active = False + + for key, value in self.triggers.items(): + if value == "rename" and "rename" not in rule_dict.keys(): + raise ValueError( + f"Trigger {key} in rule {rule_name} was defined with action rename, " + "but rename rules are not defined" + ) + if key not in self.allowed_triggers: + raise ValueError( + f"Trigger {key} in rule {rule_name} is invalid. Valid keys are {','.join(self.allowed_triggers)}" + ) + if value not in self.allowed_actions: + raise ValueError( + f"Action {value} in trigger {key} in rule {rule_name} is invalid. Valid keys are" + f" {','.join(self.allowed_actions)}" + ) + + self.rename_rule: dict[Element, str | dict] = rule_dict.get("rename", {}) + for key, value in self.rename_rule.items(): + if isinstance(value, dict): + pattern_name = value.get("pattern", None) + if pattern_name and pattern_name not in self.patterns.keys(): + raise KeyError( + f"Pattern {pattern_name} was specified in rename action of rule : {self.rule_name} but that " + "pattern was not defined in re_patterns." + ) + elif not isinstance(value, str): + raise ValueError( + f"{rule_name} rule errror in 'rename' with {key}. The content of a renaming the rule must be either" + " a constant string or a dictionnary. See documentation for more details." + ) + + @property + def patterns(self): + return self.parent.patterns + + def actions_cascade(self, file_record: FileRecord): + if not file_record.match: + return file_record + + match_action = self.triggers.get("match", None) + if match_action is None: + return file_record + + if not self.is_matching_rule(file_record): + return file_record + + file_record.used_rule += self.rule_name + " " + + self.get_action_function_for("match", default="abort")(file_record, "match") + + if not file_record.destination_file.is_dataset_type_valid: + self.get_action_function_for("invalid_alf_format", default="abort")(file_record, "invalid_alf_format") + + return file_record + + def is_matching_rule(self, file_record: FileRecord): + matching_rules = file_record.matching_rules + + # no conflict between two matched rules, return the only matching rule + if len(matching_rules) == 1: + return self.rule_name == matching_rules[0] + + # get a dict of "rule" : "list of overriding rules" + overrides_dict = {rule_name: self.parent.parent.rules[rule_name].overrides for rule_name in matching_rules} + + overriden_rules = set() + for rule_name, overrides in overrides_dict.items(): + for overriden_name in overrides: + if overriden_name in matching_rules: + overriden_rules.add(overriden_name) + + remaining_rules = set(matching_rules).difference(overriden_rules) + if len(remaining_rules) == 0: + raise ValueError( + f"{','.join(set(matching_rules))} rules may be mutually overriding. Please double check your rules set." + ) + if len(remaining_rules) > 1: + raise ValueError( + f"{','.join(set(remaining_rules))} rules are matched together for one file and overridings are not" + " defined for such cases. Please double check." + ) + + if self.rule_name == list(remaining_rules)[0]: + return True + return False + + def rename_element( + self, file_record: FileRecord, element: Element, rule: RenameElementRule + ) -> Tuple[str | None, bool]: + """Return a renamed element of the source file based on the element name an content. + + Args: + file_record (FileRecord): The file to perform renaming on + element (str): the elemnt to rename (ocject, attribute, etc.) + rule (str | dict): _description_ + + Raises: + ValueError: _description_ + + Returns: + _type_: _description_ + """ + if isinstance(rule, str): # constant replacement + return rule, True + # then, it must be a dictionnary with pattern defined + pattern_name = rule["pattern"] + search_on = rule.get("search_on", "source_path") + if search_on == "source_path": + searched_string = str(file_record.source_path) + elif search_on == "source_filename": + searched_string = str(file_record.source_path.name) + else: + searched_string = file_record.source_file[search_on] # TODO make a list check in __init__ for that + + match = self.patterns[pattern_name].search(searched_string) + + # we make objects that we can use in case there is a matching or evaluation error. + # action_if_error is a bound method instance of the current class, + # that corresponds by name to what the user entered in "rename_error" : "" in rule in the json file. + # defaults to the abort method. + action_if_error = self.get_action_function_for("rename_error", default="abort") + message_error_prefix = ( + f"{element} matching error. Searched on {search_on}, with pattern {pattern_name}, matched {match}." + ) + + if eval_string := rule.get("eval", None): + try: + return eval(eval_string), True + # this occurs when there is most likely not match. + # Examples : NoneType is not supscriptable if match = None (TypeError) + # or match[3] does not exist because match contains only two elements (IndexError) + except (IndexError, TypeError) as e: + action_if_error( + file_record, + "no_match", + message=message_error_prefix + + f" Error : {e}. No match have been found. Test on https://regex101.com/", + ) + return "", False + + # this occurs when there is probably an error with the eval statement of the rule. + except Exception as e: + action_if_error( + file_record, + "evaluation_string_invalid", + message=message_error_prefix + f" Error : {e}. Evaluation string is probably invalid.", + ) + return "", False + else: # eval is not specified. We then expect to use the first element of match as rename + try: + return match[0], True + # this occurs when there is most likely not match. + except (IndexError, TypeError) as e: + action_if_error( + file_record, + "no_match_first_element", + message=message_error_prefix + + f" Error : {e}. No match have been found for first element. Test on https://regex101.com/", + ) + return "", False # we backtrack and don't change the element's value + + # actions : + def rename(self, file_record: FileRecord, source: str, *, message: str = "") -> FileRecord: + file_record.rename = True + file_record.executed_actions.append(f"{source} -> rename") + rename_status = True # will be set to false in the for loop after if any element renaming fails + for element, rule in self.rename_rule.items(): + file_record.destination_file[element], element_status = self.rename_element(file_record, element, rule) + rename_status = rename_status and element_status + + if not rename_status: # if we got a rename_error above, we skip the next steps + return file_record + + if file_record.destination_file.fullpath == file_record.source_path: + file_record.rename = False + self.get_action_function_for("rename_unchanged", default="include")(file_record, "rename_unchanged") + else: + self.get_action_function_for("rename_successfull", default="include")(file_record, "rename_successfull") + + return file_record + + def exclude(self, file_record: FileRecord, source: str, *, message: str = "") -> FileRecord: + file_record.include = False + file_record.executed_actions.append(f"{source} -> exclude") + return file_record + + def include(self, file_record: FileRecord, source: str, *, message: str = "") -> FileRecord: + file_record.include = True + file_record.executed_actions.append(f"{source} -> include") + return file_record + + def delete(self, file_record: FileRecord, source: str, *, message: str = "") -> FileRecord: + file_record.delete = True + file_record.executed_actions.append(f"{source} -> delete") + return file_record + + def abort(self, file_record: FileRecord, source: str, *, message: str = "") -> FileRecord: + file_record.abort.append(message) + file_record.executed_actions.append(f"{source} -> abort") + return file_record + + def get_action_function_for(self, trigger_name: Triggers, *, default: Actions) -> ActionFunction: + return getattr(self, self.triggers.get(trigger_name, default)) + + def __str__(self): + spacer = "\n - " + triggers_str = spacer + spacer.join([str(key) + " : " + str(value) for key, value in self.triggers.items()]) + rename_rule = spacer.join([str(key) + " : " + str(value) for key, value in self.rename_rule.items()]) + if rename_rule: + rename_rule = "\n Rename Rule :" + spacer + rename_rule + override_rule = spacer.join(self.parent.overrides) + if override_rule: + override_rule = "\n Overrides :" + spacer + override_rule + return f" Actions triggers :{triggers_str}{rename_rule}{override_rule}" + + +class Rule: + def __init__(self, rule_dict: dict, rule_name: str, parent: "Config"): + if "if" not in rule_dict.keys(): + raise ValueError(f"An if field must be defined in the rule {rule_name}") + self.rule_name = rule_name + self.parent = parent + self.rule_conditions = RuleConditions(rule_dict["if"], self, rule_name=rule_name) + self.rule_actions = RuleActions(rule_dict, rule_name, self) + overrides = rule_dict.get("overrides", []) + self.overrides = overrides if isinstance(overrides, list) else [overrides] + self.active = True + + @property + def patterns(self): + return self.parent.patterns + + def evaluate(self, file_record): + return self.rule_conditions.evaluate(file_record) if self.active else file_record + + def actions_cascade(self, file_record) -> FileRecord: + return self.rule_actions.actions_cascade(file_record) if self.active else file_record + + def __str__(self): + return f"Rule : {self.rule_name}" + "\n" + str(self.rule_actions) + "\n" + str(self.rule_conditions) + + +class Config: + patterns: Dict[str, Pattern] + rules: Dict[str, Rule] + + def __init__( + self, + rules_path: Optional[str | Path] = None, + connector: "Optional[Connector]" = None, + session: Optional[Series] = None, + ): + from alyx_connector import Connector + + if session is not None and connector and not rules_path: + # TODO + if session["projects"].iloc[0]: + pass + + if rules_path is None: + data = pkgutil.get_data(__name__, "./rules.json") + if data is None: + raise ValueError("Could not find a rules.json file !") + rules_config: RulesConfig = json.loads(data.decode("utf-8")) + else: + rules_config: RulesConfig = json.load(open(rules_path, "r")) + + self.connector = connector if connector else Connector() + + patterns: Patterns = rules_config.get("re_patterns", {}) # type: ignore + compiled_paterns = {} + for pattern_name, pattern in patterns.items(): + compiled_paterns[pattern_name] = re.compile(pattern) + self.patterns = compiled_paterns + + rules: Dict[str, Rules] = rules_config["rules"] # type: ignore + + self.rules = {rule_name: Rule(rule_dict, rule_name, self) for rule_name, rule_dict in rules.items()} + + self.excluded_folders = rules_config.get("excluded_folders", []) + + self.excluded_filenames = rules_config.get("excluded_filenames", []) + + self.cleanup_folders = rules_config.get("cleanup_folders", []) + + self.dataset_types = get_existing_datasets(self.connector) + if len(self.dataset_types) == 0: + raise ValueError( + "dataset_types is empty. Cannot register any dataset if no dataset type exists. Maybe one's connector" + " has a problem ?" + ) + + def registration_pipeline(self, session): + file_records = self.evaluate_session(session) + if not self.is_applicable(file_records): + print("Some conflicts are present, cannot continue.") + return file_records + selected_records = self.apply_to_files(file_records) + records_groups = self.apply_to_alyx(selected_records, session) + return records_groups + + def evaluate_session(self, session: Series | str) -> FilesRecordList: + + if isinstance(session, Series): + search_folder = session["path"] + else: # session is a string, not a Series + session = cast(Series, self.connector.search(id=session, no_cache=True, details=True)["path"]) + search_folder = session["path"] + + files_list = find_files(search_folder, relative=False, levels=-1, get="files") + + file_records = self.evaluate(files_list) + file_records.session = session + return file_records + + def evaluate(self, file_list: List[str] | List[Path]) -> FilesRecordList: + file_records = FilesRecordList([FileRecord(Path(file_path)) for file_path in file_list]) + + for file_record in file_records: + skip = ( + False # If we find that a find is in the excluded folders, we just discard it (not even try to match) + ) + if file_record.destination_file.collection: + if any( + [ + collection in self.excluded_folders + for collection in file_record.destination_file.collection.parts + ] + ): + skip = True + if file_record.source_path.name in self.excluded_filenames: # same for filenames + skip = True + if skip: + continue + + for rule in self.rules.values(): + rule.evaluate(file_record) + self.actions_cascade(file_records) + return file_records + + def actions_cascade(self, file_records: FilesRecordList): + file_records.actions_cascade(self) + file_records.finish_cascade(self) + file_records.check_duplicate_final_paths() + return file_records + + def is_applicable(self, file_records): + status = [len(file_record.abort) >= 1 for file_record in file_records] + return not (any(status)) + + def apply_to_files(self, file_records: FilesRecordList, do_deletes=True, do_renames=True, do_cleanup=True): + # DELETING and RENAMING + + for file_record in file_records: + file_record.apply_changes(do_deletes, do_renames) + + # just cleaning up empty folders after renaming. + # could be improved to do recursive search. + # this implementation may miss nested empty folders + if do_cleanup: + session_path = file_records[0].source_file.session_path + folders_list = find_files(session_path, relative=True, levels=-1, get="folders") + for folder in folders_list: + if folder in self.cleanup_folders: + _folder_path = os.path.join(session_path, folder) + files_in_dir = find_files(_folder_path, relative=True, levels=-1, get="files") + if len(files_in_dir): + continue # folder is not empty, we cannot clean it up + shutil.rmtree(_folder_path, ignore_errors=True) + + return file_records + + def apply_to_alyx(self, file_records: FilesRecordList, session: Optional[Series] = None): + + if session is None: + session = file_records.session + + if session is None: + raise ValueError("A session must be provided") + + selected_records: List[FileRecord] = [] + for file_record in file_records: + if file_record.inclusion_accepted: + selected_records.append(file_record) + + files_list = [ + file_record.destination_file.fullpath if file_record.rename else file_record.source_path + for file_record in selected_records + ] + + self.connector.register.files(session, files_list) + + def __str__(self): + spacer = "\n- " + rules_str = spacer + spacer.join([str(rule) + "\n" for rule in self.rules.values()]) + return f"One-Registrator with configured rules : \n{rules_str}" diff --git a/src/alyx_connector/files/registration/utils.py b/src/alyx_connector/files/registration/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..6cc2582ce01a4d51e70d0e010aa31648f914fa42 --- /dev/null +++ b/src/alyx_connector/files/registration/utils.py @@ -0,0 +1,68 @@ +import os, re, pandas as pd + +from typing import List, TYPE_CHECKING + +if TYPE_CHECKING: + from alyx_connector import Connector + + +def get_existing_datasets(one_connector: "Connector"): + existing_dst = one_connector.search("dataset-types", details=False) + existing_types = [dst["name"] for _, dst in existing_dst.iterrows() if dst["attribute"]] + return existing_types + + +def find_files( + input_path, re_pattern=None, relative=False, levels=-1, get="files", parts="all", sort=True +) -> List[str]: + """ + Get full path of files from all folders under the ``input_path`` (including itself). + Can return specific files with optionnal conditions + Args: + input_path (str): A valid path to a folder. + This folder is used as the root to return files found + (possible condition selection by giving to re_callback a function taking a regexp + pattern and a string as argument, an returning a boolean). + Returns: + list: List of the file fullpaths found under ``input_path`` folder and subfolders. + """ + # if levels = -1, we get everything whatever the depth + # (at least up to 32767 subfolders, but this should be fine...) + + if levels == -1: + levels = 32767 + current_level = 0 + output_list = [] + + if re_pattern is not None: + re_pattern = re.compile(re_pattern) + + def _recursive_search(_input_path): + nonlocal current_level + for subdir in os.listdir(_input_path): + fullpath = os.path.join(_input_path, subdir) + if os.path.isfile(fullpath): + if (get == "all" or get == "files") and (re_pattern is None or re_pattern.match(fullpath)): + output_list.append(os.path.normpath(fullpath)) + + else: + if (get == "all" or get == "dirs" or get == "folders") and ( + re_pattern is None or re_pattern.match(fullpath) + ): + output_list.append(os.path.normpath(fullpath)) + if current_level < levels: + current_level += 1 + _recursive_search(fullpath) + current_level -= 1 + + if os.path.isfile(input_path): + raise ValueError(f"Can only list files in a directory. A file was given : {input_path}") + + _recursive_search(input_path) + + if relative: + output_list = [os.path.relpath(file, start=input_path) for file in output_list] + if parts == "name": + output_list = [os.path.basename(file) for file in output_list] + + return output_list diff --git a/src/alyx_connector/files/transfers.py b/src/alyx_connector/files/transfers/transfers.py similarity index 95% rename from src/alyx_connector/files/transfers.py rename to src/alyx_connector/files/transfers/transfers.py index 30534082283acf1a0c3f609850f662eda19bb873..61295e9d47f8f38338ff6a5b6402910876e26a5e 100644 --- a/src/alyx_connector/files/transfers.py +++ b/src/alyx_connector/files/transfers/transfers.py @@ -19,6 +19,17 @@ from pandas import DataFrame, Series from typing import Optional +from typing import TypedDict, Literal + + +class Policies(TypedDict, total=False): + close_dates: Literal["conflict", "overwrite", "transfer", "ignore"] + destination_older: Literal["conflict", "overwrite", "transfer", "ignore"] + no_file_exists: Literal["conflict", "overwrite", "transfer", "ignore"] + destination_younger: Literal["conflict", "overwrite", "transfer", "ignore"] + close_dates_threshold: int + + class FileTransferManager: results: DataFrame @@ -51,7 +62,7 @@ class FileTransferManager: conflicts = results[results["decision"] == "conflict"] accepted_decisions = ["transfer", "overwrite", "ignore", "conflict"] - def conflict_pannel(conflict=None): + def conflict_pannel(conflict: Optional[Series] = None): if conflict is None: return Panel("", title="❗ Handling Conflict :", border_style="dark_blue") @@ -424,25 +435,32 @@ class FileTransferManager: ) return DataFrame(copy_results) - def fetch(self, policies=None, show_status=True): + def fetch(self, policies: Optional[Policies] = None, show_status=True): results = self.check_files(source="remote_path", destination="local_path", policies=policies) new_file_namager = FileTransferManager(self.sessions, results, direction="pull") if show_status: new_file_namager.status() return new_file_namager - def push_request(self, policies=None, show_status=True): + def push_request(self, policies: Optional[Policies] = None, show_status=True): results = self.check_files(source="local_path", destination="remote_path", policies=policies) new_file_namager = FileTransferManager(self.sessions, results, direction="push") if show_status: new_file_namager.status() return new_file_namager - def check_files(self, source="remote_path", destination="local_path", policies=None): + def pull_request(self, policies: Optional[Policies] = None, show_status=True): + results = self.check_files(source="remote_path", destination="local_path", policies=policies) + new_file_namager = FileTransferManager(self.sessions, results, direction="push") + if show_status: + new_file_namager.status() + return new_file_namager + + def check_files(self, source="remote_path", destination="local_path", policies: Optional[Policies] = None): console = Console() - default_policies = { + default_policies: Policies = { "close_dates": "conflict", "destination_older": "overwrite", "no_file_exists": "transfer", diff --git a/src/alyx_connector/web/api.py b/src/alyx_connector/web/api.py index 026157696314536f8c7daf08a22270384fcd4071..4a2c8a92c1fe5d0ae7cb480764078c37bca1aec9 100644 --- a/src/alyx_connector/web/api.py +++ b/src/alyx_connector/web/api.py @@ -1,10 +1,9 @@ from openapi_parser.specification import Operation, Specification, Path as OpenAPIPath from openapi_parser import parse as parse_openapi_schema from openapi_parser.errors import ParserError -import requests +import json, re, requests from requests.models import Response -import json -import re +from urllib.parse import urlencode from logging import getLogger from abc import ABC @@ -111,7 +110,7 @@ class EndpointUrl(str): protocol=self.client.protocol, # http or https netloc=self.client.netloc, # netloc = host+port path=self.finalized_path(**requirements_dict), # path - query_string=self.make_query_string(query_dict), # querystring example : ?thing=truc + query_string=urlencode(query_dict), # querystring example : ?thing=truc fragment=fragment, # basically an anchor, fragment example : #title1 ) return url @@ -135,11 +134,11 @@ class EndpointUrl(str): query_dict = {k: v for k, v in kwargs.items() if k not in self.requirements} return query_dict, requirements - def make_query_string(self, query_dict: dict) -> str: - query_list = [] - for key, value in query_dict.items(): - query_list.append(f"{key}={value}") - return "&".join(query_list) + # def make_query_string(self, query_dict: dict) -> str: + # query_list = [] + # for key, value in query_dict.items(): + # query_list.append(f"{key}={value}") + # return "&".join(query_list) @property def endpoint(self): diff --git a/src/alyx_connector/web/clients.py b/src/alyx_connector/web/clients.py index abd4261417dce01d7915259a29bb86a98dd2c9ca..9067a46f4907baaf4b128792cdff1dd58d7a7c70 100644 --- a/src/alyx_connector/web/clients.py +++ b/src/alyx_connector/web/clients.py @@ -12,7 +12,7 @@ from ..configuration import Configuration from .urls import UrlValidator from .api import EndpointUrl, Endpoint, APISpecification, OpenAPISpecification, Request, Operateur -from typing import Optional, Type, TypeVar, Generic, Literal, List, Dict +from typing import Optional, Type, TypeVar, Generic, Literal, List, Dict, Any, cast Specification = TypeVar("Specification", bound=APISpecification) @@ -218,7 +218,7 @@ class Client(ABC, Generic[Specification]): for result in tqdm( search_result, total=len(search_result), delay=2, desc=f"Loading {endpoint} details", file=stdout ): - retrieve_params = {name: result[name] for name in required_params} + retrieve_params = cast(Dict[str, Any], {name: result[name] for name in required_params}) detailed_results.append(self.rest(endpoint, "retrieve", **retrieve_params)) return detailed_results @@ -443,3 +443,9 @@ class ClientWithConfig(ClientWithAuth): class WebClient(ClientWithConfig): specification_class = OpenAPISpecification + + +class CreationClient: + + def __init__(self) -> None: + pass diff --git a/src/alyx_connector/web/responses.py b/src/alyx_connector/web/responses.py deleted file mode 100644 index 675097af053cc64970e1676060fa36c2bbcc97a7..0000000000000000000000000000000000000000 --- a/src/alyx_connector/web/responses.py +++ /dev/null @@ -1,196 +0,0 @@ -import math -import urllib, requests -from logging import getLogger -from collections.abc import Mapping - -from .urls import UrlValidator - -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from .clients import Client - - -logger = getLogger("alyx_conntector.web.responses") - - -class ResponseManager: - - def __init__(self, client: Client): - self.client = client - - def __getitem__(self, value): - return getattr(self, value) - - def list(self, json_response: dict, original_url: str, **kwargs): - - if isinstance(json_response, dict) and list(json_response.keys()) == [ - "count", - "next", - "previous", - "results", - ]: - if len(json_response["results"]) < json_response["count"]: - cache_args = {k: v for k, v in kwargs.items() if k in ("clobber", "expires")} - logger.debug(f"Creating a paginated response for a large Alyx request. Query : {original_url}") - json_response = _PaginatedResponse(self, json_response, cache_args, callbacks=self.fix_url) - logger.debug( - f"Paginated response total size is : {json_response.count}. " - f"Limit size is : {json_response.limit}. Query is : {json_response.query}" - ) - else: - json_response = json_response["results"] - return self.fix_url(json_response) - - def fix_url(self, response_data, fixed_keys=["admin_url"], do_fix=False): - - if isinstance(response_data, list): - return [self.fix_url(item, do_fix=False) for item in response_data] - elif isinstance(response_data, dict): - return { - key: (self.fix_url(item, do_fix=True) if key in fixed_keys else self.fix_url(item, do_fix=False)) - for key, item in response_data.items() - } - elif isinstance(response_data, _PaginatedResponse): - response_data.add_finishing_callback(self.fix_url) - return response_data - elif do_fix: - baseurl = UrlValidator.urlsplit(self.client.url) - return UrlValidator.urlsplit(response_data)._replace(scheme=baseurl.scheme, netloc=baseurl.netloc).geturl() - else: - return response_data - - -class _PaginatedResponse(Mapping): - """ - This class allows to emulate a list from a paginated response. - Provides cache functionality. - - Examples - -------- - >>> r = _PaginatedResponse(client, response) - """ - - def __init__(self, alyx, rep, cache_args=None, callbacks=[]): - """ - A paginated response cache object - - Parameters - ---------- - alyx : AlyxClient - An instance of an AlyxClient associated with the REST response - rep : dict - A paginated REST response JSON dictionary - cache_args : dict - A dict of kwargs to pass to _cache_response decorator upon subsequent requests - """ - - self.alyx = alyx - self.base_url = self.alyx.base_url - self.count = rep["count"] - self.limit = len(rep["results"]) - self._cache_args = cache_args or {} - # store URL without pagination query params - self.query = rep["next"] - # init the cache, list with None with count size - self._cache = [None] * self.count - - if not isinstance(callbacks, list): - callbacks = [callbacks] - - self.finishing_callbacks = callbacks - - # fill the cache with results of the query - self.store_results(rep, 0) - - def __len__(self): - return self.count - - def __getitem__(self, item): - """Returns an item from cache if the indices locations are already loaded, - or populates the cache chunk by chunk if some locations are empty. - """ - if isinstance(item, slice): - while None in self._cache[item]: - # .index(None) finds the first location where the cache is none, - # and populate stores a new chunk starting from here - self.populate(self._cache[item].index(None)) - elif item > self.count: - raise IndexError( - f"The paginated response has no item at position {item} : " f"it contains only {self.count} items" - ) - elif self._cache[item] is None: - self.populate(item) - return self._cache[item] - - def populate(self, idx): - """Populate a chunk of size self.limit, from an offset query depending on the value of the index required.""" - offset = self.limit * math.floor(idx / self.limit) - query = update_url_params(self.query, {"limit": self.limit, "offset": offset}) - res = self.alyx._generic_request(requests.get, query, **self._cache_args) - if self.count != res["count"]: - logger.warning( - f"remote results for {UrlValidator.urlsplit(query).path} endpoint changed; results may be inconsistent", - RuntimeWarning, - ) - self.store_results(res, offset) - - def store_results(self, res, offset): - for i, r in enumerate(res["results"][: self.count - offset]): - self._cache[i + offset] = self.finish_result(r) - - def finish_result(self, result): - """Method that should be overridden in child classes""" - for callback in self.finishing_callbacks: - result = callback(result) - return result - - def add_finishing_callback(self, callback): - if callback not in self.finishing_callbacks: - self.finishing_callbacks.append(callback) - - def __iter__(self): - for i in range(self.count): - try: - yield self.__getitem__(i) - except requests.HTTPError as e: - logger.error( - f"{e.response.status_code} error while trying to access " f"PaginatedResponse data at position {i}" - ) - raise e - - -def update_url_params(url: str, params: dict) -> str: - """Add/update the query parameters of a URL and make url safe - - Parameters - ---------- - url : str - A URL string with which to update the query parameters - params : dict - A dict of new parameters. For multiple values for the same query, use a list (see example) - - Returns - ------- - str - A new URL with said parameters updated - - Examples - ------- - >>> update_url_params('website.com/?q=', {'pg': 5}) - 'website.com/?pg=5' - - >>> update_url_params('website.com?q=xxx', {'pg': 5, 'foo': ['bar', 'baz']}) - 'website.com?q=xxx&pg=5&foo=bar&foo=baz' - """ - # Remove percent-encoding - url = urllib.parse.unquote(url) - parsed_url = urllib.parse.urlsplit(url) - # Extract URL query arguments and convert to dict - parsed_get_args = urllib.parse.parse_qs(parsed_url.query, keep_blank_values=False) - # Merge URL arguments dict with new params - parsed_get_args.update(params) - # Convert back to query string - encoded_get_args = urllib.parse.urlencode(parsed_get_args, doseq=True) - # Update parser and convert to full URL str - return parsed_url._replace(query=encoded_get_args).geturl()