@brainpilot/skills 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/package.json +2 -2
  2. package/skills/01_Meta-Skills/academic-research-hub/SKILL.md +108 -0
  3. package/skills/01_Meta-Skills/academic-research-hub/scripts/requirements.txt +17 -0
  4. package/skills/01_Meta-Skills/academic-research-hub/scripts/research.py +781 -0
  5. package/skills/01_Meta-Skills/beautiful-log/SKILL.md +64 -0
  6. package/skills/01_Meta-Skills/beautiful-log/scripts/beautiful_log.py +274 -0
  7. package/skills/01_Meta-Skills/ethoclaw-daily-paper/SKILL.md +130 -0
  8. package/skills/01_Meta-Skills/ethoclaw-daily-paper/assets/config.template.yaml +54 -0
  9. package/skills/01_Meta-Skills/ethoclaw-daily-paper/assets/top5_digest_template.md +5 -0
  10. package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/build_top5_digest.py +300 -0
  11. package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/common.py +137 -0
  12. package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/merge_results.py +106 -0
  13. package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/run_pipeline.py +177 -0
  14. package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/search_arxiv.py +162 -0
  15. package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/search_pubmed.py +202 -0
  16. package/skills/01_Meta-Skills/ethoclaw-normalize-tabular/SKILL.md +173 -0
  17. package/skills/01_Meta-Skills/ethoclaw-normalize-tabular/scripts/normalize_data.py +874 -0
  18. package/skills/01_Meta-Skills/ethoclaw-pdf-research/SKILL.md +134 -0
  19. package/skills/01_Meta-Skills/ethoclaw-pdf-research/references/confirmation-prompts.md +31 -0
  20. package/skills/01_Meta-Skills/ethoclaw-pdf-research/references/output-patterns.md +45 -0
  21. package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/build_markdown_deliverables.py +41 -0
  22. package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/build_research_log.py +84 -0
  23. package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/build_summary_md.py +63 -0
  24. package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/extract_pdf_bundle.py +140 -0
  25. package/skills/01_Meta-Skills/experiment-controller/SKILL.md +140 -0
  26. package/skills/01_Meta-Skills/knowledge-graph-builder/SKILL.md +366 -0
  27. package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/entity_resolution.py +120 -0
  28. package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/extraction_prompt_template.txt +19 -0
  29. package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/graph_query.py +106 -0
  30. package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/hypothesis_cli_reference.py +42 -0
  31. package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/new_data_source_template.py +116 -0
  32. package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/requirements.txt +15 -0
  33. package/skills/01_Meta-Skills/method-design/SKILL.md +61 -0
  34. package/skills/01_Meta-Skills/multi-search-engine/SKILL.md +119 -0
  35. package/skills/01_Meta-Skills/research-idea/SKILL.md +65 -0
  36. package/skills/05_EEG_ERP/eeg-skill/SKILL.md +197 -0
  37. package/skills/05_EEG_ERP/meg-skill/SKILL.md +188 -0
  38. package/skills/05_EEG_ERP/meg-skill/scripts/time_frequency.py +223 -0
  39. package/skills/05_EEG_ERP/mne-eeg-tool/SKILL.md +165 -0
  40. package/skills/05_EEG_ERP/mne-eeg-tool/scripts/eeg_pipeline_reference.py +231 -0
  41. package/skills/05_EEG_ERP/seed-iv-skill/SKILL.md +184 -0
  42. package/skills/05_EEG_ERP/seed-iv-skill/scripts/classify_seed_iv.py +154 -0
  43. package/skills/05_EEG_ERP/seed-iv-skill/scripts/extract_seed_iv_features.py +190 -0
  44. package/skills/05_EEG_ERP/seed-iv-skill/scripts/validate_seed_iv.py +102 -0
  45. package/skills/05_EEG_ERP/seed-vig-skill/SKILL.md +182 -0
  46. package/skills/05_EEG_ERP/seed-vig-skill/scripts/classify_seed_vig.py +165 -0
  47. package/skills/05_EEG_ERP/seed-vig-skill/scripts/extract_seed_vig_features.py +185 -0
  48. package/skills/05_EEG_ERP/seed-vig-skill/scripts/validate_seed_vig.py +88 -0
  49. package/skills/06_fMRI_Neuroimaging/abcd-skill/SKILL.md +308 -0
  50. package/skills/06_fMRI_Neuroimaging/abcd-skill/scripts/abcd_qc_summary.py +449 -0
  51. package/skills/06_fMRI_Neuroimaging/abcd-skill/scripts/extract_abcd_phenotype.py +292 -0
  52. package/skills/06_fMRI_Neuroimaging/abcd-skill/scripts/reorganize_abcd.py +387 -0
  53. package/skills/06_fMRI_Neuroimaging/abide-skill/SKILL.md +302 -0
  54. package/skills/06_fMRI_Neuroimaging/abide-skill/scripts/abide_qc_summary.py +317 -0
  55. package/skills/06_fMRI_Neuroimaging/abide-skill/scripts/extract_abide_phenotype.py +267 -0
  56. package/skills/06_fMRI_Neuroimaging/abide-skill/scripts/reorganize_abide.py +387 -0
  57. package/skills/06_fMRI_Neuroimaging/adhd200-skill/SKILL.md +244 -0
  58. package/skills/06_fMRI_Neuroimaging/adhd200-skill/scripts/adhd200_qc_summary.py +98 -0
  59. package/skills/06_fMRI_Neuroimaging/adhd200-skill/scripts/extract_adhd200_phenotype.py +134 -0
  60. package/skills/06_fMRI_Neuroimaging/adhd200-skill/scripts/reorganize_adhd200.py +206 -0
  61. package/skills/06_fMRI_Neuroimaging/adni-skill/SKILL.md +358 -0
  62. package/skills/06_fMRI_Neuroimaging/adni-skill/scripts/generate_adni_task_files.py +1305 -0
  63. package/skills/06_fMRI_Neuroimaging/adni-skill/scripts/generate_vqa_from_tasks.py +766 -0
  64. package/skills/06_fMRI_Neuroimaging/adni-skill/scripts/reorganize_adni.py +491 -0
  65. package/skills/06_fMRI_Neuroimaging/aibl-skill/SKILL.md +295 -0
  66. package/skills/06_fMRI_Neuroimaging/aibl-skill/scripts/aibl_qc_summary.py +260 -0
  67. package/skills/06_fMRI_Neuroimaging/aibl-skill/scripts/extract_aibl_phenotype.py +365 -0
  68. package/skills/06_fMRI_Neuroimaging/aibl-skill/scripts/reorganize_aibl.py +394 -0
  69. package/skills/06_fMRI_Neuroimaging/aomic-skill/SKILL.md +292 -0
  70. package/skills/06_fMRI_Neuroimaging/aomic-skill/scripts/aomic_qc_summary.py +258 -0
  71. package/skills/06_fMRI_Neuroimaging/aomic-skill/scripts/extract_aomic_phenotype.py +284 -0
  72. package/skills/06_fMRI_Neuroimaging/aomic-skill/scripts/reorganize_aomic.py +322 -0
  73. package/skills/06_fMRI_Neuroimaging/asl-skill/SKILL.md +168 -0
  74. package/skills/06_fMRI_Neuroimaging/asl-skill/scripts/compute_cbf.py +224 -0
  75. package/skills/06_fMRI_Neuroimaging/bids-organizer/SKILL.md +241 -0
  76. package/skills/06_fMRI_Neuroimaging/bold5000-skill/SKILL.md +186 -0
  77. package/skills/06_fMRI_Neuroimaging/bold5000-skill/scripts/bold5000_qc_summary.py +96 -0
  78. package/skills/06_fMRI_Neuroimaging/bold5000-skill/scripts/extract_bold5000_stimulus.py +125 -0
  79. package/skills/06_fMRI_Neuroimaging/bold5000-skill/scripts/reorganize_bold5000.py +102 -0
  80. package/skills/06_fMRI_Neuroimaging/camcan-skill/SKILL.md +213 -0
  81. package/skills/06_fMRI_Neuroimaging/camcan-skill/scripts/camcan_qc_summary.py +131 -0
  82. package/skills/06_fMRI_Neuroimaging/camcan-skill/scripts/extract_camcan_phenotype.py +145 -0
  83. package/skills/06_fMRI_Neuroimaging/camcan-skill/scripts/validate_camcan.py +141 -0
  84. package/skills/06_fMRI_Neuroimaging/cobre-skill/SKILL.md +201 -0
  85. package/skills/06_fMRI_Neuroimaging/cobre-skill/scripts/cobre_qc_summary.py +95 -0
  86. package/skills/06_fMRI_Neuroimaging/cobre-skill/scripts/extract_cobre_phenotype.py +104 -0
  87. package/skills/06_fMRI_Neuroimaging/cobre-skill/scripts/reorganize_cobre.py +140 -0
  88. package/skills/06_fMRI_Neuroimaging/conn-tool/SKILL.md +180 -0
  89. package/skills/06_fMRI_Neuroimaging/dcm2nii/SKILL.md +189 -0
  90. package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/SKILL.md +183 -0
  91. package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/dmt_har_med_qc_summary.py +96 -0
  92. package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/extract_dmt_har_med_phenotype.py +121 -0
  93. package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/reorganize_dmt_har_med.py +125 -0
  94. package/skills/06_fMRI_Neuroimaging/dwi-skill/SKILL.md +359 -0
  95. package/skills/06_fMRI_Neuroimaging/fmri-skill/SKILL.md +371 -0
  96. package/skills/06_fMRI_Neuroimaging/fmriprep-tool/SKILL.md +228 -0
  97. package/skills/06_fMRI_Neuroimaging/freesurfer-tool/SKILL.md +286 -0
  98. package/skills/06_fMRI_Neuroimaging/freesurfer-tool/scripts/freesurfer_processor.py +145 -0
  99. package/skills/06_fMRI_Neuroimaging/fsl-tool/SKILL.md +208 -0
  100. package/skills/06_fMRI_Neuroimaging/hbn-skill/SKILL.md +271 -0
  101. package/skills/06_fMRI_Neuroimaging/hbn-skill/scripts/extract_hbn_phenotype.py +107 -0
  102. package/skills/06_fMRI_Neuroimaging/hbn-skill/scripts/hbn_qc_summary.py +96 -0
  103. package/skills/06_fMRI_Neuroimaging/hbn-skill/scripts/reorganize_hbn.py +150 -0
  104. package/skills/06_fMRI_Neuroimaging/hcpa-skill/SKILL.md +210 -0
  105. package/skills/06_fMRI_Neuroimaging/hcpa-skill/scripts/extract_hcpa_phenotype.py +146 -0
  106. package/skills/06_fMRI_Neuroimaging/hcpa-skill/scripts/hcpa_qc_summary.py +120 -0
  107. package/skills/06_fMRI_Neuroimaging/hcpa-skill/scripts/reorganize_hcpa.py +155 -0
  108. package/skills/06_fMRI_Neuroimaging/hcpd-skill/SKILL.md +210 -0
  109. package/skills/06_fMRI_Neuroimaging/hcpd-skill/scripts/extract_hcpd_phenotype.py +148 -0
  110. package/skills/06_fMRI_Neuroimaging/hcpd-skill/scripts/hcpd_qc_summary.py +125 -0
  111. package/skills/06_fMRI_Neuroimaging/hcpd-skill/scripts/reorganize_hcpd.py +146 -0
  112. package/skills/06_fMRI_Neuroimaging/hcpep-skill/SKILL.md +215 -0
  113. package/skills/06_fMRI_Neuroimaging/hcpep-skill/scripts/extract_hcpep_phenotype.py +157 -0
  114. package/skills/06_fMRI_Neuroimaging/hcpep-skill/scripts/hcpep_qc_summary.py +143 -0
  115. package/skills/06_fMRI_Neuroimaging/hcpep-skill/scripts/reorganize_hcpep.py +146 -0
  116. package/skills/06_fMRI_Neuroimaging/hcppipeline-tool/SKILL.md +217 -0
  117. package/skills/06_fMRI_Neuroimaging/hcpya-skill/SKILL.md +214 -0
  118. package/skills/06_fMRI_Neuroimaging/hcpya-skill/scripts/extract_hcpya_phenotype.py +190 -0
  119. package/skills/06_fMRI_Neuroimaging/hcpya-skill/scripts/hcpya_qc_summary.py +152 -0
  120. package/skills/06_fMRI_Neuroimaging/hcpya-skill/scripts/reorganize_hcpya.py +203 -0
  121. package/skills/06_fMRI_Neuroimaging/ixi-skill/SKILL.md +198 -0
  122. package/skills/06_fMRI_Neuroimaging/ixi-skill/scripts/ixi_qc_summary.py +137 -0
  123. package/skills/06_fMRI_Neuroimaging/ixi-skill/scripts/reorganize_ixi.py +190 -0
  124. package/skills/06_fMRI_Neuroimaging/mnd-skill/SKILL.md +191 -0
  125. package/skills/06_fMRI_Neuroimaging/mnd-skill/scripts/extract_mnd_phenotype.py +143 -0
  126. package/skills/06_fMRI_Neuroimaging/mnd-skill/scripts/mnd_qc_summary.py +120 -0
  127. package/skills/06_fMRI_Neuroimaging/mnd-skill/scripts/validate_mnd.py +107 -0
  128. package/skills/06_fMRI_Neuroimaging/mschallenge-skill/SKILL.md +203 -0
  129. package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/analyze_lesions.py +119 -0
  130. package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/longitudinal_lesion.py +148 -0
  131. package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/mschallenge_qc_summary.py +132 -0
  132. package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/validate_mschallenge.py +116 -0
  133. package/skills/06_fMRI_Neuroimaging/nibabel-skill/SKILL.md +184 -0
  134. package/skills/06_fMRI_Neuroimaging/nibabel-skill/scripts/atlas_coordinate_reference.py +61 -0
  135. package/skills/06_fMRI_Neuroimaging/nibabel-skill/scripts/freesurfer_io_reference.py +34 -0
  136. package/skills/06_fMRI_Neuroimaging/nibabel-skill/scripts/nifti_inspection_reference.py +35 -0
  137. package/skills/06_fMRI_Neuroimaging/nifd-skill/SKILL.md +205 -0
  138. package/skills/06_fMRI_Neuroimaging/nifd-skill/scripts/extract_nifd_phenotype.py +132 -0
  139. package/skills/06_fMRI_Neuroimaging/nifd-skill/scripts/nifd_qc_summary.py +111 -0
  140. package/skills/06_fMRI_Neuroimaging/nifd-skill/scripts/validate_nifd.py +111 -0
  141. package/skills/06_fMRI_Neuroimaging/nii2dcm/SKILL.md +143 -0
  142. package/skills/06_fMRI_Neuroimaging/nilearn-tool/SKILL.md +266 -0
  143. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/connectome_reference.py +65 -0
  144. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/denoise_timeseries_reference.py +58 -0
  145. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/hierarchical_parcellation_reference.py +53 -0
  146. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/kmeans_parcellation_reference.py +53 -0
  147. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/preprocess_bold_reference.py +76 -0
  148. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/rest_dictlearning_reference.py +56 -0
  149. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/rest_ica_reference.py +59 -0
  150. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/second_level_glm_reference.py +58 -0
  151. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/spacenet_classifier_reference.py +59 -0
  152. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/svm_classifier_reference.py +60 -0
  153. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/task_glm_reference.py +63 -0
  154. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/zalff_summary_reference.py +109 -0
  155. package/skills/06_fMRI_Neuroimaging/nsd-skill/SKILL.md +210 -0
  156. package/skills/06_fMRI_Neuroimaging/nsd-skill/scripts/extract_nsd_stimulus.py +171 -0
  157. package/skills/06_fMRI_Neuroimaging/nsd-skill/scripts/nsd_qc_summary.py +142 -0
  158. package/skills/06_fMRI_Neuroimaging/nsd-skill/scripts/validate_nsd.py +142 -0
  159. package/skills/06_fMRI_Neuroimaging/oasis-skill/SKILL.md +205 -0
  160. package/skills/06_fMRI_Neuroimaging/oasis-skill/scripts/extract_oasis_phenotype.py +126 -0
  161. package/skills/06_fMRI_Neuroimaging/oasis-skill/scripts/oasis_qc_summary.py +115 -0
  162. package/skills/06_fMRI_Neuroimaging/oasis-skill/scripts/validate_oasis.py +119 -0
  163. package/skills/06_fMRI_Neuroimaging/pet-skill/SKILL.md +173 -0
  164. package/skills/06_fMRI_Neuroimaging/pet-skill/scripts/compute_suvr.py +202 -0
  165. package/skills/06_fMRI_Neuroimaging/pnc-skill/SKILL.md +206 -0
  166. package/skills/06_fMRI_Neuroimaging/pnc-skill/scripts/extract_pnc_phenotype.py +136 -0
  167. package/skills/06_fMRI_Neuroimaging/pnc-skill/scripts/pnc_qc_summary.py +116 -0
  168. package/skills/06_fMRI_Neuroimaging/pnc-skill/scripts/validate_pnc.py +120 -0
  169. package/skills/06_fMRI_Neuroimaging/ppmi-skill/SKILL.md +209 -0
  170. package/skills/06_fMRI_Neuroimaging/ppmi-skill/scripts/extract_ppmi_phenotype.py +138 -0
  171. package/skills/06_fMRI_Neuroimaging/ppmi-skill/scripts/ppmi_qc_summary.py +111 -0
  172. package/skills/06_fMRI_Neuroimaging/ppmi-skill/scripts/validate_ppmi.py +117 -0
  173. package/skills/06_fMRI_Neuroimaging/qsiprep-tool/SKILL.md +320 -0
  174. package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/SKILL.md +215 -0
  175. package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/extract_rest_mdd_phenotype.py +132 -0
  176. package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/harmonize_sites.py +152 -0
  177. package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/rest_mdd_qc_summary.py +124 -0
  178. package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/validate_rest_mdd.py +103 -0
  179. package/skills/06_fMRI_Neuroimaging/smri-skill/SKILL.md +302 -0
  180. package/skills/06_fMRI_Neuroimaging/tcp-skill/SKILL.md +204 -0
  181. package/skills/06_fMRI_Neuroimaging/tcp-skill/scripts/extract_tcp_phenotype.py +139 -0
  182. package/skills/06_fMRI_Neuroimaging/tcp-skill/scripts/tcp_qc_summary.py +111 -0
  183. package/skills/06_fMRI_Neuroimaging/tcp-skill/scripts/validate_tcp.py +99 -0
  184. package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/SKILL.md +217 -0
  185. package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/scripts/extract_ucla_cnp_phenotype.py +145 -0
  186. package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/scripts/ucla_cnp_qc_summary.py +111 -0
  187. package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/scripts/validate_ucla_cnp.py +113 -0
  188. package/skills/06_fMRI_Neuroimaging/ukb-skill/SKILL.md +310 -0
  189. package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/build_ukb_survival.py +210 -0
  190. package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/extract_ukb_cases.py +308 -0
  191. package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/extract_ukb_phenotype.py +232 -0
  192. package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/ukb_qc_summary.py +158 -0
  193. package/skills/06_fMRI_Neuroimaging/wmh-segmentation/SKILL.md +133 -0
  194. package/skills/07_Computational_Modeling/detrending/SKILL.md +118 -0
  195. package/skills/07_Computational_Modeling/dictlearning/SKILL.md +122 -0
  196. package/skills/07_Computational_Modeling/filtering/SKILL.md +121 -0
  197. package/skills/07_Computational_Modeling/glm/SKILL.md +153 -0
  198. package/skills/07_Computational_Modeling/hierarchical/SKILL.md +121 -0
  199. package/skills/07_Computational_Modeling/ica/SKILL.md +122 -0
  200. package/skills/07_Computational_Modeling/kmeans/SKILL.md +119 -0
  201. package/skills/07_Computational_Modeling/run_models/SKILL.md +427 -0
  202. package/skills/07_Computational_Modeling/spacenet/SKILL.md +122 -0
  203. package/skills/07_Computational_Modeling/svm/SKILL.md +120 -0
  204. package/skills/08_Computational_Neuroscience/brain_gnn/SKILL.md +183 -0
  205. package/skills/08_Computational_Neuroscience/dipy-tool/SKILL.md +239 -0
  206. package/skills/08_Computational_Neuroscience/dipy-tool/scripts/dti_metrics_reference.py +70 -0
  207. package/skills/08_Computational_Neuroscience/dipy-tool/scripts/load_and_mask_reference.py +76 -0
  208. package/skills/08_Computational_Neuroscience/dipy-tool/scripts/roi_stats_reference.py +59 -0
  209. package/skills/08_Computational_Neuroscience/fm_app/SKILL.md +195 -0
  210. package/skills/08_Computational_Neuroscience/neurostorm/SKILL.md +151 -0
  211. package/skills/13_Visualization/brain-visualization/SKILL.md +191 -0
  212. package/skills/13_Visualization/brain-visualization/scripts/connectome_reference.py +108 -0
  213. package/skills/13_Visualization/brain-visualization/scripts/freesurfer_ply_reference.py +54 -0
  214. package/skills/13_Visualization/brain-visualization/scripts/zalff_summary_reference.py +116 -0
  215. package/skills/13_Visualization/ethoclaw-paper-figure-layout/SKILL.md +78 -0
  216. package/skills/13_Visualization/ethoclaw-paper-figure-layout/assets/naturecomm_figures.tex +74 -0
  217. package/skills/13_Visualization/ethoclaw-paper-figure-layout/scripts/layout_results_foldered.py +579 -0
  218. package/skills/14_Writing/overleaf-skill/SKILL.md +184 -0
  219. package/skills/14_Writing/overleaf-skill/scripts/install.sh +30 -0
  220. package/skills/14_Writing/paper-writing/SKILL.md +146 -0
  221. package/skills/14_Writing/paper-writing/scripts/data_statement_templates.py +164 -0
  222. package/skills/14_Writing/paper-writing/scripts/figure_templates.py +315 -0
  223. package/skills/14_Writing/paper-writing/scripts/nature_figure_style.py +214 -0
  224. package/skills/14_Writing/paper-writing/scripts/section_phrasebank.py +246 -0
  225. package/skills/16_Animal_Behavior/deeplabcut/SKILL.md +154 -0
  226. package/skills/16_Animal_Behavior/deeplabcut/references/3d-pose.md +89 -0
  227. package/skills/16_Animal_Behavior/deeplabcut/references/maDLC.md +123 -0
  228. package/skills/16_Animal_Behavior/deeplabcut/references/modelzoo.md +98 -0
  229. package/skills/16_Animal_Behavior/deeplabcut/references/standard-pipeline.md +165 -0
  230. package/skills/16_Animal_Behavior/deeplabcut/references/utilities.md +146 -0
  231. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/SKILL.md +274 -0
  232. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/report_template_en.html +112 -0
  233. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/report_template_en.md +21 -0
  234. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/cluster-section.md +5 -0
  235. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/heatmap-section.md +5 -0
  236. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/integrated-interpretation.md +3 -0
  237. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/overview.md +3 -0
  238. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/project-summary.md +3 -0
  239. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/radar-section.md +5 -0
  240. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/raw-trajectory.md +3 -0
  241. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/sample-check.md +3 -0
  242. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/single-subject-section.md +3 -0
  243. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/stats-section.md +5 -0
  244. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/epm.md +52 -0
  245. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/fst.md +37 -0
  246. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/nor.md +39 -0
  247. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/oft.md +43 -0
  248. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/tcst.md +45 -0
  249. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/tst.md +36 -0
  250. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/input-types.md +59 -0
  251. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/interpretation-guardrails.md +45 -0
  252. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/metadata-schema.md +57 -0
  253. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/report-sections.md +86 -0
  254. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/section-selection-rules.md +169 -0
  255. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/scripts/build_report_manifest.py +27 -0
  256. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/scripts/render_report.py +34 -0
  257. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/scripts/report_utils.py +1121 -0
  258. package/skills/16_Animal_Behavior/ethoclaw-animal-grounding/SKILL.md +390 -0
  259. package/skills/16_Animal_Behavior/ethoclaw-animal-grounding/reference_code.py +98 -0
  260. package/skills/16_Animal_Behavior/ethoclaw-animal-pose-estimation/SKILL.md +336 -0
  261. package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/README.md +21 -0
  262. package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/SKILL.md +41 -0
  263. package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/batch_kinematic_generator.py +663 -0
  264. package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/config.json +19 -0
  265. package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/generate_kinematic_parameter.py +401 -0
  266. package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/kinematic_generator.py +265 -0
  267. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/SKILL.md +72 -0
  268. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/references/config.example.toml +56 -0
  269. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/scripts/cluster_all_params.py +232 -0
  270. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/scripts/cluster_all_params_from_config.py +236 -0
  271. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-radar-generate/SKILL.md +68 -0
  272. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-radar-generate/references/notes.md +5 -0
  273. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-radar-generate/scripts/plot_h5_radar.py +513 -0
  274. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/SKILL.md +52 -0
  275. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/config.toml +81 -0
  276. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/references/stats-rule.md +18 -0
  277. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/scripts/h5_inspect.py +79 -0
  278. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/scripts/h5_violin_batch.py +624 -0
  279. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/scripts/h5_violin_stats.py +438 -0
  280. package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/SKILL.md +280 -0
  281. package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/core_scripts/heatmap_trajectory.py +790 -0
  282. package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/core_scripts/heatmap_velocity.py +855 -0
  283. package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/reference_data/reference_2d.csv +101 -0
  284. package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/reference_data/reference_2d.h5 +0 -0
  285. package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/reference_data/reference_data_readme.md +126 -0
