From 63c07d709ea799532d0ad54982164bb6bc0fa5c3 Mon Sep 17 00:00:00 2001 From: "Guillaume V." Date: Wed, 8 Jul 2026 17:06:36 +0200 Subject: [PATCH] Update [FreeSurfer] : Make notebook create missing Girder output path folders + add default path inside girder dataset --- .../freesurfer_longitudinal.ipynb | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/examples/freesurfer/freesurfer_longitudinal_processing/freesurfer_longitudinal.ipynb b/examples/freesurfer/freesurfer_longitudinal_processing/freesurfer_longitudinal.ipynb index 30d9b89..d336c1c 100644 --- a/examples/freesurfer/freesurfer_longitudinal_processing/freesurfer_longitudinal.ipynb +++ b/examples/freesurfer/freesurfer_longitudinal_processing/freesurfer_longitudinal.ipynb @@ -93,7 +93,34 @@ " parent = folder.parent\n", " for f in folder.iterdir():\n", " f.rename(parent / f.name)\n", - " shutil.rmtree(folder)\n" + " shutil.rmtree(folder)\n", + "\n", + "def ensure_girder_path(client, path):\n", + " \"\"\"\n", + " Create missing Girder folders in a path like:\n", + " /collection/name/folder/subfolder\n", + " \"\"\"\n", + " parts = path.strip(\"/\").split(\"/\")\n", + " current = \"/\" + \"/\".join(parts[:2])\n", + " resource = client.resourceLookup(current)\n", + " parent_id = resource[\"_id\"]\n", + " parent_type = resource[\"_modelType\"]\n", + " for part in parts[2:-1]:\n", + " next_path = current + \"/\" + part\n", + " try:\n", + " resource = client.resourceLookup(next_path)\n", + " except Exception:\n", + " resource = client.createFolder(\n", + " parent_id,\n", + " part,\n", + " parentType=parent_type\n", + " )\n", + "\n", + " parent_id = resource[\"_id\"]\n", + " parent_type = \"folder\"\n", + " current = next_path\n", + "\n", + " return resource" ], "id": "18aa877afac9a865", "outputs": [], @@ -133,7 +160,7 @@ "# Girder\n", "GIRDER_CLIENT = GirderClient(apiUrl='GIRDER_URL') # Your Girder API endpoint url (ex : https://srmnopt.creatis.insa-lyon.fr/warehouse/api/v1 or https://myriad.creatis.insa-lyon.fr/api/v1)\n", "GIRDER_DATASET_PATH = '/collection/COLLECTION_NAME/FOLDER_NAME' # Your Girder path to the dataset, can be in collections or user folders\n", - "GIRDER_OUTPUT_PATH = '/user/USER_NAME/FOLDER_NAME' # Your Girder path to the final outputs folder (must already exist), can be in collections or user folders\n", + "GIRDER_OUTPUT_PATH = GIRDER_DATASET_PATH + '/derivatives/freesurfer' # Your Girder path to the final outputs folder, can be in collections or user folders. Defaults to `GIRDER_DATASET_PATH/derivatives/freesurfer` but can be changed to format '/user/USER_NAME/FOLDER_NAME' or '/collection/COLLECTION_NAME/FOLDER_NAME'. The girder folders will be created automatically if they do not exist, but the script cannot create collections.\n", "\n", "# Local\n", "LOCAL_DATASET_PATH = Path('~/PATH').expanduser() # Your local dataset path, where the Girder dataset will be downloaded, must already exist and be empty. Do not add unrelated custom files in this directory and its subdirectories as it may break vip executions.\n", @@ -716,8 +743,13 @@ " moved_files.append((license_path, temp_path))\n", "\n", "try :\n", + " output_folder = ensure_girder_path(\n", + " cfg.GIRDER_CLIENT,\n", + " cfg.GIRDER_OUTPUT_PATH\n", + " )\n", + "\n", " # Upload full freesurfer dir (outputs) to Girder selected path GIRDER_OUTPUT_PATH\n", - " cfg.GIRDER_CLIENT.upload(str(FREESURFER_DIR), cfg.GIRDER_CLIENT.resourceLookup(cfg.GIRDER_OUTPUT_PATH)['_id'], leafFoldersAsItems=True, reuseExisting=True)\n", + " cfg.GIRDER_CLIENT.upload(str(FREESURFER_DIR), output_folder[\"_id\"], leafFoldersAsItems=True, reuseExisting=True)\n", "finally:\n", " restore_files(moved_files)\n", " print(f\"✅ Done: uploaded FreeSurfer outputs to Girder path '{cfg.GIRDER_OUTPUT_PATH}'.\")"