@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,271 @@
1
+ ---
2
+ name: hbn-skill
3
+ description: "Use this skill whenever the user wants an end-to-end workflow for the Healthy Brain Network (HBN) dataset, including download, BIDS organization, and multimodal processing of sMRI, dMRI, rs-fMRI, task-fMRI, and EEG data. Triggers include: 'HBN', 'Healthy Brain Network', 'process HBN', 'HBN fMRI', 'HBN EEG', or any request to run the HBN multimodal pipeline. This is the NeuroClaw dataset-orchestration layer for HBN."
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
+ - dwi-skill
11
+ - eeg-skill
12
+ - bids-organizer
13
+ - claw-shell
14
+ ---
15
+ # HBN Skill (Dataset-Orchestration Layer)
16
+
17
+ ## Overview
18
+ `hbn-skill` is the NeuroClaw orchestration skill for the **Healthy Brain Network (HBN)** dataset.
19
+
20
+ It coordinates a fixed multi-phase workflow:
21
+ 1. Download HBN data from the FCP/INDI repository.
22
+ 2. Prepare and validate BIDS-style data organization for downstream processing.
23
+ 3. Delegate modality pipelines to `smri-skill`, `fmri-skill`, `dwi-skill`, and `eeg-skill`.
24
+
25
+ It also provides **phenotype extraction** and **QC integration** paths:
26
+ - Extract and merge HBN phenotype tables (psychiatric, behavioral, cognitive, lifestyle, genetics, actigraphy).
27
+ - Generate per-subject QC summaries with exclusion lists.
28
+
29
+ This skill follows NeuroClaw hierarchy:
30
+ - Defines **WHAT to do**, not low-level implementation details.
31
+ - Does **not** execute direct shell commands itself.
32
+ - Delegates all execution via `claw-shell` to base/tool skills.
33
+
34
+ **Research use only.**
35
+
36
+ ---
37
+
38
+ ## Download Stage (Mandatory First Step)
39
+
40
+ ### Source
41
+ HBN data is distributed through the **FCP/INDI** repository:
42
+ - Website: https://fcon_1000.projects.nitrc.org/indi/cmi_healthy_brain_network/
43
+
44
+ ### Supported HBN Data Packages
45
+ - **Imaging data**: T1w, T2w, dMRI, rs-fMRI, task-fMRI (NIfTI format)
46
+ - **EEG data**: resting-state and task EEG recordings
47
+ - **Phenotype data**: CSV/TSV files with psychiatric, behavioral, cognitive, lifestyle, genetics, actigraphy measures
48
+ - **Sites**: Rutgers University Brain Imaging Center (primary), with additional sites planned
49
+
50
+ ### Delegation Rules for Download
51
+ - Environment/setup checks: `dependency-planner` + `conda-env-manager`
52
+ - 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
+ - Target subset (full cohort, specific sites, or age groups)
57
+ - Subject list scope (full or custom IDs)
58
+ - Destination directory with sufficient disk space
59
+
60
+ ---
61
+
62
+ ## Narrow Path: HBN Raw NIfTI -> BIDS Staging
63
+
64
+ Use this path when the task only asks to reorganize raw HBN NIfTI files into a BIDS-style dataset and does not require preprocessing, ROI extraction, phenotype merging, or downstream analysis.
65
+
66
+ ### When this narrow path should dominate
67
+ - The task objective is limited to HBN NIfTI staging, BIDS renaming, sidecar handling, and dataset-level metadata.
68
+ - Inputs are already local HBN NIfTI files or HBN-style subject folders.
69
+ - The required deliverable is a direct staging script or command sequence, not a plan for fMRIPrep or downstream analysis.
70
+
71
+ ### Narrow-path contract
72
+ - Do not widen the solution to fMRIPrep, ROI extraction, phenotype merging, or downstream analysis unless the task explicitly requires them.
73
+ - Treat this as a direct file-organization problem: scan HBN subject layout, normalize subject labels, map modalities to BIDS names, copy or symlink NIfTI plus matching sidecars, and write dataset-level metadata plus staging logs.
74
+ - If the task is benchmark-style, prefer a single direct end-to-end staging script over a confirmation-first orchestration plan.
75
+
76
+ ### Expected narrow-path behavior
77
+ 1. Detect HBN-style subject IDs (e.g., `NDARAA075AMK`) and normalize to BIDS labels such as `sub-NDARAA075AMK`.
78
+ 2. Detect session information (e.g., `ses-1`, `ses-2`) from directory structure.
79
+ 3. Route modalities:
80
+ - T1w -> `anat/*_T1w`
81
+ - T2w -> `anat/*_T2w`
82
+ - dMRI -> `dwi/*_dwi`
83
+ - rs-fMRI/BOLD -> `func/*_task-rest_bold`
84
+ - task-fMRI/BOLD -> `func/*_task-<name>_bold`
85
+ - EEG -> `eeg/*_eeg`
86
+ 4. Preserve or rename matching JSON sidecars when available.
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 HBN download, 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_hbn.py`.
97
+ 6. Delegate to modality skills:
98
+ - `smri-skill` for structural MRI (T1w, T2w)
99
+ - `fmri-skill` for functional MRI (rs-fMRI, task-fMRI)
100
+ - `dwi-skill` for diffusion MRI (dMRI)
101
+ - `eeg-skill` for EEG recordings
102
+ 7. If phenotype extraction is requested, run `scripts/extract_hbn_phenotype.py`.
103
+ 8. If QC summary is requested, run `scripts/hbn_qc_summary.py`.
104
+ 9. Save outputs into an HBN-centered structure under `hbn_output/`.
105
+
106
+ ---
107
+
108
+ ## Input Layout (Example)
109
+
110
+ Subject `NDARAA075AMK`:
111
+
112
+ ```
113
+ hbn_raw/
114
+ NDARAA075AMK/
115
+ ses-1/
116
+ anat/
117
+ sub-NDARAA075AMK_ses-1_T1w.nii.gz
118
+ func/
119
+ sub-NDARAA075AMK_ses-1_task-rest_bold.nii.gz
120
+ dwi/
121
+ sub-NDARAA075AMK_ses-1_dwi.nii.gz
122
+ eeg/
123
+ sub-NDARAA075AMK_ses-1_task-rest_eeg.set
124
+ ses-2/
125
+ ...
126
+ phenotype/
127
+ hbn_phenotype.csv
128
+ ```
129
+
130
+ ---
131
+
132
+ ## BIDS Preparation
133
+
134
+ ### Script: `scripts/reorganize_hbn.py`
135
+
136
+ Converts HBN raw directory structure to BIDS-compliant layout.
137
+
138
+ ```bash
139
+ python skills/hbn-skill/scripts/reorganize_hbn.py \
140
+ --input /path/to/hbn_raw \
141
+ --output /path/to/hbn_bids
142
+ ```
143
+
144
+ Features:
145
+ - Subject ID normalization to BIDS `sub-NDARXXXXXXXXX`
146
+ - Session detection from directory structure
147
+ - Modality routing: T1w, T2w, dMRI, rs-fMRI, task-fMRI, EEG
148
+ - `dataset_description.json` and `participants.tsv` generation
149
+ - Dry-run mode: `--dry-run` to preview without copying
150
+
151
+ ---
152
+
153
+ ## Multimodal Processing Delegation
154
+
155
+ | Modality | Delegated skill | Typical tasks | Main outputs |
156
+ |---|---|---|---|
157
+ | sMRI (T1w, T2w) | `smri-skill` | brain extraction, tissue segmentation, cortical reconstruction | `smri_output/` |
158
+ | fMRI (rs-fMRI, task-fMRI) | `fmri-skill` | preprocessing, denoising, ROI time series, connectivity, task GLM | `fmri_output/` |
159
+ | dMRI | `dwi-skill` | eddy correction, tensor metrics, tractography, connectome | `dwi_output/` |
160
+ | EEG | `eeg-skill` | artifact removal, filtering, epoch extraction, spectral analysis | `eeg_output/` |
161
+
162
+ ---
163
+
164
+ ## Phenotype Extraction
165
+
166
+ ### Script: `scripts/extract_hbn_phenotype.py`
167
+
168
+ ```bash
169
+ python skills/hbn-skill/scripts/extract_hbn_phenotype.py \
170
+ --phenotype-dir /path/to/hbn_raw/phenotype \
171
+ --output /path/to/hbn_output/phenotype/merged_phenotype.csv \
172
+ --imaging-ids /path/to/hbn_output/bids/participants.tsv
173
+ ```
174
+
175
+ HBN phenotype domains include:
176
+ - Psychiatric assessments (CBCL, KSADS)
177
+ - Behavioral measures
178
+ - Cognitive assessments
179
+ - Lifestyle and environmental factors
180
+ - Genetics
181
+ - Actigraphy
182
+
183
+ ---
184
+
185
+ ## QC Integration
186
+
187
+ ### Script: `scripts/hbn_qc_summary.py`
188
+
189
+ ```bash
190
+ python skills/hbn-skill/scripts/hbn_qc_summary.py \
191
+ --fmriprep-dir /path/to/hbn_output/fmriprep \
192
+ --output /path/to/hbn_output/qc/qc_summary.csv \
193
+ --exclude-output /path/to/hbn_output/qc/exclude_list.csv \
194
+ --fd-threshold 0.3
195
+ ```
196
+
197
+ ---
198
+
199
+ ## Recommended Output Layout
200
+ All assets should be organized under `./hbn_output/`:
201
+ - `hbn_output/raw/` (downloaded original files)
202
+ - `hbn_output/bids/` (staged BIDS data)
203
+ - `hbn_output/smri/` (links or copies from `smri_output/`)
204
+ - `hbn_output/fmri/` (links or copies from `fmri_output/`)
205
+ - `hbn_output/dwi/` (links or copies from `dwi_output/`)
206
+ - `hbn_output/eeg/` (links or copies from `eeg_output/`)
207
+ - `hbn_output/phenotype/` (merged phenotype tables)
208
+ - `hbn_output/qc/` (QC summaries and exclusion lists)
209
+ - `hbn_output/logs/` (download + orchestration logs)
210
+
211
+ ---
212
+
213
+ ## Benchmark Adapter Guidance
214
+
215
+ For benchmark-style prompts, do not force the full `download -> staging -> multimodal processing` orchestration when the task is only asking for local HBN data staging or organization.
216
+
217
+ - If the task starts from raw HBN data already present on disk and only asks for BIDS-style staging / organization:
218
+ - skip the mandatory download stage
219
+ - default to the narrow path `local raw HBN discovery -> BIDS-style staging -> minimal metadata -> validation/report`
220
+ - In benchmark mode, do not require explicit confirmation before presenting the direct staging solution.
221
+
222
+ ---
223
+
224
+ ## Safety and Execution Policy
225
+ - No execution before explicit plan confirmation.
226
+ - All execution must be routed via `claw-shell`.
227
+ - Missing dependencies must be resolved by `dependency-planner` before running.
228
+
229
+ ---
230
+
231
+ ## Important Notes and Limitations
232
+ - HBN is a pediatric/adolescent cohort (ages 5-21); age-appropriate processing parameters may be needed.
233
+ - HBN includes EEG data in addition to standard neuroimaging modalities.
234
+ - HBN data is released in waves; not all subjects have all modalities.
235
+ - HBN subject IDs use NDAR format (e.g., `NDARAA075AMK`).
236
+ - `hbn-skill` is orchestration-only; detailed preprocessing logic remains in modality skills.
237
+
238
+ ---
239
+
240
+ ## When to Call This Skill
241
+ - User asks for end-to-end HBN workflow.
242
+ - User asks to download HBN data and then run multimodal processing.
243
+ - User needs BIDS staging for raw HBN NIfTI files.
244
+ - User asks to extract and merge HBN phenotype tables.
245
+ - User needs HBN-specific QC summaries and exclusion lists.
246
+
247
+ ---
248
+
249
+ ## Complementary / Related Skills
250
+ - `smri-skill`
251
+ - `fmri-skill`
252
+ - `dwi-skill`
253
+ - `eeg-skill`
254
+ - `bids-organizer`
255
+ - `fmriprep-tool`
256
+ - `qsiprep-tool`
257
+ - `freesurfer-tool`
258
+ - `mne-eeg-tool`
259
+ - `dependency-planner`
260
+ - `conda-env-manager`
261
+ - `claw-shell`
262
+
263
+ ---
264
+
265
+ ## Reference
266
+ - HBN: https://fcon_1000.projects.nitrc.org/indi/cmi_healthy_brain_network/
267
+ - BIDS spec: https://bids.neuroimaging.io/
268
+
269
+ Created At: 2026-05-06 10:49 HKT
270
+ Last Updated At: 2026-05-06 10:49 HKT
271
+ Author: chengwang96
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env python3
2
+ """Extract and merge HBN 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
9
+
10
+ try:
11
+ import pandas as pd
12
+ except ImportError:
13
+ print("Error: pandas is required.", file=sys.stderr)
14
+ sys.exit(1)
15
+
16
+ COLUMN_MAP = {
17
+ "participant_id": "subject_id",
18
+ "subject": "subject_id",
19
+ "SUBJECT_ID": "subject_id",
20
+ "src_subject_id": "subject_id",
21
+ "age": "age",
22
+ "interview_age": "age",
23
+ "sex": "sex",
24
+ "gender": "sex",
25
+ "handedness": "handedness",
26
+ "site": "site",
27
+ "study_site": "site",
28
+ }
29
+
30
+
31
+ def normalize_subject_id(raw_id) -> str:
32
+ clean = re.sub(r"[^a-zA-Z0-9]", "", str(raw_id).strip())
33
+ return f"sub-{clean}"
34
+
35
+
36
+ def main() -> int:
37
+ parser = argparse.ArgumentParser(description="Extract HBN phenotype data.")
38
+ parser.add_argument("--phenotype-dir", help="Directory containing HBN phenotype CSV/TSV files")
39
+ parser.add_argument("--phenotype-file", help="Direct path to HBN phenotype CSV/TSV file")
40
+ parser.add_argument("--output", required=True, help="Output path for phenotype CSV")
41
+ parser.add_argument("--imaging-ids", help="Path to BIDS participants.tsv for filtering")
42
+ args = parser.parse_args()
43
+
44
+ phenotype_files = []
45
+ if args.phenotype_file:
46
+ p = Path(args.phenotype_file).resolve()
47
+ if p.exists():
48
+ phenotype_files.append(p)
49
+ elif args.phenotype_dir:
50
+ phenotype_dir = Path(args.phenotype_dir).resolve()
51
+ if phenotype_dir.exists():
52
+ phenotype_files = sorted(f for f in phenotype_dir.iterdir() if f.is_file() and f.suffix in (".csv", ".tsv"))
53
+
54
+ if not phenotype_files:
55
+ print("[ERROR] No phenotype files found.", file=sys.stderr)
56
+ return 1
57
+
58
+ print(f"Found {len(phenotype_files)} phenotype file(s)")
59
+
60
+ dataframes = []
61
+ for f in phenotype_files:
62
+ try:
63
+ df = pd.read_csv(f, sep=None, engine="python", low_memory=False)
64
+ rename = {k: v for k, v in COLUMN_MAP.items() if k in df.columns and v not in df.columns}
65
+ df = df.rename(columns=rename)
66
+ dataframes.append(df)
67
+ except Exception as e:
68
+ print(f"[WARN] Failed to read {f}: {e}")
69
+
70
+ if not dataframes:
71
+ print("[ERROR] No data loaded.", file=sys.stderr)
72
+ return 1
73
+
74
+ merged = dataframes[0]
75
+ for df in dataframes[1:]:
76
+ if "subject_id" in merged.columns and "subject_id" in df.columns:
77
+ new_cols = [c for c in df.columns if c not in merged.columns or c == "subject_id"]
78
+ merged = pd.merge(merged, df[new_cols], on="subject_id", how="outer")
79
+ else:
80
+ merged = pd.concat([merged, df], ignore_index=True)
81
+
82
+ if args.imaging_ids:
83
+ imaging_path = Path(args.imaging_ids).resolve()
84
+ if imaging_path.exists() and "subject_id" in merged.columns:
85
+ id_df = pd.read_csv(imaging_path, sep="\t")
86
+ for col in ["participant_id", "subject_id"]:
87
+ if col in id_df.columns:
88
+ imaging_ids = set(id_df[col].astype(str).str.strip())
89
+ normalized = {normalize_subject_id(sid) for sid in imaging_ids} | imaging_ids
90
+ merged["_norm"] = merged["subject_id"].apply(normalize_subject_id)
91
+ merged = merged[merged["_norm"].isin(normalized) | merged["subject_id"].astype(str).isin(normalized)]
92
+ merged = merged.drop(columns=["_norm"])
93
+ break
94
+
95
+ output_path = Path(args.output).resolve()
96
+ output_path.parent.mkdir(parents=True, exist_ok=True)
97
+ merged.to_csv(output_path, index=False)
98
+ print(f"\nWrote {len(merged)} rows x {len(merged.columns)} columns to {output_path}")
99
+
100
+ if "site" in merged.columns:
101
+ print(f"\nSite distribution:\n{merged['site'].value_counts().to_string()}")
102
+
103
+ return 0
104
+
105
+
106
+ if __name__ == "__main__":
107
+ sys.exit(main())
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env python3
2
+ """Generate per-subject QC summaries and exclusion lists for HBN."""
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
+ qc[subject_id]["n_volumes"] = qc[subject_id].get("n_volumes", 0) + metrics["n_volumes"]
39
+ else:
40
+ qc[subject_id] = metrics
41
+ return qc
42
+
43
+
44
+ def main() -> int:
45
+ parser = argparse.ArgumentParser(description="Generate HBN QC summaries.")
46
+ parser.add_argument("--fmriprep-dir", help="Path to fMRIPrep output directory")
47
+ parser.add_argument("--output", required=True, help="Output path for QC summary CSV")
48
+ parser.add_argument("--exclude-output", help="Output path for exclusion list CSV")
49
+ parser.add_argument("--fd-threshold", type=float, default=0.3, help="Mean FD threshold (default: 0.3)")
50
+ parser.add_argument("--max-fd-threshold", type=float, default=5.0, help="Max FD threshold (default: 5.0)")
51
+ args = parser.parse_args()
52
+
53
+ fmriprep_qc = {}
54
+ if args.fmriprep_dir:
55
+ fp_dir = Path(args.fmriprep_dir).resolve()
56
+ if fp_dir.exists():
57
+ print(f"Collecting fMRIPrep QC from {fp_dir}...")
58
+ fmriprep_qc = collect_fmriprep_qc(fp_dir)
59
+ print(f" Found {len(fmriprep_qc)} subjects")
60
+
61
+ if not fmriprep_qc:
62
+ print("[ERROR] No QC data collected.", file=sys.stderr)
63
+ return 1
64
+
65
+ rows = []
66
+ excluded = []
67
+ for sub_id in sorted(fmriprep_qc.keys()):
68
+ fp = fmriprep_qc[sub_id]
69
+ reasons = []
70
+ if fp.get("mean_fd", 0) > args.fd_threshold:
71
+ reasons.append(f"mean_fd={fp['mean_fd']:.3f}>{args.fd_threshold}")
72
+ if fp.get("max_fd", 0) > args.max_fd_threshold:
73
+ reasons.append(f"max_fd={fp['max_fd']:.3f}>{args.max_fd_threshold}")
74
+ 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)}
75
+ if reasons:
76
+ excluded.append(sub_id)
77
+ rows.append(row)
78
+
79
+ summary_df = pd.DataFrame(rows)
80
+ output_path = Path(args.output).resolve()
81
+ output_path.parent.mkdir(parents=True, exist_ok=True)
82
+ summary_df.to_csv(output_path, index=False)
83
+ print(f"\nQC Summary: {len(summary_df)} subjects -> {output_path}")
84
+ print(f" Excluded: {len(excluded)} / {len(summary_df)} ({100*len(excluded)/max(len(summary_df),1):.1f}%)")
85
+
86
+ if args.exclude_output:
87
+ exclude_path = Path(args.exclude_output).resolve()
88
+ exclude_path.parent.mkdir(parents=True, exist_ok=True)
89
+ summary_df[summary_df["exclude"] == True][["subject_id", "exclude_reasons"]].to_csv(exclude_path, index=False)
90
+ print(f" Exclusion list: {exclude_path}")
91
+
92
+ return 0
93
+
94
+
95
+ if __name__ == "__main__":
96
+ sys.exit(main())
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env python3
2
+ """Reorganize HBN raw data into BIDS-compliant directory structure."""
3
+ import argparse
4
+ import csv
5
+ import json
6
+ import re
7
+ import shutil
8
+ import sys
9
+ from pathlib import Path
10
+ from typing import Dict, List, Optional, Tuple
11
+
12
+ SIDECAR_EXTENSIONS = [".json", ".bval", ".bvec", ".tsv"]
13
+ MODALITY_MAP = {
14
+ "T1w": ("T1w", "anat"),
15
+ "T2w": ("T2w", "anat"),
16
+ "dwi": ("dwi", "dwi"),
17
+ "bold": ("task-rest_bold", "func"),
18
+ "task-rest_bold": ("task-rest_bold", "func"),
19
+ "task-rest_run-1_bold": ("task-rest_run-1_bold", "func"),
20
+ "task-rest_run-2_bold": ("task-rest_run-2_bold", "func"),
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_task_name(filename: str) -> Optional[str]:
30
+ match = re.search(r"task-([a-zA-Z0-9]+)", filename)
31
+ return match.group(1) if match else None
32
+
33
+
34
+ def detect_modality(filename: str) -> Optional[Tuple[str, str]]:
35
+ name_lower = filename.lower()
36
+ for key, (bids_suffix, bids_folder) in MODALITY_MAP.items():
37
+ if key.lower() in name_lower:
38
+ return (bids_suffix, bids_folder)
39
+ if "eeg" in name_lower:
40
+ return ("eeg", "eeg")
41
+ return None
42
+
43
+
44
+ def find_nifti_files(directory: Path) -> List[Path]:
45
+ return [f for f in directory.rglob("*") if f.is_file() and (f.name.endswith(".nii") or f.name.endswith(".nii.gz"))]
46
+
47
+
48
+ def copy_with_sidecars(src_nifti: Path, dst_dir: Path, dst_stem: str) -> None:
49
+ dst_dir.mkdir(parents=True, exist_ok=True)
50
+ ext = ".nii.gz" if src_nifti.name.endswith(".nii.gz") else ".nii"
51
+ dst_nifti = dst_dir / f"{dst_stem}{ext}"
52
+ if not dst_nifti.exists():
53
+ shutil.copy2(str(src_nifti), str(dst_nifti))
54
+ src_stem = src_nifti.name[:-7] if src_nifti.name.endswith(".nii.gz") else src_nifti.name[:-4]
55
+ for sidecar_ext in SIDECAR_EXTENSIONS:
56
+ src_sidecar = src_nifti.parent / f"{src_stem}{sidecar_ext}"
57
+ if src_sidecar.exists():
58
+ dst_sidecar = dst_dir / f"{dst_stem}{sidecar_ext}"
59
+ if not dst_sidecar.exists():
60
+ shutil.copy2(str(src_sidecar), str(dst_sidecar))
61
+
62
+
63
+ def write_dataset_description(bids_root: Path) -> None:
64
+ desc = {
65
+ "Name": "Healthy Brain Network (HBN)",
66
+ "BIDSVersion": "1.8.0",
67
+ "DatasetType": "raw",
68
+ "GeneratedBy": [{"Name": "NeuroClaw hbn-skill", "Version": "1.0.0"}],
69
+ }
70
+ (bids_root / "dataset_description.json").write_text(json.dumps(desc, indent=2), encoding="utf-8")
71
+
72
+
73
+ def write_participants_tsv(bids_root: Path, participants: List[Dict[str, str]]) -> None:
74
+ tsv_path = bids_root / "participants.tsv"
75
+ with open(tsv_path, "w", encoding="utf-8", newline="") as f:
76
+ writer = csv.writer(f, delimiter="\t")
77
+ writer.writerow(["participant_id"])
78
+ seen = set()
79
+ for p in participants:
80
+ pid = p["participant_id"]
81
+ if pid not in seen:
82
+ writer.writerow([pid])
83
+ seen.add(pid)
84
+
85
+
86
+ def main() -> int:
87
+ parser = argparse.ArgumentParser(description="Reorganize HBN raw data into BIDS structure.")
88
+ parser.add_argument("--input", required=True, help="Path to HBN raw data directory")
89
+ parser.add_argument("--output", required=True, help="Path to output BIDS directory")
90
+ parser.add_argument("--dry-run", action="store_true", help="Preview without copying")
91
+ args = parser.parse_args()
92
+
93
+ input_dir = Path(args.input).resolve()
94
+ output_dir = Path(args.output).resolve()
95
+ if not input_dir.exists():
96
+ print(f"Input directory does not exist: {input_dir}", file=sys.stderr)
97
+ return 1
98
+
99
+ output_dir.mkdir(parents=True, exist_ok=True)
100
+ participants: List[Dict[str, str]] = []
101
+ converted = skipped = failed = 0
102
+
103
+ for subject_dir in sorted(p for p in input_dir.iterdir() if p.is_dir() and not p.name.startswith(".")):
104
+ sub_label = normalize_subject_id(subject_dir.name)
105
+ participants.append({"participant_id": sub_label})
106
+
107
+ # HBN may have session directories (ses-1, ses-2, etc.)
108
+ session_dirs = [d for d in subject_dir.iterdir() if d.is_dir() and d.name.startswith("ses-")]
109
+ if not session_dirs:
110
+ session_dirs = [subject_dir]
111
+
112
+ for ses_dir in session_dirs:
113
+ ses_label = ses_dir.name if ses_dir.name.startswith("ses-") else "ses-1"
114
+ for nifti in find_nifti_files(ses_dir):
115
+ result = detect_modality(nifti.name)
116
+ if result is None:
117
+ result = detect_modality(nifti.parent.name)
118
+ if result is None:
119
+ failed += 1
120
+ continue
121
+
122
+ bids_suffix, bids_folder = result
123
+
124
+ # Handle task-fMRI: extract task name from filename
125
+ task_name = detect_task_name(nifti.name)
126
+ if task_name and bids_folder == "func":
127
+ bids_suffix = f"task-{task_name}_bold"
128
+
129
+ bids_sub_dir = output_dir / sub_label / ses_label / bids_folder
130
+ dst_stem = f"{sub_label}_{ses_label}_{bids_suffix}"
131
+ if (bids_sub_dir / f"{dst_stem}.nii.gz").exists():
132
+ skipped += 1
133
+ continue
134
+ if args.dry_run:
135
+ print(f"[DRY] {sub_label}/{ses_label}/{bids_folder}/{dst_stem}")
136
+ else:
137
+ copy_with_sidecars(nifti, bids_sub_dir, dst_stem)
138
+ print(f"[OK] {sub_label} / {ses_label} / {bids_folder} / {dst_stem}")
139
+ converted += 1
140
+
141
+ if not args.dry_run and converted > 0:
142
+ write_dataset_description(output_dir)
143
+ write_participants_tsv(output_dir, participants)
144
+
145
+ print(f"\nDone. Converted={converted}, Skipped={skipped}, Failed={failed}")
146
+ return 0 if failed == 0 else 2
147
+
148
+
149
+ if __name__ == "__main__":
150
+ sys.exit(main())