@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,244 @@
1
+ ---
2
+ name: adhd200-skill
3
+ description: "Use this skill whenever the user wants an end-to-end workflow for the ADHD-200 dataset, including download, BIDS organization, and processing of sMRI and rs-fMRI data. Triggers include: 'ADHD-200', 'ADHD200', 'process ADHD data', 'ADHD fMRI', or any request to run the ADHD-200 pipeline. This is the NeuroClaw dataset-orchestration layer for ADHD-200."
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
+ - fmri-skill
10
+ - bids-organizer
11
+ - claw-shell
12
+ ---
13
+ # ADHD-200 Skill (Dataset-Orchestration Layer)
14
+
15
+ ## Overview
16
+ `adhd200-skill` is the NeuroClaw orchestration skill for the **ADHD-200** dataset.
17
+
18
+ It coordinates a fixed three-phase workflow:
19
+ 1. Download ADHD-200 data from the FCP/INDI repository.
20
+ 2. Prepare and validate BIDS-style data organization for downstream processing.
21
+ 3. Delegate modality pipelines to `smri-skill` and `fmri-skill`.
22
+
23
+ It also provides **phenotype extraction** and **QC integration** paths:
24
+ - Extract and merge ADHD-200 phenotype tables (diagnosis, ADHD measures, demographics, medication).
25
+ - Generate per-subject QC summaries with exclusion lists.
26
+
27
+ This skill follows NeuroClaw hierarchy:
28
+ - Defines **WHAT to do**, not low-level implementation details.
29
+ - Does **not** execute direct shell commands itself.
30
+ - Delegates all execution via `claw-shell` to base/tool skills.
31
+
32
+ **Research use only.**
33
+
34
+ ---
35
+
36
+ ## Download Stage (Mandatory First Step)
37
+
38
+ ### Source
39
+ ADHD-200 data is distributed through the **FCP/INDI** repository:
40
+ - Website: https://fcon_1000.projects.nitrc.org/indi/adhd200/
41
+
42
+ ### Supported ADHD-200 Data Packages
43
+ - **Imaging data**: T1w, rs-fMRI (NIfTI format) from 8 imaging sites
44
+ - **Phenotype data**: CSV files with diagnosis, ADHD measures, demographics, medication history, QC measures
45
+ - **Sites**: Peking, Brown, NYU, KKI, NeuroImage, OHSU, Pitt, Washington University
46
+
47
+ ### Delegation Rules for Download
48
+ - Environment/setup checks: `dependency-planner` + `conda-env-manager`
49
+ - Download tool installation and execution: `claw-shell`
50
+ - Optional raw-data organization to BIDS-style staging: `bids-organizer`
51
+
52
+ ### Download Inputs to Confirm in Plan
53
+ - Target subset (full cohort, specific sites, or ADHD/control only)
54
+ - Subject list scope (full or custom IDs)
55
+ - Destination directory with sufficient disk space
56
+
57
+ ---
58
+
59
+ ## Narrow Path: ADHD-200 Raw NIfTI -> BIDS Staging
60
+
61
+ Use this path when the task only asks to reorganize raw ADHD-200 NIfTI files into a BIDS-style dataset and does not require preprocessing, ROI extraction, phenotype merging, or downstream analysis.
62
+
63
+ ### When this narrow path should dominate
64
+ - The task objective is limited to ADHD-200 NIfTI staging, BIDS renaming, sidecar handling, and dataset-level metadata.
65
+ - Inputs are already local ADHD-200 NIfTI files or ADHD-200-style subject/site folders.
66
+ - The required deliverable is a direct staging script or command sequence, not a plan for fMRIPrep or downstream analysis.
67
+
68
+ ### Narrow-path contract
69
+ - Do not widen the solution to fMRIPrep, ROI extraction, phenotype merging, or downstream analysis unless the task explicitly requires them.
70
+ - Treat this as a direct file-organization problem: scan ADHD-200 subject/site layout, normalize subject labels, map modalities to BIDS names, copy or symlink NIfTI plus matching sidecars, and write dataset-level metadata plus staging logs.
71
+ - If the task is benchmark-style, prefer a single direct end-to-end staging script over a confirmation-first orchestration plan.
72
+
73
+ ### Expected narrow-path behavior
74
+ 1. Detect ADHD-200-style subject IDs (numeric, e.g., `0010002`) and normalize to BIDS labels such as `sub-0010002`.
75
+ 2. Detect site information and encode in `participants.tsv`.
76
+ 3. Route modalities:
77
+ - T1w -> `anat/*_T1w`
78
+ - rs-fMRI/BOLD -> `func/*_task-rest_bold`
79
+ 4. Preserve or rename matching JSON sidecars when available.
80
+ 5. Emit dataset-level outputs such as `dataset_description.json`, `participants.tsv`, `README`, and a manifest or skipped-file report.
81
+
82
+ ---
83
+
84
+ ## Core Workflow (Never Bypassed)
85
+ 1. Identify user target: full ADHD-200 download, imaging subset, phenotype extraction, or BIDS staging only.
86
+ 2. Generate a numbered plan with tools, outputs, runtime, storage, and risks.
87
+ 3. Wait for explicit confirmation (`YES` / `execute` / `proceed`).
88
+ 4. On confirmation, run download stage first (if needed).
89
+ 5. After download success, run BIDS preparation using `scripts/reorganize_adhd200.py`.
90
+ 6. Delegate to modality skills:
91
+ - `smri-skill` for structural MRI (T1w)
92
+ - `fmri-skill` for resting-state fMRI (rs-fMRI)
93
+ 7. If phenotype extraction is requested, run `scripts/extract_adhd200_phenotype.py`.
94
+ 8. If QC summary is requested, run `scripts/adhd200_qc_summary.py`.
95
+ 9. Save outputs into an ADHD-200-centered structure under `adhd200_output/`.
96
+
97
+ ---
98
+
99
+ ## Input Layout (Example)
100
+
101
+ Subject `0010002` from site Peking:
102
+
103
+ ```
104
+ adhd200_raw/
105
+ Peking/
106
+ 0010002/
107
+ anat/
108
+ anat.nii.gz
109
+ func/
110
+ rest.nii.gz
111
+ phenotype/
112
+ ADHD200_..._phenotypic.csv
113
+ ```
114
+
115
+ ---
116
+
117
+ ## BIDS Preparation
118
+
119
+ ### Script: `scripts/reorganize_adhd200.py`
120
+
121
+ Converts ADHD-200 raw directory structure to BIDS-compliant layout.
122
+
123
+ ```bash
124
+ python skills/adhd200-skill/scripts/reorganize_adhd200.py \
125
+ --input /path/to/adhd200_raw \
126
+ --output /path/to/adhd200_bids \
127
+ --phenotype /path/to/adhd200_raw/phenotype/ADHD200_phenotypic.csv
128
+ ```
129
+
130
+ Features:
131
+ - Subject ID normalization: numeric ADHD-200 IDs to BIDS `sub-NNNNNNN`
132
+ - Site extraction and encoding in `participants.tsv`
133
+ - Modality routing: T1w, rs-fMRI
134
+ - `dataset_description.json` and `participants.tsv` generation with phenotype metadata
135
+ - Dry-run mode: `--dry-run` to preview without copying
136
+
137
+ ---
138
+
139
+ ## Multimodal Processing Delegation
140
+
141
+ | Modality | Delegated skill | Typical tasks | Main outputs |
142
+ |---|---|---|---|
143
+ | sMRI (T1w) | `smri-skill` | brain extraction, tissue segmentation, cortical reconstruction | `smri_output/` |
144
+ | rs-fMRI | `fmri-skill` | preprocessing, denoising, ROI time series, connectivity | `fmri_output/` |
145
+
146
+ ---
147
+
148
+ ## Phenotype Extraction
149
+
150
+ ### Script: `scripts/extract_adhd200_phenotype.py`
151
+
152
+ ```bash
153
+ python skills/adhd200-skill/scripts/extract_adhd200_phenotype.py \
154
+ --phenotype-dir /path/to/adhd200_raw/phenotype \
155
+ --output /path/to/adhd200_output/phenotype/merged_phenotype.csv \
156
+ --columns subject,DX,AGE,SEX,ADHD_Index,Inatt,HyperImp \
157
+ --imaging-ids /path/to/adhd200_output/bids/participants.tsv
158
+ ```
159
+
160
+ ---
161
+
162
+ ## QC Integration
163
+
164
+ ### Script: `scripts/adhd200_qc_summary.py`
165
+
166
+ ```bash
167
+ python skills/adhd200-skill/scripts/adhd200_qc_summary.py \
168
+ --fmriprep-dir /path/to/adhd200_output/fmriprep \
169
+ --freesurfer-dir /path/to/adhd200_output/smri/freesurfer \
170
+ --output /path/to/adhd200_output/qc/qc_summary.csv \
171
+ --exclude-output /path/to/adhd200_output/qc/exclude_list.csv \
172
+ --fd-threshold 0.3
173
+ ```
174
+
175
+ ---
176
+
177
+ ## Recommended Output Layout
178
+ All assets should be organized under `./adhd200_output/`:
179
+ - `adhd200_output/raw/` (downloaded original files)
180
+ - `adhd200_output/bids/` (staged BIDS data)
181
+ - `adhd200_output/smri/` (links or copies from `smri_output/`)
182
+ - `adhd200_output/fmri/` (links or copies from `fmri_output/`)
183
+ - `adhd200_output/phenotype/` (merged phenotype tables)
184
+ - `adhd200_output/qc/` (QC summaries and exclusion lists)
185
+ - `adhd200_output/logs/` (download + orchestration logs)
186
+
187
+ ---
188
+
189
+ ## Benchmark Adapter Guidance
190
+
191
+ For benchmark-style prompts, do not force the full `download -> staging -> multimodal processing` orchestration when the task is only asking for local ADHD-200 data staging or organization.
192
+
193
+ - If the task starts from raw ADHD-200 data already present on disk and only asks for BIDS-style staging / organization:
194
+ - skip the mandatory download stage
195
+ - default to the narrow path `local raw ADHD-200 discovery -> BIDS-style staging -> minimal metadata -> validation/report`
196
+ - In benchmark mode, do not require explicit confirmation before presenting the direct staging solution.
197
+
198
+ ---
199
+
200
+ ## Safety and Execution Policy
201
+ - No execution before explicit plan confirmation.
202
+ - All execution must be routed via `claw-shell`.
203
+ - Missing dependencies must be resolved by `dependency-planner` before running.
204
+
205
+ ---
206
+
207
+ ## Important Notes and Limitations
208
+ - ADHD-200 has heterogeneous acquisition parameters across 8 sites; site effects must be addressed in analysis.
209
+ - ADHD-200 subject IDs are numeric and vary in length across sites.
210
+ - Diagnosis labels vary by site (ADHD-combined, ADHD-inattentive, ADHD-hyperactive, typically developing).
211
+ - ADHD-200 data does not include task-fMRI; only resting-state fMRI is available.
212
+ - `adhd200-skill` is orchestration-only; detailed preprocessing logic remains in `smri-skill` and `fmri-skill`.
213
+
214
+ ---
215
+
216
+ ## When to Call This Skill
217
+ - User asks for end-to-end ADHD-200 workflow.
218
+ - User asks to download ADHD-200 data and then run sMRI/rs-fMRI processing.
219
+ - User needs BIDS staging for raw ADHD-200 NIfTI files.
220
+ - User asks to extract and merge ADHD-200 phenotype tables.
221
+ - User needs ADHD-200-specific QC summaries and exclusion lists.
222
+
223
+ ---
224
+
225
+ ## Complementary / Related Skills
226
+ - `smri-skill`
227
+ - `fmri-skill`
228
+ - `bids-organizer`
229
+ - `fmriprep-tool`
230
+ - `freesurfer-tool`
231
+ - `brain_gnn`
232
+ - `dependency-planner`
233
+ - `conda-env-manager`
234
+ - `claw-shell`
235
+
236
+ ---
237
+
238
+ ## Reference
239
+ - ADHD-200: https://fcon_1000.projects.nitrc.org/indi/adhd200/
240
+ - BIDS spec: https://bids.neuroimaging.io/
241
+
242
+ Created At: 2026-05-06 01:50 HKT
243
+ Last Updated At: 2026-05-06 01:50 HKT
244
+ Author: chengwang96
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env python3
2
+ """Generate per-subject QC summaries and exclusion lists for ADHD-200."""
3
+ import argparse
4
+ import sys
5
+ from pathlib import Path
6
+ from typing import Dict, List, Tuple
7
+
8
+ try:
9
+ import pandas as pd
10
+ except ImportError:
11
+ print("Error: pandas is required.", file=sys.stderr)
12
+ sys.exit(1)
13
+
14
+
15
+ def detect_delimiter(file_path: Path) -> str:
16
+ with open(file_path, "r", encoding="utf-8") as f:
17
+ return "\t" if "\t" in f.readline() else ","
18
+
19
+
20
+ def collect_fmriprep_qc(fmriprep_dir: Path) -> Dict[str, Dict[str, float]]:
21
+ qc = {}
22
+ for confounds_file in fmriprep_dir.rglob("**/*_desc-confounds_timeseries.tsv"):
23
+ subject_id = next((p for p in confounds_file.parts if p.startswith("sub-")), None)
24
+ if not subject_id:
25
+ continue
26
+ try:
27
+ df = pd.read_csv(confounds_file, sep=detect_delimiter(confounds_file), low_memory=False)
28
+ except Exception:
29
+ continue
30
+ fd_col = next((c for c in ["framewise_displacement", "fd", "FD"] if c in df.columns), None)
31
+ if fd_col:
32
+ fd = pd.to_numeric(df[fd_col], errors="coerce").dropna()
33
+ if len(fd) > 0:
34
+ metrics = {"mean_fd": float(fd.mean()), "max_fd": float(fd.max()), "n_volumes": len(df)}
35
+ if subject_id in qc:
36
+ qc[subject_id]["mean_fd"] = max(qc[subject_id].get("mean_fd", 0), metrics["mean_fd"])
37
+ qc[subject_id]["max_fd"] = max(qc[subject_id].get("max_fd", 0), metrics["max_fd"])
38
+ else:
39
+ qc[subject_id] = metrics
40
+ return qc
41
+
42
+
43
+ def generate_qc_summary(fmriprep_qc: Dict, fd_threshold: float, max_fd_threshold: float) -> Tuple["pd.DataFrame", List[str]]:
44
+ rows = []
45
+ excluded = []
46
+ for sub_id in sorted(fmriprep_qc.keys()):
47
+ fp = fmriprep_qc[sub_id]
48
+ reasons = []
49
+ if fp.get("mean_fd", 0) > fd_threshold:
50
+ reasons.append(f"mean_fd={fp['mean_fd']:.3f}>{fd_threshold}")
51
+ if fp.get("max_fd", 0) > max_fd_threshold:
52
+ reasons.append(f"max_fd={fp['max_fd']:.3f}>{max_fd_threshold}")
53
+ row = {"subject_id": sub_id, "mean_fd": fp.get("mean_fd"), "max_fd": fp.get("max_fd"), "n_volumes": fp.get("n_volumes"), "exclude": bool(reasons), "exclude_reasons": "; ".join(reasons)}
54
+ if reasons:
55
+ excluded.append(sub_id)
56
+ rows.append(row)
57
+ return pd.DataFrame(rows), excluded
58
+
59
+
60
+ def main() -> int:
61
+ parser = argparse.ArgumentParser(description="Generate ADHD-200 QC summaries.")
62
+ parser.add_argument("--fmriprep-dir", help="Path to fMRIPrep output directory")
63
+ parser.add_argument("--output", required=True, help="Output path for QC summary CSV")
64
+ parser.add_argument("--exclude-output", help="Output path for exclusion list CSV")
65
+ parser.add_argument("--fd-threshold", type=float, default=0.3, help="Mean FD threshold (default: 0.3)")
66
+ parser.add_argument("--max-fd-threshold", type=float, default=5.0, help="Max FD threshold (default: 5.0)")
67
+ args = parser.parse_args()
68
+
69
+ fmriprep_qc = {}
70
+ if args.fmriprep_dir:
71
+ fp_dir = Path(args.fmriprep_dir).resolve()
72
+ if fp_dir.exists():
73
+ print(f"Collecting fMRIPrep QC from {fp_dir}...")
74
+ fmriprep_qc = collect_fmriprep_qc(fp_dir)
75
+ print(f" Found {len(fmriprep_qc)} subjects")
76
+
77
+ if not fmriprep_qc:
78
+ print("[ERROR] No QC data collected.", file=sys.stderr)
79
+ return 1
80
+
81
+ summary_df, excluded = generate_qc_summary(fmriprep_qc, args.fd_threshold, args.max_fd_threshold)
82
+ output_path = Path(args.output).resolve()
83
+ output_path.parent.mkdir(parents=True, exist_ok=True)
84
+ summary_df.to_csv(output_path, index=False)
85
+ print(f"\nQC Summary: {len(summary_df)} subjects -> {output_path}")
86
+ print(f" Excluded: {len(excluded)} / {len(summary_df)} ({100*len(excluded)/max(len(summary_df),1):.1f}%)")
87
+
88
+ if args.exclude_output:
89
+ exclude_path = Path(args.exclude_output).resolve()
90
+ exclude_path.parent.mkdir(parents=True, exist_ok=True)
91
+ summary_df[summary_df["exclude"] == True][["subject_id", "exclude_reasons"]].to_csv(exclude_path, index=False)
92
+ print(f" Exclusion list: {exclude_path}")
93
+
94
+ return 0
95
+
96
+
97
+ if __name__ == "__main__":
98
+ sys.exit(main())
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env python3
2
+ """Extract and merge ADHD-200 phenotype tables for downstream analysis."""
3
+ import argparse
4
+ import csv
5
+ import re
6
+ import sys
7
+ from pathlib import Path
8
+ from typing import Dict, List, Optional, Set
9
+
10
+ try:
11
+ import pandas as pd
12
+ except ImportError:
13
+ print("Error: pandas is required. Install with: pip install pandas", file=sys.stderr)
14
+ sys.exit(1)
15
+
16
+ COLUMN_MAP = {
17
+ "subject": "subject_id",
18
+ "SUBJECT_ID": "subject_id",
19
+ "Subject": "subject_id",
20
+ "DX": "diagnosis",
21
+ "DX_GROUP": "diagnosis",
22
+ "AGE": "age",
23
+ "AGE_AT_SCAN": "age",
24
+ "SEX": "sex",
25
+ "ADHD_Index": "adhd_index",
26
+ "Inatt": "inattention",
27
+ "HyperImp": "hyperactivity",
28
+ "SITE_ID": "site",
29
+ "HANDEDNESS": "handedness",
30
+ }
31
+
32
+
33
+ def normalize_subject_id(raw_id) -> str:
34
+ clean = re.sub(r"[^a-zA-Z0-9]", "", str(raw_id).strip())
35
+ return f"sub-{clean}"
36
+
37
+
38
+ def read_phenotype_file(file_path: Path) -> Optional["pd.DataFrame"]:
39
+ try:
40
+ return pd.read_csv(file_path, sep=None, engine="python", low_memory=False)
41
+ except Exception as e:
42
+ print(f"[WARN] Failed to read {file_path}: {e}", file=sys.stderr)
43
+ return None
44
+
45
+
46
+ def main() -> int:
47
+ parser = argparse.ArgumentParser(description="Extract and merge ADHD-200 phenotype tables.")
48
+ parser.add_argument("--phenotype-dir", help="Directory containing ADHD-200 phenotype CSV files")
49
+ parser.add_argument("--phenotype-file", help="Direct path to ADHD-200 phenotype CSV file")
50
+ parser.add_argument("--output", required=True, help="Output path for merged phenotype CSV")
51
+ parser.add_argument("--columns", help="Comma-separated list of columns to select (default: all)")
52
+ parser.add_argument("--imaging-ids", help="Path to BIDS participants.tsv for imaging subject filtering")
53
+ parser.add_argument("--missing-threshold", type=float, default=0.5, help="Drop columns with > this fraction missing")
54
+ args = parser.parse_args()
55
+
56
+ phenotype_files = []
57
+ if args.phenotype_file:
58
+ p = Path(args.phenotype_file).resolve()
59
+ if p.exists():
60
+ phenotype_files.append(p)
61
+ elif args.phenotype_dir:
62
+ phenotype_dir = Path(args.phenotype_dir).resolve()
63
+ if phenotype_dir.exists():
64
+ phenotype_files = sorted(f for f in phenotype_dir.iterdir() if f.is_file() and f.suffix in (".csv", ".tsv"))
65
+
66
+ if not phenotype_files:
67
+ print("[ERROR] No phenotype files found.", file=sys.stderr)
68
+ return 1
69
+
70
+ print(f"Found {len(phenotype_files)} phenotype file(s)")
71
+
72
+ dataframes = []
73
+ for f in phenotype_files:
74
+ df = read_phenotype_file(f)
75
+ if df is not None and len(df) > 0:
76
+ rename = {k: v for k, v in COLUMN_MAP.items() if k in df.columns and v not in df.columns}
77
+ df = df.rename(columns=rename)
78
+ dataframes.append(df)
79
+
80
+ if not dataframes:
81
+ print("[ERROR] No data loaded.", file=sys.stderr)
82
+ return 1
83
+
84
+ merged = dataframes[0]
85
+ for df in dataframes[1:]:
86
+ if "subject_id" in merged.columns and "subject_id" in df.columns:
87
+ new_cols = [c for c in df.columns if c not in merged.columns or c == "subject_id"]
88
+ merged = pd.merge(merged, df[new_cols], on="subject_id", how="outer", suffixes=("", "_dup"))
89
+ dup_cols = [c for c in merged.columns if c.endswith("_dup")]
90
+ if dup_cols:
91
+ merged = merged.drop(columns=dup_cols)
92
+ else:
93
+ merged = pd.concat([merged, df], ignore_index=True)
94
+
95
+ if args.imaging_ids:
96
+ imaging_path = Path(args.imaging_ids).resolve()
97
+ if imaging_path.exists() and "subject_id" in merged.columns:
98
+ id_df = pd.read_csv(imaging_path, sep="\t")
99
+ for col in ["participant_id", "subject_id"]:
100
+ if col in id_df.columns:
101
+ imaging_ids = set(id_df[col].astype(str).str.strip())
102
+ normalized = {normalize_subject_id(sid) for sid in imaging_ids} | imaging_ids
103
+ merged["_norm"] = merged["subject_id"].apply(normalize_subject_id)
104
+ merged = merged[merged["_norm"].isin(normalized) | merged["subject_id"].astype(str).isin(normalized)]
105
+ merged = merged.drop(columns=["_norm"])
106
+ break
107
+
108
+ if args.columns:
109
+ requested = [c.strip() for c in args.columns.split(",")]
110
+ available = [c for c in requested if c in merged.columns]
111
+ if "subject_id" not in available and "subject_id" in merged.columns:
112
+ available = ["subject_id"] + available
113
+ if available:
114
+ merged = merged[available]
115
+
116
+ if args.missing_threshold < 1.0:
117
+ missing_frac = merged.isnull().mean()
118
+ cols_to_drop = [c for c in missing_frac[missing_frac > args.missing_threshold].index if c not in ("subject_id", "diagnosis")]
119
+ if cols_to_drop:
120
+ merged = merged.drop(columns=cols_to_drop)
121
+
122
+ output_path = Path(args.output).resolve()
123
+ output_path.parent.mkdir(parents=True, exist_ok=True)
124
+ merged.to_csv(output_path, index=False)
125
+ print(f"\nWrote {len(merged)} rows x {len(merged.columns)} columns to {output_path}")
126
+
127
+ if "diagnosis" in merged.columns:
128
+ print(f"\nDiagnosis distribution:\n{merged['diagnosis'].value_counts().to_string()}")
129
+
130
+ return 0
131
+
132
+
133
+ if __name__ == "__main__":
134
+ sys.exit(main())
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env python3
2
+ """Reorganize ADHD-200 raw data into BIDS-compliant directory structure.
3
+
4
+ Handles FCP/INDI-style subject directories, site extraction, and modality
5
+ routing for T1w and rs-fMRI.
6
+ """
7
+ import argparse
8
+ import csv
9
+ import json
10
+ import re
11
+ import shutil
12
+ import sys
13
+ from pathlib import Path
14
+ from typing import Dict, List, Optional, Tuple
15
+
16
+ SIDECAR_EXTENSIONS = [".json", ".bval", ".bvec", ".tsv"]
17
+
18
+ ADHD200_SITES = [
19
+ "Peking", "Brown", "NYU", "KKI", "NeuroImage",
20
+ "OHSU", "Pitt", "WashU", "Washington",
21
+ ]
22
+
23
+
24
+ def normalize_subject_id(raw_id: str) -> str:
25
+ clean = re.sub(r"[^a-zA-Z0-9]", "", str(raw_id).strip())
26
+ return f"sub-{clean}"
27
+
28
+
29
+ def detect_site_from_path(file_path: Path, root_dir: Path) -> str:
30
+ rel = file_path.relative_to(root_dir)
31
+ for part in rel.parts:
32
+ for site in ADHD200_SITES:
33
+ if site.lower() in part.lower():
34
+ return site
35
+ return "unknown"
36
+
37
+
38
+ def detect_modality(directory: Path, filename: str) -> Optional[Tuple[str, str]]:
39
+ name_lower = (directory.name + " " + filename).lower()
40
+ if any(k in name_lower for k in ["t1w", "t1", "anat", "mprage"]):
41
+ if "bold" not in name_lower:
42
+ return ("T1w", "anat")
43
+ if any(k in name_lower for k in ["rest", "bold", "fmri", "func", "rsfmri"]):
44
+ return ("task-rest_bold", "func")
45
+ return None
46
+
47
+
48
+ def find_nifti_files(directory: Path) -> List[Path]:
49
+ return [
50
+ f for f in directory.rglob("*")
51
+ if f.is_file() and (f.name.endswith(".nii") or f.name.endswith(".nii.gz"))
52
+ ]
53
+
54
+
55
+ def copy_with_sidecars(src_nifti: Path, dst_dir: Path, dst_stem: str) -> None:
56
+ dst_dir.mkdir(parents=True, exist_ok=True)
57
+ ext = ".nii.gz" if src_nifti.name.endswith(".nii.gz") else ".nii"
58
+ dst_nifti = dst_dir / f"{dst_stem}{ext}"
59
+ if not dst_nifti.exists():
60
+ shutil.copy2(str(src_nifti), str(dst_nifti))
61
+
62
+ src_stem = src_nifti.name[:-7] if src_nifti.name.endswith(".nii.gz") else src_nifti.name[:-4]
63
+ for sidecar_ext in SIDECAR_EXTENSIONS:
64
+ src_sidecar = src_nifti.parent / f"{src_stem}{sidecar_ext}"
65
+ if src_sidecar.exists():
66
+ dst_sidecar = dst_dir / f"{dst_stem}{sidecar_ext}"
67
+ if not dst_sidecar.exists():
68
+ shutil.copy2(str(src_sidecar), str(dst_sidecar))
69
+
70
+
71
+ def write_dataset_description(bids_root: Path) -> None:
72
+ desc = {
73
+ "Name": "ADHD-200",
74
+ "BIDSVersion": "1.8.0",
75
+ "DatasetType": "raw",
76
+ "GeneratedBy": [{"Name": "NeuroClaw adhd200-skill", "Version": "1.0.0"}],
77
+ }
78
+ (bids_root / "dataset_description.json").write_text(
79
+ json.dumps(desc, indent=2), encoding="utf-8"
80
+ )
81
+
82
+
83
+ def write_participants_tsv(bids_root: Path, participants: List[Dict[str, str]], phenotype_file: Optional[Path] = None) -> None:
84
+ phenotype_map: Dict[str, Dict[str, str]] = {}
85
+ if phenotype_file and phenotype_file.exists():
86
+ try:
87
+ with open(phenotype_file, "r", encoding="utf-8") as f:
88
+ reader = csv.DictReader(f)
89
+ for row in reader:
90
+ sid = row.get("subject", row.get("SUBJECT_ID", row.get("Subject", "")))
91
+ if sid:
92
+ phenotype_map[normalize_subject_id(sid)] = row
93
+ except Exception:
94
+ pass
95
+
96
+ tsv_path = bids_root / "participants.tsv"
97
+ headers = ["participant_id", "site"]
98
+ if phenotype_map:
99
+ sample = next(iter(phenotype_map.values()))
100
+ for col in sample:
101
+ if col not in headers and col not in ("subject", "SUBJECT_ID", "Subject"):
102
+ headers.append(col)
103
+
104
+ with open(tsv_path, "w", encoding="utf-8", newline="") as f:
105
+ writer = csv.writer(f, delimiter="\t")
106
+ writer.writerow(headers)
107
+ seen = set()
108
+ for p in participants:
109
+ pid = p["participant_id"]
110
+ if pid in seen:
111
+ continue
112
+ seen.add(pid)
113
+ row = [pid, p.get("site", "unknown")]
114
+ pheno = phenotype_map.get(pid, {})
115
+ for col in headers[2:]:
116
+ row.append(pheno.get(col, "n/a"))
117
+ writer.writerow(row)
118
+
119
+
120
+ def main() -> int:
121
+ parser = argparse.ArgumentParser(description="Reorganize ADHD-200 raw data into BIDS structure.")
122
+ parser.add_argument("--input", required=True, help="Path to ADHD-200 raw data directory")
123
+ parser.add_argument("--output", required=True, help="Path to output BIDS directory")
124
+ parser.add_argument("--phenotype", help="Path to ADHD-200 phenotype CSV file")
125
+ parser.add_argument("--dry-run", action="store_true", help="Preview without copying files")
126
+ args = parser.parse_args()
127
+
128
+ input_dir = Path(args.input).resolve()
129
+ output_dir = Path(args.output).resolve()
130
+
131
+ if not input_dir.exists():
132
+ print(f"Input directory does not exist: {input_dir}", file=sys.stderr)
133
+ return 1
134
+
135
+ output_dir.mkdir(parents=True, exist_ok=True)
136
+ participants: List[Dict[str, str]] = []
137
+ converted = skipped = failed = 0
138
+
139
+ print(f"{'[DRY RUN] ' if args.dry_run else ''}Starting ADHD-200 reorganization...\n")
140
+
141
+ subject_dirs = sorted([p for p in input_dir.iterdir() if p.is_dir() and not p.name.startswith(".")])
142
+
143
+ for subject_dir in subject_dirs:
144
+ site = detect_site_from_path(subject_dir, input_dir)
145
+ nifti_files = find_nifti_files(subject_dir)
146
+
147
+ if not nifti_files:
148
+ # Treat as site directory
149
+ for sub_dir in sorted(subject_dir.iterdir()):
150
+ if not sub_dir.is_dir():
151
+ continue
152
+ sub_label = normalize_subject_id(sub_dir.name)
153
+ participants.append({"participant_id": sub_label, "site": site})
154
+ for nifti in find_nifti_files(sub_dir):
155
+ result = detect_modality(nifti.parent, nifti.name)
156
+ if result is None:
157
+ result = detect_modality(sub_dir, nifti.name)
158
+ if result is None:
159
+ failed += 1
160
+ continue
161
+ bids_suffix, bids_folder = result
162
+ bids_sub_dir = output_dir / sub_label / "ses-1" / bids_folder
163
+ dst_stem = f"{sub_label}_ses-1_{bids_suffix}"
164
+ if (bids_sub_dir / f"{dst_stem}.nii.gz").exists():
165
+ skipped += 1
166
+ continue
167
+ if args.dry_run:
168
+ print(f"[DRY] {sub_label}/ses-1/{bids_folder}/{dst_stem}")
169
+ else:
170
+ copy_with_sidecars(nifti, bids_sub_dir, dst_stem)
171
+ print(f"[OK] {sub_label} ({site}) / {bids_folder} / {dst_stem}")
172
+ converted += 1
173
+ else:
174
+ sub_label = normalize_subject_id(subject_dir.name)
175
+ participants.append({"participant_id": sub_label, "site": site})
176
+ for nifti in nifti_files:
177
+ result = detect_modality(nifti.parent, nifti.name)
178
+ if result is None:
179
+ result = detect_modality(subject_dir, nifti.name)
180
+ if result is None:
181
+ failed += 1
182
+ continue
183
+ bids_suffix, bids_folder = result
184
+ bids_sub_dir = output_dir / sub_label / "ses-1" / bids_folder
185
+ dst_stem = f"{sub_label}_ses-1_{bids_suffix}"
186
+ if (bids_sub_dir / f"{dst_stem}.nii.gz").exists():
187
+ skipped += 1
188
+ continue
189
+ if args.dry_run:
190
+ print(f"[DRY] {sub_label}/ses-1/{bids_folder}/{dst_stem}")
191
+ else:
192
+ copy_with_sidecars(nifti, bids_sub_dir, dst_stem)
193
+ print(f"[OK] {sub_label} ({site}) / {bids_folder} / {dst_stem}")
194
+ converted += 1
195
+
196
+ if not args.dry_run and converted > 0:
197
+ write_dataset_description(output_dir)
198
+ phenotype_path = Path(args.phenotype).resolve() if args.phenotype else None
199
+ write_participants_tsv(output_dir, participants, phenotype_path)
200
+
201
+ print(f"\nDone. Converted={converted}, Skipped={skipped}, Failed={failed}")
202
+ return 0 if failed == 0 else 2
203
+
204
+
205
+ if __name__ == "__main__":
206
+ sys.exit(main())