@brainpilot/skills 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/skills/01_Meta-Skills/academic-research-hub/SKILL.md +108 -0
- package/skills/01_Meta-Skills/academic-research-hub/scripts/requirements.txt +17 -0
- package/skills/01_Meta-Skills/academic-research-hub/scripts/research.py +781 -0
- package/skills/01_Meta-Skills/beautiful-log/SKILL.md +64 -0
- package/skills/01_Meta-Skills/beautiful-log/scripts/beautiful_log.py +274 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/SKILL.md +130 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/assets/config.template.yaml +54 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/assets/top5_digest_template.md +5 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/build_top5_digest.py +300 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/common.py +137 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/merge_results.py +106 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/run_pipeline.py +177 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/search_arxiv.py +162 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/search_pubmed.py +202 -0
- package/skills/01_Meta-Skills/ethoclaw-normalize-tabular/SKILL.md +173 -0
- package/skills/01_Meta-Skills/ethoclaw-normalize-tabular/scripts/normalize_data.py +874 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/SKILL.md +134 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/references/confirmation-prompts.md +31 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/references/output-patterns.md +45 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/build_markdown_deliverables.py +41 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/build_research_log.py +84 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/build_summary_md.py +63 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/extract_pdf_bundle.py +140 -0
- package/skills/01_Meta-Skills/experiment-controller/SKILL.md +140 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/SKILL.md +366 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/entity_resolution.py +120 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/extraction_prompt_template.txt +19 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/graph_query.py +106 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/hypothesis_cli_reference.py +42 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/new_data_source_template.py +116 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/requirements.txt +15 -0
- package/skills/01_Meta-Skills/method-design/SKILL.md +61 -0
- package/skills/01_Meta-Skills/multi-search-engine/SKILL.md +119 -0
- package/skills/01_Meta-Skills/research-idea/SKILL.md +65 -0
- package/skills/05_EEG_ERP/eeg-skill/SKILL.md +197 -0
- package/skills/05_EEG_ERP/meg-skill/SKILL.md +188 -0
- package/skills/05_EEG_ERP/meg-skill/scripts/time_frequency.py +223 -0
- package/skills/05_EEG_ERP/mne-eeg-tool/SKILL.md +165 -0
- package/skills/05_EEG_ERP/mne-eeg-tool/scripts/eeg_pipeline_reference.py +231 -0
- package/skills/05_EEG_ERP/seed-iv-skill/SKILL.md +184 -0
- package/skills/05_EEG_ERP/seed-iv-skill/scripts/classify_seed_iv.py +154 -0
- package/skills/05_EEG_ERP/seed-iv-skill/scripts/extract_seed_iv_features.py +190 -0
- package/skills/05_EEG_ERP/seed-iv-skill/scripts/validate_seed_iv.py +102 -0
- package/skills/05_EEG_ERP/seed-vig-skill/SKILL.md +182 -0
- package/skills/05_EEG_ERP/seed-vig-skill/scripts/classify_seed_vig.py +165 -0
- package/skills/05_EEG_ERP/seed-vig-skill/scripts/extract_seed_vig_features.py +185 -0
- package/skills/05_EEG_ERP/seed-vig-skill/scripts/validate_seed_vig.py +88 -0
- package/skills/06_fMRI_Neuroimaging/abcd-skill/SKILL.md +308 -0
- package/skills/06_fMRI_Neuroimaging/abcd-skill/scripts/abcd_qc_summary.py +449 -0
- package/skills/06_fMRI_Neuroimaging/abcd-skill/scripts/extract_abcd_phenotype.py +292 -0
- package/skills/06_fMRI_Neuroimaging/abcd-skill/scripts/reorganize_abcd.py +387 -0
- package/skills/06_fMRI_Neuroimaging/abide-skill/SKILL.md +302 -0
- package/skills/06_fMRI_Neuroimaging/abide-skill/scripts/abide_qc_summary.py +317 -0
- package/skills/06_fMRI_Neuroimaging/abide-skill/scripts/extract_abide_phenotype.py +267 -0
- package/skills/06_fMRI_Neuroimaging/abide-skill/scripts/reorganize_abide.py +387 -0
- package/skills/06_fMRI_Neuroimaging/adhd200-skill/SKILL.md +244 -0
- package/skills/06_fMRI_Neuroimaging/adhd200-skill/scripts/adhd200_qc_summary.py +98 -0
- package/skills/06_fMRI_Neuroimaging/adhd200-skill/scripts/extract_adhd200_phenotype.py +134 -0
- package/skills/06_fMRI_Neuroimaging/adhd200-skill/scripts/reorganize_adhd200.py +206 -0
- package/skills/06_fMRI_Neuroimaging/adni-skill/SKILL.md +358 -0
- package/skills/06_fMRI_Neuroimaging/adni-skill/scripts/generate_adni_task_files.py +1305 -0
- package/skills/06_fMRI_Neuroimaging/adni-skill/scripts/generate_vqa_from_tasks.py +766 -0
- package/skills/06_fMRI_Neuroimaging/adni-skill/scripts/reorganize_adni.py +491 -0
- package/skills/06_fMRI_Neuroimaging/aibl-skill/SKILL.md +295 -0
- package/skills/06_fMRI_Neuroimaging/aibl-skill/scripts/aibl_qc_summary.py +260 -0
- package/skills/06_fMRI_Neuroimaging/aibl-skill/scripts/extract_aibl_phenotype.py +365 -0
- package/skills/06_fMRI_Neuroimaging/aibl-skill/scripts/reorganize_aibl.py +394 -0
- package/skills/06_fMRI_Neuroimaging/aomic-skill/SKILL.md +292 -0
- package/skills/06_fMRI_Neuroimaging/aomic-skill/scripts/aomic_qc_summary.py +258 -0
- package/skills/06_fMRI_Neuroimaging/aomic-skill/scripts/extract_aomic_phenotype.py +284 -0
- package/skills/06_fMRI_Neuroimaging/aomic-skill/scripts/reorganize_aomic.py +322 -0
- package/skills/06_fMRI_Neuroimaging/asl-skill/SKILL.md +168 -0
- package/skills/06_fMRI_Neuroimaging/asl-skill/scripts/compute_cbf.py +224 -0
- package/skills/06_fMRI_Neuroimaging/bids-organizer/SKILL.md +241 -0
- package/skills/06_fMRI_Neuroimaging/bold5000-skill/SKILL.md +186 -0
- package/skills/06_fMRI_Neuroimaging/bold5000-skill/scripts/bold5000_qc_summary.py +96 -0
- package/skills/06_fMRI_Neuroimaging/bold5000-skill/scripts/extract_bold5000_stimulus.py +125 -0
- package/skills/06_fMRI_Neuroimaging/bold5000-skill/scripts/reorganize_bold5000.py +102 -0
- package/skills/06_fMRI_Neuroimaging/camcan-skill/SKILL.md +213 -0
- package/skills/06_fMRI_Neuroimaging/camcan-skill/scripts/camcan_qc_summary.py +131 -0
- package/skills/06_fMRI_Neuroimaging/camcan-skill/scripts/extract_camcan_phenotype.py +145 -0
- package/skills/06_fMRI_Neuroimaging/camcan-skill/scripts/validate_camcan.py +141 -0
- package/skills/06_fMRI_Neuroimaging/cobre-skill/SKILL.md +201 -0
- package/skills/06_fMRI_Neuroimaging/cobre-skill/scripts/cobre_qc_summary.py +95 -0
- package/skills/06_fMRI_Neuroimaging/cobre-skill/scripts/extract_cobre_phenotype.py +104 -0
- package/skills/06_fMRI_Neuroimaging/cobre-skill/scripts/reorganize_cobre.py +140 -0
- package/skills/06_fMRI_Neuroimaging/conn-tool/SKILL.md +180 -0
- package/skills/06_fMRI_Neuroimaging/dcm2nii/SKILL.md +189 -0
- package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/SKILL.md +183 -0
- package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/dmt_har_med_qc_summary.py +96 -0
- package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/extract_dmt_har_med_phenotype.py +121 -0
- package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/reorganize_dmt_har_med.py +125 -0
- package/skills/06_fMRI_Neuroimaging/dwi-skill/SKILL.md +359 -0
- package/skills/06_fMRI_Neuroimaging/fmri-skill/SKILL.md +371 -0
- package/skills/06_fMRI_Neuroimaging/fmriprep-tool/SKILL.md +228 -0
- package/skills/06_fMRI_Neuroimaging/freesurfer-tool/SKILL.md +286 -0
- package/skills/06_fMRI_Neuroimaging/freesurfer-tool/scripts/freesurfer_processor.py +145 -0
- package/skills/06_fMRI_Neuroimaging/fsl-tool/SKILL.md +208 -0
- package/skills/06_fMRI_Neuroimaging/hbn-skill/SKILL.md +271 -0
- package/skills/06_fMRI_Neuroimaging/hbn-skill/scripts/extract_hbn_phenotype.py +107 -0
- package/skills/06_fMRI_Neuroimaging/hbn-skill/scripts/hbn_qc_summary.py +96 -0
- package/skills/06_fMRI_Neuroimaging/hbn-skill/scripts/reorganize_hbn.py +150 -0
- package/skills/06_fMRI_Neuroimaging/hcpa-skill/SKILL.md +210 -0
- package/skills/06_fMRI_Neuroimaging/hcpa-skill/scripts/extract_hcpa_phenotype.py +146 -0
- package/skills/06_fMRI_Neuroimaging/hcpa-skill/scripts/hcpa_qc_summary.py +120 -0
- package/skills/06_fMRI_Neuroimaging/hcpa-skill/scripts/reorganize_hcpa.py +155 -0
- package/skills/06_fMRI_Neuroimaging/hcpd-skill/SKILL.md +210 -0
- package/skills/06_fMRI_Neuroimaging/hcpd-skill/scripts/extract_hcpd_phenotype.py +148 -0
- package/skills/06_fMRI_Neuroimaging/hcpd-skill/scripts/hcpd_qc_summary.py +125 -0
- package/skills/06_fMRI_Neuroimaging/hcpd-skill/scripts/reorganize_hcpd.py +146 -0
- package/skills/06_fMRI_Neuroimaging/hcpep-skill/SKILL.md +215 -0
- package/skills/06_fMRI_Neuroimaging/hcpep-skill/scripts/extract_hcpep_phenotype.py +157 -0
- package/skills/06_fMRI_Neuroimaging/hcpep-skill/scripts/hcpep_qc_summary.py +143 -0
- package/skills/06_fMRI_Neuroimaging/hcpep-skill/scripts/reorganize_hcpep.py +146 -0
- package/skills/06_fMRI_Neuroimaging/hcppipeline-tool/SKILL.md +217 -0
- package/skills/06_fMRI_Neuroimaging/hcpya-skill/SKILL.md +214 -0
- package/skills/06_fMRI_Neuroimaging/hcpya-skill/scripts/extract_hcpya_phenotype.py +190 -0
- package/skills/06_fMRI_Neuroimaging/hcpya-skill/scripts/hcpya_qc_summary.py +152 -0
- package/skills/06_fMRI_Neuroimaging/hcpya-skill/scripts/reorganize_hcpya.py +203 -0
- package/skills/06_fMRI_Neuroimaging/ixi-skill/SKILL.md +198 -0
- package/skills/06_fMRI_Neuroimaging/ixi-skill/scripts/ixi_qc_summary.py +137 -0
- package/skills/06_fMRI_Neuroimaging/ixi-skill/scripts/reorganize_ixi.py +190 -0
- package/skills/06_fMRI_Neuroimaging/mnd-skill/SKILL.md +191 -0
- package/skills/06_fMRI_Neuroimaging/mnd-skill/scripts/extract_mnd_phenotype.py +143 -0
- package/skills/06_fMRI_Neuroimaging/mnd-skill/scripts/mnd_qc_summary.py +120 -0
- package/skills/06_fMRI_Neuroimaging/mnd-skill/scripts/validate_mnd.py +107 -0
- package/skills/06_fMRI_Neuroimaging/mschallenge-skill/SKILL.md +203 -0
- package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/analyze_lesions.py +119 -0
- package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/longitudinal_lesion.py +148 -0
- package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/mschallenge_qc_summary.py +132 -0
- package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/validate_mschallenge.py +116 -0
- package/skills/06_fMRI_Neuroimaging/nibabel-skill/SKILL.md +184 -0
- package/skills/06_fMRI_Neuroimaging/nibabel-skill/scripts/atlas_coordinate_reference.py +61 -0
- package/skills/06_fMRI_Neuroimaging/nibabel-skill/scripts/freesurfer_io_reference.py +34 -0
- package/skills/06_fMRI_Neuroimaging/nibabel-skill/scripts/nifti_inspection_reference.py +35 -0
- package/skills/06_fMRI_Neuroimaging/nifd-skill/SKILL.md +205 -0
- package/skills/06_fMRI_Neuroimaging/nifd-skill/scripts/extract_nifd_phenotype.py +132 -0
- package/skills/06_fMRI_Neuroimaging/nifd-skill/scripts/nifd_qc_summary.py +111 -0
- package/skills/06_fMRI_Neuroimaging/nifd-skill/scripts/validate_nifd.py +111 -0
- package/skills/06_fMRI_Neuroimaging/nii2dcm/SKILL.md +143 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/SKILL.md +266 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/connectome_reference.py +65 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/denoise_timeseries_reference.py +58 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/hierarchical_parcellation_reference.py +53 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/kmeans_parcellation_reference.py +53 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/preprocess_bold_reference.py +76 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/rest_dictlearning_reference.py +56 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/rest_ica_reference.py +59 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/second_level_glm_reference.py +58 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/spacenet_classifier_reference.py +59 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/svm_classifier_reference.py +60 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/task_glm_reference.py +63 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/zalff_summary_reference.py +109 -0
- package/skills/06_fMRI_Neuroimaging/nsd-skill/SKILL.md +210 -0
- package/skills/06_fMRI_Neuroimaging/nsd-skill/scripts/extract_nsd_stimulus.py +171 -0
- package/skills/06_fMRI_Neuroimaging/nsd-skill/scripts/nsd_qc_summary.py +142 -0
- package/skills/06_fMRI_Neuroimaging/nsd-skill/scripts/validate_nsd.py +142 -0
- package/skills/06_fMRI_Neuroimaging/oasis-skill/SKILL.md +205 -0
- package/skills/06_fMRI_Neuroimaging/oasis-skill/scripts/extract_oasis_phenotype.py +126 -0
- package/skills/06_fMRI_Neuroimaging/oasis-skill/scripts/oasis_qc_summary.py +115 -0
- package/skills/06_fMRI_Neuroimaging/oasis-skill/scripts/validate_oasis.py +119 -0
- package/skills/06_fMRI_Neuroimaging/pet-skill/SKILL.md +173 -0
- package/skills/06_fMRI_Neuroimaging/pet-skill/scripts/compute_suvr.py +202 -0
- package/skills/06_fMRI_Neuroimaging/pnc-skill/SKILL.md +206 -0
- package/skills/06_fMRI_Neuroimaging/pnc-skill/scripts/extract_pnc_phenotype.py +136 -0
- package/skills/06_fMRI_Neuroimaging/pnc-skill/scripts/pnc_qc_summary.py +116 -0
- package/skills/06_fMRI_Neuroimaging/pnc-skill/scripts/validate_pnc.py +120 -0
- package/skills/06_fMRI_Neuroimaging/ppmi-skill/SKILL.md +209 -0
- package/skills/06_fMRI_Neuroimaging/ppmi-skill/scripts/extract_ppmi_phenotype.py +138 -0
- package/skills/06_fMRI_Neuroimaging/ppmi-skill/scripts/ppmi_qc_summary.py +111 -0
- package/skills/06_fMRI_Neuroimaging/ppmi-skill/scripts/validate_ppmi.py +117 -0
- package/skills/06_fMRI_Neuroimaging/qsiprep-tool/SKILL.md +320 -0
- package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/SKILL.md +215 -0
- package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/extract_rest_mdd_phenotype.py +132 -0
- package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/harmonize_sites.py +152 -0
- package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/rest_mdd_qc_summary.py +124 -0
- package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/validate_rest_mdd.py +103 -0
- package/skills/06_fMRI_Neuroimaging/smri-skill/SKILL.md +302 -0
- package/skills/06_fMRI_Neuroimaging/tcp-skill/SKILL.md +204 -0
- package/skills/06_fMRI_Neuroimaging/tcp-skill/scripts/extract_tcp_phenotype.py +139 -0
- package/skills/06_fMRI_Neuroimaging/tcp-skill/scripts/tcp_qc_summary.py +111 -0
- package/skills/06_fMRI_Neuroimaging/tcp-skill/scripts/validate_tcp.py +99 -0
- package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/SKILL.md +217 -0
- package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/scripts/extract_ucla_cnp_phenotype.py +145 -0
- package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/scripts/ucla_cnp_qc_summary.py +111 -0
- package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/scripts/validate_ucla_cnp.py +113 -0
- package/skills/06_fMRI_Neuroimaging/ukb-skill/SKILL.md +310 -0
- package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/build_ukb_survival.py +210 -0
- package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/extract_ukb_cases.py +308 -0
- package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/extract_ukb_phenotype.py +232 -0
- package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/ukb_qc_summary.py +158 -0
- package/skills/06_fMRI_Neuroimaging/wmh-segmentation/SKILL.md +133 -0
- package/skills/07_Computational_Modeling/detrending/SKILL.md +118 -0
- package/skills/07_Computational_Modeling/dictlearning/SKILL.md +122 -0
- package/skills/07_Computational_Modeling/filtering/SKILL.md +121 -0
- package/skills/07_Computational_Modeling/glm/SKILL.md +153 -0
- package/skills/07_Computational_Modeling/hierarchical/SKILL.md +121 -0
- package/skills/07_Computational_Modeling/ica/SKILL.md +122 -0
- package/skills/07_Computational_Modeling/kmeans/SKILL.md +119 -0
- package/skills/07_Computational_Modeling/run_models/SKILL.md +427 -0
- package/skills/07_Computational_Modeling/spacenet/SKILL.md +122 -0
- package/skills/07_Computational_Modeling/svm/SKILL.md +120 -0
- package/skills/08_Computational_Neuroscience/brain_gnn/SKILL.md +183 -0
- package/skills/08_Computational_Neuroscience/dipy-tool/SKILL.md +239 -0
- package/skills/08_Computational_Neuroscience/dipy-tool/scripts/dti_metrics_reference.py +70 -0
- package/skills/08_Computational_Neuroscience/dipy-tool/scripts/load_and_mask_reference.py +76 -0
- package/skills/08_Computational_Neuroscience/dipy-tool/scripts/roi_stats_reference.py +59 -0
- package/skills/08_Computational_Neuroscience/fm_app/SKILL.md +195 -0
- package/skills/08_Computational_Neuroscience/neurostorm/SKILL.md +151 -0
- package/skills/13_Visualization/brain-visualization/SKILL.md +191 -0
- package/skills/13_Visualization/brain-visualization/scripts/connectome_reference.py +108 -0
- package/skills/13_Visualization/brain-visualization/scripts/freesurfer_ply_reference.py +54 -0
- package/skills/13_Visualization/brain-visualization/scripts/zalff_summary_reference.py +116 -0
- package/skills/13_Visualization/ethoclaw-paper-figure-layout/SKILL.md +78 -0
- package/skills/13_Visualization/ethoclaw-paper-figure-layout/assets/naturecomm_figures.tex +74 -0
- package/skills/13_Visualization/ethoclaw-paper-figure-layout/scripts/layout_results_foldered.py +579 -0
- package/skills/14_Writing/overleaf-skill/SKILL.md +184 -0
- package/skills/14_Writing/overleaf-skill/scripts/install.sh +30 -0
- package/skills/14_Writing/paper-writing/SKILL.md +146 -0
- package/skills/14_Writing/paper-writing/scripts/data_statement_templates.py +164 -0
- package/skills/14_Writing/paper-writing/scripts/figure_templates.py +315 -0
- package/skills/14_Writing/paper-writing/scripts/nature_figure_style.py +214 -0
- package/skills/14_Writing/paper-writing/scripts/section_phrasebank.py +246 -0
- package/skills/16_Animal_Behavior/deeplabcut/SKILL.md +154 -0
- package/skills/16_Animal_Behavior/deeplabcut/references/3d-pose.md +89 -0
- package/skills/16_Animal_Behavior/deeplabcut/references/maDLC.md +123 -0
- package/skills/16_Animal_Behavior/deeplabcut/references/modelzoo.md +98 -0
- package/skills/16_Animal_Behavior/deeplabcut/references/standard-pipeline.md +165 -0
- package/skills/16_Animal_Behavior/deeplabcut/references/utilities.md +146 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/SKILL.md +274 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/report_template_en.html +112 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/report_template_en.md +21 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/cluster-section.md +5 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/heatmap-section.md +5 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/integrated-interpretation.md +3 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/overview.md +3 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/project-summary.md +3 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/radar-section.md +5 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/raw-trajectory.md +3 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/sample-check.md +3 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/single-subject-section.md +3 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/stats-section.md +5 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/epm.md +52 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/fst.md +37 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/nor.md +39 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/oft.md +43 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/tcst.md +45 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/tst.md +36 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/input-types.md +59 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/interpretation-guardrails.md +45 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/metadata-schema.md +57 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/report-sections.md +86 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/section-selection-rules.md +169 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/scripts/build_report_manifest.py +27 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/scripts/render_report.py +34 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/scripts/report_utils.py +1121 -0
- package/skills/16_Animal_Behavior/ethoclaw-animal-grounding/SKILL.md +390 -0
- package/skills/16_Animal_Behavior/ethoclaw-animal-grounding/reference_code.py +98 -0
- package/skills/16_Animal_Behavior/ethoclaw-animal-pose-estimation/SKILL.md +336 -0
- package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/README.md +21 -0
- package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/SKILL.md +41 -0
- package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/batch_kinematic_generator.py +663 -0
- package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/config.json +19 -0
- package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/generate_kinematic_parameter.py +401 -0
- package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/kinematic_generator.py +265 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/SKILL.md +72 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/references/config.example.toml +56 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/scripts/cluster_all_params.py +232 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/scripts/cluster_all_params_from_config.py +236 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-radar-generate/SKILL.md +68 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-radar-generate/references/notes.md +5 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-radar-generate/scripts/plot_h5_radar.py +513 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/SKILL.md +52 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/config.toml +81 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/references/stats-rule.md +18 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/scripts/h5_inspect.py +79 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/scripts/h5_violin_batch.py +624 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/scripts/h5_violin_stats.py +438 -0
- package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/SKILL.md +280 -0
- package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/core_scripts/heatmap_trajectory.py +790 -0
- package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/core_scripts/heatmap_velocity.py +855 -0
- package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/reference_data/reference_2d.csv +101 -0
- package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/reference_data/reference_2d.h5 +0 -0
- package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/reference_data/reference_data_readme.md +126 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dmt-har-med-skill
|
|
3
|
+
description: "Use this skill whenever the user wants an end-to-end workflow for the DMT-HAR-MED dataset (ds006644), including download, BIDS organization, and processing of rs-fMRI data from a psychedelic intervention study. Triggers include: 'DMT-HAR-MED', 'DMT HAR MED', 'ds006644', 'process DMT data', 'psychedelic fMRI', or any request to run the DMT-HAR-MED pipeline. This is the NeuroClaw dataset-orchestration layer for DMT-HAR-MED."
|
|
4
|
+
license: MIT License (NeuroClaw custom skill - freely modifiable within the project)
|
|
5
|
+
layer: subagent
|
|
6
|
+
skill_type: dataset
|
|
7
|
+
dependencies:
|
|
8
|
+
- fmri-skill
|
|
9
|
+
- bids-organizer
|
|
10
|
+
- claw-shell
|
|
11
|
+
---
|
|
12
|
+
# DMT-HAR-MED Skill (Dataset-Orchestration Layer)
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
`dmt-har-med-skill` is the NeuroClaw orchestration skill for the **DMT-HAR-MED** dataset (OpenNeuro ds006644).
|
|
16
|
+
|
|
17
|
+
DMT-HAR-MED contains rs-fMRI data from 40 participants in a psychedelic intervention study investigating the effects of N,N-Dimethyltryptamine (DMT) on brain function. The dataset includes multiple experimental conditions (DMT, placebo) and behavioral/physiological measurements.
|
|
18
|
+
|
|
19
|
+
It coordinates a fixed three-phase workflow:
|
|
20
|
+
1. Download DMT-HAR-MED data from OpenNeuro.
|
|
21
|
+
2. Prepare and validate BIDS-style data organization.
|
|
22
|
+
3. Delegate fMRI processing to `fmri-skill`.
|
|
23
|
+
|
|
24
|
+
It also provides **phenotype extraction** and **QC integration** paths:
|
|
25
|
+
- Extract DMT-HAR-MED phenotype data (intervention conditions, behavioral measures).
|
|
26
|
+
- Generate per-subject QC summaries with exclusion lists.
|
|
27
|
+
|
|
28
|
+
This skill follows NeuroClaw hierarchy:
|
|
29
|
+
- Defines **WHAT to do**, not low-level implementation details.
|
|
30
|
+
- Does **not** execute direct shell commands itself.
|
|
31
|
+
- Delegates all execution via `claw-shell` to base/tool skills.
|
|
32
|
+
|
|
33
|
+
**Research use only.**
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Download Stage (Mandatory First Step)
|
|
38
|
+
|
|
39
|
+
### Source
|
|
40
|
+
DMT-HAR-MED data is available on OpenNeuro:
|
|
41
|
+
- Website: https://openneuro.org/datasets/ds006644/versions/1.0.1
|
|
42
|
+
|
|
43
|
+
### Supported DMT-HAR-MED Data Packages
|
|
44
|
+
- **Imaging data**: rs-fMRI (NIfTI format)
|
|
45
|
+
- **Phenotype data**: intervention conditions, behavioral and physiological measurements
|
|
46
|
+
- **Participants**: 40 participants with psychedelic intervention
|
|
47
|
+
|
|
48
|
+
### Delegation Rules for Download
|
|
49
|
+
- Environment/setup checks: `dependency-planner` + `conda-env-manager`
|
|
50
|
+
- OpenNeuro dataset download: `claw-shell` (via `openneuro` CLI or `datalad`)
|
|
51
|
+
- Optional raw-data organization to BIDS-style staging: `bids-organizer`
|
|
52
|
+
|
|
53
|
+
### Download Inputs to Confirm in Plan
|
|
54
|
+
- Subject list scope (full or custom subset)
|
|
55
|
+
- Destination directory with sufficient disk space
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Core Workflow (Never Bypassed)
|
|
60
|
+
1. Identify user target: download, BIDS staging, or full preprocessing.
|
|
61
|
+
2. Generate a numbered plan with tools, outputs, runtime, storage, and risks.
|
|
62
|
+
3. Wait for explicit confirmation (`YES` / `execute` / `proceed`).
|
|
63
|
+
4. On confirmation, run download stage first (if needed).
|
|
64
|
+
5. After download success, verify/prepare BIDS staging using `scripts/reorganize_dmt_har_med.py`.
|
|
65
|
+
6. Delegate to `fmri-skill` for rs-fMRI processing.
|
|
66
|
+
7. If phenotype extraction is requested, run `scripts/extract_dmt_har_med_phenotype.py`.
|
|
67
|
+
8. If QC summary is requested, run `scripts/dmt_har_med_qc_summary.py`.
|
|
68
|
+
9. Save outputs into a DMT-HAR-MED-centered structure under `dmt_har_med_output/`.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## BIDS Preparation
|
|
73
|
+
|
|
74
|
+
### Script: `scripts/reorganize_dmt_har_med.py`
|
|
75
|
+
|
|
76
|
+
Verifies and optionally reorganizes DMT-HAR-MED data to BIDS-compliant layout.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
python skills/dmt-har-med-skill/scripts/reorganize_dmt_har_med.py \
|
|
80
|
+
--input /path/to/dmt_har_med_raw \
|
|
81
|
+
--output /path/to/dmt_har_med_bids
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Features:
|
|
85
|
+
- BIDS validation and verification
|
|
86
|
+
- Subject ID normalization
|
|
87
|
+
- Modality routing: rs-fMRI
|
|
88
|
+
- `dataset_description.json` and `participants.tsv` generation
|
|
89
|
+
- Dry-run mode: `--dry-run` to preview
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Phenotype Extraction
|
|
94
|
+
|
|
95
|
+
### Script: `scripts/extract_dmt_har_med_phenotype.py`
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
python skills/dmt-har-med-skill/scripts/extract_dmt_har_med_phenotype.py \
|
|
99
|
+
--phenotype-dir /path/to/dmt_har_med_raw/phenotype \
|
|
100
|
+
--output /path/to/dmt_har_med_output/phenotype/merged_phenotype.csv \
|
|
101
|
+
--imaging-ids /path/to/dmt_har_med_output/bids/participants.tsv
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## QC Integration
|
|
107
|
+
|
|
108
|
+
### Script: `scripts/dmt_har_med_qc_summary.py`
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
python skills/dmt-har-med-skill/scripts/dmt_har_med_qc_summary.py \
|
|
112
|
+
--fmriprep-dir /path/to/dmt_har_med_output/fmriprep \
|
|
113
|
+
--output /path/to/dmt_har_med_output/qc/qc_summary.csv \
|
|
114
|
+
--exclude-output /path/to/dmt_har_med_output/qc/exclude_list.csv \
|
|
115
|
+
--fd-threshold 0.3
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Recommended Output Layout
|
|
121
|
+
All assets should be organized under `./dmt_har_med_output/`:
|
|
122
|
+
- `dmt_har_med_output/raw/` (downloaded original files)
|
|
123
|
+
- `dmt_har_med_output/bids/` (BIDS data)
|
|
124
|
+
- `dmt_har_med_output/fmri/` (links or copies from `fmri_output/`)
|
|
125
|
+
- `dmt_har_med_output/phenotype/` (merged phenotype tables)
|
|
126
|
+
- `dmt_har_med_output/qc/` (QC summaries and exclusion lists)
|
|
127
|
+
- `dmt_har_med_output/logs/` (download + orchestration logs)
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Benchmark Adapter Guidance
|
|
132
|
+
|
|
133
|
+
For benchmark-style prompts, do not force the full `download -> staging -> multimodal processing` orchestration when the task is only asking for local DMT-HAR-MED data staging or organization.
|
|
134
|
+
|
|
135
|
+
- If the task starts from raw DMT-HAR-MED data already present on disk and only asks for BIDS-style staging / validation:
|
|
136
|
+
- skip the mandatory download stage
|
|
137
|
+
- default to the narrow path `local raw DMT-HAR-MED discovery -> BIDS validation -> minimal metadata -> report`
|
|
138
|
+
- In benchmark mode, do not require explicit confirmation before presenting the direct staging solution.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Safety and Execution Policy
|
|
143
|
+
- No execution before explicit plan confirmation.
|
|
144
|
+
- All execution must be routed via `claw-shell`.
|
|
145
|
+
- Missing dependencies must be resolved by `dependency-planner` before running.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Important Notes and Limitations
|
|
150
|
+
- DMT-HAR-MED is a specialized psychedelic intervention dataset; analysis requires domain expertise.
|
|
151
|
+
- DMT-HAR-MED data from OpenNeuro is already in BIDS format; re-staging may not be needed.
|
|
152
|
+
- The dataset includes multiple experimental conditions; event files define condition timing.
|
|
153
|
+
- DMT-HAR-MED includes only rs-fMRI; no structural (T1w) or diffusion data is available.
|
|
154
|
+
- `dmt-har-med-skill` is orchestration-only; detailed preprocessing logic remains in `fmri-skill`.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## When to Call This Skill
|
|
159
|
+
- User asks for end-to-end DMT-HAR-MED workflow.
|
|
160
|
+
- User asks to download DMT-HAR-MED data and then run rs-fMRI processing.
|
|
161
|
+
- User needs BIDS validation for DMT-HAR-MED data.
|
|
162
|
+
- User asks to extract DMT-HAR-MED phenotype data.
|
|
163
|
+
- User needs DMT-HAR-MED-specific QC summaries.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Complementary / Related Skills
|
|
168
|
+
- `fmri-skill`
|
|
169
|
+
- `bids-organizer`
|
|
170
|
+
- `fmriprep-tool`
|
|
171
|
+
- `dependency-planner`
|
|
172
|
+
- `conda-env-manager`
|
|
173
|
+
- `claw-shell`
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Reference
|
|
178
|
+
- DMT-HAR-MED: https://openneuro.org/datasets/ds006644/versions/1.0.1
|
|
179
|
+
- BIDS spec: https://bids.neuroimaging.io/
|
|
180
|
+
|
|
181
|
+
Created At: 2026-05-06 01:56 HKT
|
|
182
|
+
Last Updated At: 2026-05-06 01:56 HKT
|
|
183
|
+
Author: chengwang96
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate per-subject QC summaries and exclusion lists for DMT-HAR-MED."""
|
|
3
|
+
import argparse
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Dict, List, Tuple
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
import pandas as pd
|
|
10
|
+
except ImportError:
|
|
11
|
+
print("Error: pandas is required.", file=sys.stderr)
|
|
12
|
+
sys.exit(1)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def detect_delimiter(file_path: Path) -> str:
|
|
16
|
+
with open(file_path, "r", encoding="utf-8") as f:
|
|
17
|
+
return "\t" if "\t" in f.readline() else ","
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def collect_fmriprep_qc(fmriprep_dir: Path) -> Dict[str, Dict[str, float]]:
|
|
21
|
+
qc = {}
|
|
22
|
+
for confounds_file in fmriprep_dir.rglob("**/*_desc-confounds_timeseries.tsv"):
|
|
23
|
+
subject_id = next((p for p in confounds_file.parts if p.startswith("sub-")), None)
|
|
24
|
+
if not subject_id:
|
|
25
|
+
continue
|
|
26
|
+
try:
|
|
27
|
+
df = pd.read_csv(confounds_file, sep=detect_delimiter(confounds_file), low_memory=False)
|
|
28
|
+
except Exception:
|
|
29
|
+
continue
|
|
30
|
+
fd_col = next((c for c in ["framewise_displacement", "fd", "FD"] if c in df.columns), None)
|
|
31
|
+
if fd_col:
|
|
32
|
+
fd = pd.to_numeric(df[fd_col], errors="coerce").dropna()
|
|
33
|
+
if len(fd) > 0:
|
|
34
|
+
metrics = {"mean_fd": float(fd.mean()), "max_fd": float(fd.max()), "n_volumes": len(df)}
|
|
35
|
+
if subject_id in qc:
|
|
36
|
+
qc[subject_id]["mean_fd"] = max(qc[subject_id].get("mean_fd", 0), metrics["mean_fd"])
|
|
37
|
+
qc[subject_id]["max_fd"] = max(qc[subject_id].get("max_fd", 0), metrics["max_fd"])
|
|
38
|
+
qc[subject_id]["n_volumes"] = qc[subject_id].get("n_volumes", 0) + metrics["n_volumes"]
|
|
39
|
+
else:
|
|
40
|
+
qc[subject_id] = metrics
|
|
41
|
+
return qc
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def main() -> int:
|
|
45
|
+
parser = argparse.ArgumentParser(description="Generate DMT-HAR-MED QC summaries.")
|
|
46
|
+
parser.add_argument("--fmriprep-dir", help="Path to fMRIPrep output directory")
|
|
47
|
+
parser.add_argument("--output", required=True, help="Output path for QC summary CSV")
|
|
48
|
+
parser.add_argument("--exclude-output", help="Output path for exclusion list CSV")
|
|
49
|
+
parser.add_argument("--fd-threshold", type=float, default=0.3, help="Mean FD threshold (default: 0.3)")
|
|
50
|
+
parser.add_argument("--max-fd-threshold", type=float, default=5.0, help="Max FD threshold (default: 5.0)")
|
|
51
|
+
args = parser.parse_args()
|
|
52
|
+
|
|
53
|
+
fmriprep_qc = {}
|
|
54
|
+
if args.fmriprep_dir:
|
|
55
|
+
fp_dir = Path(args.fmriprep_dir).resolve()
|
|
56
|
+
if fp_dir.exists():
|
|
57
|
+
print(f"Collecting fMRIPrep QC from {fp_dir}...")
|
|
58
|
+
fmriprep_qc = collect_fmriprep_qc(fp_dir)
|
|
59
|
+
print(f" Found {len(fmriprep_qc)} subjects")
|
|
60
|
+
|
|
61
|
+
if not fmriprep_qc:
|
|
62
|
+
print("[ERROR] No QC data collected.", file=sys.stderr)
|
|
63
|
+
return 1
|
|
64
|
+
|
|
65
|
+
rows = []
|
|
66
|
+
excluded = []
|
|
67
|
+
for sub_id in sorted(fmriprep_qc.keys()):
|
|
68
|
+
fp = fmriprep_qc[sub_id]
|
|
69
|
+
reasons = []
|
|
70
|
+
if fp.get("mean_fd", 0) > args.fd_threshold:
|
|
71
|
+
reasons.append(f"mean_fd={fp['mean_fd']:.3f}>{args.fd_threshold}")
|
|
72
|
+
if fp.get("max_fd", 0) > args.max_fd_threshold:
|
|
73
|
+
reasons.append(f"max_fd={fp['max_fd']:.3f}>{args.max_fd_threshold}")
|
|
74
|
+
row = {"subject_id": sub_id, "mean_fd": fp.get("mean_fd"), "max_fd": fp.get("max_fd"), "n_volumes": fp.get("n_volumes"), "exclude": bool(reasons), "exclude_reasons": "; ".join(reasons)}
|
|
75
|
+
if reasons:
|
|
76
|
+
excluded.append(sub_id)
|
|
77
|
+
rows.append(row)
|
|
78
|
+
|
|
79
|
+
summary_df = pd.DataFrame(rows)
|
|
80
|
+
output_path = Path(args.output).resolve()
|
|
81
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
82
|
+
summary_df.to_csv(output_path, index=False)
|
|
83
|
+
print(f"\nQC Summary: {len(summary_df)} subjects -> {output_path}")
|
|
84
|
+
print(f" Excluded: {len(excluded)} / {len(summary_df)} ({100*len(excluded)/max(len(summary_df),1):.1f}%)")
|
|
85
|
+
|
|
86
|
+
if args.exclude_output:
|
|
87
|
+
exclude_path = Path(args.exclude_output).resolve()
|
|
88
|
+
exclude_path.parent.mkdir(parents=True, exist_ok=True)
|
|
89
|
+
summary_df[summary_df["exclude"] == True][["subject_id", "exclude_reasons"]].to_csv(exclude_path, index=False)
|
|
90
|
+
print(f" Exclusion list: {exclude_path}")
|
|
91
|
+
|
|
92
|
+
return 0
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
if __name__ == "__main__":
|
|
96
|
+
sys.exit(main())
|
package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/extract_dmt_har_med_phenotype.py
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Extract and merge DMT-HAR-MED phenotype data for downstream analysis."""
|
|
3
|
+
import argparse
|
|
4
|
+
import csv
|
|
5
|
+
import re
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Dict, List, Optional
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
import pandas as pd
|
|
12
|
+
except ImportError:
|
|
13
|
+
print("Error: pandas is required.", file=sys.stderr)
|
|
14
|
+
sys.exit(1)
|
|
15
|
+
|
|
16
|
+
COLUMN_MAP = {
|
|
17
|
+
"participant_id": "subject_id",
|
|
18
|
+
"subject": "subject_id",
|
|
19
|
+
"SUBJECT_ID": "subject_id",
|
|
20
|
+
"group": "condition",
|
|
21
|
+
"GROUP": "condition",
|
|
22
|
+
"condition": "condition",
|
|
23
|
+
"age": "age",
|
|
24
|
+
"AGE": "age",
|
|
25
|
+
"sex": "sex",
|
|
26
|
+
"SEX": "sex",
|
|
27
|
+
"gender": "sex",
|
|
28
|
+
"session": "session",
|
|
29
|
+
"SESSION": "session",
|
|
30
|
+
"visit": "session",
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
CONDITION_LABELS = {
|
|
34
|
+
"DMT": "dmt",
|
|
35
|
+
"dmt": "dmt",
|
|
36
|
+
"placebo": "placebo",
|
|
37
|
+
"Placebo": "placebo",
|
|
38
|
+
"control": "placebo",
|
|
39
|
+
"Control": "placebo",
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def normalize_subject_id(raw_id) -> str:
|
|
44
|
+
clean = re.sub(r"[^a-zA-Z0-9]", "", str(raw_id).strip())
|
|
45
|
+
return f"sub-{clean}"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def main() -> int:
|
|
49
|
+
parser = argparse.ArgumentParser(description="Extract DMT-HAR-MED phenotype data.")
|
|
50
|
+
parser.add_argument("--phenotype-dir", help="Directory containing phenotype CSV/TSV files")
|
|
51
|
+
parser.add_argument("--phenotype-file", help="Direct path to phenotype CSV/TSV file")
|
|
52
|
+
parser.add_argument("--output", required=True, help="Output path for phenotype CSV")
|
|
53
|
+
parser.add_argument("--imaging-ids", help="Path to BIDS participants.tsv for filtering")
|
|
54
|
+
args = parser.parse_args()
|
|
55
|
+
|
|
56
|
+
phenotype_files = []
|
|
57
|
+
if args.phenotype_file:
|
|
58
|
+
p = Path(args.phenotype_file).resolve()
|
|
59
|
+
if p.exists():
|
|
60
|
+
phenotype_files.append(p)
|
|
61
|
+
elif args.phenotype_dir:
|
|
62
|
+
phenotype_dir = Path(args.phenotype_dir).resolve()
|
|
63
|
+
if phenotype_dir.exists():
|
|
64
|
+
phenotype_files = sorted(f for f in phenotype_dir.iterdir() if f.is_file() and f.suffix in (".csv", ".tsv"))
|
|
65
|
+
|
|
66
|
+
if not phenotype_files:
|
|
67
|
+
print("[ERROR] No phenotype files found.", file=sys.stderr)
|
|
68
|
+
return 1
|
|
69
|
+
|
|
70
|
+
print(f"Found {len(phenotype_files)} phenotype file(s)")
|
|
71
|
+
|
|
72
|
+
dataframes = []
|
|
73
|
+
for f in phenotype_files:
|
|
74
|
+
try:
|
|
75
|
+
df = pd.read_csv(f, sep=None, engine="python", low_memory=False)
|
|
76
|
+
rename = {k: v for k, v in COLUMN_MAP.items() if k in df.columns and v not in df.columns}
|
|
77
|
+
df = df.rename(columns=rename)
|
|
78
|
+
if "condition" in df.columns:
|
|
79
|
+
df["condition"] = df["condition"].map(lambda x: CONDITION_LABELS.get(str(x), str(x).lower()))
|
|
80
|
+
dataframes.append(df)
|
|
81
|
+
except Exception as e:
|
|
82
|
+
print(f"[WARN] Failed to read {f}: {e}")
|
|
83
|
+
|
|
84
|
+
if not dataframes:
|
|
85
|
+
print("[ERROR] No data loaded.", file=sys.stderr)
|
|
86
|
+
return 1
|
|
87
|
+
|
|
88
|
+
merged = dataframes[0]
|
|
89
|
+
for df in dataframes[1:]:
|
|
90
|
+
if "subject_id" in merged.columns and "subject_id" in df.columns:
|
|
91
|
+
new_cols = [c for c in df.columns if c not in merged.columns or c == "subject_id"]
|
|
92
|
+
merged = pd.merge(merged, df[new_cols], on="subject_id", how="outer")
|
|
93
|
+
else:
|
|
94
|
+
merged = pd.concat([merged, df], ignore_index=True)
|
|
95
|
+
|
|
96
|
+
if args.imaging_ids:
|
|
97
|
+
imaging_path = Path(args.imaging_ids).resolve()
|
|
98
|
+
if imaging_path.exists() and "subject_id" in merged.columns:
|
|
99
|
+
id_df = pd.read_csv(imaging_path, sep="\t")
|
|
100
|
+
for col in ["participant_id", "subject_id"]:
|
|
101
|
+
if col in id_df.columns:
|
|
102
|
+
imaging_ids = set(id_df[col].astype(str).str.strip())
|
|
103
|
+
normalized = {normalize_subject_id(sid) for sid in imaging_ids} | imaging_ids
|
|
104
|
+
merged["_norm"] = merged["subject_id"].apply(normalize_subject_id)
|
|
105
|
+
merged = merged[merged["_norm"].isin(normalized) | merged["subject_id"].astype(str).isin(normalized)]
|
|
106
|
+
merged = merged.drop(columns=["_norm"])
|
|
107
|
+
break
|
|
108
|
+
|
|
109
|
+
output_path = Path(args.output).resolve()
|
|
110
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
111
|
+
merged.to_csv(output_path, index=False)
|
|
112
|
+
print(f"\nWrote {len(merged)} rows x {len(merged.columns)} columns to {output_path}")
|
|
113
|
+
|
|
114
|
+
if "condition" in merged.columns:
|
|
115
|
+
print(f"\nCondition distribution:\n{merged['condition'].value_counts().to_string()}")
|
|
116
|
+
|
|
117
|
+
return 0
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
if __name__ == "__main__":
|
|
121
|
+
sys.exit(main())
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Validate and optionally reorganize DMT-HAR-MED OpenNeuro BIDS data."""
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import shutil
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Dict, List, Optional
|
|
9
|
+
|
|
10
|
+
BIDS_MODALITIES = {"T1w": "anat", "T2w": "anat", "FLAIR": "anat",
|
|
11
|
+
"task-rest_bold": "func", "task-*_bold": "func",
|
|
12
|
+
"dwi": "dwi", "bold": "func"}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def validate_bids(bids_root: Path) -> Dict[str, List[str]]:
|
|
16
|
+
"""Validate BIDS structure and return report."""
|
|
17
|
+
issues: Dict[str, List[str]] = {"errors": [], "warnings": []}
|
|
18
|
+
if not (bids_root / "dataset_description.json").exists():
|
|
19
|
+
issues["errors"].append("Missing dataset_description.json")
|
|
20
|
+
participants_tsv = bids_root / "participants.tsv"
|
|
21
|
+
if not participants_tsv.exists():
|
|
22
|
+
issues["warnings"].append("Missing participants.tsv")
|
|
23
|
+
subject_dirs = sorted(d for d in bids_root.iterdir() if d.is_dir() and d.name.startswith("sub-"))
|
|
24
|
+
if not subject_dirs:
|
|
25
|
+
issues["errors"].append("No subject directories found")
|
|
26
|
+
for sub_dir in subject_dirs:
|
|
27
|
+
session_dirs = [d for d in sub_dir.iterdir() if d.is_dir() and d.name.startswith("ses-")]
|
|
28
|
+
if not session_dirs:
|
|
29
|
+
session_dirs = [sub_dir]
|
|
30
|
+
for ses_dir in session_dirs:
|
|
31
|
+
func_dir = ses_dir / "func"
|
|
32
|
+
anat_dir = ses_dir / "anat"
|
|
33
|
+
if not func_dir.exists() and not anat_dir.exists():
|
|
34
|
+
issues["warnings"].append(f"{sub_dir.name}/{ses_dir.name}: no func/ or anat/ directory")
|
|
35
|
+
return issues
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def collect_nifti_manifest(bids_root: Path) -> List[Dict[str, str]]:
|
|
39
|
+
"""Collect all NIfTI files in BIDS directory."""
|
|
40
|
+
manifest = []
|
|
41
|
+
for nifti in sorted(bids_root.rglob("*.nii.gz")):
|
|
42
|
+
rel = nifti.relative_to(bids_root)
|
|
43
|
+
parts = rel.parts
|
|
44
|
+
subject = next((p for p in parts if p.startswith("sub-")), "unknown")
|
|
45
|
+
session = next((p for p in parts if p.startswith("ses-")), "")
|
|
46
|
+
modality_dir = next((p for p in parts if p in ("anat", "func", "dwi", "fmap")), "unknown")
|
|
47
|
+
manifest.append({
|
|
48
|
+
"subject": subject,
|
|
49
|
+
"session": session,
|
|
50
|
+
"modality": modality_dir,
|
|
51
|
+
"filename": nifti.name,
|
|
52
|
+
"path": str(rel),
|
|
53
|
+
})
|
|
54
|
+
return manifest
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def copy_to_output(bids_root: Path, output_dir: Path, manifest: List[Dict[str, str]]) -> int:
|
|
58
|
+
"""Copy BIDS files to output directory."""
|
|
59
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
60
|
+
copied = 0
|
|
61
|
+
for entry in manifest:
|
|
62
|
+
src = bids_root / entry["path"]
|
|
63
|
+
dst = output_dir / entry["path"]
|
|
64
|
+
dst.parent.mkdir(parents=True, exist_ok=True)
|
|
65
|
+
if not dst.exists():
|
|
66
|
+
shutil.copy2(str(src), str(dst))
|
|
67
|
+
copied += 1
|
|
68
|
+
return copied
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def main() -> int:
|
|
72
|
+
parser = argparse.ArgumentParser(description="Validate/reorganize DMT-HAR-MED BIDS data.")
|
|
73
|
+
parser.add_argument("--input", required=True, help="Path to DMT-HAR-MED BIDS directory")
|
|
74
|
+
parser.add_argument("--output", help="Output path for reorganized BIDS directory")
|
|
75
|
+
parser.add_argument("--validate-only", action="store_true", help="Only validate, don't copy")
|
|
76
|
+
parser.add_argument("--manifest-output", help="Output path for NIfTI manifest TSV")
|
|
77
|
+
args = parser.parse_args()
|
|
78
|
+
|
|
79
|
+
input_dir = Path(args.input).resolve()
|
|
80
|
+
if not input_dir.exists():
|
|
81
|
+
print(f"Input directory not found: {input_dir}", file=sys.stderr)
|
|
82
|
+
return 1
|
|
83
|
+
|
|
84
|
+
print(f"Validating BIDS structure at {input_dir}...")
|
|
85
|
+
issues = validate_bids(input_dir)
|
|
86
|
+
|
|
87
|
+
if issues["errors"]:
|
|
88
|
+
print(f"\n[ERRORS] ({len(issues['errors'])}):")
|
|
89
|
+
for e in issues["errors"]:
|
|
90
|
+
print(f" - {e}")
|
|
91
|
+
if issues["warnings"]:
|
|
92
|
+
print(f"\n[WARNINGS] ({len(issues['warnings'])}):")
|
|
93
|
+
for w in issues["warnings"]:
|
|
94
|
+
print(f" - {w}")
|
|
95
|
+
if not issues["errors"] and not issues["warnings"]:
|
|
96
|
+
print(" BIDS structure looks valid.")
|
|
97
|
+
|
|
98
|
+
manifest = collect_nifti_manifest(input_dir)
|
|
99
|
+
print(f"\nFound {len(manifest)} NIfTI files")
|
|
100
|
+
|
|
101
|
+
subjects = set(e["subject"] for e in manifest)
|
|
102
|
+
modalities = set(e["modality"] for e in manifest)
|
|
103
|
+
print(f" Subjects: {len(subjects)}")
|
|
104
|
+
print(f" Modalities: {', '.join(sorted(modalities))}")
|
|
105
|
+
|
|
106
|
+
if args.manifest_output:
|
|
107
|
+
import csv
|
|
108
|
+
manifest_path = Path(args.manifest_output).resolve()
|
|
109
|
+
manifest_path.parent.mkdir(parents=True, exist_ok=True)
|
|
110
|
+
with open(manifest_path, "w", encoding="utf-8", newline="") as f:
|
|
111
|
+
writer = csv.DictWriter(f, fieldnames=manifest[0].keys(), delimiter="\t")
|
|
112
|
+
writer.writeheader()
|
|
113
|
+
writer.writerows(manifest)
|
|
114
|
+
print(f" Manifest: {manifest_path}")
|
|
115
|
+
|
|
116
|
+
if not args.validate_only and args.output:
|
|
117
|
+
output_dir = Path(args.output).resolve()
|
|
118
|
+
copied = copy_to_output(input_dir, output_dir, manifest)
|
|
119
|
+
print(f"\nCopied {copied} files to {output_dir}")
|
|
120
|
+
|
|
121
|
+
return 0
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
if __name__ == "__main__":
|
|
125
|
+
sys.exit(main())
|