@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.
- 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,205 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: oasis-skill
|
|
3
|
+
description: "Use this skill whenever the user wants an end-to-end workflow for the OASIS (Open Access Series of Imaging Studies) dataset, including BIDS validation, multimodal processing of sMRI, and phenotype extraction for aging and Alzheimer's disease research. Triggers include: 'OASIS', 'OASIS-1', 'OASIS-2', 'OASIS-3', 'process OASIS data', 'Alzheimer', or any request to run the OASIS 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
|
+
- bids-organizer
|
|
10
|
+
- claw-shell
|
|
11
|
+
complementary_skills:
|
|
12
|
+
- fmri-skill
|
|
13
|
+
- asl-skill
|
|
14
|
+
- pet-skill
|
|
15
|
+
- brain-visualization
|
|
16
|
+
---
|
|
17
|
+
# OASIS Skill (Dataset-Orchestration Layer)
|
|
18
|
+
|
|
19
|
+
## Overview
|
|
20
|
+
|
|
21
|
+
`oasis-skill` is the NeuroClaw orchestration skill for the **OASIS (Open Access Series of Imaging Studies)** dataset, founded by the Knight Alzheimer Disease Research Center at Washington University.
|
|
22
|
+
|
|
23
|
+
It strictly follows the NeuroClaw hierarchical design principles:
|
|
24
|
+
- This skill **only describes WHAT needs to be done** and **which tool skill to delegate to**.
|
|
25
|
+
- It contains **no implementation code or concrete commands**.
|
|
26
|
+
- All concrete execution is delegated to existing base/tool skills via `claw-shell`.
|
|
27
|
+
- Companion scripts in `scripts/` provide reference implementations for BIDS validation, phenotype extraction, and QC.
|
|
28
|
+
|
|
29
|
+
**Core workflow (never bypassed):**
|
|
30
|
+
1. Identify input OASIS data and target modalities.
|
|
31
|
+
2. Generate a **numbered execution plan** clearly stating WHAT needs to be done and which tool skill will handle each step.
|
|
32
|
+
3. Present the full plan, estimated runtime, resource requirements, and risks to the user and wait for explicit confirmation ("YES" / "execute" / "proceed").
|
|
33
|
+
4. On confirmation, delegate every step to the appropriate skill via `claw-shell`.
|
|
34
|
+
5. After execution, save all outputs in a clean directory structure (`oasis_output/`).
|
|
35
|
+
|
|
36
|
+
**Research use only.**
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Quick Reference
|
|
41
|
+
|
|
42
|
+
| Task | What needs to be done | Delegate to | Expected output |
|
|
43
|
+
|---|---|---|---|
|
|
44
|
+
| BIDS validation | Validate OASIS BIDS structure | `scripts/validate_oasis.py` | Validation report |
|
|
45
|
+
| sMRI processing | Brain extraction, tissue segmentation, cortical thickness | `smri-skill` | `smri_output/` derivatives |
|
|
46
|
+
| Phenotype extraction | CDR, MMSE, demographic data | `scripts/extract_oasis_phenotype.py` | Merged phenotype CSV |
|
|
47
|
+
| QC summary | Per-subject quality control | `scripts/oasis_qc_summary.py` | QC summary + exclusion list |
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Dataset Characteristics
|
|
52
|
+
|
|
53
|
+
- **OASIS-1 (Cross-sectional)**: ~416 subjects aged 18-96
|
|
54
|
+
- T1w MRI, some with very mild to mild AD
|
|
55
|
+
- **OASIS-2 (Longitudinal)**: ~150 subjects aged 60-96
|
|
56
|
+
- Multiple sessions, non-demented and demented
|
|
57
|
+
- **OASIS-3**: ~1,000+ subjects, longitudinal spanning ~20 years
|
|
58
|
+
- T1w, PET (amyloid, tau), ASL
|
|
59
|
+
- **Scanner**: 1.5T Siemens Vision
|
|
60
|
+
- **Clinical**: CDR (Clinical Dementia Rating), MMSE, demographics
|
|
61
|
+
- **Access**: OpenNeuro ds000014 (OASIS-1), www.oasis-brains.org (OASIS-3)
|
|
62
|
+
- **Format**: BIDS-compliant (OASIS-1), raw + derivatives (OASIS-3)
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Supported Modalities
|
|
67
|
+
|
|
68
|
+
| Modality | Description | Versions |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| T1w | High-resolution structural MRI | OASIS-1, 2, 3 |
|
|
71
|
+
| PET | Amyloid (PIB/AV45), Tau (AV1451) | OASIS-3 |
|
|
72
|
+
| ASL | Arterial spin labeling perfusion | OASIS-3 |
|
|
73
|
+
| fMRI | Functional MRI | OASIS-3 (limited) |
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## OASIS Clinical Measures
|
|
78
|
+
|
|
79
|
+
| Measure | Description | Range |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| CDR | Clinical Dementia Rating | 0 (normal), 0.5 (very mild), 1 (mild), 2 (moderate), 3 (severe) |
|
|
82
|
+
| MMSE | Mini-Mental State Examination | 0-30 (higher = better) |
|
|
83
|
+
| Age | Age at scan | 18-96 years |
|
|
84
|
+
| Sex | Biological sex | M/F |
|
|
85
|
+
| SES | Socioeconomic status | 1-5 |
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## BIDS Preparation
|
|
90
|
+
|
|
91
|
+
### Script: `scripts/validate_oasis.py`
|
|
92
|
+
|
|
93
|
+
Validates OASIS BIDS structure and generates a compliance report.
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
python skills/oasis-skill/scripts/validate_oasis.py \
|
|
97
|
+
--input /path/to/OASIS/bids \
|
|
98
|
+
--output /path/to/oasis_output/qc/bids_validation.csv
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Features:
|
|
102
|
+
- BIDS directory structure validation
|
|
103
|
+
- Version detection (OASIS-1 vs OASIS-2 vs OASIS-3)
|
|
104
|
+
- Modality completeness check
|
|
105
|
+
- CDR/MMSE availability verification
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Core Workflow (Never Bypassed)
|
|
110
|
+
|
|
111
|
+
1. Identify user target: full OASIS processing, sMRI only, phenotype extraction, or BIDS validation only.
|
|
112
|
+
2. Generate a numbered plan with tools, outputs, runtime, storage, and risks.
|
|
113
|
+
3. Wait for explicit confirmation (`YES` / `execute` / `proceed`).
|
|
114
|
+
4. On confirmation, run BIDS validation using `scripts/validate_oasis.py`.
|
|
115
|
+
5. Delegate to `smri-skill` for structural MRI processing.
|
|
116
|
+
6. If PET data available (OASIS-3), delegate to `pet-skill`.
|
|
117
|
+
7. If ASL data available (OASIS-3), delegate to `asl-skill`.
|
|
118
|
+
8. If phenotype extraction is requested, run `scripts/extract_oasis_phenotype.py`.
|
|
119
|
+
9. If QC summary is requested, run `scripts/oasis_qc_summary.py`.
|
|
120
|
+
10. Save outputs into `oasis_output/`.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Modality Processing Delegation
|
|
125
|
+
|
|
126
|
+
| Modality | Delegated skill | Typical tasks | Main outputs |
|
|
127
|
+
|---|---|---|---|
|
|
128
|
+
| sMRI (T1w) | `smri-skill` | brain extraction, tissue segmentation, cortical thickness | `smri_output/` derivatives |
|
|
129
|
+
| PET | `pet-skill` | SUVR computation, reference region selection | `pet_output/` SUVR maps |
|
|
130
|
+
| ASL | `asl-skill` | CBF quantification | `asl_output/` CBF maps |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Standard Output Layout
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
oasis_output/
|
|
138
|
+
├── bids/ # BIDS-staged data (or validation report)
|
|
139
|
+
├── smri/ # Structural MRI derivatives
|
|
140
|
+
├── pet/ # PET derivatives (SUVR maps)
|
|
141
|
+
├── asl/ # ASL derivatives (CBF maps)
|
|
142
|
+
├── phenotype/ # Merged phenotype tables (CDR, MMSE, demographics)
|
|
143
|
+
├── qc/ # QC summaries and exclusion lists
|
|
144
|
+
└── logs/ # Processing logs
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Benchmark Adapter Guidance
|
|
150
|
+
|
|
151
|
+
For benchmark-style prompts, do not force the full orchestration when the task only asks for local OASIS data validation.
|
|
152
|
+
|
|
153
|
+
- If the task starts from OASIS data already present on disk and only asks for BIDS validation:
|
|
154
|
+
- Skip the download stage
|
|
155
|
+
- Default to the narrow path `local OASIS discovery -> BIDS validation -> report`
|
|
156
|
+
- In benchmark mode, do not require explicit confirmation before presenting the validation solution.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Safety and Execution Policy
|
|
161
|
+
- No execution before explicit plan confirmation.
|
|
162
|
+
- All execution must be routed via `claw-shell`.
|
|
163
|
+
- Missing dependencies must be resolved by `dependency-planner` before running.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Important Notes and Limitations
|
|
168
|
+
- OASIS-1 is the most commonly used version; OASIS-3 adds PET and longitudinal data.
|
|
169
|
+
- Age range is very wide (18-96); analyses should account for age effects.
|
|
170
|
+
- CDR is the primary dementia staging tool; MMSE provides additional cognitive screening.
|
|
171
|
+
- OASIS-1 uses 1.5T scanner; resolution is lower than modern 3T/7T datasets.
|
|
172
|
+
- `oasis-skill` is orchestration-only; detailed preprocessing logic remains in modality skills.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## When to Call This Skill
|
|
177
|
+
- User asks for end-to-end OASIS workflow.
|
|
178
|
+
- User asks to process OASIS structural MRI data.
|
|
179
|
+
- User needs BIDS validation for OASIS data.
|
|
180
|
+
- User asks to extract OASIS phenotype data (CDR, MMSE, demographics).
|
|
181
|
+
- User asks for Alzheimer's disease neuroimaging analysis.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Complementary / Related Skills
|
|
186
|
+
- `smri-skill` → structural MRI preprocessing
|
|
187
|
+
- `pet-skill` → PET imaging (amyloid, tau)
|
|
188
|
+
- `asl-skill` → arterial spin labeling perfusion
|
|
189
|
+
- `fmri-skill` → functional MRI (if available)
|
|
190
|
+
- `bids-organizer` → BIDS validation and organization
|
|
191
|
+
- `brain-visualization` → visualization of derivatives
|
|
192
|
+
- `dependency-planner` → dependency resolution
|
|
193
|
+
- `conda-env-manager` → environment management
|
|
194
|
+
- `claw-shell` → command execution
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Reference
|
|
199
|
+
- OASIS: https://www.oasis-brains.org/
|
|
200
|
+
- Marcus et al. (2007): Open Access Series of Imaging Studies (OASIS). Journal of Cognitive Neuroscience.
|
|
201
|
+
- OpenNeuro ds000014
|
|
202
|
+
|
|
203
|
+
Created At: 2026-05-06 13:55 HKT
|
|
204
|
+
Last Updated At: 2026-05-06 13:55 HKT
|
|
205
|
+
Author: chengwang96
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Extract and merge OASIS phenotype data.
|
|
3
|
+
|
|
4
|
+
Reads OASIS phenotype files (CDR, MMSE, demographics)
|
|
5
|
+
and produces a merged phenotype table aligned with imaging subject list.
|
|
6
|
+
"""
|
|
7
|
+
import argparse
|
|
8
|
+
import csv
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Dict, List, Optional
|
|
12
|
+
|
|
13
|
+
COLUMN_MAP = {
|
|
14
|
+
"subject_id": ["subject", "Subject", "participant_id", "MR ID", "ID"],
|
|
15
|
+
"age": ["age", "Age", "M/F"],
|
|
16
|
+
"sex": ["sex", "Sex", "M/F", "Gender"],
|
|
17
|
+
"cdr": ["CDR", "cdr"],
|
|
18
|
+
"mmse": ["MMSE", "mmse"],
|
|
19
|
+
"ses": ["SES", "ses"],
|
|
20
|
+
"education": ["Educ", "education", "Education"],
|
|
21
|
+
"group": ["Group", "group", "ClinicalStatus"],
|
|
22
|
+
"delay": ["Delay", "delay"],
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def load_csv(path: Path) -> List[Dict[str, str]]:
|
|
27
|
+
delimiter = "\t" if path.suffix == ".tsv" else ","
|
|
28
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
29
|
+
reader = csv.DictReader(f, delimiter=delimiter)
|
|
30
|
+
return list(reader)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def find_column(row: Dict[str, str], candidates: List[str]) -> Optional[str]:
|
|
34
|
+
for col in candidates:
|
|
35
|
+
if col in row:
|
|
36
|
+
return col
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def extract_phenotype(
|
|
41
|
+
phenotype_files: List[Path],
|
|
42
|
+
imaging_ids: Optional[List[str]] = None,
|
|
43
|
+
columns: Optional[List[str]] = None,
|
|
44
|
+
) -> List[Dict[str, str]]:
|
|
45
|
+
all_data = []
|
|
46
|
+
for fpath in phenotype_files:
|
|
47
|
+
rows = load_csv(fpath)
|
|
48
|
+
all_data.extend(rows)
|
|
49
|
+
|
|
50
|
+
if not all_data:
|
|
51
|
+
return []
|
|
52
|
+
|
|
53
|
+
target_columns = columns if columns else list(COLUMN_MAP.keys())
|
|
54
|
+
merged = {}
|
|
55
|
+
|
|
56
|
+
for row in all_data:
|
|
57
|
+
subj_col = find_column(row, COLUMN_MAP["subject_id"])
|
|
58
|
+
if subj_col is None:
|
|
59
|
+
continue
|
|
60
|
+
subj_id = row[subj_col].strip()
|
|
61
|
+
if not subj_id:
|
|
62
|
+
continue
|
|
63
|
+
|
|
64
|
+
if subj_id not in merged:
|
|
65
|
+
merged[subj_id] = {"subject_id": subj_id}
|
|
66
|
+
|
|
67
|
+
for target_col in target_columns:
|
|
68
|
+
if target_col == "subject_id":
|
|
69
|
+
continue
|
|
70
|
+
if target_col in merged[subj_id] and merged[subj_id][target_col]:
|
|
71
|
+
continue
|
|
72
|
+
candidates = COLUMN_MAP.get(target_col, [target_col])
|
|
73
|
+
src_col = find_column(row, candidates)
|
|
74
|
+
if src_col and row.get(src_col, "").strip():
|
|
75
|
+
merged[subj_id][target_col] = row[src_col].strip()
|
|
76
|
+
|
|
77
|
+
result = list(merged.values())
|
|
78
|
+
if imaging_ids:
|
|
79
|
+
imaging_set = set(imaging_ids)
|
|
80
|
+
result = [r for r in result if r["subject_id"] in imaging_set]
|
|
81
|
+
return result
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def main() -> int:
|
|
85
|
+
parser = argparse.ArgumentParser(description="Extract OASIS phenotype data.")
|
|
86
|
+
parser.add_argument("--phenotype-files", required=True, nargs="+")
|
|
87
|
+
parser.add_argument("--output", required=True)
|
|
88
|
+
parser.add_argument("--imaging-ids")
|
|
89
|
+
parser.add_argument("--columns")
|
|
90
|
+
args = parser.parse_args()
|
|
91
|
+
|
|
92
|
+
phenotype_files = [Path(f).resolve() for f in args.phenotype_files]
|
|
93
|
+
for f in phenotype_files:
|
|
94
|
+
if not f.exists():
|
|
95
|
+
print(f"File not found: {f}", file=sys.stderr)
|
|
96
|
+
return 1
|
|
97
|
+
|
|
98
|
+
imaging_ids = None
|
|
99
|
+
if args.imaging_ids:
|
|
100
|
+
id_file = Path(args.imaging_ids).resolve()
|
|
101
|
+
if id_file.exists():
|
|
102
|
+
imaging_ids = [l.strip() for l in id_file.read_text().splitlines() if l.strip()]
|
|
103
|
+
|
|
104
|
+
columns = None
|
|
105
|
+
if args.columns:
|
|
106
|
+
columns = [c.strip() for c in args.columns.split(",")]
|
|
107
|
+
|
|
108
|
+
merged = extract_phenotype(phenotype_files, imaging_ids, columns)
|
|
109
|
+
if not merged:
|
|
110
|
+
print("[ERROR] No phenotype data extracted.", file=sys.stderr)
|
|
111
|
+
return 1
|
|
112
|
+
|
|
113
|
+
output_path = Path(args.output).resolve()
|
|
114
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
115
|
+
fieldnames = list(merged[0].keys())
|
|
116
|
+
with open(output_path, "w", newline="", encoding="utf-8") as f:
|
|
117
|
+
writer = csv.DictWriter(f, fieldnames=fieldnames)
|
|
118
|
+
writer.writeheader()
|
|
119
|
+
writer.writerows(merged)
|
|
120
|
+
|
|
121
|
+
print(f"Phenotype: {len(merged)} subjects, {len(fieldnames)} columns -> {output_path}")
|
|
122
|
+
return 0
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
if __name__ == "__main__":
|
|
126
|
+
sys.exit(main())
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate per-subject QC summaries for OASIS processing.
|
|
3
|
+
|
|
4
|
+
Aging/AD-specific: tracks CDR group and applies appropriate QC criteria.
|
|
5
|
+
"""
|
|
6
|
+
import argparse
|
|
7
|
+
import csv
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Dict, List
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def load_confounds(confounds_path: Path) -> Dict[str, float]:
|
|
14
|
+
metrics = {"fd_mean": float("nan"), "fd_max": float("nan")}
|
|
15
|
+
try:
|
|
16
|
+
import pandas as pd
|
|
17
|
+
df = pd.read_csv(confounds_path, sep="\t")
|
|
18
|
+
if "framewise_displacement" in df.columns:
|
|
19
|
+
fd = df["framewise_displacement"].dropna()
|
|
20
|
+
metrics["fd_mean"] = float(fd.mean())
|
|
21
|
+
metrics["fd_max"] = float(fd.max())
|
|
22
|
+
except Exception:
|
|
23
|
+
pass
|
|
24
|
+
return metrics
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def check_exclusion(metrics: Dict[str, float], fd_threshold: float = 0.3) -> List[str]:
|
|
28
|
+
reasons = []
|
|
29
|
+
if not (metrics["fd_mean"] != metrics["fd_mean"]):
|
|
30
|
+
if metrics["fd_mean"] > fd_threshold:
|
|
31
|
+
reasons.append(f"FD mean {metrics['fd_mean']:.3f} > {fd_threshold}")
|
|
32
|
+
return reasons
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def main() -> int:
|
|
36
|
+
parser = argparse.ArgumentParser(description="Generate QC summaries for OASIS processing.")
|
|
37
|
+
parser.add_argument("--fmriprep-dir", help="Path to fMRIPrep output directory")
|
|
38
|
+
parser.add_argument("--output", required=True)
|
|
39
|
+
parser.add_argument("--exclude-output")
|
|
40
|
+
parser.add_argument("--fd-threshold", type=float, default=0.3)
|
|
41
|
+
parser.add_argument("--phenotype-file", help="CSV with CDR/MMSE info")
|
|
42
|
+
args = parser.parse_args()
|
|
43
|
+
|
|
44
|
+
output_path = Path(args.output).resolve()
|
|
45
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
46
|
+
|
|
47
|
+
phenotype_map = {}
|
|
48
|
+
if args.phenotype_file:
|
|
49
|
+
pheno_path = Path(args.phenotype_file).resolve()
|
|
50
|
+
if pheno_path.exists():
|
|
51
|
+
with open(pheno_path, "r", encoding="utf-8") as f:
|
|
52
|
+
reader = csv.DictReader(f)
|
|
53
|
+
for row in reader:
|
|
54
|
+
subj = row.get("subject_id") or row.get("Subject", "")
|
|
55
|
+
if subj:
|
|
56
|
+
phenotype_map[subj] = row
|
|
57
|
+
|
|
58
|
+
subjects = set()
|
|
59
|
+
if args.fmriprep_dir:
|
|
60
|
+
fmriprep_dir = Path(args.fmriprep_dir).resolve()
|
|
61
|
+
if fmriprep_dir.exists():
|
|
62
|
+
for d in fmriprep_dir.glob("sub-*"):
|
|
63
|
+
if d.is_dir():
|
|
64
|
+
subjects.add(d.name)
|
|
65
|
+
|
|
66
|
+
if not subjects:
|
|
67
|
+
print("[WARN] No subjects found.", file=sys.stderr)
|
|
68
|
+
return 1
|
|
69
|
+
|
|
70
|
+
results = []
|
|
71
|
+
excluded = []
|
|
72
|
+
for subj in sorted(subjects):
|
|
73
|
+
metrics = {"subject_id": subj}
|
|
74
|
+
|
|
75
|
+
if subj in phenotype_map:
|
|
76
|
+
pheno = phenotype_map[subj]
|
|
77
|
+
if "cdr" in pheno:
|
|
78
|
+
metrics["cdr"] = pheno["cdr"]
|
|
79
|
+
if "mmse" in pheno:
|
|
80
|
+
metrics["mmse"] = pheno["mmse"]
|
|
81
|
+
|
|
82
|
+
if args.fmriprep_dir:
|
|
83
|
+
confounds_files = list(Path(args.fmriprep_dir).glob(f"{subj}/func/*_desc-confounds_timeseries.tsv"))
|
|
84
|
+
if confounds_files:
|
|
85
|
+
metrics.update(load_confounds(confounds_files[0]))
|
|
86
|
+
|
|
87
|
+
exclusion_reasons = check_exclusion(metrics, args.fd_threshold)
|
|
88
|
+
metrics["excluded"] = len(exclusion_reasons) > 0
|
|
89
|
+
metrics["exclusion_reasons"] = "; ".join(exclusion_reasons)
|
|
90
|
+
|
|
91
|
+
results.append(metrics)
|
|
92
|
+
if exclusion_reasons:
|
|
93
|
+
excluded.append({"subject_id": subj, "reasons": "; ".join(exclusion_reasons)})
|
|
94
|
+
|
|
95
|
+
if results:
|
|
96
|
+
fieldnames = list(results[0].keys())
|
|
97
|
+
with open(output_path, "w", newline="", encoding="utf-8") as f:
|
|
98
|
+
writer = csv.DictWriter(f, fieldnames=fieldnames)
|
|
99
|
+
writer.writeheader()
|
|
100
|
+
writer.writerows(results)
|
|
101
|
+
print(f"QC: {len(results)} subjects, {len(excluded)} excluded -> {output_path}")
|
|
102
|
+
|
|
103
|
+
if args.exclude_output and excluded:
|
|
104
|
+
exclude_path = Path(args.exclude_output).resolve()
|
|
105
|
+
exclude_path.parent.mkdir(parents=True, exist_ok=True)
|
|
106
|
+
with open(exclude_path, "w", newline="", encoding="utf-8") as f:
|
|
107
|
+
writer = csv.DictWriter(f, fieldnames=["subject_id", "reasons"])
|
|
108
|
+
writer.writeheader()
|
|
109
|
+
writer.writerows(excluded)
|
|
110
|
+
|
|
111
|
+
return 0
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
if __name__ == "__main__":
|
|
115
|
+
sys.exit(main())
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Validate OASIS BIDS structure and generate compliance report.
|
|
3
|
+
|
|
4
|
+
Checks directory structure, version detection, and modality completeness.
|
|
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 detect_version(input_dir: Path) -> str:
|
|
14
|
+
"""Detect OASIS version from directory structure."""
|
|
15
|
+
subjects = list(input_dir.glob("sub-*"))
|
|
16
|
+
if not subjects:
|
|
17
|
+
return "unknown"
|
|
18
|
+
# OASIS-1: sub-OAS1* pattern, OASIS-2: longitudinal with sessions
|
|
19
|
+
sample = subjects[0]
|
|
20
|
+
if "OAS1" in sample.name:
|
|
21
|
+
sessions = list(sample.glob("ses-*"))
|
|
22
|
+
return "OASIS-2" if sessions else "OASIS-1"
|
|
23
|
+
if "OAS3" in sample.name:
|
|
24
|
+
return "OASIS-3"
|
|
25
|
+
return "unknown"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def validate_subject(subject_dir: Path) -> Dict[str, any]:
|
|
29
|
+
report = {
|
|
30
|
+
"subject": subject_dir.name,
|
|
31
|
+
"anat_complete": False,
|
|
32
|
+
"n_sessions": 0,
|
|
33
|
+
"pet_present": False,
|
|
34
|
+
"asl_present": False,
|
|
35
|
+
"missing_files": [],
|
|
36
|
+
"warnings": [],
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# Count sessions
|
|
40
|
+
sessions = [d for d in subject_dir.glob("ses-*") if d.is_dir()]
|
|
41
|
+
report["n_sessions"] = len(sessions) if sessions else 1
|
|
42
|
+
|
|
43
|
+
# Check anat (in first session or root)
|
|
44
|
+
anat_dir = subject_dir / "anat"
|
|
45
|
+
if not anat_dir.exists() and sessions:
|
|
46
|
+
anat_dir = sessions[0] / "anat"
|
|
47
|
+
|
|
48
|
+
if anat_dir.exists():
|
|
49
|
+
t1w_files = list(anat_dir.glob("*_T1w.nii.gz"))
|
|
50
|
+
report["anat_complete"] = len(t1w_files) > 0
|
|
51
|
+
if not t1w_files:
|
|
52
|
+
report["missing_files"].append("anat/*_T1w.nii.gz")
|
|
53
|
+
else:
|
|
54
|
+
report["missing_files"].append("anat/")
|
|
55
|
+
|
|
56
|
+
# Check PET
|
|
57
|
+
pet_dir = subject_dir / "pet"
|
|
58
|
+
if pet_dir.exists() or any(s / "pet" for s in sessions if (s / "pet").exists()):
|
|
59
|
+
report["pet_present"] = True
|
|
60
|
+
|
|
61
|
+
# Check ASL
|
|
62
|
+
asl_dir = subject_dir / "perf"
|
|
63
|
+
if asl_dir.exists() or any(s / "perf" for s in sessions if (s / "perf").exists()):
|
|
64
|
+
report["asl_present"] = True
|
|
65
|
+
|
|
66
|
+
return report
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def main() -> int:
|
|
70
|
+
parser = argparse.ArgumentParser(description="Validate OASIS BIDS structure.")
|
|
71
|
+
parser.add_argument("--input", required=True)
|
|
72
|
+
parser.add_argument("--output", required=True)
|
|
73
|
+
args = parser.parse_args()
|
|
74
|
+
|
|
75
|
+
input_dir = Path(args.input).resolve()
|
|
76
|
+
if not input_dir.exists():
|
|
77
|
+
print(f"Input directory not found: {input_dir}", file=sys.stderr)
|
|
78
|
+
return 1
|
|
79
|
+
|
|
80
|
+
version = detect_version(input_dir)
|
|
81
|
+
print(f"Detected OASIS version: {version}")
|
|
82
|
+
|
|
83
|
+
subjects = sorted([d for d in input_dir.glob("sub-*") if d.is_dir()])
|
|
84
|
+
print(f"Found {len(subjects)} subjects in {input_dir}")
|
|
85
|
+
|
|
86
|
+
if not subjects:
|
|
87
|
+
print("[ERROR] No subjects found.", file=sys.stderr)
|
|
88
|
+
return 1
|
|
89
|
+
|
|
90
|
+
results = []
|
|
91
|
+
for sub_dir in subjects:
|
|
92
|
+
report = validate_subject(sub_dir)
|
|
93
|
+
results.append(report)
|
|
94
|
+
|
|
95
|
+
output_path = Path(args.output).resolve()
|
|
96
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
97
|
+
|
|
98
|
+
fieldnames = ["subject", "anat_complete", "n_sessions", "pet_present", "asl_present", "missing_files", "warnings"]
|
|
99
|
+
with open(output_path, "w", newline="", encoding="utf-8") as f:
|
|
100
|
+
writer = csv.DictWriter(f, fieldnames=fieldnames)
|
|
101
|
+
writer.writeheader()
|
|
102
|
+
for r in results:
|
|
103
|
+
r["missing_files"] = "; ".join(r["missing_files"])
|
|
104
|
+
r["warnings"] = "; ".join(r["warnings"])
|
|
105
|
+
writer.writerow(r)
|
|
106
|
+
|
|
107
|
+
print(f"\nValidation Summary:")
|
|
108
|
+
print(f" Version: {version}")
|
|
109
|
+
print(f" Total subjects: {len(results)}")
|
|
110
|
+
print(f" With T1w: {sum(1 for r in results if r['anat_complete'])}")
|
|
111
|
+
print(f" With PET: {sum(1 for r in results if r['pet_present'])}")
|
|
112
|
+
print(f" With ASL: {sum(1 for r in results if r['asl_present'])}")
|
|
113
|
+
print(f" Output: {output_path}")
|
|
114
|
+
|
|
115
|
+
return 0
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
if __name__ == "__main__":
|
|
119
|
+
sys.exit(main())
|