@brainpilot/skills 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/package.json +2 -2
  2. package/skills/01_Meta-Skills/academic-research-hub/SKILL.md +108 -0
  3. package/skills/01_Meta-Skills/academic-research-hub/scripts/requirements.txt +17 -0
  4. package/skills/01_Meta-Skills/academic-research-hub/scripts/research.py +781 -0
  5. package/skills/01_Meta-Skills/beautiful-log/SKILL.md +64 -0
  6. package/skills/01_Meta-Skills/beautiful-log/scripts/beautiful_log.py +274 -0
  7. package/skills/01_Meta-Skills/ethoclaw-daily-paper/SKILL.md +130 -0
  8. package/skills/01_Meta-Skills/ethoclaw-daily-paper/assets/config.template.yaml +54 -0
  9. package/skills/01_Meta-Skills/ethoclaw-daily-paper/assets/top5_digest_template.md +5 -0
  10. package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/build_top5_digest.py +300 -0
  11. package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/common.py +137 -0
  12. package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/merge_results.py +106 -0
  13. package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/run_pipeline.py +177 -0
  14. package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/search_arxiv.py +162 -0
  15. package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/search_pubmed.py +202 -0
  16. package/skills/01_Meta-Skills/ethoclaw-normalize-tabular/SKILL.md +173 -0
  17. package/skills/01_Meta-Skills/ethoclaw-normalize-tabular/scripts/normalize_data.py +874 -0
  18. package/skills/01_Meta-Skills/ethoclaw-pdf-research/SKILL.md +134 -0
  19. package/skills/01_Meta-Skills/ethoclaw-pdf-research/references/confirmation-prompts.md +31 -0
  20. package/skills/01_Meta-Skills/ethoclaw-pdf-research/references/output-patterns.md +45 -0
  21. package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/build_markdown_deliverables.py +41 -0
  22. package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/build_research_log.py +84 -0
  23. package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/build_summary_md.py +63 -0
  24. package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/extract_pdf_bundle.py +140 -0
  25. package/skills/01_Meta-Skills/experiment-controller/SKILL.md +140 -0
  26. package/skills/01_Meta-Skills/knowledge-graph-builder/SKILL.md +366 -0
  27. package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/entity_resolution.py +120 -0
  28. package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/extraction_prompt_template.txt +19 -0
  29. package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/graph_query.py +106 -0
  30. package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/hypothesis_cli_reference.py +42 -0
  31. package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/new_data_source_template.py +116 -0
  32. package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/requirements.txt +15 -0
  33. package/skills/01_Meta-Skills/method-design/SKILL.md +61 -0
  34. package/skills/01_Meta-Skills/multi-search-engine/SKILL.md +119 -0
  35. package/skills/01_Meta-Skills/research-idea/SKILL.md +65 -0
  36. package/skills/05_EEG_ERP/eeg-skill/SKILL.md +197 -0
  37. package/skills/05_EEG_ERP/meg-skill/SKILL.md +188 -0
  38. package/skills/05_EEG_ERP/meg-skill/scripts/time_frequency.py +223 -0
  39. package/skills/05_EEG_ERP/mne-eeg-tool/SKILL.md +165 -0
  40. package/skills/05_EEG_ERP/mne-eeg-tool/scripts/eeg_pipeline_reference.py +231 -0
  41. package/skills/05_EEG_ERP/seed-iv-skill/SKILL.md +184 -0
  42. package/skills/05_EEG_ERP/seed-iv-skill/scripts/classify_seed_iv.py +154 -0
  43. package/skills/05_EEG_ERP/seed-iv-skill/scripts/extract_seed_iv_features.py +190 -0
  44. package/skills/05_EEG_ERP/seed-iv-skill/scripts/validate_seed_iv.py +102 -0
  45. package/skills/05_EEG_ERP/seed-vig-skill/SKILL.md +182 -0
  46. package/skills/05_EEG_ERP/seed-vig-skill/scripts/classify_seed_vig.py +165 -0
  47. package/skills/05_EEG_ERP/seed-vig-skill/scripts/extract_seed_vig_features.py +185 -0
  48. package/skills/05_EEG_ERP/seed-vig-skill/scripts/validate_seed_vig.py +88 -0
  49. package/skills/06_fMRI_Neuroimaging/abcd-skill/SKILL.md +308 -0
  50. package/skills/06_fMRI_Neuroimaging/abcd-skill/scripts/abcd_qc_summary.py +449 -0
  51. package/skills/06_fMRI_Neuroimaging/abcd-skill/scripts/extract_abcd_phenotype.py +292 -0
  52. package/skills/06_fMRI_Neuroimaging/abcd-skill/scripts/reorganize_abcd.py +387 -0
  53. package/skills/06_fMRI_Neuroimaging/abide-skill/SKILL.md +302 -0
  54. package/skills/06_fMRI_Neuroimaging/abide-skill/scripts/abide_qc_summary.py +317 -0
  55. package/skills/06_fMRI_Neuroimaging/abide-skill/scripts/extract_abide_phenotype.py +267 -0
  56. package/skills/06_fMRI_Neuroimaging/abide-skill/scripts/reorganize_abide.py +387 -0
  57. package/skills/06_fMRI_Neuroimaging/adhd200-skill/SKILL.md +244 -0
  58. package/skills/06_fMRI_Neuroimaging/adhd200-skill/scripts/adhd200_qc_summary.py +98 -0
  59. package/skills/06_fMRI_Neuroimaging/adhd200-skill/scripts/extract_adhd200_phenotype.py +134 -0
  60. package/skills/06_fMRI_Neuroimaging/adhd200-skill/scripts/reorganize_adhd200.py +206 -0
  61. package/skills/06_fMRI_Neuroimaging/adni-skill/SKILL.md +358 -0
  62. package/skills/06_fMRI_Neuroimaging/adni-skill/scripts/generate_adni_task_files.py +1305 -0
  63. package/skills/06_fMRI_Neuroimaging/adni-skill/scripts/generate_vqa_from_tasks.py +766 -0
  64. package/skills/06_fMRI_Neuroimaging/adni-skill/scripts/reorganize_adni.py +491 -0
  65. package/skills/06_fMRI_Neuroimaging/aibl-skill/SKILL.md +295 -0
  66. package/skills/06_fMRI_Neuroimaging/aibl-skill/scripts/aibl_qc_summary.py +260 -0
  67. package/skills/06_fMRI_Neuroimaging/aibl-skill/scripts/extract_aibl_phenotype.py +365 -0
  68. package/skills/06_fMRI_Neuroimaging/aibl-skill/scripts/reorganize_aibl.py +394 -0
  69. package/skills/06_fMRI_Neuroimaging/aomic-skill/SKILL.md +292 -0
  70. package/skills/06_fMRI_Neuroimaging/aomic-skill/scripts/aomic_qc_summary.py +258 -0
  71. package/skills/06_fMRI_Neuroimaging/aomic-skill/scripts/extract_aomic_phenotype.py +284 -0
  72. package/skills/06_fMRI_Neuroimaging/aomic-skill/scripts/reorganize_aomic.py +322 -0
  73. package/skills/06_fMRI_Neuroimaging/asl-skill/SKILL.md +168 -0
  74. package/skills/06_fMRI_Neuroimaging/asl-skill/scripts/compute_cbf.py +224 -0
  75. package/skills/06_fMRI_Neuroimaging/bids-organizer/SKILL.md +241 -0
  76. package/skills/06_fMRI_Neuroimaging/bold5000-skill/SKILL.md +186 -0
  77. package/skills/06_fMRI_Neuroimaging/bold5000-skill/scripts/bold5000_qc_summary.py +96 -0
  78. package/skills/06_fMRI_Neuroimaging/bold5000-skill/scripts/extract_bold5000_stimulus.py +125 -0
  79. package/skills/06_fMRI_Neuroimaging/bold5000-skill/scripts/reorganize_bold5000.py +102 -0
  80. package/skills/06_fMRI_Neuroimaging/camcan-skill/SKILL.md +213 -0
  81. package/skills/06_fMRI_Neuroimaging/camcan-skill/scripts/camcan_qc_summary.py +131 -0
  82. package/skills/06_fMRI_Neuroimaging/camcan-skill/scripts/extract_camcan_phenotype.py +145 -0
  83. package/skills/06_fMRI_Neuroimaging/camcan-skill/scripts/validate_camcan.py +141 -0
  84. package/skills/06_fMRI_Neuroimaging/cobre-skill/SKILL.md +201 -0
  85. package/skills/06_fMRI_Neuroimaging/cobre-skill/scripts/cobre_qc_summary.py +95 -0
  86. package/skills/06_fMRI_Neuroimaging/cobre-skill/scripts/extract_cobre_phenotype.py +104 -0
  87. package/skills/06_fMRI_Neuroimaging/cobre-skill/scripts/reorganize_cobre.py +140 -0
  88. package/skills/06_fMRI_Neuroimaging/conn-tool/SKILL.md +180 -0
  89. package/skills/06_fMRI_Neuroimaging/dcm2nii/SKILL.md +189 -0
  90. package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/SKILL.md +183 -0
  91. package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/dmt_har_med_qc_summary.py +96 -0
  92. package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/extract_dmt_har_med_phenotype.py +121 -0
  93. package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/reorganize_dmt_har_med.py +125 -0
  94. package/skills/06_fMRI_Neuroimaging/dwi-skill/SKILL.md +359 -0
  95. package/skills/06_fMRI_Neuroimaging/fmri-skill/SKILL.md +371 -0
  96. package/skills/06_fMRI_Neuroimaging/fmriprep-tool/SKILL.md +228 -0
  97. package/skills/06_fMRI_Neuroimaging/freesurfer-tool/SKILL.md +286 -0
  98. package/skills/06_fMRI_Neuroimaging/freesurfer-tool/scripts/freesurfer_processor.py +145 -0
  99. package/skills/06_fMRI_Neuroimaging/fsl-tool/SKILL.md +208 -0
  100. package/skills/06_fMRI_Neuroimaging/hbn-skill/SKILL.md +271 -0
  101. package/skills/06_fMRI_Neuroimaging/hbn-skill/scripts/extract_hbn_phenotype.py +107 -0
  102. package/skills/06_fMRI_Neuroimaging/hbn-skill/scripts/hbn_qc_summary.py +96 -0
  103. package/skills/06_fMRI_Neuroimaging/hbn-skill/scripts/reorganize_hbn.py +150 -0
  104. package/skills/06_fMRI_Neuroimaging/hcpa-skill/SKILL.md +210 -0
  105. package/skills/06_fMRI_Neuroimaging/hcpa-skill/scripts/extract_hcpa_phenotype.py +146 -0
  106. package/skills/06_fMRI_Neuroimaging/hcpa-skill/scripts/hcpa_qc_summary.py +120 -0
  107. package/skills/06_fMRI_Neuroimaging/hcpa-skill/scripts/reorganize_hcpa.py +155 -0
  108. package/skills/06_fMRI_Neuroimaging/hcpd-skill/SKILL.md +210 -0
  109. package/skills/06_fMRI_Neuroimaging/hcpd-skill/scripts/extract_hcpd_phenotype.py +148 -0
  110. package/skills/06_fMRI_Neuroimaging/hcpd-skill/scripts/hcpd_qc_summary.py +125 -0
  111. package/skills/06_fMRI_Neuroimaging/hcpd-skill/scripts/reorganize_hcpd.py +146 -0
  112. package/skills/06_fMRI_Neuroimaging/hcpep-skill/SKILL.md +215 -0
  113. package/skills/06_fMRI_Neuroimaging/hcpep-skill/scripts/extract_hcpep_phenotype.py +157 -0
  114. package/skills/06_fMRI_Neuroimaging/hcpep-skill/scripts/hcpep_qc_summary.py +143 -0
  115. package/skills/06_fMRI_Neuroimaging/hcpep-skill/scripts/reorganize_hcpep.py +146 -0
  116. package/skills/06_fMRI_Neuroimaging/hcppipeline-tool/SKILL.md +217 -0
  117. package/skills/06_fMRI_Neuroimaging/hcpya-skill/SKILL.md +214 -0
  118. package/skills/06_fMRI_Neuroimaging/hcpya-skill/scripts/extract_hcpya_phenotype.py +190 -0
  119. package/skills/06_fMRI_Neuroimaging/hcpya-skill/scripts/hcpya_qc_summary.py +152 -0
  120. package/skills/06_fMRI_Neuroimaging/hcpya-skill/scripts/reorganize_hcpya.py +203 -0
  121. package/skills/06_fMRI_Neuroimaging/ixi-skill/SKILL.md +198 -0
  122. package/skills/06_fMRI_Neuroimaging/ixi-skill/scripts/ixi_qc_summary.py +137 -0
  123. package/skills/06_fMRI_Neuroimaging/ixi-skill/scripts/reorganize_ixi.py +190 -0
  124. package/skills/06_fMRI_Neuroimaging/mnd-skill/SKILL.md +191 -0
  125. package/skills/06_fMRI_Neuroimaging/mnd-skill/scripts/extract_mnd_phenotype.py +143 -0
  126. package/skills/06_fMRI_Neuroimaging/mnd-skill/scripts/mnd_qc_summary.py +120 -0
  127. package/skills/06_fMRI_Neuroimaging/mnd-skill/scripts/validate_mnd.py +107 -0
  128. package/skills/06_fMRI_Neuroimaging/mschallenge-skill/SKILL.md +203 -0
  129. package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/analyze_lesions.py +119 -0
  130. package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/longitudinal_lesion.py +148 -0
  131. package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/mschallenge_qc_summary.py +132 -0
  132. package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/validate_mschallenge.py +116 -0
  133. package/skills/06_fMRI_Neuroimaging/nibabel-skill/SKILL.md +184 -0
  134. package/skills/06_fMRI_Neuroimaging/nibabel-skill/scripts/atlas_coordinate_reference.py +61 -0
  135. package/skills/06_fMRI_Neuroimaging/nibabel-skill/scripts/freesurfer_io_reference.py +34 -0
  136. package/skills/06_fMRI_Neuroimaging/nibabel-skill/scripts/nifti_inspection_reference.py +35 -0
  137. package/skills/06_fMRI_Neuroimaging/nifd-skill/SKILL.md +205 -0
  138. package/skills/06_fMRI_Neuroimaging/nifd-skill/scripts/extract_nifd_phenotype.py +132 -0
  139. package/skills/06_fMRI_Neuroimaging/nifd-skill/scripts/nifd_qc_summary.py +111 -0
  140. package/skills/06_fMRI_Neuroimaging/nifd-skill/scripts/validate_nifd.py +111 -0
  141. package/skills/06_fMRI_Neuroimaging/nii2dcm/SKILL.md +143 -0
  142. package/skills/06_fMRI_Neuroimaging/nilearn-tool/SKILL.md +266 -0
  143. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/connectome_reference.py +65 -0
  144. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/denoise_timeseries_reference.py +58 -0
  145. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/hierarchical_parcellation_reference.py +53 -0
  146. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/kmeans_parcellation_reference.py +53 -0
  147. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/preprocess_bold_reference.py +76 -0
  148. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/rest_dictlearning_reference.py +56 -0
  149. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/rest_ica_reference.py +59 -0
  150. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/second_level_glm_reference.py +58 -0
  151. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/spacenet_classifier_reference.py +59 -0
  152. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/svm_classifier_reference.py +60 -0
  153. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/task_glm_reference.py +63 -0
  154. package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/zalff_summary_reference.py +109 -0
  155. package/skills/06_fMRI_Neuroimaging/nsd-skill/SKILL.md +210 -0
  156. package/skills/06_fMRI_Neuroimaging/nsd-skill/scripts/extract_nsd_stimulus.py +171 -0
  157. package/skills/06_fMRI_Neuroimaging/nsd-skill/scripts/nsd_qc_summary.py +142 -0
  158. package/skills/06_fMRI_Neuroimaging/nsd-skill/scripts/validate_nsd.py +142 -0
  159. package/skills/06_fMRI_Neuroimaging/oasis-skill/SKILL.md +205 -0
  160. package/skills/06_fMRI_Neuroimaging/oasis-skill/scripts/extract_oasis_phenotype.py +126 -0
  161. package/skills/06_fMRI_Neuroimaging/oasis-skill/scripts/oasis_qc_summary.py +115 -0
  162. package/skills/06_fMRI_Neuroimaging/oasis-skill/scripts/validate_oasis.py +119 -0
  163. package/skills/06_fMRI_Neuroimaging/pet-skill/SKILL.md +173 -0
  164. package/skills/06_fMRI_Neuroimaging/pet-skill/scripts/compute_suvr.py +202 -0
  165. package/skills/06_fMRI_Neuroimaging/pnc-skill/SKILL.md +206 -0
  166. package/skills/06_fMRI_Neuroimaging/pnc-skill/scripts/extract_pnc_phenotype.py +136 -0
  167. package/skills/06_fMRI_Neuroimaging/pnc-skill/scripts/pnc_qc_summary.py +116 -0
  168. package/skills/06_fMRI_Neuroimaging/pnc-skill/scripts/validate_pnc.py +120 -0
  169. package/skills/06_fMRI_Neuroimaging/ppmi-skill/SKILL.md +209 -0
  170. package/skills/06_fMRI_Neuroimaging/ppmi-skill/scripts/extract_ppmi_phenotype.py +138 -0
  171. package/skills/06_fMRI_Neuroimaging/ppmi-skill/scripts/ppmi_qc_summary.py +111 -0
  172. package/skills/06_fMRI_Neuroimaging/ppmi-skill/scripts/validate_ppmi.py +117 -0
  173. package/skills/06_fMRI_Neuroimaging/qsiprep-tool/SKILL.md +320 -0
  174. package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/SKILL.md +215 -0
  175. package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/extract_rest_mdd_phenotype.py +132 -0
  176. package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/harmonize_sites.py +152 -0
  177. package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/rest_mdd_qc_summary.py +124 -0
  178. package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/validate_rest_mdd.py +103 -0
  179. package/skills/06_fMRI_Neuroimaging/smri-skill/SKILL.md +302 -0
  180. package/skills/06_fMRI_Neuroimaging/tcp-skill/SKILL.md +204 -0
  181. package/skills/06_fMRI_Neuroimaging/tcp-skill/scripts/extract_tcp_phenotype.py +139 -0
  182. package/skills/06_fMRI_Neuroimaging/tcp-skill/scripts/tcp_qc_summary.py +111 -0
  183. package/skills/06_fMRI_Neuroimaging/tcp-skill/scripts/validate_tcp.py +99 -0
  184. package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/SKILL.md +217 -0
  185. package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/scripts/extract_ucla_cnp_phenotype.py +145 -0
  186. package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/scripts/ucla_cnp_qc_summary.py +111 -0
  187. package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/scripts/validate_ucla_cnp.py +113 -0
  188. package/skills/06_fMRI_Neuroimaging/ukb-skill/SKILL.md +310 -0
  189. package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/build_ukb_survival.py +210 -0
  190. package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/extract_ukb_cases.py +308 -0
  191. package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/extract_ukb_phenotype.py +232 -0
  192. package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/ukb_qc_summary.py +158 -0
  193. package/skills/06_fMRI_Neuroimaging/wmh-segmentation/SKILL.md +133 -0
  194. package/skills/07_Computational_Modeling/detrending/SKILL.md +118 -0
  195. package/skills/07_Computational_Modeling/dictlearning/SKILL.md +122 -0
  196. package/skills/07_Computational_Modeling/filtering/SKILL.md +121 -0
  197. package/skills/07_Computational_Modeling/glm/SKILL.md +153 -0
  198. package/skills/07_Computational_Modeling/hierarchical/SKILL.md +121 -0
  199. package/skills/07_Computational_Modeling/ica/SKILL.md +122 -0
  200. package/skills/07_Computational_Modeling/kmeans/SKILL.md +119 -0
  201. package/skills/07_Computational_Modeling/run_models/SKILL.md +427 -0
  202. package/skills/07_Computational_Modeling/spacenet/SKILL.md +122 -0
  203. package/skills/07_Computational_Modeling/svm/SKILL.md +120 -0
  204. package/skills/08_Computational_Neuroscience/brain_gnn/SKILL.md +183 -0
  205. package/skills/08_Computational_Neuroscience/dipy-tool/SKILL.md +239 -0
  206. package/skills/08_Computational_Neuroscience/dipy-tool/scripts/dti_metrics_reference.py +70 -0
  207. package/skills/08_Computational_Neuroscience/dipy-tool/scripts/load_and_mask_reference.py +76 -0
  208. package/skills/08_Computational_Neuroscience/dipy-tool/scripts/roi_stats_reference.py +59 -0
  209. package/skills/08_Computational_Neuroscience/fm_app/SKILL.md +195 -0
  210. package/skills/08_Computational_Neuroscience/neurostorm/SKILL.md +151 -0
  211. package/skills/13_Visualization/brain-visualization/SKILL.md +191 -0
  212. package/skills/13_Visualization/brain-visualization/scripts/connectome_reference.py +108 -0
  213. package/skills/13_Visualization/brain-visualization/scripts/freesurfer_ply_reference.py +54 -0
  214. package/skills/13_Visualization/brain-visualization/scripts/zalff_summary_reference.py +116 -0
  215. package/skills/13_Visualization/ethoclaw-paper-figure-layout/SKILL.md +78 -0
  216. package/skills/13_Visualization/ethoclaw-paper-figure-layout/assets/naturecomm_figures.tex +74 -0
  217. package/skills/13_Visualization/ethoclaw-paper-figure-layout/scripts/layout_results_foldered.py +579 -0
  218. package/skills/14_Writing/overleaf-skill/SKILL.md +184 -0
  219. package/skills/14_Writing/overleaf-skill/scripts/install.sh +30 -0
  220. package/skills/14_Writing/paper-writing/SKILL.md +146 -0
  221. package/skills/14_Writing/paper-writing/scripts/data_statement_templates.py +164 -0
  222. package/skills/14_Writing/paper-writing/scripts/figure_templates.py +315 -0
  223. package/skills/14_Writing/paper-writing/scripts/nature_figure_style.py +214 -0
  224. package/skills/14_Writing/paper-writing/scripts/section_phrasebank.py +246 -0
  225. package/skills/16_Animal_Behavior/deeplabcut/SKILL.md +154 -0
  226. package/skills/16_Animal_Behavior/deeplabcut/references/3d-pose.md +89 -0
  227. package/skills/16_Animal_Behavior/deeplabcut/references/maDLC.md +123 -0
  228. package/skills/16_Animal_Behavior/deeplabcut/references/modelzoo.md +98 -0
  229. package/skills/16_Animal_Behavior/deeplabcut/references/standard-pipeline.md +165 -0
  230. package/skills/16_Animal_Behavior/deeplabcut/references/utilities.md +146 -0
  231. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/SKILL.md +274 -0
  232. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/report_template_en.html +112 -0
  233. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/report_template_en.md +21 -0
  234. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/cluster-section.md +5 -0
  235. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/heatmap-section.md +5 -0
  236. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/integrated-interpretation.md +3 -0
  237. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/overview.md +3 -0
  238. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/project-summary.md +3 -0
  239. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/radar-section.md +5 -0
  240. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/raw-trajectory.md +3 -0
  241. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/sample-check.md +3 -0
  242. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/single-subject-section.md +3 -0
  243. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/stats-section.md +5 -0
  244. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/epm.md +52 -0
  245. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/fst.md +37 -0
  246. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/nor.md +39 -0
  247. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/oft.md +43 -0
  248. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/tcst.md +45 -0
  249. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/tst.md +36 -0
  250. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/input-types.md +59 -0
  251. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/interpretation-guardrails.md +45 -0
  252. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/metadata-schema.md +57 -0
  253. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/report-sections.md +86 -0
  254. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/section-selection-rules.md +169 -0
  255. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/scripts/build_report_manifest.py +27 -0
  256. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/scripts/render_report.py +34 -0
  257. package/skills/16_Animal_Behavior/ethoclaw-analysis-report/scripts/report_utils.py +1121 -0
  258. package/skills/16_Animal_Behavior/ethoclaw-animal-grounding/SKILL.md +390 -0
  259. package/skills/16_Animal_Behavior/ethoclaw-animal-grounding/reference_code.py +98 -0
  260. package/skills/16_Animal_Behavior/ethoclaw-animal-pose-estimation/SKILL.md +336 -0
  261. package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/README.md +21 -0
  262. package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/SKILL.md +41 -0
  263. package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/batch_kinematic_generator.py +663 -0
  264. package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/config.json +19 -0
  265. package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/generate_kinematic_parameter.py +401 -0
  266. package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/kinematic_generator.py +265 -0
  267. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/SKILL.md +72 -0
  268. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/references/config.example.toml +56 -0
  269. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/scripts/cluster_all_params.py +232 -0
  270. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/scripts/cluster_all_params_from_config.py +236 -0
  271. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-radar-generate/SKILL.md +68 -0
  272. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-radar-generate/references/notes.md +5 -0
  273. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-radar-generate/scripts/plot_h5_radar.py +513 -0
  274. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/SKILL.md +52 -0
  275. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/config.toml +81 -0
  276. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/references/stats-rule.md +18 -0
  277. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/scripts/h5_inspect.py +79 -0
  278. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/scripts/h5_violin_batch.py +624 -0
  279. package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/scripts/h5_violin_stats.py +438 -0
  280. package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/SKILL.md +280 -0
  281. package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/core_scripts/heatmap_trajectory.py +790 -0
  282. package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/core_scripts/heatmap_velocity.py +855 -0
  283. package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/reference_data/reference_2d.csv +101 -0
  284. package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/reference_data/reference_2d.h5 +0 -0
  285. package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/reference_data/reference_data_readme.md +126 -0
