@brainpilot/skills 0.0.6 → 0.0.8

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,183 @@
1
+ ---
2
+ name: dmt-har-med-skill
3
+ description: "Use this skill whenever the user wants an end-to-end workflow for the DMT-HAR-MED dataset (ds006644), including download, BIDS organization, and processing of rs-fMRI data from a psychedelic intervention study. Triggers include: 'DMT-HAR-MED', 'DMT HAR MED', 'ds006644', 'process DMT data', 'psychedelic fMRI', or any request to run the DMT-HAR-MED pipeline. This is the NeuroClaw dataset-orchestration layer for DMT-HAR-MED."
4
+ license: MIT License (NeuroClaw custom skill - freely modifiable within the project)
5
+ layer: subagent
6
+ skill_type: dataset
7
+ dependencies:
8
+ - fmri-skill
9
+ - bids-organizer
10
+ - claw-shell
11
+ ---
12
+ # DMT-HAR-MED Skill (Dataset-Orchestration Layer)
13
+
14
+ ## Overview
15
+ `dmt-har-med-skill` is the NeuroClaw orchestration skill for the **DMT-HAR-MED** dataset (OpenNeuro ds006644).
16
+
17
+ DMT-HAR-MED contains rs-fMRI data from 40 participants in a psychedelic intervention study investigating the effects of N,N-Dimethyltryptamine (DMT) on brain function. The dataset includes multiple experimental conditions (DMT, placebo) and behavioral/physiological measurements.
18
+
19
+ It coordinates a fixed three-phase workflow:
20
+ 1. Download DMT-HAR-MED data from OpenNeuro.
21
+ 2. Prepare and validate BIDS-style data organization.
22
+ 3. Delegate fMRI processing to `fmri-skill`.
23
+
24
+ It also provides **phenotype extraction** and **QC integration** paths:
25
+ - Extract DMT-HAR-MED phenotype data (intervention conditions, behavioral measures).
26
+ - Generate per-subject QC summaries with exclusion lists.
27
+
28
+ This skill follows NeuroClaw hierarchy:
29
+ - Defines **WHAT to do**, not low-level implementation details.
30
+ - Does **not** execute direct shell commands itself.
31
+ - Delegates all execution via `claw-shell` to base/tool skills.
32
+
33
+ **Research use only.**
34
+
35
+ ---
36
+
37
+ ## Download Stage (Mandatory First Step)
38
+
39
+ ### Source
40
+ DMT-HAR-MED data is available on OpenNeuro:
41
+ - Website: https://openneuro.org/datasets/ds006644/versions/1.0.1
42
+
43
+ ### Supported DMT-HAR-MED Data Packages
44
+ - **Imaging data**: rs-fMRI (NIfTI format)
45
+ - **Phenotype data**: intervention conditions, behavioral and physiological measurements
46
+ - **Participants**: 40 participants with psychedelic intervention
47
+
48
+ ### Delegation Rules for Download
49
+ - Environment/setup checks: `dependency-planner` + `conda-env-manager`
50
+ - OpenNeuro dataset download: `claw-shell` (via `openneuro` CLI or `datalad`)
51
+ - Optional raw-data organization to BIDS-style staging: `bids-organizer`
52
+
53
+ ### Download Inputs to Confirm in Plan
54
+ - Subject list scope (full or custom subset)
55
+ - Destination directory with sufficient disk space
56
+
57
+ ---
58
+
59
+ ## Core Workflow (Never Bypassed)
60
+ 1. Identify user target: download, BIDS staging, or full preprocessing.
61
+ 2. Generate a numbered plan with tools, outputs, runtime, storage, and risks.
62
+ 3. Wait for explicit confirmation (`YES` / `execute` / `proceed`).
63
+ 4. On confirmation, run download stage first (if needed).
64
+ 5. After download success, verify/prepare BIDS staging using `scripts/reorganize_dmt_har_med.py`.
65
+ 6. Delegate to `fmri-skill` for rs-fMRI processing.
66
+ 7. If phenotype extraction is requested, run `scripts/extract_dmt_har_med_phenotype.py`.
67
+ 8. If QC summary is requested, run `scripts/dmt_har_med_qc_summary.py`.
68
+ 9. Save outputs into a DMT-HAR-MED-centered structure under `dmt_har_med_output/`.
69
+
70
+ ---
71
+
72
+ ## BIDS Preparation
73
+
74
+ ### Script: `scripts/reorganize_dmt_har_med.py`
75
+
76
+ Verifies and optionally reorganizes DMT-HAR-MED data to BIDS-compliant layout.
77
+
78
+ ```bash
79
+ python skills/dmt-har-med-skill/scripts/reorganize_dmt_har_med.py \
80
+ --input /path/to/dmt_har_med_raw \
81
+ --output /path/to/dmt_har_med_bids
82
+ ```
83
+
84
+ Features:
85
+ - BIDS validation and verification
86
+ - Subject ID normalization
87
+ - Modality routing: rs-fMRI
88
+ - `dataset_description.json` and `participants.tsv` generation
89
+ - Dry-run mode: `--dry-run` to preview
90
+
91
+ ---
92
+
93
+ ## Phenotype Extraction
94
+
95
+ ### Script: `scripts/extract_dmt_har_med_phenotype.py`
96
+
97
+ ```bash
98
+ python skills/dmt-har-med-skill/scripts/extract_dmt_har_med_phenotype.py \
99
+ --phenotype-dir /path/to/dmt_har_med_raw/phenotype \
100
+ --output /path/to/dmt_har_med_output/phenotype/merged_phenotype.csv \
101
+ --imaging-ids /path/to/dmt_har_med_output/bids/participants.tsv
102
+ ```
103
+
104
+ ---
105
+
106
+ ## QC Integration
107
+
108
+ ### Script: `scripts/dmt_har_med_qc_summary.py`
109
+
110
+ ```bash
111
+ python skills/dmt-har-med-skill/scripts/dmt_har_med_qc_summary.py \
112
+ --fmriprep-dir /path/to/dmt_har_med_output/fmriprep \
113
+ --output /path/to/dmt_har_med_output/qc/qc_summary.csv \
114
+ --exclude-output /path/to/dmt_har_med_output/qc/exclude_list.csv \
115
+ --fd-threshold 0.3
116
+ ```
117
+
118
+ ---
119
+
120
+ ## Recommended Output Layout
121
+ All assets should be organized under `./dmt_har_med_output/`:
122
+ - `dmt_har_med_output/raw/` (downloaded original files)
123
+ - `dmt_har_med_output/bids/` (BIDS data)
124
+ - `dmt_har_med_output/fmri/` (links or copies from `fmri_output/`)
125
+ - `dmt_har_med_output/phenotype/` (merged phenotype tables)
126
+ - `dmt_har_med_output/qc/` (QC summaries and exclusion lists)
127
+ - `dmt_har_med_output/logs/` (download + orchestration logs)
128
+
129
+ ---
130
+
131
+ ## Benchmark Adapter Guidance
132
+
133
+ For benchmark-style prompts, do not force the full `download -> staging -> multimodal processing` orchestration when the task is only asking for local DMT-HAR-MED data staging or organization.
134
+
135
+ - If the task starts from raw DMT-HAR-MED data already present on disk and only asks for BIDS-style staging / validation:
136
+ - skip the mandatory download stage
137
+ - default to the narrow path `local raw DMT-HAR-MED discovery -> BIDS validation -> minimal metadata -> report`
138
+ - In benchmark mode, do not require explicit confirmation before presenting the direct staging solution.
139
+
140
+ ---
141
+
142
+ ## Safety and Execution Policy
143
+ - No execution before explicit plan confirmation.
144
+ - All execution must be routed via `claw-shell`.
145
+ - Missing dependencies must be resolved by `dependency-planner` before running.
146
+
147
+ ---
148
+
149
+ ## Important Notes and Limitations
150
+ - DMT-HAR-MED is a specialized psychedelic intervention dataset; analysis requires domain expertise.
151
+ - DMT-HAR-MED data from OpenNeuro is already in BIDS format; re-staging may not be needed.
152
+ - The dataset includes multiple experimental conditions; event files define condition timing.
153
+ - DMT-HAR-MED includes only rs-fMRI; no structural (T1w) or diffusion data is available.
154
+ - `dmt-har-med-skill` is orchestration-only; detailed preprocessing logic remains in `fmri-skill`.
155
+
156
+ ---
157
+
158
+ ## When to Call This Skill
159
+ - User asks for end-to-end DMT-HAR-MED workflow.
160
+ - User asks to download DMT-HAR-MED data and then run rs-fMRI processing.
161
+ - User needs BIDS validation for DMT-HAR-MED data.
162
+ - User asks to extract DMT-HAR-MED phenotype data.
163
+ - User needs DMT-HAR-MED-specific QC summaries.
164
+
165
+ ---
166
+
167
+ ## Complementary / Related Skills
168
+ - `fmri-skill`
169
+ - `bids-organizer`
170
+ - `fmriprep-tool`
171
+ - `dependency-planner`
172
+ - `conda-env-manager`
173
+ - `claw-shell`
174
+
175
+ ---
176
+
177
+ ## Reference
178
+ - DMT-HAR-MED: https://openneuro.org/datasets/ds006644/versions/1.0.1
179
+ - BIDS spec: https://bids.neuroimaging.io/
180
+
181
+ Created At: 2026-05-06 01:56 HKT
182
+ Last Updated At: 2026-05-06 01:56 HKT
183
+ Author: chengwang96
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env python3
2
+ """Generate per-subject QC summaries and exclusion lists for DMT-HAR-MED."""
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 DMT-HAR-MED 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,121 @@
1
+ #!/usr/bin/env python3
2
+ """Extract and merge DMT-HAR-MED phenotype data 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
+ "group": "condition",
21
+ "GROUP": "condition",
22
+ "condition": "condition",
23
+ "age": "age",
24
+ "AGE": "age",
25
+ "sex": "sex",
26
+ "SEX": "sex",
27
+ "gender": "sex",
28
+ "session": "session",
29
+ "SESSION": "session",
30
+ "visit": "session",
31
+ }
32
+
33
+ CONDITION_LABELS = {
34
+ "DMT": "dmt",
35
+ "dmt": "dmt",
36
+ "placebo": "placebo",
37
+ "Placebo": "placebo",
38
+ "control": "placebo",
39
+ "Control": "placebo",
40
+ }
41
+
42
+
43
+ def normalize_subject_id(raw_id) -> str:
44
+ clean = re.sub(r"[^a-zA-Z0-9]", "", str(raw_id).strip())
45
+ return f"sub-{clean}"
46
+
47
+
48
+ def main() -> int:
49
+ parser = argparse.ArgumentParser(description="Extract DMT-HAR-MED phenotype data.")
50
+ parser.add_argument("--phenotype-dir", help="Directory containing phenotype CSV/TSV files")
51
+ parser.add_argument("--phenotype-file", help="Direct path to phenotype CSV/TSV file")
52
+ parser.add_argument("--output", required=True, help="Output path for phenotype CSV")
53
+ parser.add_argument("--imaging-ids", help="Path to BIDS participants.tsv for filtering")
54
+ args = parser.parse_args()
55
+
56
+ phenotype_files = []
57
+ if args.phenotype_file:
58
+ p = Path(args.phenotype_file).resolve()
59
+ if p.exists():
60
+ phenotype_files.append(p)
61
+ elif args.phenotype_dir:
62
+ phenotype_dir = Path(args.phenotype_dir).resolve()
63
+ if phenotype_dir.exists():
64
+ phenotype_files = sorted(f for f in phenotype_dir.iterdir() if f.is_file() and f.suffix in (".csv", ".tsv"))
65
+
66
+ if not phenotype_files:
67
+ print("[ERROR] No phenotype files found.", file=sys.stderr)
68
+ return 1
69
+
70
+ print(f"Found {len(phenotype_files)} phenotype file(s)")
71
+
72
+ dataframes = []
73
+ for f in phenotype_files:
74
+ try:
75
+ df = pd.read_csv(f, sep=None, engine="python", low_memory=False)
76
+ rename = {k: v for k, v in COLUMN_MAP.items() if k in df.columns and v not in df.columns}
77
+ df = df.rename(columns=rename)
78
+ if "condition" in df.columns:
79
+ df["condition"] = df["condition"].map(lambda x: CONDITION_LABELS.get(str(x), str(x).lower()))
80
+ dataframes.append(df)
81
+ except Exception as e:
82
+ print(f"[WARN] Failed to read {f}: {e}")
83
+
84
+ if not dataframes:
85
+ print("[ERROR] No data loaded.", file=sys.stderr)
86
+ return 1
87
+
88
+ merged = dataframes[0]
89
+ for df in dataframes[1:]:
90
+ if "subject_id" in merged.columns and "subject_id" in df.columns:
91
+ new_cols = [c for c in df.columns if c not in merged.columns or c == "subject_id"]
92
+ merged = pd.merge(merged, df[new_cols], on="subject_id", how="outer")
93
+ else:
94
+ merged = pd.concat([merged, df], ignore_index=True)
95
+
96
+ if args.imaging_ids:
97
+ imaging_path = Path(args.imaging_ids).resolve()
98
+ if imaging_path.exists() and "subject_id" in merged.columns:
99
+ id_df = pd.read_csv(imaging_path, sep="\t")
100
+ for col in ["participant_id", "subject_id"]:
101
+ if col in id_df.columns:
102
+ imaging_ids = set(id_df[col].astype(str).str.strip())
103
+ normalized = {normalize_subject_id(sid) for sid in imaging_ids} | imaging_ids
104
+ merged["_norm"] = merged["subject_id"].apply(normalize_subject_id)
105
+ merged = merged[merged["_norm"].isin(normalized) | merged["subject_id"].astype(str).isin(normalized)]
106
+ merged = merged.drop(columns=["_norm"])
107
+ break
108
+
109
+ output_path = Path(args.output).resolve()
110
+ output_path.parent.mkdir(parents=True, exist_ok=True)
111
+ merged.to_csv(output_path, index=False)
112
+ print(f"\nWrote {len(merged)} rows x {len(merged.columns)} columns to {output_path}")
113
+
114
+ if "condition" in merged.columns:
115
+ print(f"\nCondition distribution:\n{merged['condition'].value_counts().to_string()}")
116
+
117
+ return 0
118
+
119
+
120
+ if __name__ == "__main__":
121
+ sys.exit(main())
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env python3
2
+ """Validate and optionally reorganize DMT-HAR-MED OpenNeuro BIDS data."""
3
+ import argparse
4
+ import json
5
+ import shutil
6
+ import sys
7
+ from pathlib import Path
8
+ from typing import Dict, List, Optional
9
+
10
+ BIDS_MODALITIES = {"T1w": "anat", "T2w": "anat", "FLAIR": "anat",
11
+ "task-rest_bold": "func", "task-*_bold": "func",
12
+ "dwi": "dwi", "bold": "func"}
13
+
14
+
15
+ def validate_bids(bids_root: Path) -> Dict[str, List[str]]:
16
+ """Validate BIDS structure and return report."""
17
+ issues: Dict[str, List[str]] = {"errors": [], "warnings": []}
18
+ if not (bids_root / "dataset_description.json").exists():
19
+ issues["errors"].append("Missing dataset_description.json")
20
+ participants_tsv = bids_root / "participants.tsv"
21
+ if not participants_tsv.exists():
22
+ issues["warnings"].append("Missing participants.tsv")
23
+ subject_dirs = sorted(d for d in bids_root.iterdir() if d.is_dir() and d.name.startswith("sub-"))
24
+ if not subject_dirs:
25
+ issues["errors"].append("No subject directories found")
26
+ for sub_dir in subject_dirs:
27
+ session_dirs = [d for d in sub_dir.iterdir() if d.is_dir() and d.name.startswith("ses-")]
28
+ if not session_dirs:
29
+ session_dirs = [sub_dir]
30
+ for ses_dir in session_dirs:
31
+ func_dir = ses_dir / "func"
32
+ anat_dir = ses_dir / "anat"
33
+ if not func_dir.exists() and not anat_dir.exists():
34
+ issues["warnings"].append(f"{sub_dir.name}/{ses_dir.name}: no func/ or anat/ directory")
35
+ return issues
36
+
37
+
38
+ def collect_nifti_manifest(bids_root: Path) -> List[Dict[str, str]]:
39
+ """Collect all NIfTI files in BIDS directory."""
40
+ manifest = []
41
+ for nifti in sorted(bids_root.rglob("*.nii.gz")):
42
+ rel = nifti.relative_to(bids_root)
43
+ parts = rel.parts
44
+ subject = next((p for p in parts if p.startswith("sub-")), "unknown")
45
+ session = next((p for p in parts if p.startswith("ses-")), "")
46
+ modality_dir = next((p for p in parts if p in ("anat", "func", "dwi", "fmap")), "unknown")
47
+ manifest.append({
48
+ "subject": subject,
49
+ "session": session,
50
+ "modality": modality_dir,
51
+ "filename": nifti.name,
52
+ "path": str(rel),
53
+ })
54
+ return manifest
55
+
56
+
57
+ def copy_to_output(bids_root: Path, output_dir: Path, manifest: List[Dict[str, str]]) -> int:
58
+ """Copy BIDS files to output directory."""
59
+ output_dir.mkdir(parents=True, exist_ok=True)
60
+ copied = 0
61
+ for entry in manifest:
62
+ src = bids_root / entry["path"]
63
+ dst = output_dir / entry["path"]
64
+ dst.parent.mkdir(parents=True, exist_ok=True)
65
+ if not dst.exists():
66
+ shutil.copy2(str(src), str(dst))
67
+ copied += 1
68
+ return copied
69
+
70
+
71
+ def main() -> int:
72
+ parser = argparse.ArgumentParser(description="Validate/reorganize DMT-HAR-MED BIDS data.")
73
+ parser.add_argument("--input", required=True, help="Path to DMT-HAR-MED BIDS directory")
74
+ parser.add_argument("--output", help="Output path for reorganized BIDS directory")
75
+ parser.add_argument("--validate-only", action="store_true", help="Only validate, don't copy")
76
+ parser.add_argument("--manifest-output", help="Output path for NIfTI manifest TSV")
77
+ args = parser.parse_args()
78
+
79
+ input_dir = Path(args.input).resolve()
80
+ if not input_dir.exists():
81
+ print(f"Input directory not found: {input_dir}", file=sys.stderr)
82
+ return 1
83
+
84
+ print(f"Validating BIDS structure at {input_dir}...")
85
+ issues = validate_bids(input_dir)
86
+
87
+ if issues["errors"]:
88
+ print(f"\n[ERRORS] ({len(issues['errors'])}):")
89
+ for e in issues["errors"]:
90
+ print(f" - {e}")
91
+ if issues["warnings"]:
92
+ print(f"\n[WARNINGS] ({len(issues['warnings'])}):")
93
+ for w in issues["warnings"]:
94
+ print(f" - {w}")
95
+ if not issues["errors"] and not issues["warnings"]:
96
+ print(" BIDS structure looks valid.")
97
+
98
+ manifest = collect_nifti_manifest(input_dir)
99
+ print(f"\nFound {len(manifest)} NIfTI files")
100
+
101
+ subjects = set(e["subject"] for e in manifest)
102
+ modalities = set(e["modality"] for e in manifest)
103
+ print(f" Subjects: {len(subjects)}")
104
+ print(f" Modalities: {', '.join(sorted(modalities))}")
105
+
106
+ if args.manifest_output:
107
+ import csv
108
+ manifest_path = Path(args.manifest_output).resolve()
109
+ manifest_path.parent.mkdir(parents=True, exist_ok=True)
110
+ with open(manifest_path, "w", encoding="utf-8", newline="") as f:
111
+ writer = csv.DictWriter(f, fieldnames=manifest[0].keys(), delimiter="\t")
112
+ writer.writeheader()
113
+ writer.writerows(manifest)
114
+ print(f" Manifest: {manifest_path}")
115
+
116
+ if not args.validate_only and args.output:
117
+ output_dir = Path(args.output).resolve()
118
+ copied = copy_to_output(input_dir, output_dir, manifest)
119
+ print(f"\nCopied {copied} files to {output_dir}")
120
+
121
+ return 0
122
+
123
+
124
+ if __name__ == "__main__":
125
+ sys.exit(main())