@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,145 @@
1
+ #!/usr/bin/env python3
2
+ """Extract and merge Cam-CAN phenotype data.
3
+
4
+ Reads Cam-CAN phenotype files (cognitive, sensory, health measures)
5
+ and produces a merged phenotype table aligned with imaging subject list.
6
+ """
7
+ import argparse
8
+ import csv
9
+ import sys
10
+ from pathlib import Path
11
+ from typing import Dict, List, Optional
12
+
13
+ # Column mapping for Cam-CAN phenotype data
14
+ COLUMN_MAP = {
15
+ "subject_id": ["subject", "Subject", "participant_id", "SubID"],
16
+ "age": ["age", "Age", "Age_in_Yrs"],
17
+ "sex": ["sex", "Sex", "Gender"],
18
+ "handedness": ["handedness", "Handedness"],
19
+ # Cognitive measures
20
+ "picture_vocab": ["PictureVocab", "picture_vocab_score"],
21
+ "card_sorting": ["CardSort", "card_sorting_score"],
22
+ "flanker": ["Flanker", "flanker_score"],
23
+ "list_sorting": ["ListSort", "list_sorting_score"],
24
+ "pattern_comparison": ["PatternComp", "pattern_comparison_score"],
25
+ "picture_sequence": ["PictureSeq", "picture_sequence_score"],
26
+ "reading": ["Reading", "reading_score"],
27
+ # Sensory measures
28
+ "hearing": ["Hearing", "hearing_threshold"],
29
+ "vision": ["Vision", "vision_acuity"],
30
+ # Health measures
31
+ "mmse": ["MMSE", "mmse_score"],
32
+ "moca": ["MOCA", "moca_score"],
33
+ # Grip strength
34
+ "grip_strength_left": ["GripLeft", "grip_strength_left"],
35
+ "grip_strength_right": ["GripRight", "grip_strength_right"],
36
+ }
37
+
38
+
39
+ def load_csv(path: Path) -> List[Dict[str, str]]:
40
+ """Load CSV/TSV file and return list of dicts."""
41
+ delimiter = "\t" if path.suffix == ".tsv" else ","
42
+ with open(path, "r", encoding="utf-8") as f:
43
+ reader = csv.DictReader(f, delimiter=delimiter)
44
+ return list(reader)
45
+
46
+
47
+ def find_column(row: Dict[str, str], candidates: List[str]) -> Optional[str]:
48
+ """Find the first matching column name in a row."""
49
+ for col in candidates:
50
+ if col in row:
51
+ return col
52
+ return None
53
+
54
+
55
+ def extract_phenotype(
56
+ phenotype_files: List[Path],
57
+ imaging_ids: Optional[List[str]] = None,
58
+ columns: Optional[List[str]] = None,
59
+ ) -> List[Dict[str, str]]:
60
+ """Extract and merge phenotype data from multiple files."""
61
+ all_data = []
62
+ for fpath in phenotype_files:
63
+ rows = load_csv(fpath)
64
+ all_data.extend(rows)
65
+
66
+ if not all_data:
67
+ return []
68
+
69
+ target_columns = columns if columns else list(COLUMN_MAP.keys())
70
+ merged = {}
71
+
72
+ for row in all_data:
73
+ subj_col = find_column(row, COLUMN_MAP["subject_id"])
74
+ if subj_col is None:
75
+ continue
76
+ subj_id = row[subj_col].strip()
77
+ if not subj_id:
78
+ continue
79
+
80
+ if subj_id not in merged:
81
+ merged[subj_id] = {"subject_id": subj_id}
82
+
83
+ for target_col in target_columns:
84
+ if target_col == "subject_id":
85
+ continue
86
+ if target_col in merged[subj_id] and merged[subj_id][target_col]:
87
+ continue
88
+ candidates = COLUMN_MAP.get(target_col, [target_col])
89
+ src_col = find_column(row, candidates)
90
+ if src_col and row.get(src_col, "").strip():
91
+ merged[subj_id][target_col] = row[src_col].strip()
92
+
93
+ result = list(merged.values())
94
+ if imaging_ids:
95
+ imaging_set = set(imaging_ids)
96
+ result = [r for r in result if r["subject_id"] in imaging_set]
97
+ return result
98
+
99
+
100
+ def main() -> int:
101
+ parser = argparse.ArgumentParser(
102
+ description="Extract Cam-CAN phenotype data."
103
+ )
104
+ parser.add_argument("--phenotype-files", required=True, nargs="+",
105
+ help="Paths to Cam-CAN phenotype CSV/TSV files")
106
+ parser.add_argument("--output", required=True, help="Output path for merged phenotype CSV")
107
+ parser.add_argument("--imaging-ids", help="Text file with imaging subject IDs to filter")
108
+ parser.add_argument("--columns", help="Comma-separated columns to extract")
109
+ args = parser.parse_args()
110
+
111
+ phenotype_files = [Path(f).resolve() for f in args.phenotype_files]
112
+ for f in phenotype_files:
113
+ if not f.exists():
114
+ print(f"File not found: {f}", file=sys.stderr)
115
+ return 1
116
+
117
+ imaging_ids = None
118
+ if args.imaging_ids:
119
+ id_file = Path(args.imaging_ids).resolve()
120
+ if id_file.exists():
121
+ imaging_ids = [l.strip() for l in id_file.read_text().splitlines() if l.strip()]
122
+
123
+ columns = None
124
+ if args.columns:
125
+ columns = [c.strip() for c in args.columns.split(",")]
126
+
127
+ merged = extract_phenotype(phenotype_files, imaging_ids, columns)
128
+ if not merged:
129
+ print("[ERROR] No phenotype data extracted.", file=sys.stderr)
130
+ return 1
131
+
132
+ output_path = Path(args.output).resolve()
133
+ output_path.parent.mkdir(parents=True, exist_ok=True)
134
+ fieldnames = list(merged[0].keys())
135
+ with open(output_path, "w", newline="", encoding="utf-8") as f:
136
+ writer = csv.DictWriter(f, fieldnames=fieldnames)
137
+ writer.writeheader()
138
+ writer.writerows(merged)
139
+
140
+ print(f"Phenotype: {len(merged)} subjects, {len(fieldnames)} columns -> {output_path}")
141
+ return 0
142
+
143
+
144
+ if __name__ == "__main__":
145
+ sys.exit(main())
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env python3
2
+ """Validate Cam-CAN BIDS structure and generate compliance report.
3
+
4
+ Checks directory structure, modality completeness, sidecar JSON presence,
5
+ and participant ID consistency across modalities.
6
+ """
7
+ import argparse
8
+ import csv
9
+ import json
10
+ import sys
11
+ from pathlib import Path
12
+ from typing import Dict, List
13
+
14
+ # Expected modalities for Cam-CAN
15
+ EXPECTED_MODALITIES = {
16
+ "anat": ["T1w"],
17
+ "func": ["task-rest_bold", "task-movie_bold"],
18
+ "meg": ["task-rest_meg", "task-auditory_meg", "task-visual_meg"],
19
+ "dwi": ["dwi"],
20
+ }
21
+
22
+
23
+ def validate_subject(subject_dir: Path) -> Dict[str, any]:
24
+ """Validate a single subject's BIDS structure."""
25
+ report = {
26
+ "subject": subject_dir.name,
27
+ "anat_complete": False,
28
+ "func_complete": False,
29
+ "meg_complete": False,
30
+ "dwi_complete": False,
31
+ "missing_files": [],
32
+ "warnings": [],
33
+ }
34
+
35
+ # Check anat
36
+ anat_dir = subject_dir / "anat"
37
+ if anat_dir.exists():
38
+ t1w_files = list(anat_dir.glob("*_T1w.nii.gz"))
39
+ report["anat_complete"] = len(t1w_files) > 0
40
+ if not t1w_files:
41
+ report["missing_files"].append("anat/*_T1w.nii.gz")
42
+ # Check sidecar JSON
43
+ for f in t1w_files:
44
+ json_file = f.with_suffix("").with_suffix(".json")
45
+ if not json_file.exists():
46
+ report["warnings"].append(f"Missing sidecar: {json_file.name}")
47
+ else:
48
+ report["missing_files"].append("anat/")
49
+
50
+ # Check func
51
+ func_dir = subject_dir / "func"
52
+ if func_dir.exists():
53
+ rest_bold = list(func_dir.glob("*_task-rest_bold.nii.gz"))
54
+ movie_bold = list(func_dir.glob("*_task-movie_bold.nii.gz"))
55
+ report["func_complete"] = len(rest_bold) > 0 and len(movie_bold) > 0
56
+ if not rest_bold:
57
+ report["missing_files"].append("func/*_task-rest_bold.nii.gz")
58
+ if not movie_bold:
59
+ report["missing_files"].append("func/*_task-movie_bold.nii.gz")
60
+ else:
61
+ report["missing_files"].append("func/")
62
+
63
+ # Check meg
64
+ meg_dir = subject_dir / "meg"
65
+ if meg_dir.exists():
66
+ meg_files = list(meg_dir.glob("*_meg.fif"))
67
+ if not meg_files:
68
+ meg_files = list(meg_dir.glob("*_meg.ds"))
69
+ report["meg_complete"] = len(meg_files) > 0
70
+ if not meg_files:
71
+ report["missing_files"].append("meg/*_meg.fif or .ds")
72
+ else:
73
+ report["missing_files"].append("meg/")
74
+
75
+ # Check dwi
76
+ dwi_dir = subject_dir / "dwi"
77
+ if dwi_dir.exists():
78
+ dwi_files = list(dwi_dir.glob("*_dwi.nii.gz"))
79
+ report["dwi_complete"] = len(dwi_files) > 0
80
+ if not dwi_files:
81
+ report["missing_files"].append("dwi/*_dwi.nii.gz")
82
+ else:
83
+ report["missing_files"].append("dwi/")
84
+
85
+ return report
86
+
87
+
88
+ def main() -> int:
89
+ parser = argparse.ArgumentParser(
90
+ description="Validate Cam-CAN BIDS structure."
91
+ )
92
+ parser.add_argument("--input", required=True, help="Path to Cam-CAN BIDS directory")
93
+ parser.add_argument("--output", required=True, help="Output path for validation CSV")
94
+ args = parser.parse_args()
95
+
96
+ input_dir = Path(args.input).resolve()
97
+ if not input_dir.exists():
98
+ print(f"Input directory not found: {input_dir}", file=sys.stderr)
99
+ return 1
100
+
101
+ # Find subjects
102
+ subjects = sorted([d for d in input_dir.glob("sub-*") if d.is_dir()])
103
+ print(f"Found {len(subjects)} subjects in {input_dir}")
104
+
105
+ if not subjects:
106
+ print("[ERROR] No subjects found.", file=sys.stderr)
107
+ return 1
108
+
109
+ # Validate each subject
110
+ results = []
111
+ for sub_dir in subjects:
112
+ report = validate_subject(sub_dir)
113
+ results.append(report)
114
+
115
+ # Write output
116
+ output_path = Path(args.output).resolve()
117
+ output_path.parent.mkdir(parents=True, exist_ok=True)
118
+
119
+ fieldnames = ["subject", "anat_complete", "func_complete", "meg_complete", "dwi_complete", "missing_files", "warnings"]
120
+ with open(output_path, "w", newline="", encoding="utf-8") as f:
121
+ writer = csv.DictWriter(f, fieldnames=fieldnames)
122
+ writer.writeheader()
123
+ for r in results:
124
+ r["missing_files"] = "; ".join(r["missing_files"])
125
+ r["warnings"] = "; ".join(r["warnings"])
126
+ writer.writerow(r)
127
+
128
+ # Summary
129
+ complete_subjects = sum(1 for r in results if r["anat_complete"] and r["func_complete"])
130
+ print(f"\nValidation Summary:")
131
+ print(f" Total subjects: {len(results)}")
132
+ print(f" Complete (anat+func): {complete_subjects}")
133
+ print(f" With MEG: {sum(1 for r in results if r['meg_complete'])}")
134
+ print(f" With DWI: {sum(1 for r in results if r['dwi_complete'])}")
135
+ print(f" Output: {output_path}")
136
+
137
+ return 0
138
+
139
+
140
+ if __name__ == "__main__":
141
+ sys.exit(main())
@@ -0,0 +1,201 @@
1
+ ---
2
+ name: cobre-skill
3
+ description: "Use this skill whenever the user wants an end-to-end workflow for the COBRE dataset, including download, BIDS organization, and processing of sMRI and rs-fMRI data for schizophrenia research. Triggers include: 'COBRE', 'process COBRE', 'COBRE schizophrenia', 'COBRE fMRI', or any request to run the COBRE pipeline. This is the NeuroClaw dataset-orchestration layer for COBRE."
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
+ # COBRE Skill (Dataset-Orchestration Layer)
14
+
15
+ ## Overview
16
+ `cobre-skill` is the NeuroClaw orchestration skill for the **COBRE (Center for Biomedical Research Excellence)** dataset.
17
+
18
+ COBRE contains 147 participants: 72 schizophrenia patients and 75 healthy controls, with T1w structural and rs-fMRI data. It is commonly used as a benchmark for brain disorder classification.
19
+
20
+ It coordinates a fixed three-phase workflow:
21
+ 1. Download COBRE 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` and `fmri-skill`.
24
+
25
+ It also provides **phenotype extraction** and **QC integration** paths:
26
+ - Extract COBRE phenotype data (diagnosis, demographics, handedness).
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
+ COBRE data is distributed through the **FCP/INDI** repository:
42
+ - Website: https://fcon_1000.projects.nitrc.org/indi/retro/cobre.html
43
+
44
+ ### Supported COBRE Data Packages
45
+ - **Imaging data**: T1w, rs-fMRI (NIfTI format)
46
+ - **Phenotype data**: CSV files with diagnosis, demographics, handedness
47
+ - **Participants**: 147 total (72 schizophrenia, 75 healthy controls)
48
+
49
+ ### Delegation Rules for Download
50
+ - Environment/setup checks: `dependency-planner` + `conda-env-manager`
51
+ - Download tool installation and execution: `claw-shell`
52
+ - Optional raw-data organization to BIDS-style staging: `bids-organizer`
53
+
54
+ ### Download Inputs to Confirm in Plan
55
+ - Subject list scope (full or custom subset)
56
+ - Whether to download raw data or preprocessed derivatives
57
+ - Destination directory with sufficient disk space
58
+
59
+ ---
60
+
61
+ ## Narrow Path: COBRE Raw NIfTI -> BIDS Staging
62
+
63
+ Use this path when the task only asks to reorganize raw COBRE NIfTI files into a BIDS-style dataset and does not require preprocessing or downstream analysis.
64
+
65
+ ### Expected narrow-path behavior
66
+ 1. Detect COBRE-style subject IDs (numeric) and normalize to BIDS labels such as `sub-NNNNN`.
67
+ 2. Route modalities:
68
+ - T1w -> `anat/*_T1w`
69
+ - rs-fMRI/BOLD -> `func/*_task-rest_bold`
70
+ 3. Preserve or rename matching JSON sidecars when available.
71
+ 4. Emit dataset-level outputs such as `dataset_description.json`, `participants.tsv`.
72
+
73
+ ---
74
+
75
+ ## Core Workflow (Never Bypassed)
76
+ 1. Identify user target: full COBRE download, imaging subset, phenotype extraction, or BIDS staging only.
77
+ 2. Generate a numbered plan with tools, outputs, runtime, storage, and risks.
78
+ 3. Wait for explicit confirmation (`YES` / `execute` / `proceed`).
79
+ 4. On confirmation, run download stage first (if needed).
80
+ 5. After download success, run BIDS preparation using `scripts/reorganize_cobre.py`.
81
+ 6. Delegate to modality skills:
82
+ - `smri-skill` for structural MRI (T1w)
83
+ - `fmri-skill` for resting-state fMRI (rs-fMRI)
84
+ 7. If phenotype extraction is requested, run `scripts/extract_cobre_phenotype.py`.
85
+ 8. If QC summary is requested, run `scripts/cobre_qc_summary.py`.
86
+ 9. Save outputs into a COBRE-centered structure under `cobre_output/`.
87
+
88
+ ---
89
+
90
+ ## BIDS Preparation
91
+
92
+ ### Script: `scripts/reorganize_cobre.py`
93
+
94
+ Converts COBRE raw directory structure to BIDS-compliant layout.
95
+
96
+ ```bash
97
+ python skills/cobre-skill/scripts/reorganize_cobre.py \
98
+ --input /path/to/cobre_raw \
99
+ --output /path/to/cobre_bids \
100
+ --phenotype /path/to/cobre_raw/phenotype/cobre_phenotypic.csv
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Phenotype Extraction
106
+
107
+ ### Script: `scripts/extract_cobre_phenotype.py`
108
+
109
+ ```bash
110
+ python skills/cobre-skill/scripts/extract_cobre_phenotype.py \
111
+ --phenotype-dir /path/to/cobre_raw/phenotype \
112
+ --output /path/to/cobre_output/phenotype/merged_phenotype.csv \
113
+ --imaging-ids /path/to/cobre_output/bids/participants.tsv
114
+ ```
115
+
116
+ ---
117
+
118
+ ## QC Integration
119
+
120
+ ### Script: `scripts/cobre_qc_summary.py`
121
+
122
+ ```bash
123
+ python skills/cobre-skill/scripts/cobre_qc_summary.py \
124
+ --fmriprep-dir /path/to/cobre_output/fmriprep \
125
+ --output /path/to/cobre_output/qc/qc_summary.csv \
126
+ --exclude-output /path/to/cobre_output/qc/exclude_list.csv \
127
+ --fd-threshold 0.3
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Recommended Output Layout
133
+ All assets should be organized under `./cobre_output/`:
134
+ - `cobre_output/raw/` (downloaded original COBRE files)
135
+ - `cobre_output/bids/` (staged BIDS data)
136
+ - `cobre_output/smri/` (links or copies from `smri_output/`)
137
+ - `cobre_output/fmri/` (links or copies from `fmri_output/`)
138
+ - `cobre_output/phenotype/` (merged phenotype tables)
139
+ - `cobre_output/qc/` (QC summaries and exclusion lists)
140
+ - `cobre_output/logs/` (download + orchestration logs)
141
+
142
+ ---
143
+
144
+ ## Benchmark Adapter Guidance
145
+
146
+ For benchmark-style prompts, do not force the full `download -> staging -> multimodal processing` orchestration when the task is only asking for local COBRE data staging or organization.
147
+
148
+ - If the task starts from raw COBRE data already present on disk and only asks for BIDS-style staging / organization:
149
+ - skip the mandatory download stage
150
+ - default to the narrow path `local raw COBRE discovery -> BIDS-style staging -> minimal metadata -> validation/report`
151
+ - In benchmark mode, do not require explicit confirmation before presenting the direct staging solution.
152
+
153
+ ---
154
+
155
+ ## Safety and Execution Policy
156
+ - No execution before explicit plan confirmation.
157
+ - All execution must be routed via `claw-shell`.
158
+ - Missing dependencies must be resolved by `dependency-planner` before running.
159
+
160
+ ---
161
+
162
+ ## Important Notes and Limitations
163
+ - COBRE is a single-site dataset from the University of New Mexico; no site effects to address.
164
+ - COBRE has a small sample size (147 subjects); cross-validation strategies should account for this.
165
+ - Diagnosis labels: schizophrenia (1) vs. healthy control (2).
166
+ - COBRE data does not include task-fMRI; only resting-state fMRI is available.
167
+ - `cobre-skill` is orchestration-only; detailed preprocessing logic remains in `smri-skill` and `fmri-skill`.
168
+
169
+ ---
170
+
171
+ ## When to Call This Skill
172
+ - User asks for end-to-end COBRE workflow.
173
+ - User asks to download COBRE data and then run sMRI/rs-fMRI processing.
174
+ - User needs BIDS staging for raw COBRE NIfTI files.
175
+ - User asks to extract COBRE phenotype data.
176
+ - User needs COBRE-specific QC summaries and exclusion lists.
177
+ - User wants to run schizophrenia classification with BrainGNN or other models on COBRE.
178
+
179
+ ---
180
+
181
+ ## Complementary / Related Skills
182
+ - `smri-skill`
183
+ - `fmri-skill`
184
+ - `bids-organizer`
185
+ - `fmriprep-tool`
186
+ - `freesurfer-tool`
187
+ - `brain_gnn`
188
+ - `neurostorm`
189
+ - `dependency-planner`
190
+ - `conda-env-manager`
191
+ - `claw-shell`
192
+
193
+ ---
194
+
195
+ ## Reference
196
+ - COBRE: https://fcon_1000.projects.nitrc.org/indi/retro/cobre.html
197
+ - BIDS spec: https://bids.neuroimaging.io/
198
+
199
+ Created At: 2026-05-06 01:54 HKT
200
+ Last Updated At: 2026-05-06 01:54 HKT
201
+ Author: chengwang96
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env python3
2
+ """Generate per-subject QC summaries and exclusion lists for COBRE."""
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 main() -> int:
44
+ parser = argparse.ArgumentParser(description="Generate COBRE QC summaries.")
45
+ parser.add_argument("--fmriprep-dir", help="Path to fMRIPrep output directory")
46
+ parser.add_argument("--output", required=True, help="Output path for QC summary CSV")
47
+ parser.add_argument("--exclude-output", help="Output path for exclusion list CSV")
48
+ parser.add_argument("--fd-threshold", type=float, default=0.3, help="Mean FD threshold (default: 0.3)")
49
+ parser.add_argument("--max-fd-threshold", type=float, default=5.0, help="Max FD threshold (default: 5.0)")
50
+ args = parser.parse_args()
51
+
52
+ fmriprep_qc = {}
53
+ if args.fmriprep_dir:
54
+ fp_dir = Path(args.fmriprep_dir).resolve()
55
+ if fp_dir.exists():
56
+ print(f"Collecting fMRIPrep QC from {fp_dir}...")
57
+ fmriprep_qc = collect_fmriprep_qc(fp_dir)
58
+ print(f" Found {len(fmriprep_qc)} subjects")
59
+
60
+ if not fmriprep_qc:
61
+ print("[ERROR] No QC data collected.", file=sys.stderr)
62
+ return 1
63
+
64
+ rows = []
65
+ excluded = []
66
+ for sub_id in sorted(fmriprep_qc.keys()):
67
+ fp = fmriprep_qc[sub_id]
68
+ reasons = []
69
+ if fp.get("mean_fd", 0) > args.fd_threshold:
70
+ reasons.append(f"mean_fd={fp['mean_fd']:.3f}>{args.fd_threshold}")
71
+ if fp.get("max_fd", 0) > args.max_fd_threshold:
72
+ reasons.append(f"max_fd={fp['max_fd']:.3f}>{args.max_fd_threshold}")
73
+ 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)}
74
+ if reasons:
75
+ excluded.append(sub_id)
76
+ rows.append(row)
77
+
78
+ summary_df = pd.DataFrame(rows)
79
+ output_path = Path(args.output).resolve()
80
+ output_path.parent.mkdir(parents=True, exist_ok=True)
81
+ summary_df.to_csv(output_path, index=False)
82
+ print(f"\nQC Summary: {len(summary_df)} subjects -> {output_path}")
83
+ print(f" Excluded: {len(excluded)} / {len(summary_df)} ({100*len(excluded)/max(len(summary_df),1):.1f}%)")
84
+
85
+ if args.exclude_output:
86
+ exclude_path = Path(args.exclude_output).resolve()
87
+ exclude_path.parent.mkdir(parents=True, exist_ok=True)
88
+ summary_df[summary_df["exclude"] == True][["subject_id", "exclude_reasons"]].to_csv(exclude_path, index=False)
89
+ print(f" Exclusion list: {exclude_path}")
90
+
91
+ return 0
92
+
93
+
94
+ if __name__ == "__main__":
95
+ sys.exit(main())
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env python3
2
+ """Extract and merge COBRE 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
+ "subject": "subject_id",
18
+ "SUBJECT_ID": "subject_id",
19
+ "Subject": "subject_id",
20
+ "DX": "diagnosis",
21
+ "DX_GROUP": "diagnosis",
22
+ "AGE": "age",
23
+ "SEX": "sex",
24
+ "HANDEDNESS": "handedness",
25
+ }
26
+
27
+
28
+ def normalize_subject_id(raw_id) -> str:
29
+ clean = re.sub(r"[^a-zA-Z0-9]", "", str(raw_id).strip())
30
+ return f"sub-{clean}"
31
+
32
+
33
+ def main() -> int:
34
+ parser = argparse.ArgumentParser(description="Extract COBRE phenotype data.")
35
+ parser.add_argument("--phenotype-dir", help="Directory containing COBRE phenotype CSV files")
36
+ parser.add_argument("--phenotype-file", help="Direct path to COBRE phenotype CSV file")
37
+ parser.add_argument("--output", required=True, help="Output path for phenotype CSV")
38
+ parser.add_argument("--imaging-ids", help="Path to BIDS participants.tsv for filtering")
39
+ args = parser.parse_args()
40
+
41
+ phenotype_files = []
42
+ if args.phenotype_file:
43
+ p = Path(args.phenotype_file).resolve()
44
+ if p.exists():
45
+ phenotype_files.append(p)
46
+ elif args.phenotype_dir:
47
+ phenotype_dir = Path(args.phenotype_dir).resolve()
48
+ if phenotype_dir.exists():
49
+ phenotype_files = sorted(f for f in phenotype_dir.iterdir() if f.is_file() and f.suffix in (".csv", ".tsv"))
50
+
51
+ if not phenotype_files:
52
+ print("[ERROR] No phenotype files found.", file=sys.stderr)
53
+ return 1
54
+
55
+ print(f"Found {len(phenotype_files)} phenotype file(s)")
56
+
57
+ dataframes = []
58
+ for f in phenotype_files:
59
+ try:
60
+ df = pd.read_csv(f, sep=None, engine="python", low_memory=False)
61
+ rename = {k: v for k, v in COLUMN_MAP.items() if k in df.columns and v not in df.columns}
62
+ df = df.rename(columns=rename)
63
+ dataframes.append(df)
64
+ except Exception as e:
65
+ print(f"[WARN] Failed to read {f}: {e}")
66
+
67
+ if not dataframes:
68
+ print("[ERROR] No data loaded.", file=sys.stderr)
69
+ return 1
70
+
71
+ merged = dataframes[0]
72
+ for df in dataframes[1:]:
73
+ if "subject_id" in merged.columns and "subject_id" in df.columns:
74
+ new_cols = [c for c in df.columns if c not in merged.columns or c == "subject_id"]
75
+ merged = pd.merge(merged, df[new_cols], on="subject_id", how="outer")
76
+ else:
77
+ merged = pd.concat([merged, df], ignore_index=True)
78
+
79
+ if args.imaging_ids:
80
+ imaging_path = Path(args.imaging_ids).resolve()
81
+ if imaging_path.exists() and "subject_id" in merged.columns:
82
+ id_df = pd.read_csv(imaging_path, sep="\t")
83
+ for col in ["participant_id", "subject_id"]:
84
+ if col in id_df.columns:
85
+ imaging_ids = set(id_df[col].astype(str).str.strip())
86
+ normalized = {normalize_subject_id(sid) for sid in imaging_ids} | imaging_ids
87
+ merged["_norm"] = merged["subject_id"].apply(normalize_subject_id)
88
+ merged = merged[merged["_norm"].isin(normalized) | merged["subject_id"].astype(str).isin(normalized)]
89
+ merged = merged.drop(columns=["_norm"])
90
+ break
91
+
92
+ output_path = Path(args.output).resolve()
93
+ output_path.parent.mkdir(parents=True, exist_ok=True)
94
+ merged.to_csv(output_path, index=False)
95
+ print(f"\nWrote {len(merged)} rows x {len(merged.columns)} columns to {output_path}")
96
+
97
+ if "diagnosis" in merged.columns:
98
+ print(f"\nDiagnosis distribution:\n{merged['diagnosis'].value_counts().to_string()}")
99
+
100
+ return 0
101
+
102
+
103
+ if __name__ == "__main__":
104
+ sys.exit(main())