@@ -0,0 +1,295 @@
1
+ ---
2
+ name: aibl-skill
3
+ description: "Use this skill whenever the user wants an end-to-end workflow for the AIBL (Australian Imaging, Biomarkers and Lifestyle) dataset, including data access guidance, BIDS organization, and multimodal processing of sMRI and PET (PiB, FDG, tau). Triggers include: 'AIBL', 'AIBL data', 'process AIBL', 'AIBL PET', 'AIBL MRI', or any request to run the AIBL multimodal pipeline. This is the NeuroClaw dataset-orchestration layer for AIBL."
4
+ license: MIT License (NeuroClaw custom skill - freely modifiable within the project)
5
+ layer: subagent
6
+ skill_type: dataset
7
+ dependencies:
8
+ - smri-skill
9
+ - bids-organizer
10
+ - claw-shell
11
+ complementary_skills:
12
+ - pet-skill
13
+ ---
14
+ # AIBL Skill (Dataset-Orchestration Layer)
15
+
16
+ ## Overview
17
+ `aibl-skill` is the NeuroClaw orchestration skill for the **AIBL (Australian Imaging, Biomarkers and Lifestyle)** dataset.
18
+
19
+ It coordinates a fixed three-phase workflow:
20
+ 1. Guide AIBL data access and download from the AIBL research portal.
21
+ 2. Prepare and validate BIDS-style data organization for downstream processing.
22
+ 3. Delegate modality pipelines to `smri-skill` for structural MRI and PET processing.
23
+
24
+ It also provides **phenotype extraction** and **QC integration** paths:
25
+ - Extract and merge AIBL phenotype tables (cognitive assessments, blood biomarkers, APOE genotype, lifestyle data).
26
+ - Generate per-subject QC summaries with exclusion lists.
27
+
28
+ This skill follows NeuroClaw hierarchy:
29
+ - Defines **WHAT to do**, not low-level implementation details.
30
+ - Does **not** execute direct shell commands itself.
31
+ - Delegates all execution via `claw-shell` to base/tool skills.
32
+
33
+ **Research use only.**
34
+
35
+ ---
36
+
37
+ ## Download Stage (Mandatory First Step)
38
+
39
+ ### Source
40
+ AIBL data is distributed through the **AIBL research portal**:
41
+ - Website: https://aibl.csiro.au/
42
+ - Data access: requires registration and data use agreement
43
+ - Imaging data available via LONI Image Data Archive (IDA): https://ida.loni.usc.edu/
44
+
45
+ ### Supported AIBL Data Packages
46
+ - **Imaging data**: T1w MRI, PET (PiB amyloid, FDG metabolism, tau)
47
+ - **Phenotype data**: cognitive assessments (CDR, MMSE, MoCA, ADAS-Cog), blood biomarkers (Aβ42, Aβ40, p-tau, NfL), APOE genotype, lifestyle and demographic data
48
+ - **Derived imaging data**: FreeSurfer outputs (if available)
49
+
50
+ ### Delegation Rules for Download
51
+ - Environment/setup checks: `dependency-planner` + `conda-env-manager`
52
+ - LONI IDA download tool installation and execution: `claw-shell`
53
+ - Optional raw-data organization to BIDS-style staging: `bids-organizer`
54
+
55
+ ### Download Inputs to Confirm in Plan
56
+ - LONI IDA credentials/authorized access
57
+ - Target data package (imaging only, phenotype only, or both)
58
+ - Subject list scope (full cohort or custom subset)
59
+ - AIBL phase (screening, baseline, 18-month, 36-month, 54-month, etc.)
60
+ - Destination directory with sufficient disk space
61
+
62
+ ---
63
+
64
+ ## Narrow Path: AIBL Raw Data -> BIDS Staging
65
+
66
+ Use this path when the task only asks to reorganize raw AIBL files into a BIDS-style dataset and does not require preprocessing, ROI extraction, phenotype merging, or downstream analysis.
67
+
68
+ ### When this narrow path should dominate
69
+ - The task objective is limited to AIBL data staging, BIDS renaming, sidecar handling, and dataset-level metadata.
70
+ - Inputs are already local AIBL files or AIBL-style subject/date folders.
71
+ - The required deliverable is a direct staging script or command sequence, not a plan for preprocessing or downstream analysis.
72
+
73
+ ### Narrow-path contract
74
+ - Do not widen the solution to preprocessing, ROI extraction, phenotype merging, or downstream analysis unless the task explicitly requires them.
75
+ - Treat this as a direct file-organization problem: scan AIBL subject/session layout, normalize subject labels, map modalities to BIDS names, copy or symlink files plus matching sidecars, and write dataset-level metadata plus staging logs.
76
+ - If the task is benchmark-style, prefer a single direct end-to-end staging script over a confirmation-first orchestration plan.
77
+
78
+ ### Expected narrow-path behavior
79
+ 1. Detect AIBL-style subject IDs (e.g., `002_S_0295`) and normalize to BIDS labels such as `sub-002S0295`.
80
+ 2. Detect visit/timepoint information and normalize to session labels such as `ses-screening`, `ses-baseline`, `ses-18month`, etc.
81
+ 3. Route modalities:
82
+ - T1w/MPRAGE -> `anat/*_T1w`
83
+ - PET PiB -> `pet/*_pet` (tracer: PiB)
84
+ - PET FDG -> `pet/*_pet` (tracer: FDG)
85
+ - PET tau -> `pet/*_pet` (tracer: tau)
86
+ 4. Preserve or rename matching JSON sidecars when available; if metadata is absent, create only the minimal dataset files required by the task and log the limitation.
87
+ 5. Emit dataset-level outputs such as `dataset_description.json`, `participants.tsv`, `README`, and a manifest or skipped-file report.
88
+
89
+ ---
90
+
91
+ ## Core Workflow (Never Bypassed)
92
+ 1. Identify user target: full AIBL processing, imaging subset, phenotype extraction, or BIDS staging only.
93
+ 2. Generate a numbered plan with tools, outputs, runtime, storage, and risks.
94
+ 3. Wait for explicit confirmation (`YES` / `execute` / `proceed`).
95
+ 4. On confirmation, run download stage first (if needed).
96
+ 5. After download success, run BIDS preparation using `scripts/reorganize_aibl.py`.
97
+ 6. Delegate to `smri-skill` for structural MRI processing (brain extraction, tissue segmentation, cortical reconstruction).
98
+ 7. If PET processing is requested, handle PET-specific preprocessing (spatial normalization, SUVR computation).
99
+ 8. If phenotype extraction is requested, run `scripts/extract_aibl_phenotype.py`.
100
+ 9. If QC summary is requested, run `scripts/aibl_qc_summary.py`.
101
+ 10. Save outputs into an AIBL-centered structure under `aibl_output/`.
102
+
103
+ ---
104
+
105
+ ## Input Layout (Example)
106
+
107
+ Subject `002_S_0295` (T1w + PET):
108
+
109
+ ```
110
+ aibl_raw/
111
+ 002_S_0295/
112
+ screening/
113
+ T1/
114
+ 002_S_0295_T1.nii.gz
115
+ 002_S_0295_T1.json
116
+ PET_PiB/
117
+ 002_S_0295_PET_PiB.nii.gz
118
+ 002_S_0295_PET_PiB.json
119
+ PET_FDG/
120
+ 002_S_0295_PET_FDG.nii.gz
121
+ 002_S_0295_PET_FDG.json
122
+ phenotype/
123
+ cognitive_assessments.csv
124
+ blood_biomarkers.csv
125
+ apoe_genotype.csv
126
+ demographics.csv
127
+ ```
128
+
129
+ ---
130
+
131
+ ## BIDS Preparation
132
+
133
+ ### Script: `scripts/reorganize_aibl.py`
134
+
135
+ Converts AIBL raw directory structure to BIDS-compliant layout.
136
+
137
+ ```bash
138
+ python skills/aibl-skill/scripts/reorganize_aibl.py \
139
+ --input /path/to/aibl_raw \
140
+ --output /path/to/aibl_bids \
141
+ --participants-file /path/to/aibl_raw/phenotype/demographics.csv
142
+ ```
143
+
144
+ Features:
145
+ - Subject ID normalization: AIBL format to BIDS `sub-002S0295`
146
+ - Session mapping: AIBL visit names to BIDS `ses-` labels
147
+ - Modality routing: T1w, PET (PiB, FDG, tau)
148
+ - Sidecar JSON preservation and validation
149
+ - `dataset_description.json` and `participants.tsv` generation
150
+ - Dry-run mode: `--dry-run` to preview without copying
151
+
152
+ ---
153
+
154
+ ## Modality Processing Delegation
155
+
156
+ After BIDS staging completes, `aibl-skill` delegates by modality:
157
+
158
+ | Modality | Delegated skill | Typical tasks | Main outputs |
159
+ |---|---|---|---|
160
+ | sMRI (T1w) | `smri-skill` | brain extraction, tissue segmentation, cortical reconstruction, ROI morphometry | `smri_output/` derivatives and stats |
161
+ | PET (PiB/FDG/tau) | `pet-skill` | spatial normalization to template, SUVR computation, reference region quantification | `pet_output/` SUVR maps and ROI values |
162
+
163
+ ### Delegation Strategy
164
+ - If user asks for full multimodal AIBL analysis: run sMRI -> PET in ordered phases.
165
+ - If user asks for one modality only: call only the corresponding modality skill.
166
+ - PET processing typically requires co-registration to T1w first, then normalization to standard space.
167
+
168
+ ---
169
+
170
+ ## Phenotype Extraction
171
+
172
+ ### Script: `scripts/extract_aibl_phenotype.py`
173
+
174
+ Extracts and merges AIBL phenotype tables for downstream analysis.
175
+
176
+ ```bash
177
+ python skills/aibl-skill/scripts/extract_aibl_phenotype.py \
178
+ --phenotype-dir /path/to/aibl_raw/phenotype \
179
+ --output /path/to/aibl_output/phenotype/merged_phenotype.csv \
180
+ --columns subject_id,visit,diagnosis,age,sex,mmse,cdr,apoe \
181
+ --imaging-ids /path/to/aibl_output/bids/participants.tsv
182
+ ```
183
+
184
+ Features:
185
+ - Reads AIBL phenotype CSV/TSV files (cognitive, biomarker, genetic, demographic)
186
+ - Column selection and renaming
187
+ - Visit alignment (screening, baseline, 18-month, 36-month, 54-month)
188
+ - Missing value handling (filter or impute)
189
+ - Cross-reference with imaging subject list to keep only subjects with both imaging and phenotype data
190
+ - Diagnostic group classification: healthy controls (HC), mild cognitive impairment (MCI), Alzheimer's disease (AD)
191
+ - Outputs merged CSV ready for statistical analysis or model training
192
+
193
+ ---
194
+
195
+ ## QC Integration
196
+
197
+ ### Script: `scripts/aibl_qc_summary.py`
198
+
199
+ Generates per-subject QC summaries and exclusion lists.
200
+
201
+ ```bash
202
+ python skills/aibl-skill/scripts/aibl_qc_summary.py \
203
+ --fmriprep-dir /path/to/aibl_output/fmriprep \
204
+ --freesurfer-dir /path/to/aibl_output/smri/freesurfer \
205
+ --output /path/to/aibl_output/qc/qc_summary.csv \
206
+ --exclude-output /path/to/aibl_output/qc/exclude_list.csv \
207
+ --fd-threshold 0.3
208
+ ```
209
+
210
+ Features:
211
+ - Reads fMRIPrep confounds (if fMRI data available)
212
+ - Reads FreeSurfer recon-all QC metrics
213
+ - Structural quality assessment (motion artifacts, coverage)
214
+ - Applies exclusion criteria: motion threshold (FD), structural quality
215
+ - Outputs per-subject QC summary CSV and exclusion list CSV
216
+
217
+ ---
218
+
219
+ ## Recommended Output Layout
220
+ All assets should be organized under `./aibl_output/`:
221
+ - `aibl_output/raw/` (downloaded original AIBL files)
222
+ - `aibl_output/bids/` (staged BIDS data)
223
+ - `aibl_output/smri/` (links or copies from `smri_output/`)
224
+ - `aibl_output/pet/` (PET processing outputs)
225
+ - `aibl_output/phenotype/` (merged phenotype tables)
226
+ - `aibl_output/qc/` (QC summaries and exclusion lists)
227
+ - `aibl_output/logs/` (download + orchestration logs)
228
+
229
+ ---
230
+
231
+ ## Benchmark Adapter Guidance
232
+
233
+ For benchmark-style prompts, do not force the full `download -> staging -> multimodal processing` orchestration when the task is only asking for local AIBL data staging or organization.
234
+
235
+ - If the task starts from raw AIBL data already present on disk and only asks for BIDS-style staging / organization:
236
+ - skip the mandatory download stage
237
+ - do not automatically delegate to `smri-skill`
238
+ - default to the narrow path `local raw AIBL discovery -> BIDS-style staging -> minimal metadata -> validation/report`
239
+ - In benchmark mode, do not require explicit confirmation before presenting the direct staging solution.
240
+ - Preserve the AIBL-centered output contract under `aibl_output/bids/` when the task is specifically a staging benchmark.
241
+ - Only use the full multimodal orchestration and confirmation-heavy workflow when the prompt explicitly asks for download, end-to-end multimodal AIBL processing, or post-staging structural / PET analysis.
242
+
243
+ ---
244
+
245
+ ## Safety and Execution Policy
246
+ - No execution before explicit plan confirmation.
247
+ - All execution must be routed via `claw-shell`.
248
+ - Missing dependencies must be resolved by `dependency-planner` before running.
249
+ - If download fails for partial subjects, continue batch with clear failure report and retry list.
250
+
251
+ ---
252
+
253
+ ## Important Notes and Limitations
254
+ - AIBL imaging data includes both structural MRI and multiple PET tracers (PiB, FDG, tau). PET processing requires tracer-specific workflows.
255
+ - LONI IDA download requires authenticated access and compliance with the AIBL Data Use Agreement.
256
+ - AIBL subject IDs follow the format `XXX_S_XXXX`; normalization to BIDS labels must be consistent across all stages.
257
+ - AIBL has multiple follow-up timepoints (screening through 54-month); session handling must account for longitudinal structure.
258
+ - AIBL phenotype tables may use different delimiter formats across releases; auto-detection is recommended.
259
+ - PET SUVR computation requires reference region definition (e.g., cerebellar cortex for PiB, pons for FDG).
260
+ - `aibl-skill` is orchestration-only; detailed preprocessing logic remains in `smri-skill` and PET processing tools.
261
+
262
+ ---
263
+
264
+ ## When to Call This Skill
265
+ - User asks for end-to-end AIBL workflow.
266
+ - User asks to process AIBL MRI and/or PET data.
267
+ - User needs BIDS staging for raw AIBL files.
268
+ - User asks to extract and merge AIBL phenotype tables (cognitive, biomarker, genetic).
269
+ - User asks for AIBL-specific QC summaries and exclusion lists.
270
+ - User needs a single entry point for AIBL multimodal orchestration.
271
+
272
+ ---
273
+
274
+ ## Complementary / Related Skills
275
+ - `smri-skill`
276
+ - `pet-skill` → PET processing (SUVR computation, tracer-specific reference regions, partial volume correction)
277
+ - `bids-organizer`
278
+ - `freesurfer-tool`
279
+ - `nibabel-skill`
280
+ - `brain-visualization`
281
+ - `dependency-planner`
282
+ - `conda-env-manager`
283
+ - `claw-shell`
284
+
285
+ ---
286
+
287
+ ## Reference
288
+ - AIBL Study: https://aibl.csiro.au/
289
+ - LONI IDA: https://ida.loni.usc.edu/
290
+ - BIDS spec: https://bids.neuroimaging.io/
291
+ - BIDS PET extension: https://bids-specification.readthedocs.io/en/stable/04-modality-specific-files/09-positron-emission-tomography.html
292
+
293
+ Created At: 2026-05-06 11:24 HKT
294
+ Last Updated At: 2026-05-06 12:19 HKT
295
+ Author: chengwang96
@@ -0,0 +1,260 @@
1
+ #!/usr/bin/env python3
2
+ """Generate per-subject QC summaries and exclusion lists for AIBL.
3
+
4
+ Combines fMRIPrep confounds (if available), FreeSurfer recon-all metrics,
5
+ and structural quality assessment to produce a unified QC report.
6
+ """
7
+ import argparse
8
+ import sys
9
+ from pathlib import Path
10
+ from typing import Dict, List, Tuple
11
+
12
+ try:
13
+ import pandas as pd
14
+ except ImportError:
15
+ print("Error: pandas is required. Install with: pip install pandas", file=sys.stderr)
16
+ sys.exit(1)
17
+
18
+
19
+ def detect_delimiter(file_path: Path) -> str:
20
+ """Detect whether file uses tab or comma delimiter."""
21
+ with open(file_path, "r", encoding="utf-8") as f:
22
+ first_line = f.readline()
23
+ if "\t" in first_line:
24
+ return "\t"
25
+ return ","
26
+
27
+
28
+ def collect_fmriprep_qc(fmriprep_dir: Path) -> Dict[str, Dict[str, float]]:
29
+ """Collect QC metrics from fMRIPrep outputs (if fMRI data available)."""
30
+ qc = {}
31
+
32
+ confounds_patterns = [
33
+ "**/desc-confounds_timeseries.tsv",
34
+ "**/*_desc-confounds_timeseries.tsv",
35
+ "**/confounds.tsv",
36
+ ]
37
+
38
+ confounds_files = []
39
+ for pattern in confounds_patterns:
40
+ confounds_files.extend(fmriprep_dir.rglob(pattern))
41
+
42
+ for confounds_file in confounds_files:
43
+ subject_id = None
44
+ for part in confounds_file.parts:
45
+ if part.startswith("sub-"):
46
+ subject_id = part
47
+ break
48
+
49
+ if not subject_id:
50
+ continue
51
+
52
+ delimiter = detect_delimiter(confounds_file)
53
+ try:
54
+ df = pd.read_csv(confounds_file, sep=delimiter, low_memory=False)
55
+ except Exception:
56
+ continue
57
+
58
+ fd_col = None
59
+ for col_name in ["framewise_displacement", "fd", "FD"]:
60
+ if col_name in df.columns:
61
+ fd_col = col_name
62
+ break
63
+
64
+ metrics = {"n_volumes": len(df)}
65
+
66
+ if fd_col:
67
+ fd_values = pd.to_numeric(df[fd_col], errors="coerce").dropna()
68
+ if len(fd_values) > 0:
69
+ metrics["mean_fd"] = float(fd_values.mean())
70
+ metrics["max_fd"] = float(fd_values.max())
71
+ else:
72
+ metrics["mean_fd"] = 0.0
73
+ metrics["max_fd"] = 0.0
74
+
75
+ if subject_id in qc:
76
+ existing = qc[subject_id]
77
+ existing["mean_fd"] = max(existing.get("mean_fd", 0), metrics.get("mean_fd", 0))
78
+ existing["max_fd"] = max(existing.get("max_fd", 0), metrics.get("max_fd", 0))
79
+ existing["n_volumes"] = existing.get("n_volumes", 0) + metrics.get("n_volumes", 0)
80
+ else:
81
+ qc[subject_id] = metrics
82
+
83
+ return qc
84
+
85
+
86
+ def collect_freesurfer_qc(freesurfer_dir: Path) -> Dict[str, Dict[str, float]]:
87
+ """Collect QC metrics from FreeSurfer recon-all outputs."""
88
+ qc = {}
89
+
90
+ for subject_dir in sorted(freesurfer_dir.rglob("sub-*")):
91
+ if not subject_dir.is_dir():
92
+ continue
93
+
94
+ subject_id = None
95
+ for part in subject_dir.parts:
96
+ if part.startswith("sub-"):
97
+ subject_id = part
98
+ break
99
+ if not subject_id:
100
+ subject_id = subject_dir.name
101
+
102
+ # Check for recon-all log
103
+ recon_log = None
104
+ matches = list(freesurfer_dir.rglob(f"{subject_id}/**/recon-all.log"))
105
+ if matches:
106
+ recon_log = matches[0]
107
+
108
+ completed = False
109
+ if recon_log and recon_log.exists():
110
+ try:
111
+ with open(recon_log, "r", encoding="utf-8", errors="ignore") as f:
112
+ content = f.read()
113
+ completed = "finished without error" in content.lower() or "recon-all -done" in content.lower()
114
+ except Exception:
115
+ pass
116
+
117
+ # Read aseg.stats for volume metrics
118
+ aseg_matches = list(freesurfer_dir.rglob(f"{subject_id}**/aseg.stats"))
119
+ total_brain_vol = None
120
+ etiv = None
121
+
122
+ if aseg_matches:
123
+ aseg_file = aseg_matches[0]
124
+ try:
125
+ with open(aseg_file, "r", encoding="utf-8", errors="ignore") as f:
126
+ for line in f:
127
+ if "EstimatedTotalIntraCranialVol" in line:
128
+ parts = line.split()
129
+ if len(parts) >= 4:
130
+ try:
131
+ etiv = float(parts[3])
132
+ except ValueError:
133
+ pass
134
+ elif "BrainSegVol" in line and "Not" not in line:
135
+ parts = line.split()
136
+ if len(parts) >= 4:
137
+ try:
138
+ total_brain_vol = float(parts[3])
139
+ except ValueError:
140
+ pass
141
+ except Exception:
142
+ pass
143
+
144
+ metrics = {"completed": completed}
145
+ if total_brain_vol is not None:
146
+ metrics["total_brain_volume"] = total_brain_vol
147
+ if etiv is not None:
148
+ metrics["estimated_total_intracranial_volume"] = etiv
149
+
150
+ qc[subject_id] = metrics
151
+
152
+ return qc
153
+
154
+
155
+ def generate_qc_summary(
156
+ fmriprep_qc: Dict[str, Dict[str, float]],
157
+ freesurfer_qc: Dict[str, Dict[str, float]],
158
+ fd_threshold: float = 0.3,
159
+ max_fd_threshold: float = 5.0,
160
+ ) -> Tuple["pd.DataFrame", List[str]]:
161
+ """Generate QC summary DataFrame and exclusion list."""
162
+ all_subjects = set()
163
+ all_subjects.update(fmriprep_qc.keys())
164
+ all_subjects.update(freesurfer_qc.keys())
165
+
166
+ rows = []
167
+ excluded = []
168
+
169
+ for sub_id in sorted(all_subjects):
170
+ row = {"subject_id": sub_id}
171
+ exclude_reasons = []
172
+
173
+ fp = fmriprep_qc.get(sub_id, {})
174
+ row["mean_fd"] = fp.get("mean_fd", None)
175
+ row["max_fd"] = fp.get("max_fd", None)
176
+ row["n_volumes"] = fp.get("n_volumes", None)
177
+
178
+ fs = freesurfer_qc.get(sub_id, {})
179
+ row["fs_completed"] = fs.get("completed", None)
180
+ row["total_brain_volume"] = fs.get("total_brain_volume", None)
181
+ row["etiv"] = fs.get("estimated_total_intracranial_volume", None)
182
+
183
+ if row["mean_fd"] is not None and row["mean_fd"] > fd_threshold:
184
+ exclude_reasons.append(f"mean_fd={row['mean_fd']:.3f}>{fd_threshold}")
185
+
186
+ if row["max_fd"] is not None and row["max_fd"] > max_fd_threshold:
187
+ exclude_reasons.append(f"max_fd={row['max_fd']:.3f}>{max_fd_threshold}")
188
+
189
+ if row["fs_completed"] is False:
190
+ exclude_reasons.append("FreeSurfer recon-all incomplete")
191
+
192
+ row["exclude"] = len(exclude_reasons) > 0
193
+ row["exclude_reasons"] = "; ".join(exclude_reasons) if exclude_reasons else ""
194
+
195
+ if exclude_reasons:
196
+ excluded.append(sub_id)
197
+
198
+ rows.append(row)
199
+
200
+ df = pd.DataFrame(rows)
201
+ return df, excluded
202
+
203
+
204
+ def main() -> int:
205
+ parser = argparse.ArgumentParser(
206
+ description="Generate per-subject QC summaries and exclusion lists for AIBL."
207
+ )
208
+ parser.add_argument("--fmriprep-dir", help="Path to fMRIPrep output directory")
209
+ parser.add_argument("--freesurfer-dir", help="Path to FreeSurfer output directory")
210
+ parser.add_argument("--output", required=True, help="Output path for QC summary CSV")
211
+ parser.add_argument("--exclude-output", help="Output path for exclusion list CSV")
212
+ parser.add_argument("--fd-threshold", type=float, default=0.3, help="Mean FD threshold (default: 0.3)")
213
+ parser.add_argument("--max-fd-threshold", type=float, default=5.0, help="Max FD threshold (default: 5.0)")
214
+ args = parser.parse_args()
215
+
216
+ fmriprep_qc = {}
217
+ freesurfer_qc = {}
218
+
219
+ if args.fmriprep_dir:
220
+ fp_dir = Path(args.fmriprep_dir).resolve()
221
+ if fp_dir.exists():
222
+ print(f"Collecting fMRIPrep QC from {fp_dir}...")
223
+ fmriprep_qc = collect_fmriprep_qc(fp_dir)
224
+ print(f" Found {len(fmriprep_qc)} subjects")
225
+
226
+ if args.freesurfer_dir:
227
+ fs_dir = Path(args.freesurfer_dir).resolve()
228
+ if fs_dir.exists():
229
+ print(f"Collecting FreeSurfer QC from {fs_dir}...")
230
+ freesurfer_qc = collect_freesurfer_qc(fs_dir)
231
+ print(f" Found {len(freesurfer_qc)} subjects")
232
+
233
+ if not fmriprep_qc and not freesurfer_qc:
234
+ print("[ERROR] No QC data collected. Check input paths.", file=sys.stderr)
235
+ return 1
236
+
237
+ summary_df, excluded = generate_qc_summary(
238
+ fmriprep_qc=fmriprep_qc,
239
+ freesurfer_qc=freesurfer_qc,
240
+ fd_threshold=args.fd_threshold,
241
+ max_fd_threshold=args.max_fd_threshold,
242
+ )
243
+
244
+ output_path = Path(args.output).resolve()
245
+ output_path.parent.mkdir(parents=True, exist_ok=True)
246
+ summary_df.to_csv(output_path, index=False)
247
+ print(f"\nQC Summary: {len(summary_df)} subjects -> {output_path}")
248
+ print(f" Excluded: {len(excluded)} / {len(summary_df)} ({100*len(excluded)/max(len(summary_df),1):.1f}%)")
249
+
250
+ if args.exclude_output:
251
+ exclude_path = Path(args.exclude_output).resolve()
252
+ exclude_path.parent.mkdir(parents=True, exist_ok=True)
253
+ summary_df[summary_df["exclude"] == True][["subject_id", "exclude_reasons"]].to_csv(exclude_path, index=False)
254
+ print(f" Exclusion list: {exclude_path}")
255
+
256
+ return 0
257
+
258
+
259
+ if __name__ == "__main__":
260
+ sys.exit(main())