@@ -0,0 +1,315 @@
1
+ """
2
+ Reusable Nature-journal figure templates.
3
+
4
+ Each function creates a complete figure from data and saves it.
5
+ Derived from nature-skills/nature-figure (MIT License, Copyright 2026 Yuan Yizhe).
6
+ Source: https://github.com/Yuan1z0825/nature-skills
7
+ """
8
+
9
+ import numpy as np
10
+ import matplotlib
11
+ matplotlib.use('Agg')
12
+ import matplotlib.pyplot as plt
13
+ import matplotlib as mpl
14
+ from matplotlib import gridspec
15
+
16
+ from nature_figure_style import (
17
+ apply_publication_style, DEFAULT_COLORS, DEFAULT_COLORS_NMI_PASTEL,
18
+ add_panel_label, is_dark, finalize_figure,
19
+ )
20
+
21
+
22
+ def make_grouped_bar(ax, categories, series, labels,
23
+ ylabel='Value', colors=None,
24
+ annotate=False, bar_width=0.8,
25
+ error_kw=None):
26
+ """
27
+ Grouped bar chart.
28
+
29
+ Parameters
30
+ ----------
31
+ ax : matplotlib Axes
32
+ categories : list[str] — x-axis category names (length K)
33
+ series : list[array] — one array per group (each length K)
34
+ labels : list[str] — legend label per group
35
+ colors : list[str] | None
36
+ annotate : bool — print value above each bar
37
+ bar_width : float — total width for all bars in one category
38
+ error_kw : dict — passed to ax.bar
39
+
40
+ Returns
41
+ -------
42
+ list[BarContainer]
43
+ """
44
+ if colors is None:
45
+ colors = DEFAULT_COLORS
46
+ if error_kw is None:
47
+ error_kw = {'elinewidth': 2, 'capthick': 2, 'capsize': 10}
48
+ n_groups = len(series)
49
+ n_cats = len(categories)
50
+ w = bar_width / n_groups
51
+ x = np.arange(n_cats)
52
+ containers = []
53
+ for i, (vals, label, color) in enumerate(zip(series, labels, colors)):
54
+ offset = (i - (n_groups - 1) / 2) * w
55
+ bars = ax.bar(x + offset, vals, width=w, label=label,
56
+ color=color, edgecolor='black', linewidth=1.5,
57
+ error_kw=error_kw)
58
+ containers.append(bars)
59
+ if annotate:
60
+ for bar, val in zip(bars, vals):
61
+ ax.text(bar.get_x() + bar.get_width() / 2,
62
+ bar.get_height() + 0.01,
63
+ f'{val:.2f}', ha='center', va='bottom', fontsize=10)
64
+ ax.set_xticks(x)
65
+ ax.set_xticklabels(categories)
66
+ ax.set_ylabel(ylabel)
67
+ ax.legend()
68
+ return containers
69
+
70
+
71
+ def make_trend(ax, x, y_series, labels,
72
+ colors=None, ylabel=None, xlabel=None,
73
+ show_shadow=False, shadow_alpha=0.15,
74
+ lw=2.5, marker='o', markersize=8):
75
+ """
76
+ Multi-line trend plot.
77
+
78
+ Parameters
79
+ ----------
80
+ x : array-like — shared x values
81
+ y_series : list[array] — one 1D array per line (or 2D for mean±std)
82
+ labels : list[str]
83
+ show_shadow : bool — fill_between ± std if y_series contains 2D arrays
84
+ """
85
+ if colors is None:
86
+ colors = DEFAULT_COLORS
87
+ for y, label, color in zip(y_series, labels, colors):
88
+ y = np.asarray(y)
89
+ if y.ndim == 2:
90
+ mean, std = y.mean(0), y.std(0)
91
+ else:
92
+ mean, std = y, None
93
+ ax.plot(x, mean, color=color, lw=lw, marker=marker,
94
+ markersize=markersize, label=label)
95
+ if show_shadow and std is not None:
96
+ ax.fill_between(x, mean - std, mean + std,
97
+ color=color, alpha=shadow_alpha)
98
+ if ylabel:
99
+ ax.set_ylabel(ylabel)
100
+ if xlabel:
101
+ ax.set_xlabel(xlabel)
102
+ ax.legend()
103
+
104
+
105
+ def make_forest_plot(ax, labels, estimates, ci_low, ci_high,
106
+ colors=None, ref=0.0, xlabel=None, xlim=None,
107
+ marker='o', markersize=5, lw=1.5):
108
+ """Minimal forest plot for Nature-style clinical/statistical panels."""
109
+ y = np.arange(len(labels))[::-1]
110
+ if colors is None:
111
+ colors = ['#B64342'] * len(labels)
112
+ for yi, est, lo, hi, color in zip(y, estimates, ci_low, ci_high, colors):
113
+ ax.plot([lo, hi], [yi, yi], color=color, lw=lw)
114
+ ax.plot(est, yi, marker=marker, ms=markersize, color=color)
115
+ ax.axvline(ref, color='#767676', linestyle='--', linewidth=1.2, alpha=0.8)
116
+ ax.set_yticks(y)
117
+ ax.set_yticklabels(labels)
118
+ if xlabel:
119
+ ax.set_xlabel(xlabel)
120
+ if xlim is not None:
121
+ ax.set_xlim(xlim)
122
+ ax.spines['right'].set_visible(False)
123
+ ax.spines['top'].set_visible(False)
124
+
125
+
126
+ def make_heatmap(ax, matrix, x_labels=None, y_labels=None,
127
+ cmap='magma', cbar_label=None, annotate=False,
128
+ fmt='{:.2f}', fontsize=12):
129
+ """2D heatmap with optional colorbar and cell annotations."""
130
+ im = ax.imshow(matrix, cmap=cmap, aspect='auto')
131
+ if cbar_label:
132
+ cbar = ax.figure.colorbar(im, ax=ax)
133
+ cbar.set_label(cbar_label)
134
+ if x_labels:
135
+ ax.set_xticks(range(len(x_labels)))
136
+ ax.set_xticklabels(x_labels, rotation=30, ha='right')
137
+ if y_labels:
138
+ ax.set_yticks(range(len(y_labels)))
139
+ ax.set_yticklabels(y_labels)
140
+ if annotate:
141
+ norm = mpl.colors.Normalize(vmin=matrix.min(), vmax=matrix.max())
142
+ cm_obj = plt.get_cmap(cmap)
143
+ for (i, j), val in np.ndenumerate(matrix):
144
+ r, g, b, _ = cm_obj(norm(val))
145
+ lum = 0.299 * r + 0.587 * g + 0.114 * b
146
+ color = 'white' if lum < 0.5 else 'black'
147
+ ax.text(j, i, fmt.format(val), ha='center', va='center',
148
+ fontsize=fontsize, color=color)
149
+ ax.set_frame_on(False)
150
+
151
+
152
+ # ─────────────────────────────────────────────────────────────────────────────
153
+ # Complete Figure Templates
154
+ # ─────────────────────────────────────────────────────────────────────────────
155
+
156
+ def template_grouped_bar_with_legend_panel(methods, metrics, mean_dict, std_dict,
157
+ colors=None, out_path='./figures/comparison'):
158
+ """
159
+ Multi-metric grouped bar chart with a dedicated legend panel.
160
+
161
+ Parameters
162
+ ----------
163
+ methods : list[str] — method names
164
+ metrics : list[str] — metric names
165
+ mean_dict : dict[str,array] — metric -> array of means per method
166
+ std_dict : dict[str,array] — metric -> array of stds per method
167
+ colors : list[str] — one color per method
168
+ out_path : str — save path (no extension)
169
+ """
170
+ apply_publication_style(font_size=24, axes_linewidth=3)
171
+ if colors is None:
172
+ colors = DEFAULT_COLORS[:len(methods)]
173
+
174
+ fig = plt.figure(figsize=(28, 6))
175
+ gs = gridspec.GridSpec(1, len(metrics) + 1)
176
+
177
+ handles, labels = None, None
178
+ for col, metric in enumerate(metrics):
179
+ ax = fig.add_subplot(gs[col])
180
+ bars = ax.bar(
181
+ range(len(methods)), mean_dict[metric],
182
+ yerr=std_dict[metric], capsize=5,
183
+ color=colors, label=methods,
184
+ error_kw={'elinewidth': 2, 'capthick': 2},
185
+ )
186
+ if col == 0:
187
+ handles, labels = ax.get_legend_handles_labels()
188
+ ax.set_xticks([])
189
+ y_vals = mean_dict[metric]
190
+ margin = (y_vals.max() - y_vals.min()) * 0.15
191
+ ax.set_ylim([y_vals.min() - margin, y_vals.max() + margin])
192
+ ax.set_ylabel(metric, fontsize=32)
193
+
194
+ ax_leg = fig.add_subplot(gs[-1])
195
+ ax_leg.legend(handles, labels, fontsize=28, loc='center', frameon=False)
196
+ ax_leg.set_axis_off()
197
+
198
+ return finalize_figure(fig, out_path, formats=['png', 'pdf'])
199
+
200
+
201
+ def template_ablation_bar(configs, values, stds=None,
202
+ out_path='./figures/ablation'):
203
+ """
204
+ Horizontal ablation bar chart with alpha-graduated colors.
205
+
206
+ Parameters
207
+ ----------
208
+ configs : list[str] — ablation configuration names
209
+ values : array — performance values
210
+ stds : array|None — standard deviations
211
+ """
212
+ apply_publication_style(font_size=24, axes_linewidth=3)
213
+
214
+ n = len(configs)
215
+ blue_rgb = (0.215686, 0.458824, 0.729412)
216
+ alphas = np.linspace(0.2, 1.0, n)
217
+ colors = [(blue_rgb[0], blue_rgb[1], blue_rgb[2], a) for a in alphas]
218
+
219
+ fig, ax = plt.subplots(figsize=(12, 6))
220
+ ax.barh(range(n), values, xerr=stds, color=colors, ecolor='k', capsize=5)
221
+ ax.set_yticks(range(n))
222
+ ax.set_yticklabels(configs)
223
+ ax.set_xlim([values.min() - 0.05, values.max() + 0.03])
224
+ ax.set_xlabel('Score', fontsize=32)
225
+
226
+ return finalize_figure(fig, out_path, formats=['png'])
227
+
228
+
229
+ def template_multi_panel_trend(methods, x, y_dict, panel_names,
230
+ colors=None, out_path='./figures/trends'):
231
+ """
232
+ Multi-panel trend plot with shared legend panel.
233
+
234
+ Parameters
235
+ ----------
236
+ methods : list[str]
237
+ x : array — shared x values
238
+ y_dict : dict[str, list[array]] — panel_name -> list of y arrays per method
239
+ panel_names : list[str]
240
+ colors : list[str]
241
+ """
242
+ apply_publication_style(font_size=15, axes_linewidth=2)
243
+ if colors is None:
244
+ colors = DEFAULT_COLORS[:len(methods)]
245
+
246
+ fig, axes = plt.subplots(1, len(panel_names) + 1, figsize=(18, 5))
247
+ handles, labels = None, None
248
+
249
+ for idx, (ax, name) in enumerate(zip(axes[:len(panel_names)], panel_names)):
250
+ for method, color in zip(methods, colors):
251
+ y = y_dict[name][method]
252
+ ax.plot(x, y, color=color, lw=2.5, marker='o', markersize=6, label=method)
253
+ ax.set_title(name, fontsize=18)
254
+ ax.set_xlabel('Epoch', fontsize=16)
255
+ ax.set_ylabel('Loss', fontsize=16)
256
+ if idx == 0:
257
+ handles, labels = ax.get_legend_handles_labels()
258
+
259
+ axes[-1].legend(handles, labels, fontsize=14, loc='center', frameon=False)
260
+ axes[-1].set_axis_off()
261
+
262
+ return finalize_figure(fig, out_path, formats=['png', 'pdf'])
263
+
264
+
265
+ def template_dual_colormap_heatmap(matrix, methods, metrics,
266
+ out_path='./figures/heatmap'):
267
+ """
268
+ Heatmap with dual colormaps (positive=Reds, negative=Blues_r).
269
+
270
+ Parameters
271
+ ----------
272
+ matrix : 2D array — rows=methods, cols=metrics
273
+ methods : list[str]
274
+ metrics : list[str] — even indices positive, odd indices negative
275
+ """
276
+ apply_publication_style(font_size=16, axes_linewidth=2)
277
+
278
+ fig, ax = plt.subplots(figsize=(10, 6))
279
+ n_rows, n_cols = matrix.shape
280
+ vmax = matrix.max(0)
281
+
282
+ for j in range(n_cols):
283
+ is_positive = (j % 2 == 0)
284
+ cmap = plt.cm.Reds if is_positive else plt.cm.Blues_r
285
+ cmap = cmap.copy()
286
+ norm = mpl.colors.Normalize(
287
+ vmin=0 if is_positive else vmax[j],
288
+ vmax=vmax[j] if is_positive else 0,
289
+ )
290
+ ax.imshow(matrix[:, j:j + 1], cmap=cmap, norm=norm,
291
+ aspect='auto', extent=[j - 0.5, j + 0.5, 0, n_rows], origin='lower')
292
+
293
+ for (i, j), val in np.ndenumerate(matrix):
294
+ is_positive = (j % 2 == 0)
295
+ cmap = plt.cm.Reds if is_positive else plt.cm.Blues_r
296
+ norm = mpl.colors.Normalize(
297
+ vmin=0 if is_positive else vmax[j],
298
+ vmax=vmax[j] if is_positive else 0,
299
+ )
300
+ r, g, b, _ = cmap(norm(val))
301
+ lum = 0.299 * r + 0.587 * g + 0.114 * b
302
+ color = 'white' if lum < 0.5 else 'black'
303
+ ax.text(j, i + 0.5, f'{val:.2f}', ha='center', va='center',
304
+ fontsize=13, color=color)
305
+
306
+ ax.set_xlim(-0.5, n_cols - 0.5)
307
+ ax.set_xticks(np.arange(n_cols))
308
+ ax.set_xticklabels(metrics, rotation=30, ha='right', fontsize=14)
309
+ ax.tick_params(axis='x', bottom=False, top=False, length=0)
310
+ ax.set_yticks(np.arange(n_rows) + 0.5)
311
+ ax.set_yticklabels(methods, fontsize=14)
312
+ ax.set_frame_on(False)
313
+ ax.invert_yaxis()
314
+
315
+ return finalize_figure(fig, out_path, formats=['png'])
@@ -0,0 +1,214 @@
1
+ """
2
+ Nature-journal publication style constants and helper functions.
3
+
4
+ Derived from nature-skills/nature-figure (MIT License, Copyright 2026 Yuan Yizhe).
5
+ Source: https://github.com/Yuan1z0825/nature-skills
6
+ """
7
+
8
+ import matplotlib
9
+ matplotlib.use('Agg')
10
+ import matplotlib.pyplot as plt
11
+ import numpy as np
12
+ import os
13
+ from pathlib import Path
14
+
15
+
16
+ # ─────────────────────────────────────────────────────────────────────────────
17
+ # Color Palettes
18
+ # ─────────────────────────────────────────────────────────────────────────────
19
+
20
+ PALETTE = {
21
+ "blue_main": "#0F4D92",
22
+ "blue_secondary": "#3775BA",
23
+ "green_1": "#DDF3DE",
24
+ "green_2": "#AADCA9",
25
+ "green_3": "#8BCF8B",
26
+ "red_1": "#F6CFCB",
27
+ "red_2": "#E9A6A1",
28
+ "red_strong": "#B64342",
29
+ "neutral_light": "#CFCECE",
30
+ "neutral_mid": "#767676",
31
+ "neutral_dark": "#4D4D4D",
32
+ "neutral_black": "#272727",
33
+ "gold": "#FFD700",
34
+ "teal": "#42949E",
35
+ "violet": "#9A4D8E",
36
+ "magenta":"#EA84DD",
37
+ }
38
+
39
+ DEFAULT_COLORS = [
40
+ PALETTE["blue_main"],
41
+ PALETTE["green_3"],
42
+ PALETTE["red_strong"],
43
+ PALETTE["teal"],
44
+ PALETTE["violet"],
45
+ PALETTE["neutral_light"],
46
+ ]
47
+
48
+ PALETTE_NMI_PASTEL = {
49
+ "baseline_dark": "#484878",
50
+ "baseline_mid": "#7884B4",
51
+ "baseline_soft": "#B4C0E4",
52
+ "ours_tiny": "#E4E4F0",
53
+ "ours_base": "#E4CCD8",
54
+ "ours_large": "#F0C0CC",
55
+ "bg_lilac": "#E0E0F0",
56
+ "bg_aqua": "#E0F0F0",
57
+ "bg_peach": "#F0E0D0",
58
+ "neutral_light": "#D8D8D8",
59
+ "neutral_mid": "#A8A8A8",
60
+ "neutral_dark": "#606060",
61
+ "delta_up": "#2E9E44",
62
+ "delta_down": "#E53935",
63
+ }
64
+
65
+ DEFAULT_COLORS_NMI_PASTEL = [
66
+ PALETTE_NMI_PASTEL["baseline_dark"],
67
+ PALETTE_NMI_PASTEL["baseline_mid"],
68
+ PALETTE_NMI_PASTEL["baseline_soft"],
69
+ PALETTE_NMI_PASTEL["ours_tiny"],
70
+ PALETTE_NMI_PASTEL["ours_base"],
71
+ PALETTE_NMI_PASTEL["ours_large"],
72
+ ]
73
+
74
+ PALETTE_NATURE_IMAGING = {
75
+ "bg": "#000000",
76
+ "context": "#B8B8B8",
77
+ "cyan": "#22D7E6",
78
+ "magenta": "#FF2AD4",
79
+ "white": "#FFFFFF",
80
+ }
81
+
82
+ PALETTE_NATURE_MATERIAL = {
83
+ "aqua": "#77D7D1",
84
+ "teal": "#33B5A5",
85
+ "lilac": "#B9A7E8",
86
+ "violet": "#7C6CCF",
87
+ "callout_red": "#E53935",
88
+ "neutral": "#D9D9D9",
89
+ }
90
+
91
+ PALETTE_NATURE_CLINICAL = {
92
+ "baseline": "#272727",
93
+ "week6": "#E28E2C",
94
+ "week13": "#D24B40",
95
+ "week26": "#5B8FD6",
96
+ "year1": "#7BAA5B",
97
+ "year2": "#C45AD6",
98
+ "group_band": "#F2E6D9",
99
+ }
100
+
101
+ PALETTE_NATURE_GENOMICS = {
102
+ "neutral_light": "#D8D8D8",
103
+ "neutral_mid": "#8F8F8F",
104
+ "wave1": "#D9544D",
105
+ "wave2": "#5B7FCA",
106
+ "wave3": "#B89BD9",
107
+ "outline": "#4D4D4D",
108
+ }
109
+
110
+
111
+ # ─────────────────────────────────────────────────────────────────────────────
112
+ # Style Setup
113
+ # ─────────────────────────────────────────────────────────────────────────────
114
+
115
+ def apply_publication_style(font_size=16, axes_linewidth=2.5, use_tex=False):
116
+ """Apply Nature-style rcParams. Call once before creating any figures."""
117
+ plt.rcParams['font.family'] = 'sans-serif'
118
+ plt.rcParams['font.sans-serif'] = ['Arial', 'DejaVu Sans', 'Liberation Sans']
119
+ plt.rcParams['svg.fonttype'] = 'none'
120
+ plt.rcParams['font.size'] = font_size
121
+ plt.rcParams['axes.spines.right'] = False
122
+ plt.rcParams['axes.spines.top'] = False
123
+ plt.rcParams['axes.linewidth'] = axes_linewidth
124
+ plt.rcParams['legend.frameon'] = False
125
+ if use_tex:
126
+ plt.rcParams['text.usetex'] = True
127
+
128
+
129
+ # Presets:
130
+ # Large bar panels: apply_publication_style(font_size=24, axes_linewidth=3)
131
+ # Compact figures: apply_publication_style(font_size=15, axes_linewidth=2)
132
+ # Dense multi-panels: apply_publication_style(font_size=8, axes_linewidth=1)
133
+ # LaTeX labels: apply_publication_style(use_tex=True)
134
+
135
+
136
+ # ─────────────────────────────────────────────────────────────────────────────
137
+ # Helper Functions
138
+ # ─────────────────────────────────────────────────────────────────────────────
139
+
140
+ def is_dark(hex_color, threshold=128):
141
+ """Return True if hex color is dark (use white text on it)."""
142
+ c = hex_color.lstrip('#')
143
+ r, g, b = int(c[0:2], 16), int(c[2:4], 16), int(c[4:6], 16)
144
+ return (0.299 * r + 0.587 * g + 0.114 * b) < threshold
145
+
146
+
147
+ def add_panel_label(ax, label, x=-0.06, y=1.02, fontsize=14,
148
+ color='black', fontweight='bold'):
149
+ """Place a Nature-style panel label near the top-left edge."""
150
+ ax.text(
151
+ x, y, label,
152
+ transform=ax.transAxes,
153
+ fontsize=fontsize,
154
+ fontweight=fontweight,
155
+ color=color,
156
+ ha='left',
157
+ va='bottom',
158
+ )
159
+
160
+
161
+ def style_dark_image_ax(ax, facecolor='black'):
162
+ """Prepare an axes for microscopy / rendering plates."""
163
+ ax.set_facecolor(facecolor)
164
+ ax.set_xticks([])
165
+ ax.set_yticks([])
166
+ for spine in ax.spines.values():
167
+ spine.set_visible(False)
168
+ return ax
169
+
170
+
171
+ def annotate_bars(ax, bars, colors, fmt='{:.2f}', fontsize=32, offset=-0.10):
172
+ """Add luminance-aware text labels on bars."""
173
+ for bar, color in zip(bars, colors):
174
+ c = color.lstrip('#')
175
+ r, g, b = int(c[0:2], 16) / 255, int(c[2:4], 16) / 255, int(c[4:6], 16) / 255
176
+ lum = 0.299 * r + 0.587 * g + 0.114 * b
177
+ textcolor = 'white' if lum < 0.5 else 'black'
178
+ value = bar.get_height()
179
+ ax.text(bar.get_x() + bar.get_width() / 2,
180
+ value + offset,
181
+ fmt.format(value),
182
+ ha='center', va='bottom',
183
+ fontsize=fontsize, color=textcolor)
184
+
185
+
186
+ def finalize_figure(fig, out_path, formats=None, dpi=300,
187
+ pad=2, bbox_inches=None, close=True):
188
+ """
189
+ Apply tight_layout and save figure.
190
+
191
+ Parameters
192
+ ----------
193
+ out_path : str — path without extension, or with extension
194
+ formats : list — e.g. ['png', 'pdf']. If None, uses extension of out_path.
195
+ dpi : int — 300 standard, 600 for dense bar panels
196
+ pad : float — tight_layout pad (2 default, 1 for compact multi-panel)
197
+ """
198
+ fig.tight_layout(pad=pad)
199
+ base = Path(out_path)
200
+ os.makedirs(base.parent, exist_ok=True)
201
+ if formats is None:
202
+ formats = [base.suffix.lstrip('.') or 'png']
203
+ base = base.with_suffix('')
204
+ saved = []
205
+ for fmt in formats:
206
+ p = str(base) + f'.{fmt}'
207
+ kw = {}
208
+ if bbox_inches is not None:
209
+ kw['bbox_inches'] = bbox_inches
210
+ fig.savefig(p, dpi=dpi, **kw)
211
+ saved.append(p)
212
+ if close:
213
+ plt.close(fig)
214
+ return saved