descriptron-core 2.1.1__tar.gz → 2.1.2__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.
Files changed (136) hide show
  1. descriptron_core-2.1.2/NOTICE +59 -0
  2. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/PKG-INFO +2 -1
  3. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/pyproject.toml +1 -1
  4. descriptron_core-2.1.2/src/descriptron_core/tools/validate_centerline_lengths.py +71 -0
  5. descriptron_core-2.1.2/src/descriptron_core/tools/validate_texture_glcm.py +68 -0
  6. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/.gitignore +0 -0
  7. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/LICENSE +0 -0
  8. /descriptron_core-2.1.1/NOTICE → /descriptron_core-2.1.2/NOTICE.bak_pre_212_20260929_1100 +0 -0
  9. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/README.md +0 -0
  10. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/pyproject.toml.bak_pre_203_20260924_145320 +0 -0
  11. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/pyproject.toml.bak_pre_204_20260924_165335 +0 -0
  12. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/pyproject.toml.bak_pre_210_20260925_103754 +0 -0
  13. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/pyproject.toml.bak_pre_211_20260925_114912 +0 -0
  14. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/pyproject.toml.bak_pre_keys_20260924_165335 +0 -0
  15. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/__init__.py +0 -0
  16. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/cli.py +0 -0
  17. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/cli.py.bak_pre_keys_20260924_165335 +0 -0
  18. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/biorag_system_prompts_v1.txt +0 -0
  19. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/biorag_system_prompts_v2.txt +0 -0
  20. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/diaphorina_user_prompts.txt +0 -0
  21. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/ontologies/aism.obo +0 -0
  22. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/ontologies/pato.obo +0 -0
  23. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/SDD.xsd +0 -0
  24. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/SDD_EnumLib.xsd +0 -0
  25. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/SDD_TypeLib.xsd +0 -0
  26. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/UBIF_BasePattern.xsd +0 -0
  27. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/UBIF_CoreExtensions.xsd +0 -0
  28. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/UBIF_CoreOntology.xsd +0 -0
  29. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/UBIF_EnumLib.xsd +0 -0
  30. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/UBIF_LinneanCore.xsd +0 -0
  31. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/UBIF_TypeLib.xsd +0 -0
  32. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/w3c-schemata/xml.xsd +0 -0
  33. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/taxpub/sample_treatment_deposit_example.xml +0 -0
  34. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/taxpub/sample_zookeys_26056_tp.xml +0 -0
  35. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/schemas/taxpub/tax-treatment-NS0-v1_flat.dtd +0 -0
  36. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/taxon_profiles/TEMPLATE_taxon_profile.yaml +0 -0
  37. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/data/biorag_prompts/taxon_profiles/diaphorina_taxon_profile.yaml +0 -0
  38. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/FHS_and_CLAHE_V21.py +0 -0
  39. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_add_discrete_characters_v1.py +0 -0
  40. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_annotation_reorient_v1.py +0 -0
  41. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_annotation_screen_v1.py +0 -0
  42. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_autapomorphy_v1.py +0 -0
  43. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_calibrate_v1.py +0 -0
  44. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_calibration_figures_v1.py +0 -0
  45. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_character_gate_v1.py +0 -0
  46. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_character_reliability_v1.py +0 -0
  47. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_character_robustness_v1.py +0 -0
  48. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_collaborator_forms_v1.py +0 -0
  49. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_computed_sets_v1.py +0 -0
  50. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_confabulation_checker_v2.py +0 -0
  51. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_congruence_compare_v1.py +0 -0
  52. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_description_refiner_v1.py +0 -0
  53. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_descriptive_scoring_v1.py +0 -0
  54. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_feature_policy.py +0 -0
  55. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_frame_orientation_calibrate_v1.py +0 -0
  56. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_frame_orientation_v1.py +0 -0
  57. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_gate_compare_v1.py +0 -0
  58. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_graph_identify_v1.py +0 -0
  59. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_graph_support_figure_v1.py +0 -0
  60. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_homology_frame_v1.py +0 -0
  61. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_instrument_compare_v3.py +0 -0
  62. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_key_builder_v1.py +0 -0
  63. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_key_feature_filter_v2.py +0 -0
  64. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_key_fuzzy_figures_v1.py +0 -0
  65. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_key_fuzzy_v1.py +0 -0
  66. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_key_holdout_v1.py +0 -0
  67. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_key_jackknife_support_v1.py +0 -0
  68. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_label_conflict_check_v1.py +0 -0
  69. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_llm_backend.py +0 -0
  70. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_make_taxon_profile_v1.py +0 -0
  71. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_methods_summary_figure_v1.py +0 -0
  72. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_novelty_score_v1.py +0 -0
  73. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_ontology_annotator_v2.py +0 -0
  74. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_outgroup_batch_check_v1.py +0 -0
  75. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_outline_shape_v1.py +0 -0
  76. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/biorag_system_prompts_v1.txt +0 -0
  77. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/biorag_system_prompts_v2.txt +0 -0
  78. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/diaphorina_user_prompts.txt +0 -0
  79. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/ontologies/aism.obo +0 -0
  80. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/ontologies/pato.obo +0 -0
  81. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/SDD.xsd +0 -0
  82. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/SDD_EnumLib.xsd +0 -0
  83. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/SDD_TypeLib.xsd +0 -0
  84. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/UBIF_BasePattern.xsd +0 -0
  85. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/UBIF_CoreExtensions.xsd +0 -0
  86. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/UBIF_CoreOntology.xsd +0 -0
  87. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/UBIF_EnumLib.xsd +0 -0
  88. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/UBIF_LinneanCore.xsd +0 -0
  89. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/UBIF_TypeLib.xsd +0 -0
  90. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/w3c-schemata/xml.xsd +0 -0
  91. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/taxpub/sample_treatment_deposit_example.xml +0 -0
  92. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/taxpub/sample_zookeys_26056_tp.xml +0 -0
  93. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/schemas/taxpub/tax-treatment-NS0-v1_flat.dtd +0 -0
  94. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/taxon_profiles/TEMPLATE_taxon_profile.yaml +0 -0
  95. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_prompts/taxon_profiles/diaphorina_taxon_profile.yaml +0 -0
  96. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_rebuild_downstream_v1.sh +0 -0
  97. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_reliability_figures_v1.py +0 -0
  98. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_rename_species_v1.py +0 -0
  99. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_rerun_descriptive_tables_v1.sh +0 -0
  100. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_retest_compare_v1.py +0 -0
  101. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_specimen_id.py +0 -0
  102. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_subjective_checks_v1.py +0 -0
  103. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_type_material_v1.py +0 -0
  104. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_vlm_characters_v1.py +0 -0
  105. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_vlm_heatmap_figures_v1.py +0 -0
  106. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_vlm_reliability_figure_v1.py +0 -0
  107. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biorag_vlm_roi_figures_v1.py +0 -0
  108. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biosyslit_rag_retrieval.py +0 -0
  109. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/biosyslit_rag_retrieval_v2.py +0 -0
  110. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/build_monograph_exports_v1.py +0 -0
  111. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/build_species_treatment_docx_v2.py +0 -0
  112. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/coco_combiner_V13.py +0 -0
  113. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/coco_converter_v24.py +0 -0
  114. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/color_extraction_with_names-v8.py +0 -0
  115. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/color_phenomics_homology_v2_1.py +0 -0
  116. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/compile_specimen_data.py +0 -0
  117. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/descriptron_centerline.py +0 -0
  118. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/descriptron_coco_tools.py +0 -0
  119. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/descriptron_convert.py +0 -0
  120. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/descriptron_credentials.py +0 -0
  121. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/descriptron_joints.py +0 -0
  122. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/descriptron_metadata.py +0 -0
  123. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/descriptron_rosetta.py +0 -0
  124. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/descriptron_shape_stats.py +0 -0
  125. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/landmark_gpa_V1.py +0 -0
  126. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/landmark_gpa_V2.py +0 -0
  127. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/make_reproducibility_bundle.py +0 -0
  128. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/run_full_pipeline_v2.py +0 -0
  129. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/semi_landmark_and_kpts_procrustesV34_GPA.py +0 -0
  130. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/semi_landmark_and_kpts_procrustesV42_GPA.py +0 -0
  131. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/texture_phenomics_from_coco.py +0 -0
  132. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/texture_phenomics_homology.py +0 -0
  133. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/validate_pipeline_gm_vs_geomorph.py +0 -0
  134. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/validate_semilandmarks_vs_geomorph.py +0 -0
  135. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/validate_shape_stats_vs_geomorph.py +0 -0
  136. {descriptron_core-2.1.1 → descriptron_core-2.1.2}/src/descriptron_core/tools/validate_shape_stats_vs_rrpp.py +0 -0
