@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,210 @@
1
+ ---
2
+ name: nsd-skill
3
+ description: "Use this skill whenever the user wants an end-to-end workflow for the Natural Scenes Dataset (NSD), including data access, BIDS validation, multimodal processing of task-fMRI and structural MRI, stimulus metadata extraction, and QC integration. Triggers include: 'NSD', 'Natural Scenes Dataset', 'process NSD data', 'NSD fMRI', 'visual neuroscience', or any request to run the NSD 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
+ - bids-organizer
11
+ - claw-shell
12
+ complementary_skills:
13
+ - brain-visualization
14
+ - nibabel-skill
15
+ ---
16
+ # NSD Skill (Dataset-Orchestration Layer)
17
+
18
+ ## Overview
19
+
20
+ `nsd-skill` is the NeuroClaw orchestration skill for the **Natural Scenes Dataset (NSD)**.
21
+
22
+ It strictly follows the NeuroClaw hierarchical design principles:
23
+ - This skill **only describes WHAT needs to be done** and **which tool skill to delegate to**.
24
+ - It contains **no implementation code or concrete commands**.
25
+ - All concrete execution is delegated to existing base/tool skills via `claw-shell`.
26
+ - Companion scripts in `scripts/` provide reference implementations for BIDS validation, stimulus extraction, and QC.
27
+
28
+ **Core workflow (never bypassed):**
29
+ 1. Identify input NSD data and target modalities.
30
+ 2. Generate a **numbered execution plan** clearly stating WHAT needs to be done and which tool skill will handle each step.
31
+ 3. Present the full plan, estimated runtime, resource requirements, and risks to the user and wait for explicit confirmation ("YES" / "execute" / "proceed").
32
+ 4. On confirmation, delegate every step to the appropriate skill via `claw-shell`.
33
+ 5. After execution, save all outputs in a clean directory structure (`nsd_output/`).
34
+
35
+ **Research use only.**
36
+
37
+ ---
38
+
39
+ ## Quick Reference
40
+
41
+ | Task | What needs to be done | Delegate to | Expected output |
42
+ |---|---|---|---|
43
+ | BIDS validation | Validate NSD BIDS structure | `scripts/validate_nsd.py` | Validation report |
44
+ | sMRI processing | Brain extraction, tissue segmentation | `smri-skill` | `smri_output/` derivatives |
45
+ | task-fMRI processing | Visual task GLM, voxel-wise encoding | `fmri-skill` | `fmri_output/` task results |
46
+ | Stimulus extraction | COCO image metadata, annotations | `scripts/extract_nsd_stimulus.py` | Stimulus metadata CSV |
47
+ | QC summary | Per-subject quality control | `scripts/nsd_qc_summary.py` | QC summary + exclusion list |
48
+
49
+ ---
50
+
51
+ ## Dataset Characteristics
52
+
53
+ - **Cohort**: 8 healthy adults (subj01-subj08)
54
+ - **Scanner**: 7T Siemens MAGNETOM
55
+ - **Resolution**: 1.8mm isotropic voxels
56
+ - **Sessions**: ~30-40 scanning sessions per subject
57
+ - **Total fMRI**: ~30 hours per subject
58
+ - **Stimuli**: ~73,000 natural scene images from COCO dataset
59
+ - **Access**: OSF (Open Science Framework) and Amazon S3
60
+ - **Reference**: Allen et al. (2021), Nature Neuroscience
61
+
62
+ ---
63
+
64
+ ## Supported Modalities
65
+
66
+ | Modality | Description | Details |
67
+ |---|---|---|
68
+ | T1w | High-resolution structural MRI | 7T anatomical scans |
69
+ | task-fMRI | Visual task fMRI | Natural scene viewing with fixation task |
70
+ | dMRI | Diffusion-weighted imaging | White matter tractography |
71
+ | Retinotopy | Retinotopic mapping | Visual area identification |
72
+ | Eye-tracking | Gaze position data | During image viewing |
73
+
74
+ ---
75
+
76
+ ## NSD Task Paradigms
77
+
78
+ | Task | Description | Duration |
79
+ |---|---|---|
80
+ | NSD | Natural scene viewing (COCO images) | ~30-40 sessions × ~15 min each |
81
+ | FIXATION | Fixation task during image presentation | Continuous |
82
+
83
+ ---
84
+
85
+ ## COCO Stimulus Metadata
86
+
87
+ The NSD uses images from the COCO (Common Objects in Context) dataset:
88
+ - ~73,000 unique natural scene images
89
+ - Each image has: 5 captions, 80 object categories, segmentation masks
90
+ - Images are presented for 3 seconds each
91
+ - Subjects perform a fixation task (detect image repeat)
92
+
93
+ ---
94
+
95
+ ## BIDS Preparation
96
+
97
+ ### Script: `scripts/validate_nsd.py`
98
+
99
+ Validates NSD BIDS structure and generates a compliance report.
100
+
101
+ ```bash
102
+ python skills/nsd-skill/scripts/validate_nsd.py \
103
+ --input /path/to/NSD/bids \
104
+ --output /path/to/nsd_output/qc/bids_validation.csv
105
+ ```
106
+
107
+ Features:
108
+ - BIDS directory structure validation
109
+ - Subject completeness check (8 subjects)
110
+ - Session count validation (~30-40 sessions per subject)
111
+ - Stimulus file presence verification
112
+ - Missing data identification
113
+
114
+ ---
115
+
116
+ ## Core Workflow (Never Bypassed)
117
+
118
+ 1. Identify user target: full NSD processing, imaging subset, stimulus extraction, or BIDS validation only.
119
+ 2. Generate a numbered plan with tools, outputs, runtime, storage, and risks.
120
+ 3. Wait for explicit confirmation (`YES` / `execute` / `proceed`).
121
+ 4. On confirmation, run BIDS validation using `scripts/validate_nsd.py`.
122
+ 5. Delegate to `smri-skill` for structural MRI processing.
123
+ 6. Delegate to `fmri-skill` for task-fMRI processing (natural scene viewing).
124
+ 7. If stimulus extraction is requested, run `scripts/extract_nsd_stimulus.py`.
125
+ 8. If QC summary is requested, run `scripts/nsd_qc_summary.py`.
126
+ 9. Save outputs into `nsd_output/`.
127
+
128
+ ---
129
+
130
+ ## Modality Processing Delegation
131
+
132
+ | Modality | Delegated skill | Typical tasks | Main outputs |
133
+ |---|---|---|---|
134
+ | sMRI (T1w) | `smri-skill` | brain extraction, tissue segmentation, cortical reconstruction | `smri_output/` derivatives |
135
+ | task-fMRI | `fmri-skill` | preprocessing, denoising, voxel-wise encoding | `fmri_output/` task results |
136
+ | dMRI | `fmri-skill` | diffusion preprocessing, tensor metrics | `dwi_output/` metrics |
137
+
138
+ ---
139
+
140
+ ## Standard Output Layout
141
+
142
+ ```
143
+ nsd_output/
144
+ ├── bids/ # BIDS-staged data (or validation report)
145
+ ├── smri/ # Structural MRI derivatives
146
+ ├── fmri/ # Functional MRI derivatives (natural scene viewing)
147
+ ├── stimulus/ # COCO stimulus metadata
148
+ ├── qc/ # QC summaries and exclusion lists
149
+ └── logs/ # Processing logs
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Benchmark Adapter Guidance
155
+
156
+ For benchmark-style prompts, do not force the full orchestration when the task only asks for local NSD data validation.
157
+
158
+ - If the task starts from NSD data already present on disk and only asks for BIDS validation:
159
+ - Skip the download stage
160
+ - Default to the narrow path `local NSD discovery -> BIDS validation -> report`
161
+ - In benchmark mode, do not require explicit confirmation before presenting the validation solution.
162
+
163
+ ---
164
+
165
+ ## Safety and Execution Policy
166
+ - No execution before explicit plan confirmation.
167
+ - All execution must be routed via `claw-shell`.
168
+ - Missing dependencies must be resolved by `dependency-planner` before running.
169
+
170
+ ---
171
+
172
+ ## Important Notes and Limitations
173
+ - NSD is a high-resolution 7T dataset; processing requires significant compute resources.
174
+ - 8 subjects with dense repeated measures (~30 hours of fMRI each).
175
+ - Visual neuroscience focus: standard task GLM may not apply; consider voxel-wise encoding models.
176
+ - COCO stimulus metadata is essential for stimulus-response analyses.
177
+ - Cortical surface-based representations using FreeSurfer outputs.
178
+ - `nsd-skill` is orchestration-only; detailed preprocessing logic remains in modality skills.
179
+
180
+ ---
181
+
182
+ ## When to Call This Skill
183
+ - User asks for end-to-end NSD workflow.
184
+ - User asks to process NSD task-fMRI data.
185
+ - User needs BIDS validation for NSD data.
186
+ - User asks to extract NSD stimulus metadata (COCO images, captions, categories).
187
+ - User asks for visual cortex analysis or voxel-wise encoding.
188
+
189
+ ---
190
+
191
+ ## Complementary / Related Skills
192
+ - `smri-skill` → structural MRI preprocessing
193
+ - `fmri-skill` → functional MRI preprocessing and analysis
194
+ - `nibabel-skill` → NIfTI I/O and surface data
195
+ - `bids-organizer` → BIDS validation and organization
196
+ - `brain-visualization` → visualization of derivatives
197
+ - `dependency-planner` → dependency resolution
198
+ - `conda-env-manager` → environment management
199
+ - `claw-shell` → command execution
200
+
201
+ ---
202
+
203
+ ## Reference
204
+ - NSD: https://naturalscenesdataset.org/
205
+ - Allen et al. (2021): A massive 7T fMRI dataset to bridge cognitive neuroscience and artificial intelligence. Nature Neuroscience.
206
+ - COCO: https://cocodataset.org/
207
+
208
+ Created At: 2026-05-06 13:31 HKT
209
+ Last Updated At: 2026-05-06 13:31 HKT
210
+ Author: chengwang96
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env python3
2
+ """Extract NSD stimulus metadata from COCO annotations.
3
+
4
+ Reads NSD stimulus information (COCO image IDs, captions, categories)
5
+ and produces a merged stimulus metadata table for stimulus-response analyses.
6
+ """
7
+ import argparse
8
+ import csv
9
+ import json
10
+ import sys
11
+ from pathlib import Path
12
+ from typing import Dict, List, Optional
13
+
14
+
15
+ def load_nsd_stimulus_info(stimulus_dir: Path) -> List[Dict]:
16
+ """Load NSD stimulus info from nsd_stiminfo.tsv or equivalent."""
17
+ stim_info = []
18
+ stim_file = stimulus_dir / "nsd_stiminfo.tsv"
19
+ if stim_file.exists():
20
+ with open(stim_file, "r", encoding="utf-8") as f:
21
+ reader = csv.DictReader(f, delimiter="\t")
22
+ stim_info = list(reader)
23
+ return stim_info
24
+
25
+
26
+ def load_coco_annotations(coco_dir: Path) -> Dict[int, Dict]:
27
+ """Load COCO annotations (captions + categories) keyed by image_id."""
28
+ coco_data = {}
29
+
30
+ # Load captions
31
+ captions_file = coco_dir / "annotations" / "captions_train2017.json"
32
+ if captions_file.exists():
33
+ with open(captions_file, "r", encoding="utf-8") as f:
34
+ caps = json.load(f)
35
+ for ann in caps.get("annotations", []):
36
+ img_id = ann["image_id"]
37
+ if img_id not in coco_data:
38
+ coco_data[img_id] = {"captions": [], "categories": []}
39
+ coco_data[img_id]["captions"].append(ann["caption"])
40
+
41
+ # Load instances (categories)
42
+ instances_file = coco_dir / "annotations" / "instances_train2017.json"
43
+ if instances_file.exists():
44
+ with open(instances_file, "r", encoding="utf-8") as f:
45
+ instances = json.load(f)
46
+ # Build category id -> name map
47
+ cat_map = {c["id"]: c["name"] for c in instances.get("categories", [])}
48
+ for ann in instances.get("annotations", []):
49
+ img_id = ann["image_id"]
50
+ if img_id not in coco_data:
51
+ coco_data[img_id] = {"captions": [], "categories": []}
52
+ cat_name = cat_map.get(ann["category_id"], "unknown")
53
+ if cat_name not in coco_data[img_id]["categories"]:
54
+ coco_data[img_id]["categories"].append(cat_name)
55
+
56
+ return coco_data
57
+
58
+
59
+ def load_subject_trials(events_dir: Path, subject: str) -> List[Dict]:
60
+ """Load trial-level stimulus info from a subject's events files."""
61
+ trials = []
62
+ pattern = f"{subject}_task-nsd*_events.tsv"
63
+ for events_file in sorted(events_dir.glob(pattern)):
64
+ with open(events_file, "r", encoding="utf-8") as f:
65
+ reader = csv.DictReader(f, delimiter="\t")
66
+ for row in reader:
67
+ row["_source_file"] = events_file.name
68
+ trials.append(row)
69
+ return trials
70
+
71
+
72
+ def main() -> int:
73
+ parser = argparse.ArgumentParser(
74
+ description="Extract NSD stimulus metadata from COCO annotations."
75
+ )
76
+ parser.add_argument("--nsd-dir", required=True,
77
+ help="Path to NSD root directory (BIDS format)")
78
+ parser.add_argument("--coco-dir",
79
+ help="Path to COCO annotations directory (optional)")
80
+ parser.add_argument("--output", required=True,
81
+ help="Output path for stimulus metadata CSV")
82
+ parser.add_argument("--subject", default=None,
83
+ help="Extract for specific subject only (e.g., subj01)")
84
+ args = parser.parse_args()
85
+
86
+ nsd_dir = Path(args.nsd_dir).resolve()
87
+ if not nsd_dir.exists():
88
+ print(f"NSD directory not found: {nsd_dir}", file=sys.stderr)
89
+ return 1
90
+
91
+ output_path = Path(args.output).resolve()
92
+ output_path.parent.mkdir(parents=True, exist_ok=True)
93
+
94
+ # Load NSD stimulus info
95
+ stim_info = load_nsd_stimulus_info(nsd_dir)
96
+ print(f"Loaded {len(stim_info)} stimulus entries from nsd_stiminfo.tsv")
97
+
98
+ # Load COCO annotations if available
99
+ coco_data = {}
100
+ if args.coco_dir:
101
+ coco_dir = Path(args.coco_dir).resolve()
102
+ if coco_dir.exists():
103
+ coco_data = load_coco_annotations(coco_dir)
104
+ print(f"Loaded COCO annotations for {len(coco_data)} images")
105
+
106
+ # Determine subjects to process
107
+ if args.subject:
108
+ subjects = [args.subject]
109
+ else:
110
+ subjects = sorted([
111
+ d.name for d in nsd_dir.glob("sub-*") if d.is_dir()
112
+ ])
113
+
114
+ # Collect trial-level data
115
+ all_trials = []
116
+ for subj in subjects:
117
+ subj_dir = nsd_dir / subj / "func"
118
+ if not subj_dir.exists():
119
+ continue
120
+ trials = load_subject_trials(subj_dir, subj)
121
+ for t in trials:
122
+ t["subject_id"] = subj
123
+ all_trials.extend(trials)
124
+
125
+ # Merge stimulus info with trials
126
+ if stim_info and all_trials:
127
+ # Build lookup by stimulus index if available
128
+ stim_lookup = {}
129
+ for s in stim_info:
130
+ key = s.get("nsd_id") or s.get("stimulus_id") or s.get("0", "")
131
+ if key:
132
+ stim_lookup[str(key)] = s
133
+
134
+ for trial in all_trials:
135
+ stim_idx = trial.get("stimulus_index") or trial.get("stim_id", "")
136
+ if stim_idx and str(stim_idx) in stim_lookup:
137
+ for k, v in stim_lookup[str(stim_idx)].items():
138
+ if k not in trial:
139
+ trial[f"stim_{k}"] = v
140
+
141
+ # Enrich with COCO data if available
142
+ if coco_data and all_trials:
143
+ for trial in all_trials:
144
+ coco_id = trial.get("coco_id") or trial.get("stim_coco_id", "")
145
+ if coco_id and str(coco_id).isdigit():
146
+ cid = int(coco_id)
147
+ if cid in coco_data:
148
+ trial["coco_captions"] = " | ".join(coco_data[cid]["captions"][:3])
149
+ trial["coco_categories"] = ", ".join(coco_data[cid]["categories"])
150
+
151
+ # Output
152
+ if not all_trials and stim_info:
153
+ # Fallback: output stim_info directly
154
+ all_trials = stim_info
155
+
156
+ if not all_trials:
157
+ print("[WARN] No stimulus data found.", file=sys.stderr)
158
+ return 1
159
+
160
+ fieldnames = list(all_trials[0].keys())
161
+ with open(output_path, "w", newline="", encoding="utf-8") as f:
162
+ writer = csv.DictWriter(f, fieldnames=fieldnames)
163
+ writer.writeheader()
164
+ writer.writerows(all_trials)
165
+
166
+ print(f"Stimulus: {len(all_trials)} trials, {len(fieldnames)} columns -> {output_path}")
167
+ return 0
168
+
169
+
170
+ if __name__ == "__main__":
171
+ sys.exit(main())
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env python3
2
+ """Generate per-subject QC summaries for NSD processing.
3
+
4
+ 7T-specific QC: tracks session counts, motion metrics, and stimulus coverage.
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
+ """Extract QC metrics from fMRIPrep confounds TSV."""
15
+ metrics = {
16
+ "fd_mean": float("nan"),
17
+ "fd_max": float("nan"),
18
+ "dvars_mean": float("nan"),
19
+ }
20
+ try:
21
+ import pandas as pd
22
+ df = pd.read_csv(confounds_path, sep="\t")
23
+ if "framewise_displacement" in df.columns:
24
+ fd = df["framewise_displacement"].dropna()
25
+ metrics["fd_mean"] = float(fd.mean())
26
+ metrics["fd_max"] = float(fd.max())
27
+ if "dvars" in df.columns:
28
+ dvars = df["dvars"].dropna()
29
+ metrics["dvars_mean"] = float(dvars.mean())
30
+ except Exception:
31
+ pass
32
+ return metrics
33
+
34
+
35
+ def check_exclusion(metrics: Dict[str, float], fd_threshold: float = 0.3) -> List[str]:
36
+ """Check exclusion criteria for NSD."""
37
+ reasons = []
38
+ if not (metrics["fd_mean"] != metrics["fd_mean"]): # not NaN
39
+ if metrics["fd_mean"] > fd_threshold:
40
+ reasons.append(f"FD mean {metrics['fd_mean']:.3f} > {fd_threshold}")
41
+ return reasons
42
+
43
+
44
+ def main() -> int:
45
+ parser = argparse.ArgumentParser(
46
+ description="Generate QC summaries for NSD processing."
47
+ )
48
+ parser.add_argument("--fmriprep-dir", help="Path to fMRIPrep output directory")
49
+ parser.add_argument("--nsd-dir", help="Path to NSD BIDS root directory")
50
+ parser.add_argument("--output", required=True, help="Output path for QC summary CSV")
51
+ parser.add_argument("--exclude-output", help="Output path for exclusion list CSV")
52
+ parser.add_argument("--fd-threshold", type=float, default=0.3,
53
+ help="FD threshold in mm (default: 0.3, typical for 7T)")
54
+ args = parser.parse_args()
55
+
56
+ output_path = Path(args.output).resolve()
57
+ output_path.parent.mkdir(parents=True, exist_ok=True)
58
+
59
+ # Discover subjects
60
+ subjects = set()
61
+ if args.fmriprep_dir:
62
+ fmriprep_dir = Path(args.fmriprep_dir).resolve()
63
+ if fmriprep_dir.exists():
64
+ for d in fmriprep_dir.glob("sub-*"):
65
+ if d.is_dir():
66
+ subjects.add(d.name)
67
+ if args.nsd_dir:
68
+ nsd_dir = Path(args.nsd_dir).resolve()
69
+ if nsd_dir.exists():
70
+ for d in nsd_dir.glob("sub-*"):
71
+ if d.is_dir():
72
+ subjects.add(d.name)
73
+
74
+ if not subjects:
75
+ print("[WARN] No subjects found.", file=sys.stderr)
76
+ return 1
77
+
78
+ results = []
79
+ excluded = []
80
+ for subj in sorted(subjects):
81
+ metrics = {"subject_id": subj}
82
+
83
+ # Count sessions from BIDS structure
84
+ if args.nsd_dir:
85
+ nsd_dir = Path(args.nsd_dir).resolve()
86
+ subj_dir = nsd_dir / subj
87
+ if subj_dir.exists():
88
+ sessions = [d for d in subj_dir.glob("ses-*") if d.is_dir()]
89
+ metrics["n_sessions"] = len(sessions)
90
+ func_dir = subj_dir / "func"
91
+ if func_dir.exists():
92
+ bold_runs = list(func_dir.glob("*_task-nsd_bold.nii.gz"))
93
+ metrics["n_func_runs"] = len(bold_runs)
94
+
95
+ # Extract fMRIPrep confounds metrics
96
+ if args.fmriprep_dir:
97
+ confounds_files = list(
98
+ Path(args.fmriprep_dir).glob(f"{subj}/func/*_desc-confounds_timeseries.tsv")
99
+ )
100
+ if confounds_files:
101
+ # Average across runs
102
+ fd_means = []
103
+ fd_maxes = []
104
+ for cf in confounds_files:
105
+ run_metrics = load_confounds(cf)
106
+ if run_metrics["fd_mean"] == run_metrics["fd_mean"]: # not NaN
107
+ fd_means.append(run_metrics["fd_mean"])
108
+ fd_maxes.append(run_metrics["fd_max"])
109
+ if fd_means:
110
+ metrics["fd_mean"] = sum(fd_means) / len(fd_means)
111
+ metrics["fd_max"] = max(fd_maxes)
112
+ metrics["n_confounds_files"] = len(confounds_files)
113
+
114
+ exclusion_reasons = check_exclusion(metrics, args.fd_threshold)
115
+ metrics["excluded"] = len(exclusion_reasons) > 0
116
+ metrics["exclusion_reasons"] = "; ".join(exclusion_reasons)
117
+
118
+ results.append(metrics)
119
+ if exclusion_reasons:
120
+ excluded.append({"subject_id": subj, "reasons": "; ".join(exclusion_reasons)})
121
+
122
+ if results:
123
+ fieldnames = list(results[0].keys())
124
+ with open(output_path, "w", newline="", encoding="utf-8") as f:
125
+ writer = csv.DictWriter(f, fieldnames=fieldnames)
126
+ writer.writeheader()
127
+ writer.writerows(results)
128
+ print(f"QC: {len(results)} subjects, {len(excluded)} excluded -> {output_path}")
129
+
130
+ if args.exclude_output and excluded:
131
+ exclude_path = Path(args.exclude_output).resolve()
132
+ exclude_path.parent.mkdir(parents=True, exist_ok=True)
133
+ with open(exclude_path, "w", newline="", encoding="utf-8") as f:
134
+ writer = csv.DictWriter(f, fieldnames=["subject_id", "reasons"])
135
+ writer.writeheader()
136
+ writer.writerows(excluded)
137
+
138
+ return 0
139
+
140
+
141
+ if __name__ == "__main__":
142
+ sys.exit(main())
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env python3
2
+ """Validate NSD BIDS structure and generate compliance report.
3
+
4
+ Checks directory structure, subject completeness, session counts,
5
+ and stimulus file presence for the Natural Scenes Dataset.
6
+ """
7
+ import argparse
8
+ import csv
9
+ import sys
10
+ from pathlib import Path
11
+ from typing import Dict, List
12
+
13
+ # NSD expected subjects
14
+ NSD_SUBJECTS = [f"subj0{i}" for i in range(1, 9)] # subj01-subj08
15
+
16
+ # Expected modalities per subject
17
+ EXPECTED_MODALITIES = {
18
+ "func": ["task-nsd_bold"],
19
+ "anat": ["T1w"],
20
+ }
21
+
22
+
23
+ def validate_subject(subject_dir: Path) -> Dict[str, any]:
24
+ """Validate a single subject's NSD BIDS structure."""
25
+ report = {
26
+ "subject": subject_dir.name,
27
+ "anat_complete": False,
28
+ "func_complete": False,
29
+ "n_sessions": 0,
30
+ "n_func_runs": 0,
31
+ "stimulus_present": False,
32
+ "missing_files": [],
33
+ "warnings": [],
34
+ }
35
+
36
+ # Check anat
37
+ anat_dir = subject_dir / "anat"
38
+ if anat_dir.exists():
39
+ t1w_files = list(anat_dir.glob("*_T1w.nii.gz"))
40
+ report["anat_complete"] = len(t1w_files) > 0
41
+ if not t1w_files:
42
+ report["missing_files"].append("anat/*_T1w.nii.gz")
43
+ else:
44
+ report["missing_files"].append("anat/")
45
+
46
+ # Check func
47
+ func_dir = subject_dir / "func"
48
+ if func_dir.exists():
49
+ bold_files = list(func_dir.glob("*_task-nsd_bold.nii.gz"))
50
+ report["n_func_runs"] = len(bold_files)
51
+ report["func_complete"] = len(bold_files) > 0
52
+
53
+ # Count unique sessions from filenames
54
+ sessions = set()
55
+ for f in bold_files:
56
+ parts = f.name.split("_")
57
+ for p in parts:
58
+ if p.startswith("ses-"):
59
+ sessions.add(p)
60
+ report["n_sessions"] = len(sessions)
61
+
62
+ if not bold_files:
63
+ report["missing_files"].append("func/*_task-nsd_bold.nii.gz")
64
+ else:
65
+ report["missing_files"].append("func/")
66
+
67
+ # Check stimulus files
68
+ stim_dir = subject_dir / "func"
69
+ if stim_dir.exists():
70
+ stim_files = list(stim_dir.glob("*_events.tsv"))
71
+ report["stimulus_present"] = len(stim_files) > 0
72
+
73
+ # Warnings for session count
74
+ if report["n_sessions"] > 0 and report["n_sessions"] < 30:
75
+ report["warnings"].append(
76
+ f"Only {report['n_sessions']} sessions found (expected ~30-40)"
77
+ )
78
+
79
+ return report
80
+
81
+
82
+ def main() -> int:
83
+ parser = argparse.ArgumentParser(
84
+ description="Validate NSD BIDS structure."
85
+ )
86
+ parser.add_argument("--input", required=True, help="Path to NSD BIDS directory")
87
+ parser.add_argument("--output", required=True, help="Output path for validation CSV")
88
+ args = parser.parse_args()
89
+
90
+ input_dir = Path(args.input).resolve()
91
+ if not input_dir.exists():
92
+ print(f"Input directory not found: {input_dir}", file=sys.stderr)
93
+ return 1
94
+
95
+ # Find subjects
96
+ subjects = sorted([d for d in input_dir.glob("sub-*") if d.is_dir()])
97
+ print(f"Found {len(subjects)} subjects in {input_dir}")
98
+
99
+ if not subjects:
100
+ print("[ERROR] No subjects found.", file=sys.stderr)
101
+ return 1
102
+
103
+ # Validate each subject
104
+ results = []
105
+ for sub_dir in subjects:
106
+ report = validate_subject(sub_dir)
107
+ results.append(report)
108
+
109
+ # Write output
110
+ output_path = Path(args.output).resolve()
111
+ output_path.parent.mkdir(parents=True, exist_ok=True)
112
+
113
+ fieldnames = [
114
+ "subject", "anat_complete", "func_complete",
115
+ "n_sessions", "n_func_runs", "stimulus_present",
116
+ "missing_files", "warnings",
117
+ ]
118
+ with open(output_path, "w", newline="", encoding="utf-8") as f:
119
+ writer = csv.DictWriter(f, fieldnames=fieldnames)
120
+ writer.writeheader()
121
+ for r in results:
122
+ r["missing_files"] = "; ".join(r["missing_files"])
123
+ r["warnings"] = "; ".join(r["warnings"])
124
+ writer.writerow(r)
125
+
126
+ # Summary
127
+ complete_subjects = sum(1 for r in results if r["anat_complete"] and r["func_complete"])
128
+ print(f"\nValidation Summary:")
129
+ print(f" Total subjects: {len(results)}")
130
+ print(f" Complete (anat + func): {complete_subjects}")
131
+ print(f" With T1w: {sum(1 for r in results if r['anat_complete'])}")
132
+ print(f" With task-fMRI: {sum(1 for r in results if r['func_complete'])}")
133
+ print(f" With stimulus events: {sum(1 for r in results if r['stimulus_present'])}")
134
+ total_runs = sum(r['n_func_runs'] for r in results)
135
+ print(f" Total fMRI runs: {total_runs}")
136
+ print(f" Output: {output_path}")
137
+
138
+ return 0
139
+
140
+
141
+ if __name__ == "__main__":
142
+ sys.exit(main())