@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,205 @@
1
+ ---
2
+ name: nifd-skill
3
+ description: "Use this skill whenever the user wants an end-to-end workflow for the Neuroimaging in Frontotemporal Dementia (NIFD) dataset, including BIDS validation, multimodal processing of sMRI, rs-fMRI, and dMRI, phenotype extraction, and QC integration. Triggers include: 'NIFD', 'frontotemporal dementia', 'FTD', 'bvFTD', 'PPA', 'process NIFD data', or any request to run the NIFD multimodal pipeline."
4
+ license: MIT License (NeuroClaw custom skill - freely modifiable within the project)
5
+ layer: subagent
6
+ skill_type: dataset
7
+ dependencies:
8
+ - smri-skill
9
+ - fmri-skill
10
+ - dwi-skill
11
+ - bids-organizer
12
+ - claw-shell
13
+ complementary_skills:
14
+ - brain-visualization
15
+ - pet-skill
16
+ ---
17
+ # NIFD Skill (Dataset-Orchestration Layer)
18
+
19
+ ## Overview
20
+
21
+ `nifd-skill` is the NeuroClaw orchestration skill for the **Neuroimaging in Frontotemporal Dementia (NIFD)** dataset, collected at the UCSF Memory and Aging Center.
22
+
23
+ It strictly follows the NeuroClaw hierarchical design principles:
24
+ - This skill **only describes WHAT needs to be done** and **which tool skill to delegate to**.
25
+ - It contains **no implementation code or concrete commands**.
26
+ - All concrete execution is delegated to existing base/tool skills via `claw-shell`.
27
+ - Companion scripts in `scripts/` provide reference implementations for BIDS validation, phenotype extraction, and QC.
28
+
29
+ **Core workflow (never bypassed):**
30
+ 1. Identify input NIFD data and target modalities.
31
+ 2. Generate a **numbered execution plan** clearly stating WHAT needs to be done and which tool skill will handle each step.
32
+ 3. Present the full plan, estimated runtime, resource requirements, and risks to the user and wait for explicit confirmation ("YES" / "execute" / "proceed").
33
+ 4. On confirmation, delegate every step to the appropriate skill via `claw-shell`.
34
+ 5. After execution, save all outputs in a clean directory structure (`nifd_output/`).
35
+
36
+ **Research use only.**
37
+
38
+ ---
39
+
40
+ ## Quick Reference
41
+
42
+ | Task | What needs to be done | Delegate to | Expected output |
43
+ |---|---|---|---|
44
+ | BIDS validation | Validate NIFD BIDS structure | `scripts/validate_nifd.py` | Validation report |
45
+ | sMRI processing | Brain extraction, tissue segmentation, cortical thickness | `smri-skill` | `smri_output/` derivatives |
46
+ | rs-fMRI processing | Preprocessing, denoising, connectivity | `fmri-skill` | `fmri_output/` connectivity |
47
+ | dMRI processing | Diffusion preprocessing, tensor metrics, tractography | `dwi-skill` | `dwi_output/` metrics |
48
+ | Phenotype extraction | Diagnosis, cognitive scores, clinical measures | `scripts/extract_nifd_phenotype.py` | Merged phenotype CSV |
49
+ | QC summary | Per-subject quality control | `scripts/nifd_qc_summary.py` | QC summary + exclusion list |
50
+
51
+ ---
52
+
53
+ ## Dataset Characteristics
54
+
55
+ - **Cohort**: ~120 participants
56
+ - **bvFTD**: Behavioral variant frontotemporal dementia
57
+ - **svPPA**: Semantic variant primary progressive aphasia
58
+ - **nfvPPA**: Nonfluent variant primary progressive aphasia
59
+ - **Healthy controls**: Age-matched
60
+ - **Scanner**: 3T Siemens TIM Trio
61
+ - **Modalities**: T1w sMRI, rs-fMRI, dMRI/DTI
62
+ - **Clinical**: CDR, MMSE, neuropsychological battery
63
+ - **Access**: OpenNeuro ds004403 (or UCSF MAC portal)
64
+ - **Format**: BIDS-compliant
65
+
66
+ ---
67
+
68
+ ## Supported Modalities
69
+
70
+ | Modality | Description | Details |
71
+ |---|---|---|
72
+ | T1w | High-resolution structural MRI | 1mm isotropic, cortical thickness/atrophy |
73
+ | rs-fMRI | Resting-state functional MRI | Functional connectivity, network degeneration |
74
+ | dMRI | Diffusion-weighted imaging | DTI, white matter tract integrity |
75
+
76
+ ---
77
+
78
+ ## NIFD Diagnostic Groups
79
+
80
+ | Group | Description | Typical N |
81
+ |---|---|---|
82
+ | bvFTD | Behavioral variant FTD | ~40 |
83
+ | svPPA | Semantic variant PPA | ~20 |
84
+ | nfvPPA | Nonfluent variant PPA | ~15 |
85
+ | Control | Healthy age-matched controls | ~45 |
86
+
87
+ ---
88
+
89
+ ## BIDS Preparation
90
+
91
+ ### Script: `scripts/validate_nifd.py`
92
+
93
+ Validates NIFD BIDS structure and generates a compliance report.
94
+
95
+ ```bash
96
+ python skills/nifd-skill/scripts/validate_nifd.py \
97
+ --input /path/to/NIFD/bids \
98
+ --output /path/to/nifd_output/qc/bids_validation.csv
99
+ ```
100
+
101
+ Features:
102
+ - BIDS directory structure validation
103
+ - Diagnostic group completeness check
104
+ - Modality completeness (T1w, rs-fMRI, dMRI)
105
+ - Missing data identification
106
+
107
+ ---
108
+
109
+ ## Core Workflow (Never Bypassed)
110
+
111
+ 1. Identify user target: full NIFD processing, imaging subset, phenotype extraction, or BIDS validation only.
112
+ 2. Generate a numbered plan with tools, outputs, runtime, storage, and risks.
113
+ 3. Wait for explicit confirmation (`YES` / `execute` / `proceed`).
114
+ 4. On confirmation, run BIDS validation using `scripts/validate_nifd.py`.
115
+ 5. Delegate to `smri-skill` for structural MRI processing.
116
+ 6. Delegate to `fmri-skill` for rs-fMRI processing (functional connectivity).
117
+ 7. Delegate to `dwi-skill` for dMRI processing (white matter integrity).
118
+ 8. If phenotype extraction is requested, run `scripts/extract_nifd_phenotype.py`.
119
+ 9. If QC summary is requested, run `scripts/nifd_qc_summary.py`.
120
+ 10. Save outputs into `nifd_output/`.
121
+
122
+ ---
123
+
124
+ ## Modality Processing Delegation
125
+
126
+ | Modality | Delegated skill | Typical tasks | Main outputs |
127
+ |---|---|---|---|
128
+ | sMRI (T1w) | `smri-skill` | brain extraction, tissue segmentation, cortical thickness | `smri_output/` derivatives |
129
+ | rs-fMRI | `fmri-skill` | preprocessing, denoising, connectivity | `fmri_output/` connectivity |
130
+ | dMRI | `dwi-skill` | diffusion preprocessing, tensor metrics, tractography | `dwi_output/` metrics |
131
+
132
+ ---
133
+
134
+ ## Standard Output Layout
135
+
136
+ ```
137
+ nifd_output/
138
+ ├── bids/ # BIDS-staged data (or validation report)
139
+ ├── smri/ # Structural MRI derivatives
140
+ ├── fmri/ # Functional MRI derivatives (rs-fMRI connectivity)
141
+ ├── dwi/ # Diffusion MRI derivatives (DTI metrics)
142
+ ├── phenotype/ # Merged phenotype tables (diagnosis, cognitive)
143
+ ├── qc/ # QC summaries and exclusion lists
144
+ └── logs/ # Processing logs
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Benchmark Adapter Guidance
150
+
151
+ For benchmark-style prompts, do not force the full orchestration when the task only asks for local NIFD data validation.
152
+
153
+ - If the task starts from NIFD data already present on disk and only asks for BIDS validation:
154
+ - Skip the download stage
155
+ - Default to the narrow path `local NIFD discovery -> BIDS validation -> report`
156
+ - In benchmark mode, do not require explicit confirmation before presenting the validation solution.
157
+
158
+ ---
159
+
160
+ ## Safety and Execution Policy
161
+ - No execution before explicit plan confirmation.
162
+ - All execution must be routed via `claw-shell`.
163
+ - Missing dependencies must be resolved by `dependency-planner` before running.
164
+
165
+ ---
166
+
167
+ ## Important Notes and Limitations
168
+ - NIFD is a clinical cohort; patient data requires careful handling.
169
+ - Diagnostic groups (bvFTD, svPPA, nfvPPA) have distinct atrophy patterns; group-level analyses should account for heterogeneity.
170
+ - Cortical thickness and voxel-based morphometry are commonly used structural measures.
171
+ - Network degeneration hypothesis: FTD targets specific large-scale networks.
172
+ - `nifd-skill` is orchestration-only; detailed preprocessing logic remains in modality skills.
173
+
174
+ ---
175
+
176
+ ## When to Call This Skill
177
+ - User asks for end-to-end NIFD workflow.
178
+ - User asks to process NIFD neuroimaging data.
179
+ - User needs BIDS validation for NIFD data.
180
+ - User asks to extract NIFD phenotype data (diagnosis, cognitive scores).
181
+ - User asks for frontotemporal dementia neuroimaging analysis.
182
+
183
+ ---
184
+
185
+ ## Complementary / Related Skills
186
+ - `smri-skill` → structural MRI preprocessing
187
+ - `fmri-skill` → functional MRI preprocessing and analysis
188
+ - `dwi-skill` → diffusion MRI preprocessing
189
+ - `pet-skill` → PET imaging (tau-PET, amyloid-PET if available)
190
+ - `bids-organizer` → BIDS validation and organization
191
+ - `brain-visualization` → visualization of derivatives
192
+ - `dependency-planner` → dependency resolution
193
+ - `conda-env-manager` → environment management
194
+ - `claw-shell` → command execution
195
+
196
+ ---
197
+
198
+ ## Reference
199
+ - NIFD: UCSF Memory and Aging Center
200
+ - Frontotemporal Dementia: FTDC clinical diagnostic criteria
201
+ - OpenNeuro ds004403
202
+
203
+ Created At: 2026-05-06 13:55 HKT
204
+ Last Updated At: 2026-05-06 13:55 HKT
205
+ Author: chengwang96
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env python3
2
+ """Extract and merge NIFD phenotype data.
3
+
4
+ Reads NIFD phenotype files (diagnosis, cognitive scores)
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_MAP = {
14
+ "subject_id": ["subject", "Subject", "participant_id", "SubID", "PTID"],
15
+ "age": ["age", "Age"],
16
+ "sex": ["sex", "Sex", "Gender"],
17
+ "diagnosis": ["diagnosis", "Diagnosis", "Group", "DX"],
18
+ "diagnosis_detail": ["diagnosis_detail", "Diagnosis_Detail", "DX_detail"],
19
+ "cdr": ["CDR", "cdr"],
20
+ "cdr_sb": ["CDRSB", "cdr_sb"],
21
+ "mmse": ["MMSE", "mmse"],
22
+ "gds": ["GDS", "gds"],
23
+ "fas": ["FAS", "fas"],
24
+ "category_fluency": ["CategoryFluency", "category_fluency"],
25
+ "boston_naming": ["BostonNaming", "boston_naming"],
26
+ "trail_a": ["TrailA", "trail_a"],
27
+ "trail_b": ["TrailB", "trail_b"],
28
+ "digit_span": ["DigitSpan", "digit_span"],
29
+ }
30
+
31
+
32
+ def load_csv(path: Path) -> List[Dict[str, str]]:
33
+ delimiter = "\t" if path.suffix == ".tsv" else ","
34
+ with open(path, "r", encoding="utf-8") as f:
35
+ reader = csv.DictReader(f, delimiter=delimiter)
36
+ return list(reader)
37
+
38
+
39
+ def find_column(row: Dict[str, str], candidates: List[str]) -> Optional[str]:
40
+ for col in candidates:
41
+ if col in row:
42
+ return col
43
+ return None
44
+
45
+
46
+ def extract_phenotype(
47
+ phenotype_files: List[Path],
48
+ imaging_ids: Optional[List[str]] = None,
49
+ columns: Optional[List[str]] = None,
50
+ ) -> List[Dict[str, str]]:
51
+ all_data = []
52
+ for fpath in phenotype_files:
53
+ rows = load_csv(fpath)
54
+ all_data.extend(rows)
55
+
56
+ if not all_data:
57
+ return []
58
+
59
+ target_columns = columns if columns else list(COLUMN_MAP.keys())
60
+ merged = {}
61
+
62
+ for row in all_data:
63
+ subj_col = find_column(row, COLUMN_MAP["subject_id"])
64
+ if subj_col is None:
65
+ continue
66
+ subj_id = row[subj_col].strip()
67
+ if not subj_id:
68
+ continue
69
+
70
+ if subj_id not in merged:
71
+ merged[subj_id] = {"subject_id": subj_id}
72
+
73
+ for target_col in target_columns:
74
+ if target_col == "subject_id":
75
+ continue
76
+ if target_col in merged[subj_id] and merged[subj_id][target_col]:
77
+ continue
78
+ candidates = COLUMN_MAP.get(target_col, [target_col])
79
+ src_col = find_column(row, candidates)
80
+ if src_col and row.get(src_col, "").strip():
81
+ merged[subj_id][target_col] = row[src_col].strip()
82
+
83
+ result = list(merged.values())
84
+ if imaging_ids:
85
+ imaging_set = set(imaging_ids)
86
+ result = [r for r in result if r["subject_id"] in imaging_set]
87
+ return result
88
+
89
+
90
+ def main() -> int:
91
+ parser = argparse.ArgumentParser(description="Extract NIFD phenotype data.")
92
+ parser.add_argument("--phenotype-files", required=True, nargs="+")
93
+ parser.add_argument("--output", required=True)
94
+ parser.add_argument("--imaging-ids")
95
+ parser.add_argument("--columns")
96
+ args = parser.parse_args()
97
+
98
+ phenotype_files = [Path(f).resolve() for f in args.phenotype_files]
99
+ for f in phenotype_files:
100
+ if not f.exists():
101
+ print(f"File not found: {f}", file=sys.stderr)
102
+ return 1
103
+
104
+ imaging_ids = None
105
+ if args.imaging_ids:
106
+ id_file = Path(args.imaging_ids).resolve()
107
+ if id_file.exists():
108
+ imaging_ids = [l.strip() for l in id_file.read_text().splitlines() if l.strip()]
109
+
110
+ columns = None
111
+ if args.columns:
112
+ columns = [c.strip() for c in args.columns.split(",")]
113
+
114
+ merged = extract_phenotype(phenotype_files, imaging_ids, columns)
115
+ if not merged:
116
+ print("[ERROR] No phenotype data extracted.", file=sys.stderr)
117
+ return 1
118
+
119
+ output_path = Path(args.output).resolve()
120
+ output_path.parent.mkdir(parents=True, exist_ok=True)
121
+ fieldnames = list(merged[0].keys())
122
+ with open(output_path, "w", newline="", encoding="utf-8") as f:
123
+ writer = csv.DictWriter(f, fieldnames=fieldnames)
124
+ writer.writeheader()
125
+ writer.writerows(merged)
126
+
127
+ print(f"Phenotype: {len(merged)} subjects, {len(fieldnames)} columns -> {output_path}")
128
+ return 0
129
+
130
+
131
+ if __name__ == "__main__":
132
+ sys.exit(main())
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env python3
2
+ """Generate per-subject QC summaries for NIFD processing.
3
+
4
+ Clinical-specific: tracks diagnostic group and applies appropriate QC criteria.
5
+ """
6
+ import argparse
7
+ import csv
8
+ import sys
9
+ from pathlib import Path
10
+ from typing import Dict, List
11
+
12
+
13
+ def load_confounds(confounds_path: Path) -> Dict[str, float]:
14
+ metrics = {"fd_mean": float("nan"), "fd_max": float("nan")}
15
+ try:
16
+ import pandas as pd
17
+ df = pd.read_csv(confounds_path, sep="\t")
18
+ if "framewise_displacement" in df.columns:
19
+ fd = df["framewise_displacement"].dropna()
20
+ metrics["fd_mean"] = float(fd.mean())
21
+ metrics["fd_max"] = float(fd.max())
22
+ except Exception:
23
+ pass
24
+ return metrics
25
+
26
+
27
+ def check_exclusion(metrics: Dict[str, float], fd_threshold: float = 0.3) -> List[str]:
28
+ reasons = []
29
+ if not (metrics["fd_mean"] != metrics["fd_mean"]):
30
+ if metrics["fd_mean"] > fd_threshold:
31
+ reasons.append(f"FD mean {metrics['fd_mean']:.3f} > {fd_threshold}")
32
+ return reasons
33
+
34
+
35
+ def main() -> int:
36
+ parser = argparse.ArgumentParser(description="Generate QC summaries for NIFD processing.")
37
+ parser.add_argument("--fmriprep-dir", help="Path to fMRIPrep output directory")
38
+ parser.add_argument("--output", required=True)
39
+ parser.add_argument("--exclude-output")
40
+ parser.add_argument("--fd-threshold", type=float, default=0.3)
41
+ parser.add_argument("--diagnosis-file", help="CSV with subject diagnosis info")
42
+ args = parser.parse_args()
43
+
44
+ output_path = Path(args.output).resolve()
45
+ output_path.parent.mkdir(parents=True, exist_ok=True)
46
+
47
+ diagnosis_map = {}
48
+ if args.diagnosis_file:
49
+ diag_path = Path(args.diagnosis_file).resolve()
50
+ if diag_path.exists():
51
+ with open(diag_path, "r", encoding="utf-8") as f:
52
+ reader = csv.DictReader(f)
53
+ for row in reader:
54
+ subj = row.get("subject_id") or row.get("Subject", "")
55
+ diag = row.get("diagnosis") or row.get("Diagnosis") or row.get("Group", "")
56
+ if subj and diag:
57
+ diagnosis_map[subj] = diag
58
+
59
+ subjects = set()
60
+ if args.fmriprep_dir:
61
+ fmriprep_dir = Path(args.fmriprep_dir).resolve()
62
+ if fmriprep_dir.exists():
63
+ for d in fmriprep_dir.glob("sub-*"):
64
+ if d.is_dir():
65
+ subjects.add(d.name)
66
+
67
+ if not subjects:
68
+ print("[WARN] No subjects found.", file=sys.stderr)
69
+ return 1
70
+
71
+ results = []
72
+ excluded = []
73
+ for subj in sorted(subjects):
74
+ metrics = {"subject_id": subj}
75
+ if diagnosis_map:
76
+ metrics["diagnosis"] = diagnosis_map.get(subj, "unknown")
77
+
78
+ if args.fmriprep_dir:
79
+ confounds_files = list(Path(args.fmriprep_dir).glob(f"{subj}/func/*_desc-confounds_timeseries.tsv"))
80
+ if confounds_files:
81
+ metrics.update(load_confounds(confounds_files[0]))
82
+
83
+ exclusion_reasons = check_exclusion(metrics, args.fd_threshold)
84
+ metrics["excluded"] = len(exclusion_reasons) > 0
85
+ metrics["exclusion_reasons"] = "; ".join(exclusion_reasons)
86
+
87
+ results.append(metrics)
88
+ if exclusion_reasons:
89
+ excluded.append({"subject_id": subj, "reasons": "; ".join(exclusion_reasons)})
90
+
91
+ if results:
92
+ fieldnames = list(results[0].keys())
93
+ with open(output_path, "w", newline="", encoding="utf-8") as f:
94
+ writer = csv.DictWriter(f, fieldnames=fieldnames)
95
+ writer.writeheader()
96
+ writer.writerows(results)
97
+ print(f"QC: {len(results)} subjects, {len(excluded)} excluded -> {output_path}")
98
+
99
+ if args.exclude_output and excluded:
100
+ exclude_path = Path(args.exclude_output).resolve()
101
+ exclude_path.parent.mkdir(parents=True, exist_ok=True)
102
+ with open(exclude_path, "w", newline="", encoding="utf-8") as f:
103
+ writer = csv.DictWriter(f, fieldnames=["subject_id", "reasons"])
104
+ writer.writeheader()
105
+ writer.writerows(excluded)
106
+
107
+ return 0
108
+
109
+
110
+ if __name__ == "__main__":
111
+ sys.exit(main())
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env python3
2
+ """Validate NIFD BIDS structure and generate compliance report.
3
+
4
+ Checks directory structure, diagnostic group completeness, and modality presence.
5
+ """
6
+ import argparse
7
+ import csv
8
+ import sys
9
+ from pathlib import Path
10
+ from typing import Dict, List
11
+
12
+ EXPECTED_MODALITIES = {
13
+ "anat": ["T1w"],
14
+ "func": ["task-rest_bold"],
15
+ "dwi": ["dwi"],
16
+ }
17
+
18
+
19
+ def validate_subject(subject_dir: Path) -> Dict[str, any]:
20
+ """Validate a single subject's NIFD BIDS structure."""
21
+ report = {
22
+ "subject": subject_dir.name,
23
+ "anat_complete": False,
24
+ "rs_fMRI_present": False,
25
+ "dwi_present": False,
26
+ "missing_files": [],
27
+ "warnings": [],
28
+ }
29
+
30
+ # Check anat
31
+ anat_dir = subject_dir / "anat"
32
+ if anat_dir.exists():
33
+ t1w_files = list(anat_dir.glob("*_T1w.nii.gz"))
34
+ report["anat_complete"] = len(t1w_files) > 0
35
+ if not t1w_files:
36
+ report["missing_files"].append("anat/*_T1w.nii.gz")
37
+ else:
38
+ report["missing_files"].append("anat/")
39
+
40
+ # Check func
41
+ func_dir = subject_dir / "func"
42
+ if func_dir.exists():
43
+ rest_bold = list(func_dir.glob("*_task-rest_bold.nii.gz"))
44
+ report["rs_fMRI_present"] = len(rest_bold) > 0
45
+ if not rest_bold:
46
+ report["missing_files"].append("func/*_task-rest_bold.nii.gz")
47
+ else:
48
+ report["warnings"].append("No func directory")
49
+
50
+ # Check dwi
51
+ dwi_dir = subject_dir / "dwi"
52
+ if dwi_dir.exists():
53
+ dwi_files = list(dwi_dir.glob("*_dwi.nii.gz"))
54
+ report["dwi_present"] = len(dwi_files) > 0
55
+ if not dwi_files:
56
+ report["missing_files"].append("dwi/*_dwi.nii.gz")
57
+ else:
58
+ report["warnings"].append("No dwi directory")
59
+
60
+ return report
61
+
62
+
63
+ def main() -> int:
64
+ parser = argparse.ArgumentParser(description="Validate NIFD BIDS structure.")
65
+ parser.add_argument("--input", required=True, help="Path to NIFD BIDS directory")
66
+ parser.add_argument("--output", required=True, help="Output path for validation CSV")
67
+ args = parser.parse_args()
68
+
69
+ input_dir = Path(args.input).resolve()
70
+ if not input_dir.exists():
71
+ print(f"Input directory not found: {input_dir}", file=sys.stderr)
72
+ return 1
73
+
74
+ subjects = sorted([d for d in input_dir.glob("sub-*") if d.is_dir()])
75
+ print(f"Found {len(subjects)} subjects in {input_dir}")
76
+
77
+ if not subjects:
78
+ print("[ERROR] No subjects found.", file=sys.stderr)
79
+ return 1
80
+
81
+ results = []
82
+ for sub_dir in subjects:
83
+ report = validate_subject(sub_dir)
84
+ results.append(report)
85
+
86
+ output_path = Path(args.output).resolve()
87
+ output_path.parent.mkdir(parents=True, exist_ok=True)
88
+
89
+ fieldnames = ["subject", "anat_complete", "rs_fMRI_present", "dwi_present", "missing_files", "warnings"]
90
+ with open(output_path, "w", newline="", encoding="utf-8") as f:
91
+ writer = csv.DictWriter(f, fieldnames=fieldnames)
92
+ writer.writeheader()
93
+ for r in results:
94
+ r["missing_files"] = "; ".join(r["missing_files"])
95
+ r["warnings"] = "; ".join(r["warnings"])
96
+ writer.writerow(r)
97
+
98
+ complete = sum(1 for r in results if r["anat_complete"] and r["rs_fMRI_present"])
99
+ print(f"\nValidation Summary:")
100
+ print(f" Total subjects: {len(results)}")
101
+ print(f" Complete (anat + rs-fMRI): {complete}")
102
+ print(f" With T1w: {sum(1 for r in results if r['anat_complete'])}")
103
+ print(f" With rs-fMRI: {sum(1 for r in results if r['rs_fMRI_present'])}")
104
+ print(f" With dMRI: {sum(1 for r in results if r['dwi_present'])}")
105
+ print(f" Output: {output_path}")
106
+
107
+ return 0
108
+
109
+
110
+ if __name__ == "__main__":
111
+ sys.exit(main())