starplast 0.42.0__tar.gz
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.
- starplast-0.42.0/LICENSE +21 -0
- starplast-0.42.0/PKG-INFO +66 -0
- starplast-0.42.0/README.md +139 -0
- starplast-0.42.0/packaging/PYPI_README.md +19 -0
- starplast-0.42.0/pyproject.toml +69 -0
- starplast-0.42.0/setup.cfg +4 -0
- starplast-0.42.0/starplast/__init__.py +7 -0
- starplast-0.42.0/starplast/__main__.py +5 -0
- starplast-0.42.0/starplast/ambient.py +205 -0
- starplast-0.42.0/starplast/analysis_panel.py +2653 -0
- starplast-0.42.0/starplast/annotations.py +214 -0
- starplast-0.42.0/starplast/app.py +4225 -0
- starplast-0.42.0/starplast/archive.py +304 -0
- starplast-0.42.0/starplast/benchmark.py +98 -0
- starplast-0.42.0/starplast/build_graph.py +626 -0
- starplast-0.42.0/starplast/cellcycle.py +249 -0
- starplast-0.42.0/starplast/celldiagram.py +650 -0
- starplast-0.42.0/starplast/chat.py +374 -0
- starplast-0.42.0/starplast/chromatin.py +169 -0
- starplast-0.42.0/starplast/clustering.py +549 -0
- starplast-0.42.0/starplast/codons.py +206 -0
- starplast-0.42.0/starplast/console.py +238 -0
- starplast-0.42.0/starplast/corpus.py +156 -0
- starplast-0.42.0/starplast/data/antisense_level.tsv +8141 -0
- starplast-0.42.0/starplast/data/cdpk1_substrates.tsv +375 -0
- starplast-0.42.0/starplast/data/crosslink_models.parquet +0 -0
- starplast-0.42.0/starplast/data/crosslink_partners.tsv +495 -0
- starplast-0.42.0/starplast/data/escrt_recruitment_maxvit.tsv +9 -0
- starplast-0.42.0/starplast/data/escrt_recruitment_xgboost.tsv +14 -0
- starplast-0.42.0/starplast/data/graph.npz +0 -0
- starplast-0.42.0/starplast/data/hf_release/README.md +39 -0
- starplast-0.42.0/starplast/data/hf_release/studies.parquet +0 -0
- starplast-0.42.0/starplast/data/hf_release/study_gene_membership.parquet +0 -0
- starplast-0.42.0/starplast/data/host_bridges.parquet +0 -0
- starplast-0.42.0/starplast/data/host_interactions.parquet +0 -0
- starplast-0.42.0/starplast/data/host_proteins.parquet +0 -0
- starplast-0.42.0/starplast/data/icons/Animal_cells.svg +2464 -0
- starplast-0.42.0/starplast/data/icons/Apicomplexa_cells.svg +1250 -0
- starplast-0.42.0/starplast/data/icons/logo_01_constellation_1.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_02_constellation_2.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_03_constellation_3.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_04_constellation_4.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_05_constellation_5.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_06_constellation_6.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_07_constellation_7.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_08_constellation_8.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_09_apicoplast_1.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_10_apicoplast_2.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_11_apicoplast_3.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_12_apicoplast_4.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_13_apicoplast_5.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_14_apicoplast_6.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_15_crescent_1.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_16_crescent_2.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_17_crescent_3.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_18_crescent_4.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_19_crescent_5.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_20_crescent_6.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_21_orbit_1.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_22_orbit_2.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_23_orbit_3.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_24_orbit_4.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_25_orbit_5.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_26_orbit_6.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_27_letter_s_1.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_28_letter_s_2.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_29_letter_s_3.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_30_letter_s_4.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_31_letter_s_5.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_32_letter_s_6.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_33_letter_s_7.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_34_dark_field_1.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_35_dark_field_2.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_36_dark_field_3.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_37_dark_field_4.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_38_dark_field_5.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_39_dark_field_6.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_40_dark_field_7.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_41_galaxy_1.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_42_galaxy_2.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_43_galaxy_3.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_44_galaxy_4.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_45_galaxy_5.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_46_galaxy_6.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_47_galaxy_7.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_48_galaxy_8.svg +1 -0
- starplast-0.42.0/starplast/data/icons/logo_49_galaxy_9.svg +1 -0
- starplast-0.42.0/starplast/data/icons/starplast.svg +1 -0
- starplast-0.42.0/starplast/data/iedb_bcell_epitopes.tsv +35 -0
- starplast-0.42.0/starplast/data/interaction_studies.parquet +0 -0
- starplast-0.42.0/starplast/data/interaction_study_members.parquet +0 -0
- starplast-0.42.0/starplast/data/m6a_peaks.tsv +867 -0
- starplast-0.42.0/starplast/data/melting_temperature.tsv +3194 -0
- starplast-0.42.0/starplast/data/mentions.parquet +0 -0
- starplast-0.42.0/starplast/data/metabolites.parquet +0 -0
- starplast-0.42.0/starplast/data/mrna_stability.tsv +427 -0
- starplast-0.42.0/starplast/data/myristoylome.tsv +66 -0
- starplast-0.42.0/starplast/data/nodes.parquet +0 -0
- starplast-0.42.0/starplast/data/pf_graph.npz +0 -0
- starplast-0.42.0/starplast/data/pf_host_bridges.parquet +0 -0
- starplast-0.42.0/starplast/data/pf_mentions.parquet +0 -0
- starplast-0.42.0/starplast/data/pf_nodes.parquet +0 -0
- starplast-0.42.0/starplast/data/plasmodb_cds.tsv.gz +0 -0
- starplast-0.42.0/starplast/data/plasmodb_identity.tsv +5792 -0
- starplast-0.42.0/starplast/data/pvm_proximity.tsv +1275 -0
- starplast-0.42.0/starplast/data/questions.json +3543 -0
- starplast-0.42.0/starplast/data/secretome_partition.tsv +172 -0
- starplast-0.42.0/starplast/data/sexual_stages.tsv +4567 -0
- starplast-0.42.0/starplast/data/slot_hierarchy.json +1968 -0
- starplast-0.42.0/starplast/data/slots.json +12631 -0
- starplast-0.42.0/starplast/data/structure_search.parquet +0 -0
- starplast-0.42.0/starplast/data/structure_search_perlabel.parquet +0 -0
- starplast-0.42.0/starplast/data/study_licenses.parquet +0 -0
- starplast-0.42.0/starplast/data/toxodb_arginine_methylation.tsv +369 -0
- starplast-0.42.0/starplast/data/toxodb_cds.tsv.gz +0 -0
- starplast-0.42.0/starplast/data/toxodb_ec_numbers.tsv +8843 -0
- starplast-0.42.0/starplast/data/toxodb_enteroepithelial.tsv +7799 -0
- starplast-0.42.0/starplast/data/toxodb_epitopes.tsv +223 -0
- starplast-0.42.0/starplast/data/toxodb_gene_location.tsv +8843 -0
- starplast-0.42.0/starplast/data/toxodb_h4_acetylation.tsv +7747 -0
- starplast-0.42.0/starplast/data/toxodb_identity.tsv +8843 -0
- starplast-0.42.0/starplast/data/toxodb_macrophage.tsv +8205 -0
- starplast-0.42.0/starplast/data/toxodb_nanopore_isoforms.tsv +814 -0
- starplast-0.42.0/starplast/data/toxodb_palmitome_hydroxylamine.tsv +477 -0
- starplast-0.42.0/starplast/data/toxodb_palmitome_palmitate.tsv +496 -0
- starplast-0.42.0/starplast/data/toxodb_strain_gt1.tsv +8638 -0
- starplast-0.42.0/starplast/data/toxodb_strain_snps.tsv +8843 -0
- starplast-0.42.0/starplast/data/toxodb_strain_veg.tsv +8564 -0
- starplast-0.42.0/starplast/datasets.py +2525 -0
- starplast-0.42.0/starplast/discover.py +225 -0
- starplast-0.42.0/starplast/discovery.py +535 -0
- starplast-0.42.0/starplast/drug_sensitivity.py +97 -0
- starplast-0.42.0/starplast/embedding.py +484 -0
- starplast-0.42.0/starplast/enteric.py +144 -0
- starplast-0.42.0/starplast/expression.py +639 -0
- starplast-0.42.0/starplast/fetch_names.py +112 -0
- starplast-0.42.0/starplast/gallery.py +351 -0
- starplast-0.42.0/starplast/gpu.py +277 -0
- starplast-0.42.0/starplast/hf_publish.py +175 -0
- starplast-0.42.0/starplast/holdout_cv.py +186 -0
- starplast-0.42.0/starplast/host.py +767 -0
- starplast-0.42.0/starplast/identity.py +291 -0
- starplast-0.42.0/starplast/iedb.py +57 -0
- starplast-0.42.0/starplast/importer.py +243 -0
- starplast-0.42.0/starplast/install_gpu.py +145 -0
- starplast-0.42.0/starplast/interaction_studies.py +220 -0
- starplast-0.42.0/starplast/interactions.py +179 -0
- starplast-0.42.0/starplast/interpret.py +227 -0
- starplast-0.42.0/starplast/jobs.py +221 -0
- starplast-0.42.0/starplast/lighting.py +612 -0
- starplast-0.42.0/starplast/lipids.py +159 -0
- starplast-0.42.0/starplast/literature.py +197 -0
- starplast-0.42.0/starplast/localization.py +188 -0
- starplast-0.42.0/starplast/lod.py +148 -0
- starplast-0.42.0/starplast/logging_util.py +203 -0
- starplast-0.42.0/starplast/metabolites.py +149 -0
- starplast-0.42.0/starplast/methods.py +451 -0
- starplast-0.42.0/starplast/metrics.py +312 -0
- starplast-0.42.0/starplast/objectives.py +323 -0
- starplast-0.42.0/starplast/optimize.py +332 -0
- starplast-0.42.0/starplast/palmitome.py +80 -0
- starplast-0.42.0/starplast/paths.py +202 -0
- starplast-0.42.0/starplast/pf_graph.py +460 -0
- starplast-0.42.0/starplast/phenotype_screen.py +136 -0
- starplast-0.42.0/starplast/plasmodium.py +1683 -0
- starplast-0.42.0/starplast/proteomics.py +245 -0
- starplast-0.42.0/starplast/questions.py +113 -0
- starplast-0.42.0/starplast/rays.py +181 -0
- starplast-0.42.0/starplast/recipes.py +897 -0
- starplast-0.42.0/starplast/report.py +354 -0
- starplast-0.42.0/starplast/resistance.py +124 -0
- starplast-0.42.0/starplast/results.py +186 -0
- starplast-0.42.0/starplast/runs.py +225 -0
- starplast-0.42.0/starplast/screens.py +547 -0
- starplast-0.42.0/starplast/search.py +1056 -0
- starplast-0.42.0/starplast/searches.py +217 -0
- starplast-0.42.0/starplast/slot_tree.py +461 -0
- starplast-0.42.0/starplast/slots.py +421 -0
- starplast-0.42.0/starplast/small_tables.py +185 -0
- starplast-0.42.0/starplast/sources.py +273 -0
- starplast-0.42.0/starplast/sprite.py +677 -0
- starplast-0.42.0/starplast/structures.py +166 -0
- starplast-0.42.0/starplast/theme.py +763 -0
- starplast-0.42.0/starplast/tuning.py +358 -0
- starplast-0.42.0/starplast/validate.py +369 -0
- starplast-0.42.0/starplast/variation.py +65 -0
- starplast-0.42.0/starplast/verify.py +132 -0
- starplast-0.42.0/starplast.egg-info/PKG-INFO +66 -0
- starplast-0.42.0/starplast.egg-info/SOURCES.txt +280 -0
- starplast-0.42.0/starplast.egg-info/dependency_links.txt +1 -0
- starplast-0.42.0/starplast.egg-info/entry_points.txt +4 -0
- starplast-0.42.0/starplast.egg-info/requires.txt +35 -0
- starplast-0.42.0/starplast.egg-info/top_level.txt +1 -0
- starplast-0.42.0/tests/test_analysis.py +267 -0
- starplast-0.42.0/tests/test_analysis_panel.py +2405 -0
- starplast-0.42.0/tests/test_annotations.py +219 -0
- starplast-0.42.0/tests/test_app_controls.py +1648 -0
- starplast-0.42.0/tests/test_app_menus.py +1224 -0
- starplast-0.42.0/tests/test_app_polish.py +69 -0
- starplast-0.42.0/tests/test_app_smoke.py +238 -0
- starplast-0.42.0/tests/test_archive.py +310 -0
- starplast-0.42.0/tests/test_benchmark.py +269 -0
- starplast-0.42.0/tests/test_build_graph.py +972 -0
- starplast-0.42.0/tests/test_cellcycle.py +282 -0
- starplast-0.42.0/tests/test_celldiagram.py +566 -0
- starplast-0.42.0/tests/test_chat_stream.py +356 -0
- starplast-0.42.0/tests/test_chromatin.py +245 -0
- starplast-0.42.0/tests/test_clustering.py +623 -0
- starplast-0.42.0/tests/test_codons.py +231 -0
- starplast-0.42.0/tests/test_dataset_scripts.py +205 -0
- starplast-0.42.0/tests/test_datasets.py +483 -0
- starplast-0.42.0/tests/test_discover_cli.py +194 -0
- starplast-0.42.0/tests/test_discovery.py +355 -0
- starplast-0.42.0/tests/test_display.py +1603 -0
- starplast-0.42.0/tests/test_docs.py +91 -0
- starplast-0.42.0/tests/test_docstrings.py +69 -0
- starplast-0.42.0/tests/test_documented_numbers.py +191 -0
- starplast-0.42.0/tests/test_drug_sensitivity.py +107 -0
- starplast-0.42.0/tests/test_embedding_edges.py +542 -0
- starplast-0.42.0/tests/test_enteric.py +160 -0
- starplast-0.42.0/tests/test_expression.py +790 -0
- starplast-0.42.0/tests/test_gallery.py +487 -0
- starplast-0.42.0/tests/test_gl_compat.py +143 -0
- starplast-0.42.0/tests/test_gpu.py +507 -0
- starplast-0.42.0/tests/test_holdout_cv.py +125 -0
- starplast-0.42.0/tests/test_host.py +841 -0
- starplast-0.42.0/tests/test_identity_and_corpus.py +464 -0
- starplast-0.42.0/tests/test_iedb.py +90 -0
- starplast-0.42.0/tests/test_importer.py +300 -0
- starplast-0.42.0/tests/test_install_gpu.py +187 -0
- starplast-0.42.0/tests/test_interaction_studies.py +311 -0
- starplast-0.42.0/tests/test_interactions.py +247 -0
- starplast-0.42.0/tests/test_interpret.py +227 -0
- starplast-0.42.0/tests/test_jobs_console_chat.py +439 -0
- starplast-0.42.0/tests/test_leakage_attacks.py +140 -0
- starplast-0.42.0/tests/test_lipids.py +230 -0
- starplast-0.42.0/tests/test_literature_layers.py +375 -0
- starplast-0.42.0/tests/test_localization.py +300 -0
- starplast-0.42.0/tests/test_lod.py +140 -0
- starplast-0.42.0/tests/test_logging.py +309 -0
- starplast-0.42.0/tests/test_logos.py +165 -0
- starplast-0.42.0/tests/test_metabolites.py +218 -0
- starplast-0.42.0/tests/test_methods.py +378 -0
- starplast-0.42.0/tests/test_metrics.py +200 -0
- starplast-0.42.0/tests/test_notebook.py +96 -0
- starplast-0.42.0/tests/test_objectives.py +238 -0
- starplast-0.42.0/tests/test_optimize.py +341 -0
- starplast-0.42.0/tests/test_packaging.py +102 -0
- starplast-0.42.0/tests/test_palmitome.py +136 -0
- starplast-0.42.0/tests/test_paths.py +274 -0
- starplast-0.42.0/tests/test_pf_graph.py +532 -0
- starplast-0.42.0/tests/test_phenotype_screen.py +200 -0
- starplast-0.42.0/tests/test_pipeline_end_to_end.py +386 -0
- starplast-0.42.0/tests/test_plasmodium.py +2652 -0
- starplast-0.42.0/tests/test_proteomics.py +248 -0
- starplast-0.42.0/tests/test_publishing.py +476 -0
- starplast-0.42.0/tests/test_questions.py +111 -0
- starplast-0.42.0/tests/test_questions_tab.py +285 -0
- starplast-0.42.0/tests/test_rays.py +144 -0
- starplast-0.42.0/tests/test_readme.py +131 -0
- starplast-0.42.0/tests/test_recipes.py +757 -0
- starplast-0.42.0/tests/test_release.py +116 -0
- starplast-0.42.0/tests/test_report.py +169 -0
- starplast-0.42.0/tests/test_resistance.py +126 -0
- starplast-0.42.0/tests/test_results.py +173 -0
- starplast-0.42.0/tests/test_runs.py +198 -0
- starplast-0.42.0/tests/test_screens.py +700 -0
- starplast-0.42.0/tests/test_search.py +1390 -0
- starplast-0.42.0/tests/test_searches.py +169 -0
- starplast-0.42.0/tests/test_slot_tree.py +264 -0
- starplast-0.42.0/tests/test_slots.py +770 -0
- starplast-0.42.0/tests/test_small_tables.py +517 -0
- starplast-0.42.0/tests/test_sources.py +433 -0
- starplast-0.42.0/tests/test_sprite.py +453 -0
- starplast-0.42.0/tests/test_structures.py +325 -0
- starplast-0.42.0/tests/test_theme_and_literature.py +297 -0
- starplast-0.42.0/tests/test_tuning_edges.py +377 -0
- starplast-0.42.0/tests/test_validate.py +350 -0
- starplast-0.42.0/tests/test_variation.py +110 -0
- starplast-0.42.0/tests/test_verify.py +205 -0
- starplast-0.42.0/tests/test_visual.py +171 -0
- starplast-0.42.0/tests/test_wheel.py +33 -0
starplast-0.42.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Einar Olafsson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: starplast
|
|
3
|
+
Version: 0.42.0
|
|
4
|
+
Summary: Explore gene evidence and screen results in Toxoplasma and Plasmodium
|
|
5
|
+
Author-email: Einar Olafsson <einar.olafsson@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/EinarOlafsson/starplast
|
|
8
|
+
Project-URL: Documentation, https://einarolafsson.github.io/starplast/
|
|
9
|
+
Project-URL: Issues, https://github.com/EinarOlafsson/starplast/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/EinarOlafsson/starplast/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: toxoplasma,plasmodium,bioinformatics,CRISPR,visualization
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: numpy>=1.24
|
|
20
|
+
Requires-Dist: pandas>=2.0
|
|
21
|
+
Requires-Dist: pyarrow>=12
|
|
22
|
+
Requires-Dist: PyQt6>=6.5
|
|
23
|
+
Requires-Dist: pyqtgraph>=0.13
|
|
24
|
+
Requires-Dist: PyOpenGL>=3.1
|
|
25
|
+
Requires-Dist: scikit-learn>=1.3
|
|
26
|
+
Requires-Dist: umap-learn>=0.5
|
|
27
|
+
Requires-Dist: openpyxl>=3.1
|
|
28
|
+
Requires-Dist: xlrd>=2.0.1
|
|
29
|
+
Requires-Dist: pypdf>=4.0
|
|
30
|
+
Requires-Dist: networkx>=3.0
|
|
31
|
+
Requires-Dist: scipy>=1.10
|
|
32
|
+
Requires-Dist: matplotlib>=3.7
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
35
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
36
|
+
Requires-Dist: twine>=6; extra == "dev"
|
|
37
|
+
Requires-Dist: tomli>=2; python_version < "3.11" and extra == "dev"
|
|
38
|
+
Provides-Extra: docs
|
|
39
|
+
Requires-Dist: pdoc<17,>=15; extra == "docs"
|
|
40
|
+
Requires-Dist: markdown2<3,>=2.5; extra == "docs"
|
|
41
|
+
Provides-Extra: ingest
|
|
42
|
+
Requires-Dist: pyBigWig>=0.3; extra == "ingest"
|
|
43
|
+
Provides-Extra: gpu
|
|
44
|
+
Requires-Dist: cuml-cu12>=24.10; (sys_platform == "linux" and platform_machine == "x86_64") and extra == "gpu"
|
|
45
|
+
Requires-Dist: cupy-cuda12x>=13.0; (sys_platform == "linux" and platform_machine == "x86_64") and extra == "gpu"
|
|
46
|
+
Dynamic: license-file
|
|
47
|
+
|
|
48
|
+
# Starplast
|
|
49
|
+
|
|
50
|
+
Explore gene evidence and screen results in *Toxoplasma gondii* and
|
|
51
|
+
*Plasmodium falciparum*.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install starplast
|
|
55
|
+
starplast
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Requires Python 3.10+, a display, and OpenGL. Built gene tables and graphs are
|
|
59
|
+
included for offline browsing. Analysis runs on the CPU by default.
|
|
60
|
+
Install `starplast[gpu]` for optional CUDA 12 acceleration on Linux x86_64.
|
|
61
|
+
|
|
62
|
+
[Documentation](https://einarolafsson.github.io/starplast/) ·
|
|
63
|
+
[Source code](https://github.com/EinarOlafsson/starplast)
|
|
64
|
+
|
|
65
|
+
The package contains the application, analysis modules, and cached gene data.
|
|
66
|
+
Use `starplast[ingest]` for optional genome-coverage import support.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Starplast
|
|
2
|
+
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/starplast-wordmark-white.svg">
|
|
5
|
+
<img src="docs/assets/starplast-wordmark.svg" alt="Starplast — a Toxoplasma silhouette enclosing a constellation" width="520">
|
|
6
|
+
</picture>
|
|
7
|
+
|
|
8
|
+
[](#install)
|
|
9
|
+
[](#install)
|
|
10
|
+
[](https://einarolafsson.github.io/starplast/guide.html)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
|
|
13
|
+
[](https://github.com/EinarOlafsson/starplast/actions/workflows/docs.yml?query=branch%3Amain)
|
|
14
|
+
[](https://einarolafsson.github.io/starplast/API.html)
|
|
15
|
+
[](https://github.com/EinarOlafsson/starplast/issues)
|
|
16
|
+
[](https://github.com/EinarOlafsson/spacr)
|
|
17
|
+
|
|
18
|
+
Starplast is a desktop app for exploring gene evidence in *Toxoplasma gondii* and
|
|
19
|
+
*Plasmodium falciparum*. It brings expression, fitness screens, localization,
|
|
20
|
+
protein features, interactions, and literature annotations into one place.
|
|
21
|
+
|
|
22
|
+
Use it to look up a gene, investigate hits from a screen, compare groups of genes,
|
|
23
|
+
and choose candidates for follow-up experiments. The bundled maps contain 8,140
|
|
24
|
+
*T. gondii* genes and 5,720 *P. falciparum* genes, viewed separately.
|
|
25
|
+
|
|
26
|
+
[User guide](docs/guide.md) · [Python API](docs/API.md) ·
|
|
27
|
+
[Dataset catalogue](docs/datasets.md) · [Changes](CHANGELOG.md)
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
Python 3.10 or newer is required. The desktop app needs a display and OpenGL.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install starplast
|
|
35
|
+
starplast
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
From a checkout:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
git clone https://github.com/EinarOlafsson/starplast.git
|
|
42
|
+
cd starplast
|
|
43
|
+
pip install -e .
|
|
44
|
+
starplast
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The default installation runs analyses on the CPU. For an NVIDIA GPU on Linux
|
|
48
|
+
x86_64 with a CUDA 12 compatible driver:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install "starplast[gpu]"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
GPU dependencies are large and optional. `starplast-install-gpu` can also inspect
|
|
55
|
+
your driver and offer an installation command. macOS and Windows use CPU analysis;
|
|
56
|
+
the 3D display still uses OpenGL.
|
|
57
|
+
|
|
58
|
+
The built gene tables and graphs ship with the package. Browsing them works offline.
|
|
59
|
+
Protein structures are downloaded when requested and cached locally. Rebuilding
|
|
60
|
+
the bundled data requires the original source datasets.
|
|
61
|
+
|
|
62
|
+
## Explore a screen
|
|
63
|
+
|
|
64
|
+
1. Choose the organism under **File → Species**.
|
|
65
|
+
2. Search for a gene ID. For *T. gondii*, **File → Import data** adds your screen results.
|
|
66
|
+
3. Colour and filter the map using the measurements you want to compare.
|
|
67
|
+
4. Click a gene to read its evidence and inspect each type of relationship separately.
|
|
68
|
+
5. Select a group with a lasso or brush, then export the gene list for follow-up.
|
|
69
|
+
|
|
70
|
+
[](docs/screenshots/map_rotation.png)
|
|
71
|
+
|
|
72
|
+
The *T. gondii* map with CDPK1 (`TGME49_301440`) selected. The selected gene and
|
|
73
|
+
its five neighbours emit light; lines show attention-corrected literature
|
|
74
|
+
co-mention links. Colours show compartments. [View a still image](docs/screenshots/map_rotation.png).
|
|
75
|
+
|
|
76
|
+
Each point is a gene. Its position comes from an embedding of selected features;
|
|
77
|
+
nearby points have similar inputs, but proximity alone does not demonstrate a
|
|
78
|
+
shared function or physical interaction. Colours, relationship edges, and the
|
|
79
|
+
evidence panel provide the context needed to interpret the map. Missing evidence
|
|
80
|
+
is shown separately from measured values.
|
|
81
|
+
|
|
82
|
+
The analysis panel lets you change feature sets, build embeddings, cluster genes,
|
|
83
|
+
and evaluate recovery of labels held out from the input. Search scores help
|
|
84
|
+
prioritize candidates; they are not experimental validation. See the
|
|
85
|
+
[user guide](docs/guide.md) for controls and analysis settings.
|
|
86
|
+
|
|
87
|
+
## Working with spaCR
|
|
88
|
+
|
|
89
|
+
[spaCR](https://github.com/EinarOlafsson/spacr) handles microscopy and image-based
|
|
90
|
+
screen analysis. Its Starplast launcher installs and opens this app in a separate
|
|
91
|
+
Python environment. Starplast provides a place to explore the biological evidence
|
|
92
|
+
around those screen results. Export a gene-level table from spaCR and import it
|
|
93
|
+
into Starplast; launching the app does not transfer results automatically.
|
|
94
|
+
|
|
95
|
+
## Data and reproducibility
|
|
96
|
+
|
|
97
|
+
**[Full table of included data and source links →](docs/datasets.md)**
|
|
98
|
+
|
|
99
|
+
The catalogue lists all 128 registered datasets and computed layers, with their
|
|
100
|
+
measurements, coverage, publication references, and links to source data or inputs.
|
|
101
|
+
Coverage differs by organism and assay;
|
|
102
|
+
absence from a literature search does not establish that a gene has never been studied.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
python -m starplast.paths # show data locations and missing cache files
|
|
106
|
+
python -m starplast.build_graph # rebuild from available source datasets
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
| Variable | Purpose |
|
|
110
|
+
|---|---|
|
|
111
|
+
| `STARPLAST_CACHE` | Override the directory containing built gene tables and graphs |
|
|
112
|
+
| `STARPLAST_DATA` | Locate raw datasets used for rebuilding |
|
|
113
|
+
| `STARPLAST_STATE` | Override the directory for saved runs, annotations, and downloads |
|
|
114
|
+
|
|
115
|
+
Methods are described in [MATERIALS_AND_METHODS.md](MATERIALS_AND_METHODS.md).
|
|
116
|
+
[HANDOFF.md](HANDOFF.md) contains the development history and earlier design decisions.
|
|
117
|
+
The [repository review](docs/repository-review.md) describes the current architecture
|
|
118
|
+
and its limitations.
|
|
119
|
+
|
|
120
|
+
## Development
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
pip install -e ".[dev,docs]"
|
|
124
|
+
QT_QPA_PLATFORM=offscreen pytest tests/test_app_smoke.py tests/test_docstrings.py -q
|
|
125
|
+
python scripts/build_docs.py
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Open `docs/site/index.html` for the guide and generated API reference.
|
|
129
|
+
Some tests need source datasets, CUDA, or a working OpenGL context; see
|
|
130
|
+
[development and releases](docs/releases.md) for the release checks.
|
|
131
|
+
|
|
132
|
+
Develop on `nightly` and merge checked changes into `main`. To release, update all
|
|
133
|
+
package and runtime versions together with `python scripts/release.py bump 0.43.0` and update
|
|
134
|
+
the changelog before merging. A version increase on `main` triggers checks,
|
|
135
|
+
builds, PyPI publishing, and a GitHub release. Ordinary merges do not publish.
|
|
136
|
+
The initial PyPI account setup is described in the release guide.
|
|
137
|
+
|
|
138
|
+
The source code is distributed under the [MIT license](LICENSE).
|
|
139
|
+
Source datasets and third-party artwork retain their own licenses and attribution.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Starplast
|
|
2
|
+
|
|
3
|
+
Explore gene evidence and screen results in *Toxoplasma gondii* and
|
|
4
|
+
*Plasmodium falciparum*.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
pip install starplast
|
|
8
|
+
starplast
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires Python 3.10+, a display, and OpenGL. Built gene tables and graphs are
|
|
12
|
+
included for offline browsing. Analysis runs on the CPU by default.
|
|
13
|
+
Install `starplast[gpu]` for optional CUDA 12 acceleration on Linux x86_64.
|
|
14
|
+
|
|
15
|
+
[Documentation](https://einarolafsson.github.io/starplast/) ·
|
|
16
|
+
[Source code](https://github.com/EinarOlafsson/starplast)
|
|
17
|
+
|
|
18
|
+
The package contains the application, analysis modules, and cached gene data.
|
|
19
|
+
Use `starplast[ingest]` for optional genome-coverage import support.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "starplast"
|
|
7
|
+
version = "0.42.0"
|
|
8
|
+
description = "Explore gene evidence and screen results in Toxoplasma and Plasmodium"
|
|
9
|
+
readme = "packaging/PYPI_README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{name = "Einar Olafsson", email = "einar.olafsson@gmail.com"}]
|
|
14
|
+
keywords = ["toxoplasma", "plasmodium", "bioinformatics", "CRISPR", "visualization"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Intended Audience :: Science/Research",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Topic :: Scientific/Engineering :: Bio-Informatics",
|
|
20
|
+
]
|
|
21
|
+
dependencies = [
|
|
22
|
+
"numpy>=1.24",
|
|
23
|
+
"pandas>=2.0",
|
|
24
|
+
"pyarrow>=12",
|
|
25
|
+
"PyQt6>=6.5",
|
|
26
|
+
"pyqtgraph>=0.13",
|
|
27
|
+
"PyOpenGL>=3.1",
|
|
28
|
+
"scikit-learn>=1.3",
|
|
29
|
+
"umap-learn>=0.5",
|
|
30
|
+
"openpyxl>=3.1",
|
|
31
|
+
"xlrd>=2.0.1",
|
|
32
|
+
"pypdf>=4.0",
|
|
33
|
+
"networkx>=3.0",
|
|
34
|
+
"scipy>=1.10",
|
|
35
|
+
"matplotlib>=3.7"
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[project.optional-dependencies]
|
|
39
|
+
dev = ["pytest>=7", "build>=1.2", "twine>=6", "tomli>=2; python_version < '3.11'"]
|
|
40
|
+
docs = ["pdoc>=15,<17", "markdown2>=2.5,<3"]
|
|
41
|
+
ingest = ["pyBigWig>=0.3"]
|
|
42
|
+
gpu = [
|
|
43
|
+
"cuml-cu12>=24.10; sys_platform == 'linux' and platform_machine == 'x86_64'",
|
|
44
|
+
"cupy-cuda12x>=13.0; sys_platform == 'linux' and platform_machine == 'x86_64'"
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[project.scripts]
|
|
48
|
+
starplast = "starplast.app:main"
|
|
49
|
+
starplast-discover = "starplast.discover:main"
|
|
50
|
+
starplast-install-gpu = "starplast.install_gpu:main"
|
|
51
|
+
|
|
52
|
+
[project.urls]
|
|
53
|
+
Homepage = "https://github.com/EinarOlafsson/starplast"
|
|
54
|
+
Documentation = "https://einarolafsson.github.io/starplast/"
|
|
55
|
+
Issues = "https://github.com/EinarOlafsson/starplast/issues"
|
|
56
|
+
Changelog = "https://github.com/EinarOlafsson/starplast/blob/main/CHANGELOG.md"
|
|
57
|
+
|
|
58
|
+
[tool.setuptools]
|
|
59
|
+
packages = ["starplast"]
|
|
60
|
+
include-package-data = false
|
|
61
|
+
|
|
62
|
+
[tool.setuptools.package-data]
|
|
63
|
+
starplast = ["data/*.npz", "data/*.parquet", "data/*.tsv", "data/*.tsv.gz", "data/*.json", "data/hf_release/*.parquet", "data/hf_release/*.md", "data/icons/*.svg"]
|
|
64
|
+
|
|
65
|
+
[tool.setuptools.exclude-package-data]
|
|
66
|
+
starplast = ["data/embeddings/*"]
|
|
67
|
+
|
|
68
|
+
[tool.pytest.ini_options]
|
|
69
|
+
markers = ["slow: runs a real build or a full documentation pass; minutes rather than seconds"]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"""Explore gene evidence in Toxoplasma gondii and Plasmodium falciparum.
|
|
2
|
+
|
|
3
|
+
Use the analysis modules from Python, ``starplast-discover`` for batch searches,
|
|
4
|
+
or ``starplast`` for the desktop browser. The user guide and API examples are
|
|
5
|
+
available at https://einarolafsson.github.io/starplast/.
|
|
6
|
+
"""
|
|
7
|
+
__version__ = "0.42.0"
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""A drifting field of soft colour blobs, behind the panels.
|
|
3
|
+
|
|
4
|
+
Ported from spaCR's ambient background so the two programs look like one pair of tools, and kept to
|
|
5
|
+
the one animation that was asked for -- the blobs -- with the same controls under the same names:
|
|
6
|
+
speed, size, density, blur.
|
|
7
|
+
|
|
8
|
+
The design decision worth carrying across: **position is a pure function of the clock**, two
|
|
9
|
+
independent sines per blob rather than a random walk. A walk accumulates error, cannot be rewound,
|
|
10
|
+
and gives a different picture every time a frame is dropped; a function of time can be asked for any
|
|
11
|
+
instant, which is what makes the field paintable at whatever rate the window can manage and
|
|
12
|
+
identical at the same `t` on any machine.
|
|
13
|
+
|
|
14
|
+
Blobs are seeded on a jittered grid rather than uniformly at random. With a dozen of them, uniform
|
|
15
|
+
sampling reliably leaves one corner empty and puts three in the middle -- which reads as a bug in
|
|
16
|
+
the drawing rather than as a random arrangement.
|
|
17
|
+
"""
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import math
|
|
21
|
+
import random
|
|
22
|
+
from dataclasses import dataclass
|
|
23
|
+
|
|
24
|
+
from PyQt6 import QtCore, QtGui, QtWidgets
|
|
25
|
+
|
|
26
|
+
#: The controls, and the range each is allowed -- the same names and bounds spaCR uses, so a person
|
|
27
|
+
#: who has set this up once does not have to learn it twice.
|
|
28
|
+
SPEED_RANGE = (0.1, 4.0)
|
|
29
|
+
SIZE_RANGE = (0.25, 2.5)
|
|
30
|
+
DENSITY_RANGE = (0.25, 3.0)
|
|
31
|
+
BLUR_RANGE = (0.0, 3.0)
|
|
32
|
+
DEFAULT_SPEED = 1.0
|
|
33
|
+
DEFAULT_SIZE = 1.0
|
|
34
|
+
DEFAULT_DENSITY = 1.0
|
|
35
|
+
DEFAULT_BLUR = 0.0
|
|
36
|
+
|
|
37
|
+
#: How many blobs at density 1.0, and the grid they are seeded on.
|
|
38
|
+
BLOB_COUNT = 12
|
|
39
|
+
GRID = (4, 3)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class Blob:
|
|
44
|
+
"""One blob: where it sits, how far and how fast it wanders, how it breathes."""
|
|
45
|
+
x: float
|
|
46
|
+
y: float
|
|
47
|
+
drift_x: float
|
|
48
|
+
drift_y: float
|
|
49
|
+
rate_x: float
|
|
50
|
+
rate_y: float
|
|
51
|
+
phase_x: float
|
|
52
|
+
phase_y: float
|
|
53
|
+
radius: float
|
|
54
|
+
pulse: float
|
|
55
|
+
pulse_rate: float
|
|
56
|
+
pulse_phase: float
|
|
57
|
+
color: int
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def field(seed: int = 0, density: float = DEFAULT_DENSITY) -> list:
|
|
61
|
+
"""A reproducible set of blobs, seeded on a jittered grid.
|
|
62
|
+
|
|
63
|
+
The pool is always rolled at the top of the density range and a prefix of it painted, so raising
|
|
64
|
+
the density adds blobs rather than redrawing the ones already there: the random numbers are
|
|
65
|
+
consumed in the same order either way, and blob 3 keeps the numbers blob 3 always had.
|
|
66
|
+
"""
|
|
67
|
+
rng = random.Random(seed)
|
|
68
|
+
cols, rows = GRID
|
|
69
|
+
cells = list(range(cols * rows))
|
|
70
|
+
rng.shuffle(cells)
|
|
71
|
+
pool = int(round(BLOB_COUNT * DENSITY_RANGE[1]))
|
|
72
|
+
blobs = []
|
|
73
|
+
for i in range(pool):
|
|
74
|
+
cell = cells[i % len(cells)]
|
|
75
|
+
col, row = cell % cols, cell // cols
|
|
76
|
+
small = (i % 3) == 0
|
|
77
|
+
lo, hi = (0.10, 0.18) if small else (0.22, 0.38)
|
|
78
|
+
blobs.append(Blob(
|
|
79
|
+
x=(col + 0.15 + 0.7 * rng.random()) / cols,
|
|
80
|
+
y=(row + 0.15 + 0.7 * rng.random()) / rows,
|
|
81
|
+
drift_x=rng.uniform(0.02, 0.09), drift_y=rng.uniform(0.02, 0.09),
|
|
82
|
+
rate_x=2 * math.pi / rng.uniform(19.0, 43.0),
|
|
83
|
+
rate_y=2 * math.pi / rng.uniform(23.0, 51.0),
|
|
84
|
+
phase_x=rng.uniform(0.0, 2 * math.pi), phase_y=rng.uniform(0.0, 2 * math.pi),
|
|
85
|
+
radius=rng.uniform(lo, hi), pulse=rng.uniform(0.05, 0.16),
|
|
86
|
+
pulse_rate=2 * math.pi / rng.uniform(11.0, 29.0),
|
|
87
|
+
pulse_phase=rng.uniform(0.0, 2 * math.pi),
|
|
88
|
+
# Round-robin, not a random pick: with three colours and a dozen blobs a random
|
|
89
|
+
# assignment leaves one colour missing about one run in fifty.
|
|
90
|
+
color=i))
|
|
91
|
+
keep = max(1, int(round(BLOB_COUNT * _clamp(density, DENSITY_RANGE))))
|
|
92
|
+
return blobs[:keep]
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _clamp(value: float, bounds) -> float:
|
|
96
|
+
lo, hi = bounds
|
|
97
|
+
return float(min(max(value, lo), hi))
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def geometry(blobs, t: float, width: int, height: int, speed: float = DEFAULT_SPEED,
|
|
101
|
+
size: float = DEFAULT_SIZE) -> list:
|
|
102
|
+
"""(cx, cy, radius, colour index) per blob, in pixels, at time `t`."""
|
|
103
|
+
short = max(min(width, height), 1)
|
|
104
|
+
out = []
|
|
105
|
+
tt = t * _clamp(speed, SPEED_RANGE)
|
|
106
|
+
for b in blobs:
|
|
107
|
+
cx = (b.x + b.drift_x * math.sin(b.rate_x * tt + b.phase_x)) * width
|
|
108
|
+
cy = (b.y + b.drift_y * math.sin(b.rate_y * tt + b.phase_y)) * height
|
|
109
|
+
r = b.radius * (1.0 + b.pulse * math.sin(b.pulse_rate * tt + b.pulse_phase))
|
|
110
|
+
out.append((cx, cy, max(r * short * _clamp(size, SIZE_RANGE), 1.0), b.color))
|
|
111
|
+
return out
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class AmbientWidget(QtWidgets.QWidget):
|
|
115
|
+
"""The blob field, painted behind everything else.
|
|
116
|
+
|
|
117
|
+
Transparent to the mouse -- it is scenery, and a background that swallowed a click on the panel
|
|
118
|
+
in front of it would be a bug nobody could describe. The timer runs only while the widget is
|
|
119
|
+
visible, because sixty repaints a second of a picture nobody is looking at is sixty repaints a
|
|
120
|
+
second of a picture nobody is looking at.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
def __init__(self, colors=None, background="#0b0d10", parent=None, seed: int = 0):
|
|
124
|
+
super().__init__(parent)
|
|
125
|
+
self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)
|
|
126
|
+
self.background = QtGui.QColor(background)
|
|
127
|
+
self.colors = [QtGui.QColor(c) for c in (colors or ["#43c6d8", "#7a5cd8", "#2a9fb0"])]
|
|
128
|
+
# `blob_size`, NOT `size`: QWidget.size() is a method, and an attribute of that name
|
|
129
|
+
# shadows it -- every caller asking this widget how big it is gets a float back and
|
|
130
|
+
# "'float' object is not callable" from somewhere that never mentioned size.
|
|
131
|
+
self.speed, self.blob_size, self.density = DEFAULT_SPEED, DEFAULT_SIZE, DEFAULT_DENSITY
|
|
132
|
+
self.blur = DEFAULT_BLUR
|
|
133
|
+
self.seed = seed
|
|
134
|
+
self.blobs = field(seed, self.density)
|
|
135
|
+
self._t = 0.0
|
|
136
|
+
self._timer = QtCore.QTimer(self)
|
|
137
|
+
self._timer.setInterval(40) # 25 fps: scenery, not an animation to watch
|
|
138
|
+
self._timer.timeout.connect(self._tick)
|
|
139
|
+
|
|
140
|
+
def configure(self, **kw) -> None:
|
|
141
|
+
"""Set any of speed, size, density, blur, colors -- and rebuild if the count changed.
|
|
142
|
+
|
|
143
|
+
`size` is accepted under spaCR's name and stored as `blob_size`, since a widget cannot have
|
|
144
|
+
an attribute called `size`.
|
|
145
|
+
"""
|
|
146
|
+
density = kw.pop("density", None)
|
|
147
|
+
if "size" in kw:
|
|
148
|
+
kw["blob_size"] = kw.pop("size")
|
|
149
|
+
for k, v in kw.items():
|
|
150
|
+
if k == "colors":
|
|
151
|
+
self.colors = [QtGui.QColor(c) for c in v]
|
|
152
|
+
elif hasattr(self, k):
|
|
153
|
+
setattr(self, k, float(v))
|
|
154
|
+
if density is not None and float(density) != self.density:
|
|
155
|
+
self.density = float(density)
|
|
156
|
+
self.blobs = field(self.seed, self.density)
|
|
157
|
+
self.update()
|
|
158
|
+
|
|
159
|
+
def start(self) -> None:
|
|
160
|
+
"""Begin animating, if it is not already."""
|
|
161
|
+
if not self._timer.isActive():
|
|
162
|
+
self._timer.start()
|
|
163
|
+
|
|
164
|
+
def stop(self) -> None:
|
|
165
|
+
"""Stop animating. The field keeps its time, so starting again continues rather than jumps."""
|
|
166
|
+
self._timer.stop()
|
|
167
|
+
|
|
168
|
+
def _tick(self) -> None:
|
|
169
|
+
self._t += self._timer.interval() / 1000.0
|
|
170
|
+
self.update()
|
|
171
|
+
|
|
172
|
+
def set_time(self, t: float) -> None:
|
|
173
|
+
"""Jump to an instant. Position is a function of the clock, so this is exact."""
|
|
174
|
+
self._t = float(t)
|
|
175
|
+
self.update()
|
|
176
|
+
|
|
177
|
+
def showEvent(self, ev):
|
|
178
|
+
self.start()
|
|
179
|
+
super().showEvent(ev)
|
|
180
|
+
|
|
181
|
+
def hideEvent(self, ev):
|
|
182
|
+
self.stop()
|
|
183
|
+
super().hideEvent(ev)
|
|
184
|
+
|
|
185
|
+
def paintEvent(self, _ev):
|
|
186
|
+
p = QtGui.QPainter(self)
|
|
187
|
+
p.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing)
|
|
188
|
+
p.fillRect(self.rect(), self.background)
|
|
189
|
+
p.setPen(QtCore.Qt.PenStyle.NoPen)
|
|
190
|
+
p.setCompositionMode(QtGui.QPainter.CompositionMode.CompositionMode_Plus)
|
|
191
|
+
for cx, cy, r, ci in geometry(self.blobs, self._t, self.width(), self.height(),
|
|
192
|
+
self.speed, self.blob_size):
|
|
193
|
+
base = self.colors[ci % len(self.colors)]
|
|
194
|
+
grad = QtGui.QRadialGradient(cx, cy, r)
|
|
195
|
+
# Alpha to zero at the rim rather than a hard edge: a blob with an edge is a circle, and
|
|
196
|
+
# a circle drifting behind a panel reads as a loading spinner.
|
|
197
|
+
inner = QtGui.QColor(base)
|
|
198
|
+
inner.setAlpha(int(70 * max(0.35, 1.0 - self.blur / (BLUR_RANGE[1] + 1e-9))))
|
|
199
|
+
outer = QtGui.QColor(base)
|
|
200
|
+
outer.setAlpha(0)
|
|
201
|
+
grad.setColorAt(0.0, inner)
|
|
202
|
+
grad.setColorAt(1.0, outer)
|
|
203
|
+
p.setBrush(QtGui.QBrush(grad))
|
|
204
|
+
p.drawEllipse(QtCore.QRectF(cx - r, cy - r, 2 * r, 2 * r))
|
|
205
|
+
p.end()
|