@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,190 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Extract features from SEED-IV EEG data.
|
|
3
|
+
|
|
4
|
+
Supports Differential Entropy (DE), Power Spectral Density (PSD),
|
|
5
|
+
and band power features for emotion recognition.
|
|
6
|
+
"""
|
|
7
|
+
import argparse
|
|
8
|
+
import csv
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Dict, List, Optional
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def compute_de_features(data: np.ndarray, sfreq: float = 200.0) -> np.ndarray:
|
|
17
|
+
"""Compute Differential Entropy features across frequency bands.
|
|
18
|
+
|
|
19
|
+
DE = 0.5 * log(2*pi*e*sigma^2) for each band.
|
|
20
|
+
Bands: delta (1-4), theta (4-8), alpha (8-14), beta (14-31), gamma (31-50).
|
|
21
|
+
"""
|
|
22
|
+
from scipy.signal import butter, filtfilt
|
|
23
|
+
|
|
24
|
+
bands = {
|
|
25
|
+
"delta": (1, 4),
|
|
26
|
+
"theta": (4, 8),
|
|
27
|
+
"alpha": (8, 14),
|
|
28
|
+
"beta": (14, 31),
|
|
29
|
+
"gamma": (31, 50),
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
n_channels = data.shape[0] if data.ndim > 1 else 1
|
|
33
|
+
de_features = np.zeros((n_channels, len(bands)))
|
|
34
|
+
|
|
35
|
+
for j, (band_name, (low, high)) in enumerate(bands.items()):
|
|
36
|
+
nyq = sfreq / 2.0
|
|
37
|
+
b, a = butter(4, [low / nyq, high / nyq], btype="band")
|
|
38
|
+
if data.ndim > 1:
|
|
39
|
+
for ch in range(n_channels):
|
|
40
|
+
filtered = filtfilt(b, a, data[ch])
|
|
41
|
+
var = np.var(filtered)
|
|
42
|
+
de_features[ch, j] = 0.5 * np.log(2 * np.pi * np.e * max(var, 1e-10))
|
|
43
|
+
else:
|
|
44
|
+
filtered = filtfilt(b, a, data)
|
|
45
|
+
var = np.var(filtered)
|
|
46
|
+
de_features[0, j] = 0.5 * np.log(2 * np.pi * np.e * max(var, 1e-10))
|
|
47
|
+
|
|
48
|
+
return de_features
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def compute_psd_features(data: np.ndarray, sfreq: float = 200.0) -> np.ndarray:
|
|
52
|
+
"""Compute PSD features using Welch's method."""
|
|
53
|
+
from scipy.signal import welch
|
|
54
|
+
|
|
55
|
+
n_channels = data.shape[0] if data.ndim > 1 else 1
|
|
56
|
+
bands = {
|
|
57
|
+
"delta": (1, 4),
|
|
58
|
+
"theta": (4, 8),
|
|
59
|
+
"alpha": (8, 14),
|
|
60
|
+
"beta": (14, 31),
|
|
61
|
+
"gamma": (31, 50),
|
|
62
|
+
}
|
|
63
|
+
psd_features = np.zeros((n_channels, len(bands)))
|
|
64
|
+
|
|
65
|
+
for ch in range(n_channels if data.ndim > 1 else 1):
|
|
66
|
+
signal = data[ch] if data.ndim > 1 else data
|
|
67
|
+
freqs, psd = welch(signal, fs=sfreq, nperseg=min(256, len(signal)))
|
|
68
|
+
for j, (band_name, (low, high)) in enumerate(bands.items()):
|
|
69
|
+
mask = (freqs >= low) & (freqs <= high)
|
|
70
|
+
psd_features[ch, j] = np.trapz(psd[mask], freqs[mask]) if mask.any() else 0.0
|
|
71
|
+
|
|
72
|
+
return psd_features
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def load_eeg_file(path: Path) -> tuple:
|
|
76
|
+
"""Load EEG data from various formats."""
|
|
77
|
+
suffix = path.suffix.lower()
|
|
78
|
+
|
|
79
|
+
if suffix == ".mat":
|
|
80
|
+
import scipy.io as sio
|
|
81
|
+
mat = sio.loadmat(str(path))
|
|
82
|
+
# Find the data key
|
|
83
|
+
for key in mat:
|
|
84
|
+
if not key.startswith("_") and isinstance(mat[key], np.ndarray) and mat[key].ndim >= 2:
|
|
85
|
+
return mat[key], 200.0
|
|
86
|
+
raise ValueError(f"No EEG data found in {path}")
|
|
87
|
+
|
|
88
|
+
elif suffix in (".edf", ".bdf"):
|
|
89
|
+
import mne
|
|
90
|
+
raw = mne.io.read_raw_edf(str(path), preload=True, verbose=False)
|
|
91
|
+
return raw.get_data(), raw.info["sfreq"]
|
|
92
|
+
|
|
93
|
+
elif suffix == ".set":
|
|
94
|
+
import mne
|
|
95
|
+
raw = mne.io.read_raw_eeglab(str(path), preload=True, verbose=False)
|
|
96
|
+
return raw.get_data(), raw.info["sfreq"]
|
|
97
|
+
|
|
98
|
+
elif suffix == ".vhdr":
|
|
99
|
+
import mne
|
|
100
|
+
raw = mne.io.read_raw_brainvision(str(path), preload=True, verbose=False)
|
|
101
|
+
return raw.get_data(), raw.info["sfreq"]
|
|
102
|
+
|
|
103
|
+
else:
|
|
104
|
+
raise ValueError(f"Unsupported EEG format: {suffix}")
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def main() -> int:
|
|
108
|
+
parser = argparse.ArgumentParser(description="Extract SEED-IV EEG features.")
|
|
109
|
+
parser.add_argument("--input", required=True, help="Path to SEED-IV BIDS directory")
|
|
110
|
+
parser.add_argument("--output", required=True, help="Output directory for features")
|
|
111
|
+
parser.add_argument("--feature-type", choices=["de", "psd", "both"], default="de",
|
|
112
|
+
help="Feature type: de (Differential Entropy), psd, or both")
|
|
113
|
+
parser.add_argument("--subject", help="Process specific subject only")
|
|
114
|
+
parser.add_argument("--epoch-duration", type=float, default=4.0,
|
|
115
|
+
help="Epoch duration in seconds (default: 4.0)")
|
|
116
|
+
args = parser.parse_args()
|
|
117
|
+
|
|
118
|
+
input_dir = Path(args.input).resolve()
|
|
119
|
+
if not input_dir.exists():
|
|
120
|
+
print(f"Input directory not found: {input_dir}", file=sys.stderr)
|
|
121
|
+
return 1
|
|
122
|
+
|
|
123
|
+
output_dir = Path(args.output).resolve()
|
|
124
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
125
|
+
|
|
126
|
+
# Find subjects
|
|
127
|
+
if args.subject:
|
|
128
|
+
subjects = [args.subject]
|
|
129
|
+
else:
|
|
130
|
+
subjects = sorted([d.name for d in input_dir.glob("sub-*") if d.is_dir()])
|
|
131
|
+
|
|
132
|
+
band_names = ["delta", "theta", "alpha", "beta", "gamma"]
|
|
133
|
+
all_results = []
|
|
134
|
+
|
|
135
|
+
for subj in subjects:
|
|
136
|
+
subj_dir = input_dir / subj
|
|
137
|
+
# Find all EEG files
|
|
138
|
+
eeg_files = list(subj_dir.rglob("*.edf")) + list(subj_dir.rglob("*.set")) + \
|
|
139
|
+
list(subj_dir.rglob("*.vhdr")) + list(subj_dir.rglob("*.mat"))
|
|
140
|
+
|
|
141
|
+
for eeg_file in eeg_files:
|
|
142
|
+
try:
|
|
143
|
+
data, sfreq = load_eeg_file(eeg_file)
|
|
144
|
+
|
|
145
|
+
# Epoch the data
|
|
146
|
+
epoch_samples = int(args.epoch_duration * sfreq)
|
|
147
|
+
n_epochs = data.shape[-1] // epoch_samples if data.ndim > 1 else len(data) // epoch_samples
|
|
148
|
+
|
|
149
|
+
for epoch_idx in range(n_epochs):
|
|
150
|
+
start = epoch_idx * epoch_samples
|
|
151
|
+
end = start + epoch_samples
|
|
152
|
+
epoch_data = data[..., start:end] if data.ndim > 1 else data[start:end]
|
|
153
|
+
|
|
154
|
+
if args.feature_type in ("de", "both"):
|
|
155
|
+
de = compute_de_features(epoch_data, sfreq)
|
|
156
|
+
row = {"subject": subj, "file": eeg_file.name, "epoch": epoch_idx, "feature": "DE"}
|
|
157
|
+
for ch_idx in range(de.shape[0]):
|
|
158
|
+
for band_idx, band in enumerate(band_names):
|
|
159
|
+
row[f"ch{ch_idx}_{band}"] = f"{de[ch_idx, band_idx]:.6f}"
|
|
160
|
+
all_results.append(row)
|
|
161
|
+
|
|
162
|
+
if args.feature_type in ("psd", "both"):
|
|
163
|
+
psd = compute_psd_features(epoch_data, sfreq)
|
|
164
|
+
row = {"subject": subj, "file": eeg_file.name, "epoch": epoch_idx, "feature": "PSD"}
|
|
165
|
+
for ch_idx in range(psd.shape[0]):
|
|
166
|
+
for band_idx, band in enumerate(band_names):
|
|
167
|
+
row[f"ch{ch_idx}_{band}"] = f"{psd[ch_idx, band_idx]:.6f}"
|
|
168
|
+
all_results.append(row)
|
|
169
|
+
|
|
170
|
+
except Exception as e:
|
|
171
|
+
print(f"[WARN] Failed to process {eeg_file}: {e}", file=sys.stderr)
|
|
172
|
+
|
|
173
|
+
if not all_results:
|
|
174
|
+
print("[ERROR] No features extracted.", file=sys.stderr)
|
|
175
|
+
return 1
|
|
176
|
+
|
|
177
|
+
# Write output
|
|
178
|
+
output_path = output_dir / f"seed_iv_features_{args.feature_type}.csv"
|
|
179
|
+
fieldnames = list(all_results[0].keys())
|
|
180
|
+
with open(output_path, "w", newline="", encoding="utf-8") as f:
|
|
181
|
+
writer = csv.DictWriter(f, fieldnames=fieldnames)
|
|
182
|
+
writer.writeheader()
|
|
183
|
+
writer.writerows(all_results)
|
|
184
|
+
|
|
185
|
+
print(f"Features: {len(all_results)} epochs, {len(fieldnames)} columns -> {output_path}")
|
|
186
|
+
return 0
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
if __name__ == "__main__":
|
|
190
|
+
sys.exit(main())
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Validate SEED-IV BIDS structure and generate compliance report.
|
|
3
|
+
|
|
4
|
+
Checks directory structure, subject/session completeness, and EEG file presence.
|
|
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 validate_subject(subject_dir: Path) -> Dict[str, any]:
|
|
14
|
+
report = {
|
|
15
|
+
"subject": subject_dir.name,
|
|
16
|
+
"n_sessions": 0,
|
|
17
|
+
"eeg_complete": False,
|
|
18
|
+
"events_present": False,
|
|
19
|
+
"missing_files": [],
|
|
20
|
+
"warnings": [],
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
sessions = [d for d in subject_dir.glob("ses-*") if d.is_dir()]
|
|
24
|
+
report["n_sessions"] = len(sessions)
|
|
25
|
+
|
|
26
|
+
if not sessions:
|
|
27
|
+
# Check root-level EEG
|
|
28
|
+
eeg_dir = subject_dir / "eeg"
|
|
29
|
+
if eeg_dir.exists():
|
|
30
|
+
eeg_files = list(eeg_dir.glob("*.edf")) + list(eeg_dir.glob("*.set")) + list(eeg_dir.glob("*.vhdr"))
|
|
31
|
+
report["eeg_complete"] = len(eeg_files) > 0
|
|
32
|
+
events = list(eeg_dir.glob("*_events.tsv"))
|
|
33
|
+
report["events_present"] = len(events) > 0
|
|
34
|
+
else:
|
|
35
|
+
report["missing_files"].append("eeg/")
|
|
36
|
+
else:
|
|
37
|
+
eeg_count = 0
|
|
38
|
+
events_count = 0
|
|
39
|
+
for ses in sessions:
|
|
40
|
+
eeg_dir = ses / "eeg"
|
|
41
|
+
if eeg_dir.exists():
|
|
42
|
+
eeg_files = list(eeg_dir.glob("*.edf")) + list(eeg_dir.glob("*.set")) + list(eeg_dir.glob("*.vhdr"))
|
|
43
|
+
eeg_count += len(eeg_files)
|
|
44
|
+
events_count += len(list(eeg_dir.glob("*_events.tsv")))
|
|
45
|
+
else:
|
|
46
|
+
report["missing_files"].append(f"{ses.name}/eeg/")
|
|
47
|
+
report["eeg_complete"] = eeg_count > 0
|
|
48
|
+
report["events_present"] = events_count > 0
|
|
49
|
+
|
|
50
|
+
if report["n_sessions"] < 3:
|
|
51
|
+
report["warnings"].append(f"Only {report['n_sessions']} sessions (expected 3)")
|
|
52
|
+
|
|
53
|
+
return report
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def main() -> int:
|
|
57
|
+
parser = argparse.ArgumentParser(description="Validate SEED-IV BIDS structure.")
|
|
58
|
+
parser.add_argument("--input", required=True)
|
|
59
|
+
parser.add_argument("--output", required=True)
|
|
60
|
+
args = parser.parse_args()
|
|
61
|
+
|
|
62
|
+
input_dir = Path(args.input).resolve()
|
|
63
|
+
if not input_dir.exists():
|
|
64
|
+
print(f"Input directory not found: {input_dir}", file=sys.stderr)
|
|
65
|
+
return 1
|
|
66
|
+
|
|
67
|
+
subjects = sorted([d for d in input_dir.glob("sub-*") if d.is_dir()])
|
|
68
|
+
print(f"Found {len(subjects)} subjects in {input_dir}")
|
|
69
|
+
|
|
70
|
+
if not subjects:
|
|
71
|
+
print("[ERROR] No subjects found.", file=sys.stderr)
|
|
72
|
+
return 1
|
|
73
|
+
|
|
74
|
+
results = []
|
|
75
|
+
for sub_dir in subjects:
|
|
76
|
+
report = validate_subject(sub_dir)
|
|
77
|
+
results.append(report)
|
|
78
|
+
|
|
79
|
+
output_path = Path(args.output).resolve()
|
|
80
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
81
|
+
|
|
82
|
+
fieldnames = ["subject", "n_sessions", "eeg_complete", "events_present", "missing_files", "warnings"]
|
|
83
|
+
with open(output_path, "w", newline="", encoding="utf-8") as f:
|
|
84
|
+
writer = csv.DictWriter(f, fieldnames=fieldnames)
|
|
85
|
+
writer.writeheader()
|
|
86
|
+
for r in results:
|
|
87
|
+
r["missing_files"] = "; ".join(r["missing_files"])
|
|
88
|
+
r["warnings"] = "; ".join(r["warnings"])
|
|
89
|
+
writer.writerow(r)
|
|
90
|
+
|
|
91
|
+
print(f"\nValidation Summary:")
|
|
92
|
+
print(f" Total subjects: {len(results)}")
|
|
93
|
+
print(f" With EEG: {sum(1 for r in results if r['eeg_complete'])}")
|
|
94
|
+
print(f" With events: {sum(1 for r in results if r['events_present'])}")
|
|
95
|
+
print(f" Total sessions: {sum(r['n_sessions'] for r in results)}")
|
|
96
|
+
print(f" Output: {output_path}")
|
|
97
|
+
|
|
98
|
+
return 0
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
if __name__ == "__main__":
|
|
102
|
+
sys.exit(main())
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: seed-vig-skill
|
|
3
|
+
description: "Use this skill whenever the user wants an end-to-end workflow for the SEED-VIG (SJTU Emotion EEG Dataset - Vigilance) dataset, including EEG validation, preprocessing, feature extraction, and vigilance/fatigue detection. Triggers include: 'SEED-VIG', 'SEEDVIG', 'vigilance EEG', 'fatigue detection', 'drowsiness EEG', 'process SEED-VIG', or any request to run the SEED-VIG pipeline."
|
|
4
|
+
license: MIT License (NeuroClaw custom skill - freely modifiable within the project)
|
|
5
|
+
layer: subagent
|
|
6
|
+
skill_type: dataset
|
|
7
|
+
dependencies:
|
|
8
|
+
- eeg-skill
|
|
9
|
+
- bids-organizer
|
|
10
|
+
- claw-shell
|
|
11
|
+
complementary_skills:
|
|
12
|
+
- brain-visualization
|
|
13
|
+
---
|
|
14
|
+
# SEED-VIG Skill (Dataset-Orchestration Layer)
|
|
15
|
+
|
|
16
|
+
## Overview
|
|
17
|
+
|
|
18
|
+
`seed-vig-skill` is the NeuroClaw orchestration skill for the **SEED-VIG (SJTU Emotion EEG Dataset - Vigilance)** dataset, developed by the BCMI Lab at Shanghai Jiao Tong University for vigilance/fatigue detection research.
|
|
19
|
+
|
|
20
|
+
It strictly follows the NeuroClaw hierarchical design principles:
|
|
21
|
+
- This skill **only describes WHAT needs to be done** and **which tool skill to delegate to**.
|
|
22
|
+
- It contains **no implementation code or concrete commands**.
|
|
23
|
+
- All concrete execution is delegated to existing base/tool skills via `claw-shell`.
|
|
24
|
+
- Companion scripts in `scripts/` provide reference implementations for EEG validation, feature extraction, and vigilance classification.
|
|
25
|
+
|
|
26
|
+
**Core workflow (never bypassed):**
|
|
27
|
+
1. Identify input SEED-VIG data and target analysis.
|
|
28
|
+
2. Generate a **numbered execution plan** clearly stating WHAT needs to be done and which tool skill will handle each step.
|
|
29
|
+
3. Present the full plan, estimated runtime, resource requirements, and risks to the user and wait for explicit confirmation ("YES" / "execute" / "proceed").
|
|
30
|
+
4. On confirmation, delegate every step to the appropriate skill via `claw-shell`.
|
|
31
|
+
5. After execution, save all outputs in a clean directory structure (`seed_vig_output/`).
|
|
32
|
+
|
|
33
|
+
**Research use only.**
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Quick Reference
|
|
38
|
+
|
|
39
|
+
| Task | What needs to be done | Delegate to | Expected output |
|
|
40
|
+
|---|---|---|---|
|
|
41
|
+
| EEG validation | Validate SEED-VIG BIDS structure | `scripts/validate_seed_vig.py` | Validation report |
|
|
42
|
+
| EEG preprocessing | Filtering, artifact removal | `eeg-skill` | `eeg_output/` preprocessed EEG |
|
|
43
|
+
| Feature extraction | Band power, DE, connectivity | `scripts/extract_seed_vig_features.py` | Feature matrices |
|
|
44
|
+
| Vigilance classification | Binary/multi-class vigilance detection | `scripts/classify_seed_vig.py` | Classification results |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Dataset Characteristics
|
|
49
|
+
|
|
50
|
+
- **Cohort**: 23 healthy subjects
|
|
51
|
+
- **Task**: Simulated driving task (vigilance decrement paradigm)
|
|
52
|
+
- **EEG System**: 17-channel EEG (ESI NeuroScan or dry electrodes)
|
|
53
|
+
- **Sampling rate**: 200 Hz
|
|
54
|
+
- **Reference**: Linked mastoids (M1/M2)
|
|
55
|
+
- **Labels**: Vigilance levels (KSS scale or EEG-derived)
|
|
56
|
+
- **Duration**: ~2 hours per subject
|
|
57
|
+
- **Access**: BCMI Lab (bcmi.sjtu.edu.cn/~seed/)
|
|
58
|
+
- **Format**: MATLAB .mat files (community BIDS conversion available)
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Supported Modalities
|
|
63
|
+
|
|
64
|
+
| Modality | Description | Details |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| EEG | 17-channel EEG | ESI NeuroScan, 200 Hz |
|
|
67
|
+
| Eye tracking | Eye movement data | Blinks, gaze position |
|
|
68
|
+
| Peripheral | EOG, EMG | Eye/muscle artifacts |
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## SEED-VIG Vigilance Labels
|
|
73
|
+
|
|
74
|
+
| Label | Description | Method |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| KSS | Karolinska Sleepiness Scale | Self-report (1-9) |
|
|
77
|
+
| EEG-based | Theta/alpha/beta power ratios | Spectral analysis |
|
|
78
|
+
| Binary | Alert vs. Drowsy | Threshold-based |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## BIDS Preparation
|
|
83
|
+
|
|
84
|
+
### Script: `scripts/validate_seed_vig.py`
|
|
85
|
+
|
|
86
|
+
Validates SEED-VIG BIDS structure and generates a compliance report.
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
python skills/seed-vig-skill/scripts/validate_seed_vig.py \
|
|
90
|
+
--input /path/to/SEED-VIG/bids \
|
|
91
|
+
--output /path/to/seed_vig_output/qc/bids_validation.csv
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Features:
|
|
95
|
+
- BIDS directory structure validation
|
|
96
|
+
- Subject completeness check (23 subjects)
|
|
97
|
+
- EEG file presence verification
|
|
98
|
+
- Vigilance label availability check
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Core Workflow (Never Bypassed)
|
|
103
|
+
|
|
104
|
+
1. Identify user target: full SEED-VIG pipeline, feature extraction only, or classification only.
|
|
105
|
+
2. Generate a numbered plan with tools, outputs, runtime, storage, and risks.
|
|
106
|
+
3. Wait for explicit confirmation (`YES` / `execute` / `proceed`).
|
|
107
|
+
4. On confirmation, run BIDS validation using `scripts/validate_seed_vig.py`.
|
|
108
|
+
5. Delegate to `eeg-skill` for EEG preprocessing.
|
|
109
|
+
6. Run `scripts/extract_seed_vig_features.py` for feature extraction.
|
|
110
|
+
7. Run `scripts/classify_seed_vig.py` for vigilance classification.
|
|
111
|
+
8. Save outputs into `seed_vig_output/`.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Standard Output Layout
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
seed_vig_output/
|
|
119
|
+
├── bids/ # BIDS-staged data (or validation report)
|
|
120
|
+
├── eeg/ # Preprocessed EEG derivatives
|
|
121
|
+
├── features/ # Extracted features (band power, DE)
|
|
122
|
+
├── classification/ # Vigilance classification results
|
|
123
|
+
├── qc/ # QC summaries
|
|
124
|
+
└── logs/ # Processing logs
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Benchmark Adapter Guidance
|
|
130
|
+
|
|
131
|
+
For benchmark-style prompts, do not force the full orchestration when the task only asks for local SEED-VIG data validation.
|
|
132
|
+
|
|
133
|
+
- If the task starts from SEED-VIG data already present on disk and only asks for BIDS validation:
|
|
134
|
+
- Skip the download stage
|
|
135
|
+
- Default to the narrow path `local SEED-VIG discovery -> BIDS validation -> report`
|
|
136
|
+
- In benchmark mode, do not require explicit confirmation before presenting the validation solution.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Safety and Execution Policy
|
|
141
|
+
- No execution before explicit plan confirmation.
|
|
142
|
+
- All execution must be routed via `claw-shell`.
|
|
143
|
+
- Missing dependencies must be resolved by `dependency-planner` before running.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Important Notes and Limitations
|
|
148
|
+
- 17-channel EEG provides limited spatial resolution compared to high-density systems.
|
|
149
|
+
- Simulated driving may not fully replicate real-world drowsiness.
|
|
150
|
+
- Theta/alpha/beta power ratios are commonly used spectral features for vigilance detection.
|
|
151
|
+
- Cross-subject calibration is often needed due to individual differences in EEG patterns.
|
|
152
|
+
- `seed-vig-skill` is orchestration-only; detailed preprocessing logic remains in modality skills.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## When to Call This Skill
|
|
157
|
+
- User asks for end-to-end SEED-VIG workflow.
|
|
158
|
+
- User asks to process SEED-VIG EEG data.
|
|
159
|
+
- User needs BIDS validation for SEED-VIG data.
|
|
160
|
+
- User asks for EEG-based vigilance/fatigue detection analysis.
|
|
161
|
+
- User asks for drowsiness detection or alertness monitoring.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Complementary / Related Skills
|
|
166
|
+
- `eeg-skill` → EEG preprocessing and feature extraction
|
|
167
|
+
- `bids-organizer` → BIDS validation and organization
|
|
168
|
+
- `brain-visualization` → visualization of derivatives
|
|
169
|
+
- `dependency-planner` → dependency resolution
|
|
170
|
+
- `conda-env-manager` → environment management
|
|
171
|
+
- `claw-shell` → command execution
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Reference
|
|
176
|
+
- SEED-VIG: https://bcmi.sjtu.edu.cn/~seed/
|
|
177
|
+
- BCMI Lab, Shanghai Jiao Tong University
|
|
178
|
+
- Wei et al. (2017): EEG-based vigilance estimation using extreme learning machines. Neurocomputing.
|
|
179
|
+
|
|
180
|
+
Created At: 2026-05-06 14:21 HKT
|
|
181
|
+
Last Updated At: 2026-05-06 14:21 HKT
|
|
182
|
+
Author: chengwang96
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Classify vigilance states from SEED-VIG features.
|
|
3
|
+
|
|
4
|
+
Supports binary (alert vs. drowsy) and multi-class vigilance detection.
|
|
5
|
+
"""
|
|
6
|
+
import argparse
|
|
7
|
+
import csv
|
|
8
|
+
import json
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Dict, List, Tuple
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def load_features(features_path: Path) -> Tuple[np.ndarray, np.ndarray, List[str]]:
|
|
17
|
+
"""Load features and labels from CSV."""
|
|
18
|
+
import pandas as pd
|
|
19
|
+
df = pd.read_csv(features_path)
|
|
20
|
+
|
|
21
|
+
label_col = None
|
|
22
|
+
for col in ["vigilance", "label", "kss", "state"]:
|
|
23
|
+
if col in df.columns:
|
|
24
|
+
label_col = col
|
|
25
|
+
break
|
|
26
|
+
|
|
27
|
+
if label_col is None:
|
|
28
|
+
raise ValueError("No vigilance label column found")
|
|
29
|
+
|
|
30
|
+
feature_cols = [c for c in df.columns if c.startswith("ch") and "_" in c]
|
|
31
|
+
|
|
32
|
+
X = df[feature_cols].values.astype(float)
|
|
33
|
+
y_raw = df[label_col].values
|
|
34
|
+
|
|
35
|
+
# Binarize if needed (e.g., KSS 1-4 -> alert, 5-9 -> drowsy)
|
|
36
|
+
try:
|
|
37
|
+
y = y_raw.astype(int)
|
|
38
|
+
if y.max() > 2:
|
|
39
|
+
y = (y >= 5).astype(int) # KSS-based binarization
|
|
40
|
+
except ValueError:
|
|
41
|
+
unique = np.unique(y_raw)
|
|
42
|
+
y = np.array([0 if v == unique[0] else 1 for v in y_raw])
|
|
43
|
+
|
|
44
|
+
subjects = df["subject"].tolist() if "subject" in df.columns else [f"sub-{i}" for i in range(len(y))]
|
|
45
|
+
|
|
46
|
+
return X, y, subjects
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def classify_svm(X: np.ndarray, y: np.ndarray, subjects: List[str]) -> Dict:
|
|
50
|
+
"""SVM classification with LOSO CV."""
|
|
51
|
+
from sklearn.svm import SVC
|
|
52
|
+
from sklearn.preprocessing import StandardScaler
|
|
53
|
+
from sklearn.model_selection import LeaveOneGroupOut
|
|
54
|
+
from sklearn.metrics import classification_report, roc_auc_score
|
|
55
|
+
|
|
56
|
+
scaler = StandardScaler()
|
|
57
|
+
logo = LeaveOneGroupOut()
|
|
58
|
+
y_pred_all, y_true_all, y_score_all = [], [], []
|
|
59
|
+
|
|
60
|
+
for train_idx, test_idx in logo.split(X, y, subjects):
|
|
61
|
+
X_train = scaler.fit_transform(X[train_idx])
|
|
62
|
+
X_test = scaler.transform(X[test_idx])
|
|
63
|
+
svm = SVC(kernel="rbf", C=1.0, gamma="scale", probability=True)
|
|
64
|
+
svm.fit(X_train, y[train_idx])
|
|
65
|
+
y_pred_all.extend(svm.predict(X_test))
|
|
66
|
+
y_true_all.extend(y[test_idx])
|
|
67
|
+
y_score_all.extend(svm.predict_proba(X_test)[:, 1])
|
|
68
|
+
|
|
69
|
+
y_pred_all = np.array(y_pred_all)
|
|
70
|
+
y_true_all = np.array(y_true_all)
|
|
71
|
+
y_score_all = np.array(y_score_all)
|
|
72
|
+
|
|
73
|
+
accuracy = float(np.mean(y_pred_all == y_true_all))
|
|
74
|
+
try:
|
|
75
|
+
auc = float(roc_auc_score(y_true_all, y_score_all))
|
|
76
|
+
except ValueError:
|
|
77
|
+
auc = 0.0
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
"method": "SVM (RBF)",
|
|
81
|
+
"cv": "Leave-One-Subject-Out",
|
|
82
|
+
"accuracy": accuracy,
|
|
83
|
+
"auc": auc,
|
|
84
|
+
"n_subjects": len(set(subjects)),
|
|
85
|
+
"n_samples": len(y_true_all),
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def classify_rf(X: np.ndarray, y: np.ndarray, subjects: List[str]) -> Dict:
|
|
90
|
+
"""Random Forest classification with LOSO CV."""
|
|
91
|
+
from sklearn.ensemble import RandomForestClassifier
|
|
92
|
+
from sklearn.preprocessing import StandardScaler
|
|
93
|
+
from sklearn.model_selection import LeaveOneGroupOut
|
|
94
|
+
from sklearn.metrics import roc_auc_score
|
|
95
|
+
|
|
96
|
+
scaler = StandardScaler()
|
|
97
|
+
logo = LeaveOneGroupOut()
|
|
98
|
+
y_pred_all, y_true_all, y_score_all = [], [], []
|
|
99
|
+
|
|
100
|
+
for train_idx, test_idx in logo.split(X, y, subjects):
|
|
101
|
+
X_train = scaler.fit_transform(X[train_idx])
|
|
102
|
+
X_test = scaler.transform(X[test_idx])
|
|
103
|
+
rf = RandomForestClassifier(n_estimators=100, random_state=42)
|
|
104
|
+
rf.fit(X_train, y[train_idx])
|
|
105
|
+
y_pred_all.extend(rf.predict(X_test))
|
|
106
|
+
y_true_all.extend(y[test_idx])
|
|
107
|
+
y_score_all.extend(rf.predict_proba(X_test)[:, 1])
|
|
108
|
+
|
|
109
|
+
y_pred_all = np.array(y_pred_all)
|
|
110
|
+
y_true_all = np.array(y_true_all)
|
|
111
|
+
y_score_all = np.array(y_score_all)
|
|
112
|
+
|
|
113
|
+
accuracy = float(np.mean(y_pred_all == y_true_all))
|
|
114
|
+
try:
|
|
115
|
+
auc = float(roc_auc_score(y_true_all, y_score_all))
|
|
116
|
+
except ValueError:
|
|
117
|
+
auc = 0.0
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
"method": "Random Forest (100 trees)",
|
|
121
|
+
"cv": "Leave-One-Subject-Out",
|
|
122
|
+
"accuracy": accuracy,
|
|
123
|
+
"auc": auc,
|
|
124
|
+
"n_subjects": len(set(subjects)),
|
|
125
|
+
"n_samples": len(y_true_all),
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def main() -> int:
|
|
130
|
+
parser = argparse.ArgumentParser(description="Classify SEED-VIG vigilance states.")
|
|
131
|
+
parser.add_argument("--input", required=True, help="Path to features CSV")
|
|
132
|
+
parser.add_argument("--output", required=True, help="Output path for results")
|
|
133
|
+
parser.add_argument("--method", choices=["svm", "rf", "both"], default="both")
|
|
134
|
+
args = parser.parse_args()
|
|
135
|
+
|
|
136
|
+
input_path = Path(args.input).resolve()
|
|
137
|
+
if not input_path.exists():
|
|
138
|
+
print(f"Input file not found: {input_path}", file=sys.stderr)
|
|
139
|
+
return 1
|
|
140
|
+
|
|
141
|
+
X, y, subjects = load_features(input_path)
|
|
142
|
+
print(f"Loaded {len(y)} samples, classes: {np.unique(y)}, {len(set(subjects))} subjects")
|
|
143
|
+
|
|
144
|
+
results = []
|
|
145
|
+
if args.method in ("svm", "both"):
|
|
146
|
+
svm_result = classify_svm(X, y, subjects)
|
|
147
|
+
results.append(svm_result)
|
|
148
|
+
print(f"SVM accuracy: {svm_result['accuracy']:.4f}, AUC: {svm_result['auc']:.4f}")
|
|
149
|
+
|
|
150
|
+
if args.method in ("rf", "both"):
|
|
151
|
+
rf_result = classify_rf(X, y, subjects)
|
|
152
|
+
results.append(rf_result)
|
|
153
|
+
print(f"RF accuracy: {rf_result['accuracy']:.4f}, AUC: {rf_result['auc']:.4f}")
|
|
154
|
+
|
|
155
|
+
output_path = Path(args.output).resolve()
|
|
156
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
157
|
+
with open(output_path, "w", encoding="utf-8") as f:
|
|
158
|
+
json.dump(results, f, indent=2, default=str)
|
|
159
|
+
|
|
160
|
+
print(f"Results saved to {output_path}")
|
|
161
|
+
return 0
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
if __name__ == "__main__":
|
|
165
|
+
sys.exit(main())
|