@@ -0,0 +1,59 @@
1
+ Descriptron
2
+ Copyright 2024-2026 Alex R. Van Dam (ORCID 0000-0002-1966-0338)
3
+
4
+ This product includes software developed by Alex R. Van Dam
5
+ https://github.com/alexrvandam/Descriptron
6
+
7
+ Licensed under the Apache License, Version 2.0 (see LICENSE). Under Section
8
+ 4(d) of that licence, this NOTICE file must be included with any
9
+ redistribution of this software or of any work derived from it.
10
+
11
+ REQUIRED CITATION
12
+ -----------------
13
+ Anyone who uses Descriptron, or any software derived from it (including
14
+ descriptron-core, descriptron-vision, descriptron-gui and descriptron-mcp), in
15
+ work that is published, presented or distributed must cite:
16
+
17
+ 1. The software (Descriptron v2), by the DOI of the version used:
18
+ Van Dam, A. R. (2026). Descriptron: morphology-driven species descriptions,
19
+ keys and delimitation for dark taxa (Version 2.1.1). Zenodo.
20
+ https://doi.org/10.5281/zenodo.22958109
21
+ (all versions: https://doi.org/10.5281/zenodo.17077224;
22
+ repository: https://github.com/alexrvandam/Descriptron)
23
+
24
+ 2. The first Descriptron paper:
25
+ Van Dam, A. R. & Štarhová Serbina, L. (2026). Descriptron: Artificial
26
+ intelligence for automating taxonomic species descriptions with a
27
+ user-friendly software package. Systematic Entomology, 51(1), e70005.
28
+ https://doi.org/10.1111/syen.70005
29
+
30
+ 3. Once it is published, the Descriptron v2 paper as well. Its reference
31
+ will be added here and in CITATION.cff on publication.
32
+
33
+ BibTeX:
34
+
35
+ @software{vandam_2026_descriptron_v211,
36
+ author = {Van Dam, Alex R.},
37
+ title = {Descriptron: morphology-driven species descriptions, keys and
38
+ delimitation for dark taxa},
39
+ version = {v2.1.1},
40
+ year = {2026},
41
+ publisher = {Zenodo},
42
+ doi = {10.5281/zenodo.22958109},
43
+ url = {https://doi.org/10.5281/zenodo.22958109}
44
+ }
45
+
46
+ @article{vandam2026descriptron,
47
+ author = {Van Dam, Alex R. and Štarhová Serbina, Liliya},
48
+ title = {Descriptron: Artificial intelligence for automating taxonomic species
49
+ descriptions with a user-friendly software package},
50
+ journal = {Systematic Entomology},
51
+ volume = {51},
52
+ number = {1},
53
+ pages = {e70005},
54
+ year = {2026},
55
+ doi = {10.1111/syen.70005}
56
+ }
57
+
58
+ The same information is in CITATION.cff, which GitHub shows as
59
+ "Cite this repository".
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: descriptron-core
3
- Version: 2.1.1
3
+ Version: 2.1.2
4
4
  Summary: Evidence-tiered species descriptions, keys and audits from phenomic matrices
5
5
  Project-URL: Homepage, https://github.com/alexrvandam/Descriptron
6
6
  Project-URL: Repository, https://github.com/alexrvandam/Descriptron
@@ -9,6 +9,7 @@ Author: Alex R. Van Dam
9
9
  License: Apache-2.0
10
10
  License-File: LICENSE
11
11
  License-File: NOTICE
12
+ License-File: NOTICE.bak_pre_212_20260929_1100
12
13
  Keywords: COCO,morphometrics,phenomics,species description,taxonomy
13
14
  Classifier: Intended Audience :: Science/Research
14
15
  Classifier: License :: OSI Approved :: Apache Software License
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "descriptron-core"
7
- version = "2.1.1"
7
+ version = "2.1.2"
8
8
  description = "Evidence-tiered species descriptions, keys and audits from phenomic matrices"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env python3
2
+ """Centre-line length on shapes of known length (straight bar, arcs of increasing bend, an S-curve), at several
3
+ widths, against the straight measurement a length-along-the-main-axis would give. Writes a CSV and prints a summary;
4
+ the numbers quoted in the paper and README come from this script.
5
+
6
+ python validate_centerline_lengths.py --out_csv centerline_validation.csv
7
+ """
8
+ import argparse
9
+ import csv
10
+ import sys
11
+ from pathlib import Path
12
+
13
+ import cv2
14
+ import numpy as np
15
+
16
+ sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
17
+ import descriptron_centerline as dc # noqa: E402
18
+
19
+
20
+ def mask(pts, width, size=1000):
21
+ m = np.zeros((size, size), np.uint8)
22
+ cv2.polylines(m, [np.round(pts).astype(np.int32)], False, 1, width)
23
+ return m.astype(bool)
24
+
25
+
26
+ def arclen(p):
27
+ return float(np.hypot(*np.diff(p, axis=0).T).sum())
28
+
29
+
30
+ def axis_extent(m):
31
+ ys, xs = np.nonzero(m)
32
+ P = np.stack([xs, ys], 1).astype(float); P -= P.mean(0)
33
+ pr = P @ np.linalg.svd(P, full_matrices=False)[2][0]
34
+ return float(pr.max() - pr.min())
35
+
36
+
37
+ T = np.linspace(0, 1, 4000)
38
+ SHAPES = {"straight": np.stack([200 + 346.4 * T, 300 + 200 * T], 1)}
39
+ for deg in (60, 90, 120):
40
+ a = np.radians(-90 - deg / 2 + deg * T)
41
+ SHAPES[f"arc_{deg}deg"] = np.stack([500 + 300 * np.cos(a), 700 + 300 * np.sin(a)], 1)
42
+ SHAPES["s_curve"] = np.stack([150 + 700 * T, 500 + 120 * np.sin(2 * np.pi * T)], 1)
43
+
44
+
45
+ def main():
46
+ ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
47
+ ap.add_argument("--out_csv", required=True)
48
+ a = ap.parse_args()
49
+ rows = []
50
+ for name, pts in SHAPES.items():
51
+ for w in (6, 10, 20, 30):
52
+ m = mask(pts, w)
53
+ true = arclen(pts) + w # round caps add w/2 at each end
54
+ r = dc.centerline(m)
55
+ rows.append(dict(shape=name, width_px=w, true_length_px=round(true, 1),
56
+ centerline_px=round(r["length_px"], 1),
57
+ centerline_err_pct=round(100 * (r["length_px"] - true) / true, 2),
58
+ straight_axis_px=round(axis_extent(m), 1),
59
+ straight_err_pct=round(100 * (axis_extent(m) - true) / true, 2)))
60
+ with open(a.out_csv, "w", newline="") as fh:
61
+ wr = csv.DictWriter(fh, fieldnames=list(rows[0])); wr.writeheader(); wr.writerows(rows)
62
+ ce = np.abs([r["centerline_err_pct"] for r in rows])
63
+ print(f"centre line: |error| median {np.median(ce):.2f}%, max {ce.max():.2f}% over {len(rows)} shape x width cases")
64
+ for name in SHAPES:
65
+ s = [r["straight_err_pct"] for r in rows if r["shape"] == name]
66
+ c = [r["centerline_err_pct"] for r in rows if r["shape"] == name]
67
+ print(f" {name:12s} straight axis {min(s):+.1f} to {max(s):+.1f}% centre line {min(c):+.2f} to {max(c):+.2f}%")
68
+
69
+
70
+ if __name__ == "__main__":
71
+ main()
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env python3
2
+ """Checks of Descriptron's texture features (texture_phenomics_homology.py).
3
+
4
+ 1. Masked GLCM against scikit-image: pixels outside the mask get an extra 'outside' grey level, scikit-image builds
5
+ the symmetric GLCM, and that level's row and column are dropped; what remains is exactly the 'both pixels in the
6
+ mask' matrix Descriptron computes. (scikit-image names the two diagonals the other way round; Descriptron averages
7
+ the four directions, so its features are unaffected.)
8
+ 2. Grey-level invariance: the same image quantised to 8 and 32 levels; ratio of the feature values (1 = invariant),
9
+ for Descriptron's invariant Haralick formulas and the standard ones.
10
+
11
+ python validate_texture_glcm.py --image_glob "<dir>/*.png" --texture_script <texture_phenomics_homology.py> --out_csv out.csv
12
+ """
13
+ import argparse
14
+ import csv
15
+ import glob
16
+ import importlib.util
17
+
18
+ import cv2
19
+ import numpy as np
20
+ from skimage.feature import graycomatrix
21
+
22
+ ANGLES = (0, np.pi / 4, np.pi / 2, 3 * np.pi / 4)
23
+
24
+
25
+ def main():
26
+ ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
27
+ ap.add_argument("--image_glob", required=True); ap.add_argument("--texture_script", required=True)
28
+ ap.add_argument("--n_images", type=int, default=15); ap.add_argument("--out_csv", required=True)
29
+ a = ap.parse_args()
30
+ spec = importlib.util.spec_from_file_location("tx", a.texture_script)
31
+ tx = importlib.util.module_from_spec(spec); spec.loader.exec_module(tx)
32
+ imgs = sorted(glob.glob(a.image_glob))[: a.n_images]
33
+ rows = []
34
+ worst, n = 0.0, 0
35
+ for f in imgs:
36
+ g = cv2.imread(f, 0); q = (g // 16).astype(np.uint8)
37
+ h, w = q.shape; yy, xx = np.mgrid[:h, :w]
38
+ for s in range(3):
39
+ cy, cx, ry, rx = h * (0.3 + 0.2 * s), w * (0.3 + 0.2 * s), h * 0.25, w * 0.2
40
+ m = ((yy - cy) / ry) ** 2 + ((xx - cx) / rx) ** 2 < 1
41
+ for ang in ANGLES:
42
+ ours = tx._masked_glcm_single(q, m, 3, ang, levels=16)
43
+ sk = {np.pi / 4: 3 * np.pi / 4, 3 * np.pi / 4: np.pi / 4}.get(ang, ang)
44
+ R = graycomatrix(np.where(m, q, 16).astype(np.uint8), [3], [sk], levels=17,
45
+ symmetric=True, normed=False)[:16, :16, 0, 0].astype(float)
46
+ R /= R.sum()
47
+ worst = max(worst, float(np.abs(ours - R).max())); n += 1
48
+ full = np.ones(g.shape, bool); gf = g.astype(float); vals = {}
49
+ for L in (8, 32):
50
+ ql = np.clip((gf - gf.min()) / (gf.max() - gf.min()) * (L - 1), 0, L - 1).astype(np.uint8)
51
+ G = np.mean([tx._masked_glcm_single(ql, full, 3, an, levels=L) for an in ANGLES], axis=0)
52
+ I, J = np.meshgrid(np.arange(L), np.arange(L), indexing="ij")
53
+ vals[L] = (tx._haralick_invariant(G, levels=L),
54
+ [float((G * (I - J) ** 2).sum()), float((G / (1 + (I - J) ** 2)).sum()), float((G ** 2).sum())])
55
+ for k, name in enumerate(("contrast", "homogeneity", "energy")):
56
+ rows.append(dict(image=f, feature=name, invariant_ratio_32_vs_8=vals[32][0][k] / vals[8][0][k],
57
+ standard_ratio_32_vs_8=vals[32][1][k] / vals[8][1][k]))
58
+ with open(a.out_csv, "w", newline="") as fh:
59
+ wr = csv.DictWriter(fh, fieldnames=list(rows[0])); wr.writeheader(); wr.writerows(rows)
60
+ print(f"masked GLCM vs scikit-image: max |difference| {worst:.2e} over {n} matrices")
61
+ for name in ("contrast", "homogeneity", "energy"):
62
+ r = [x for x in rows if x["feature"] == name]
63
+ print(f"{name:12s} ratio 32/8 levels, median: invariant {np.median([x['invariant_ratio_32_vs_8'] for x in r]):.2f}"
64
+ f" standard {np.median([x['standard_ratio_32_vs_8'] for x in r]):.2f}")
65
+
66
+
67
+ if __name__ == "__main__":
68
+ main()