s3dgraphy 1.6.0.dev7__tar.gz → 1.6.0.dev8__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 (168) hide show
  1. {s3dgraphy-1.6.0.dev7/src/s3dgraphy.egg-info → s3dgraphy-1.6.0.dev8}/PKG-INFO +37 -20
  2. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/README.md +36 -19
  3. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/pyproject.toml +1 -1
  4. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/__init__.py +1 -1
  5. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/edges/edge.py +6 -0
  6. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/graphml_patcher.py +7 -4
  7. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/importer/import_graphml.py +7 -6
  8. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/hdt_node.py +7 -5
  9. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/graph_projector.py +14 -2
  10. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/graphml_writer.py +2 -1
  11. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/group_projector.py +5 -5
  12. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/paradata_store.py +4 -3
  13. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/rapporti.py +92 -5
  14. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/yed_import_pipeline.py +2 -2
  15. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/yed_rapporti_policy.py +2 -1
  16. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/yed_table_parser.py +6 -5
  17. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8/src/s3dgraphy.egg-info}/PKG-INFO +37 -20
  18. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/LICENSE +0 -0
  19. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/MANIFEST.in +0 -0
  20. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/setup.cfg +0 -0
  21. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/em.ttl +0 -0
  22. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/em_document_types.json +0 -0
  23. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/em_extractor_types.json +0 -0
  24. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/em_palette_icons.json +0 -0
  25. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/em_qualia_types.json +0 -0
  26. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/em_qualia_types_additions.json +0 -0
  27. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/em_visual_rules.json +0 -0
  28. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/hdto_extension.ttl +0 -0
  29. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/new_qualia_template.json +0 -0
  30. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/outdated_s3dgraphy.ttl +0 -0
  31. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/outdated_s3dgraphy_nomapping.ttl +0 -0
  32. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json +0 -0
  33. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json.v155.bak +0 -0
  34. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/s3Dgraphy_node_datamodel.json +0 -0
  35. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/RSF.png +0 -0
  36. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/RSF.svg +0 -0
  37. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/SF.png +0 -0
  38. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/TSU.png +0 -0
  39. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/US.png +0 -0
  40. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/USD.png +0 -0
  41. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/USVn.png +0 -0
  42. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/USVs.png +0 -0
  43. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/VSF.png +0 -0
  44. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/combiner.png +0 -0
  45. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/continuity.png +0 -0
  46. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/document.png +0 -0
  47. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/extractor.png +0 -0
  48. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/property.png +0 -0
  49. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/serSU.png +0 -0
  50. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/serUSD.png +0 -0
  51. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/2D/serUSV.png +0 -0
  52. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/RSF.glb +0 -0
  53. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/SF.glb +0 -0
  54. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/TSU.glb +0 -0
  55. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/US.glb +0 -0
  56. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/USD.glb +0 -0
  57. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/USVn.glb +0 -0
  58. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/USVs.glb +0 -0
  59. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/VSF.glb +0 -0
  60. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/combiner.glb +0 -0
  61. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/continuity.glb +0 -0
  62. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/document.glb +0 -0
  63. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/extractor.glb +0 -0
  64. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/property.glb +0 -0
  65. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/serSU.glb +0 -0
  66. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/serUSD.glb +0 -0
  67. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/JSON_config/src/3D/serUSV.glb +0 -0
  68. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/classification.py +0 -0
  69. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/data/StratiMiner_Extraction_Prompt.md +0 -0
  70. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/diagnostics.py +0 -0
  71. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/edges/__init__.py +0 -0
  72. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/edges/connections_loader.py +0 -0
  73. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/__init__.py +0 -0
  74. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/__init__.py +0 -0
  75. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/canvas_generator.py +0 -0
  76. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/edge_generator.py +0 -0
  77. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/epoch_generator.py +0 -0
  78. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/graphml_exporter.py +0 -0
  79. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/group_node_generator.py +0 -0
  80. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/node_generator.py +0 -0
  81. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/node_registry.py +0 -0
  82. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/palette_resources.py +0 -0
  83. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/paradata_generator.py +0 -0
  84. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/paradata_image_generator.py +0 -0
  85. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/paradata_node_generators.py +0 -0
  86. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/table_node_generator.py +0 -0
  87. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/graphml/utils.py +0 -0
  88. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/json_exporter.py +0 -0
  89. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/rdf_exporter.py +0 -0
  90. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/exporter/unified_xlsx_exporter.py +0 -0
  91. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/graph.py +0 -0
  92. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/importer/__init__.py +0 -0
  93. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/importer/base_importer.py +0 -0
  94. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/importer/mapped_xlsx_importer.py +0 -0
  95. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/importer/pyarchinit_importer.py +0 -0
  96. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/importer/qualia_importer.py +0 -0
  97. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/importer/unified_xlsx_importer.py +0 -0
  98. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/importer/xlsx_importer.py +0 -0
  99. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/indices.py +0 -0
  100. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/mappings/__init__.py +0 -0
  101. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/mappings/emdb/generic_specialfind_mapping.json +0 -0
  102. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/mappings/emdb/site_properties_mapping.json +0 -0
  103. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/mappings/emdb/usm_mapping.json +0 -0
  104. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/mappings/generic/excel_to_graphml_mapping.json +0 -0
  105. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/mappings/pyarchinit/pyarchinit_us_mapping.json +0 -0
  106. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/mappings/registry.py +0 -0
  107. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/mappings/template_emdb_mapping.json +0 -0
  108. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/mappings/template_pyarchinit_mapping.json +0 -0
  109. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/merge/__init__.py +0 -0
  110. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/merge/graph_merger.py +0 -0
  111. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/multigraph/__init__.py +0 -0
  112. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/multigraph/multigraph.py +0 -0
  113. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/__init__.py +0 -0
  114. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/author_node.py +0 -0
  115. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/base_node.py +0 -0
  116. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/combiner_node.py +0 -0
  117. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/document_node.py +0 -0
  118. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/embargo_node.py +0 -0
  119. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/epoch_node.py +0 -0
  120. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/extractor_node.py +0 -0
  121. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/geo_position_node.py +0 -0
  122. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/graph_node.py +0 -0
  123. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/group_node.py +0 -0
  124. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/license_node.py +0 -0
  125. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/link_node.py +0 -0
  126. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/paradata_node.py +0 -0
  127. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/property_node.py +0 -0
  128. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/representation_node.py +0 -0
  129. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/semantic_shape_node.py +0 -0
  130. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/nodes/stratigraphic_node.py +0 -0
  131. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/resolvers/__init__.py +0 -0
  132. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/resolvers/builtin_rules.py +0 -0
  133. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/resolvers/property_resolver.py +0 -0
  134. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/__init__.py +0 -0
  135. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/_db_handle.py +0 -0
  136. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/_legacy_paradata_svgs.py +0 -0
  137. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/_workspace.py +0 -0
  138. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/conflict_resolver.py +0 -0
  139. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/edge_registry.py +0 -0
  140. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/graph_ingestor.py +0 -0
  141. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/group_store.py +0 -0
  142. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/ingest_result.py +0 -0
  143. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/pyarchinit_pg_importer.py +0 -0
  144. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/uuid7.py +0 -0
  145. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/vocab_provider_core.py +0 -0
  146. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/vocab_types.py +0 -0
  147. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/yed_classifier.py +0 -0
  148. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/yed_detector.py +0 -0
  149. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/sync/yed_group_walker.py +0 -0
  150. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/templates/em_data_template.xlsx +0 -0
  151. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/templates/em_palette_template.graphml +0 -0
  152. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/temporal/__init__.py +0 -0
  153. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/temporal/inference_engine.py +0 -0
  154. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/transforms/__init__.py +0 -0
  155. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/transforms/aux_tracking.py +0 -0
  156. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/transforms/compact.py +0 -0
  157. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/transforms/materialize_continuity.py +0 -0
  158. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/utils/__init__.py +0 -0
  159. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/utils/utils.py +0 -0
  160. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy/utils/visual_layout.py +0 -0
  161. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy.egg-info/SOURCES.txt +0 -0
  162. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy.egg-info/dependency_links.txt +0 -0
  163. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy.egg-info/requires.txt +0 -0
  164. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/src/s3dgraphy.egg-info/top_level.txt +0 -0
  165. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/tests/test_composite_node_name.py +0 -0
  166. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/tests/test_filtered_import.py +0 -0
  167. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/tests/test_lossless_roundtrip.py +0 -0
  168. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev8}/tests/test_pg_importer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: s3dgraphy
3
- Version: 1.6.0.dev7
3
+ Version: 1.6.0.dev8
4
4
  Summary: 3D Stratigraphic Graph Management Library for archaeological and heritage applications
5
5
  Author-email: Emanuel Demetrescu <emanuel.demetrescu@cnr.it>
6
6
  Maintainer-email: Emanuel Demetrescu <emanuel.demetrescu@cnr.it>
@@ -97,30 +97,47 @@ pip install s3dgraphy[full] # All optional dependencies
97
97
  ## 🔧 Quick Start
98
98
 
99
99
  ```python
100
- import s3dgraphy
100
+ from s3dgraphy import Graph
101
+ from s3dgraphy.nodes import StratigraphicUnit, DocumentNode
101
102
 
102
- # Create a new stratigraphic graph
103
- graph = s3dgraphy.Graph()
103
+ # Create a new stratigraphic graph (graph_id is required)
104
+ graph = Graph("my_excavation")
104
105
 
105
- # Add stratigraphic units
106
- us1 = graph.add_node("US001", node_type="US",
107
- properties={"period": "Roman", "material": "pottery"})
108
- us2 = graph.add_node("US002", node_type="US",
109
- properties={"period": "Medieval", "material": "stone"})
106
+ # Build node objects, then add them with add_node()
107
+ wall = StratigraphicUnit("US001", name="US001", description="Stone wall foundation")
108
+ floor = StratigraphicUnit("US002", name="US002", description="Mosaic floor")
109
+ graph.add_node(wall)
110
+ graph.add_node(floor)
110
111
 
111
- # Add stratigraphic relationships
112
- graph.add_edge(us1, us2, edge_type="ABOVE",
113
- properties={"certainty": "high"})
112
+ # Add a stratigraphic relationship.
113
+ # Canonical direction is recent -> ancient: the floor (US002) is more
114
+ # recent than the wall (US001), so US002 is_after US001.
115
+ graph.add_edge("e1", "US002", "US001", "is_after")
116
+
117
+ # Attach documentation
118
+ doc = DocumentNode("DOC001", name="DOC001", description="Field photo")
119
+ graph.add_node(doc)
120
+ graph.add_edge("e2", "US001", "DOC001", "has_documentation")
114
121
 
115
122
  # Query the graph
116
- print(f"Graph contains {len(graph.nodes)} stratigraphic units")
117
- print(f"Relationships: {len(graph.edges)}")
123
+ print(f"Graph contains {len(graph.nodes)} nodes and {len(graph.edges)} edges")
124
+ us_units = graph.get_nodes_by_type("US")
118
125
 
119
- # Export to different formats
120
- graph.export_graphml("stratigraphy.graphml")
121
- graph.export_json("stratigraphy.json")
126
+ # Export to GraphML (yEd round-trip) — the exporter takes the graph directly
127
+ from s3dgraphy.exporter.graphml import GraphMLExporter
128
+ GraphMLExporter(graph).export("my_excavation.graphml")
122
129
  ```
123
130
 
131
+ > **Note on the API.** Nodes are *objects* (`StratigraphicUnit`,
132
+ > `DocumentNode`, …) created first and then added with `graph.add_node()`.
133
+ > Edges are created with `graph.add_edge(edge_id, source_id, target_id,
134
+ > edge_type)` using a **canonical** edge type from the connections
135
+ > datamodel (e.g. `is_after`, `has_property`, `has_documentation`). Invalid
136
+ > connections are downgraded to `generic_connection` with a warning rather
137
+ > than silently accepted. See the
138
+ > [API reference](https://docs.extendedmatrix.org/projects/s3dgraphy/) for
139
+ > the full node and edge catalogs.
140
+
124
141
  ## 📚 Core Features
125
142
 
126
143
  ### 🏛️ Archaeological Stratigraphic Modeling
@@ -328,12 +345,12 @@ The GPL-3.0 license ensures that s3dgraphy remains free and open source, promoti
328
345
  If you use s3dgraphy in your research, please cite:
329
346
 
330
347
  ```bibtex
331
- @software{s3dgraphy2024,
348
+ @software{s3dgraphy,
332
349
  title={s3dgraphy: 3D Stratigraphic Graph Management Library},
333
350
  author={Demetrescu, Emanuel},
334
- year={2024},
351
+ year={2026},
335
352
  url={https://github.com/zalmoxes-laran/s3dgraphy},
336
- version={0.1.1},
353
+ version={1.6.0},
337
354
  institution={CNR-ISPC (National Research Council - Institute of Heritage Science)}
338
355
  }
339
356
  ```
@@ -29,30 +29,47 @@ pip install s3dgraphy[full] # All optional dependencies
29
29
  ## 🔧 Quick Start
30
30
 
31
31
  ```python
32
- import s3dgraphy
32
+ from s3dgraphy import Graph
33
+ from s3dgraphy.nodes import StratigraphicUnit, DocumentNode
33
34
 
34
- # Create a new stratigraphic graph
35
- graph = s3dgraphy.Graph()
35
+ # Create a new stratigraphic graph (graph_id is required)
36
+ graph = Graph("my_excavation")
36
37
 
37
- # Add stratigraphic units
38
- us1 = graph.add_node("US001", node_type="US",
39
- properties={"period": "Roman", "material": "pottery"})
40
- us2 = graph.add_node("US002", node_type="US",
41
- properties={"period": "Medieval", "material": "stone"})
38
+ # Build node objects, then add them with add_node()
39
+ wall = StratigraphicUnit("US001", name="US001", description="Stone wall foundation")
40
+ floor = StratigraphicUnit("US002", name="US002", description="Mosaic floor")
41
+ graph.add_node(wall)
42
+ graph.add_node(floor)
42
43
 
43
- # Add stratigraphic relationships
44
- graph.add_edge(us1, us2, edge_type="ABOVE",
45
- properties={"certainty": "high"})
44
+ # Add a stratigraphic relationship.
45
+ # Canonical direction is recent -> ancient: the floor (US002) is more
46
+ # recent than the wall (US001), so US002 is_after US001.
47
+ graph.add_edge("e1", "US002", "US001", "is_after")
48
+
49
+ # Attach documentation
50
+ doc = DocumentNode("DOC001", name="DOC001", description="Field photo")
51
+ graph.add_node(doc)
52
+ graph.add_edge("e2", "US001", "DOC001", "has_documentation")
46
53
 
47
54
  # Query the graph
48
- print(f"Graph contains {len(graph.nodes)} stratigraphic units")
49
- print(f"Relationships: {len(graph.edges)}")
55
+ print(f"Graph contains {len(graph.nodes)} nodes and {len(graph.edges)} edges")
56
+ us_units = graph.get_nodes_by_type("US")
50
57
 
51
- # Export to different formats
52
- graph.export_graphml("stratigraphy.graphml")
53
- graph.export_json("stratigraphy.json")
58
+ # Export to GraphML (yEd round-trip) — the exporter takes the graph directly
59
+ from s3dgraphy.exporter.graphml import GraphMLExporter
60
+ GraphMLExporter(graph).export("my_excavation.graphml")
54
61
  ```
55
62
 
63
+ > **Note on the API.** Nodes are *objects* (`StratigraphicUnit`,
64
+ > `DocumentNode`, …) created first and then added with `graph.add_node()`.
65
+ > Edges are created with `graph.add_edge(edge_id, source_id, target_id,
66
+ > edge_type)` using a **canonical** edge type from the connections
67
+ > datamodel (e.g. `is_after`, `has_property`, `has_documentation`). Invalid
68
+ > connections are downgraded to `generic_connection` with a warning rather
69
+ > than silently accepted. See the
70
+ > [API reference](https://docs.extendedmatrix.org/projects/s3dgraphy/) for
71
+ > the full node and edge catalogs.
72
+
56
73
  ## 📚 Core Features
57
74
 
58
75
  ### 🏛️ Archaeological Stratigraphic Modeling
@@ -260,12 +277,12 @@ The GPL-3.0 license ensures that s3dgraphy remains free and open source, promoti
260
277
  If you use s3dgraphy in your research, please cite:
261
278
 
262
279
  ```bibtex
263
- @software{s3dgraphy2024,
280
+ @software{s3dgraphy,
264
281
  title={s3dgraphy: 3D Stratigraphic Graph Management Library},
265
282
  author={Demetrescu, Emanuel},
266
- year={2024},
283
+ year={2026},
267
284
  url={https://github.com/zalmoxes-laran/s3dgraphy},
268
- version={0.1.1},
285
+ version={1.6.0},
269
286
  institution={CNR-ISPC (National Research Council - Institute of Heritage Science)}
270
287
  }
271
288
  ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "s3dgraphy"
7
- version = "1.6.0.dev7"
7
+ version = "1.6.0.dev8"
8
8
  description = "3D Stratigraphic Graph Management Library for archaeological and heritage applications"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,4 +1,4 @@
1
- __version__ = "1.6.0.dev7"
1
+ __version__ = "1.6.0.dev8"
2
2
  __datamodel_version__ = "1.5.5" # s3Dgraphy connections datamodel version
3
3
 
4
4
  # s3Dgraphy/__init__.py
@@ -17,6 +17,12 @@ def _build_legacy_edge_types():
17
17
  return edge_types
18
18
 
19
19
  EDGE_TYPES = _build_legacy_edge_types()
20
+ """Legacy mapping ``edge_type -> {"label", "description"}``.
21
+
22
+ Rebuilt from the connections datamodel for backward compatibility; new
23
+ code should query :func:`s3dgraphy.edges.connections_loader.get_connections_datamodel`
24
+ instead. ``Edge`` validates ``edge_type`` against the keys of this dict.
25
+ """
20
26
 
21
27
  class Edge:
22
28
  """
@@ -3,10 +3,11 @@ GraphML Patcher for s3dgraphy.
3
3
 
4
4
  Patches an existing GraphML file on disk with changes from an in-memory Graph.
5
5
  Supports:
6
- - Updating existing nodes (description, name, EMID, URI)
7
- - Adding new nodes that were created in-memory
8
- - Adding new edges
9
- - EMID validation and duplicate detection
6
+
7
+ - Updating existing nodes (description, name, EMID, URI)
8
+ - Adding new nodes that were created in-memory
9
+ - Adding new edges
10
+ - EMID validation and duplicate detection
10
11
 
11
12
  This is the "twin" of the importer: it uses the same dynamic key mapping
12
13
  and the same conventions to write back what the importer can read.
@@ -1429,11 +1430,13 @@ class GraphMLPatcher:
1429
1430
  Add new edges to the GraphML XML.
1430
1431
 
1431
1432
  For each edge in the graph that does NOT have an original_edge_id:
1433
+
1432
1434
  - Generates a new edge ID
1433
1435
  - Creates <edge> XML with correct line style for the edge type
1434
1436
  - Resolves source/target using original_id or generated ID
1435
1437
 
1436
1438
  Skips:
1439
+
1437
1440
  - Edges with original_edge_id (already in the XML)
1438
1441
  - Structural edges (represented by XML nesting, not <edge> elements)
1439
1442
  - Derived has_property edges where the target PropertyNode is inside
@@ -2616,12 +2616,13 @@ class GraphMLImporter:
2616
2616
  """
2617
2617
  Verifica se un nodo è un nodo di continuità (BR).
2618
2618
  Usa una detection multi-segnale:
2619
- A) '_continuity' nel campo URL o description
2620
- B) ShapeNode con shape type 'diamond'
2621
- C) SVGNode il cui SVGContent refid punta alla risorsa
2622
- ``continuity.svg`` (refid risolto dinamicamente, vedi
2623
- build_svg_resource_map — yEd numera le Resource per ordine
2624
- di serializzazione, non c'è un id fisso)
2619
+
2620
+ A) '_continuity' nel campo URL o description
2621
+ B) ShapeNode con shape type 'diamond'
2622
+ C) SVGNode il cui SVGContent refid punta alla risorsa
2623
+ ``continuity.svg`` (refid risolto dinamicamente, vedi
2624
+ build_svg_resource_map — yEd numera le Resource per ordine
2625
+ di serializzazione, non c'è un id fisso)
2625
2626
 
2626
2627
  Args:
2627
2628
  node_element: Elemento XML del nodo
@@ -9,12 +9,14 @@ formal propositions) about a heritage entity (HC1). HDTs are hierarchically
9
9
  composable — a city HDT contains district HDTs which contain monument HDTs.
10
10
 
11
11
  Granularity connectors (declared in s3Dgraphy_connections_datamodel.json):
12
- * has_digital_twin — Node → HDTNode (HP1)
13
- * has_digital_twin_component — HDTNode → HDTNode (HP3 inverse, transitive)
14
- * contains_proposition_set — HDTNode → GraphNode (HP33)
15
- * has_digital_object_part — HDTNode → RepresentationModel* / LinkNode (HP29)
16
12
 
17
- Use case (the Colosseo example):
13
+ * has_digital_twin — Node → HDTNode (HP1)
14
+ * has_digital_twin_component — HDTNode → HDTNode (HP3 inverse, transitive)
15
+ * contains_proposition_set — HDTNode → GraphNode (HP33)
16
+ * has_digital_object_part — HDTNode → RepresentationModel* / LinkNode (HP29)
17
+
18
+ Use case (the Colosseo example)::
19
+
18
20
  colosseo_overall = HDTNode("hdt_colosseo_overall", name="Colosseo HDT")
19
21
  colosseo_flavian = HDTNode("hdt_colosseo_flavian", name="Colosseo Flavian phase")
20
22
  colosseo_medieval = HDTNode("hdt_colosseo_medieval", name="Colosseo medieval fortress")
@@ -578,6 +578,11 @@ class GraphProjector:
578
578
  except Exception:
579
579
  period_datazione = {}
580
580
 
581
+ # Localized US/USM → canonical alias map (the single source in
582
+ # sync.rapporti) so non-Italian unita_tipo codes are recognised as
583
+ # stratigraphic units in the gating + node-class factory below.
584
+ from .rapporti import canonical_unita_tipo
585
+
581
586
  for (us_val, node_uuid, sito_v, area, unita_tipo,
582
587
  periodo_ini, fase_ini, rapporti_raw, d_strat,
583
588
  d_interp, attivita, struttura,
@@ -586,6 +591,13 @@ class GraphProjector:
586
591
  if not us_name:
587
592
  continue
588
593
  ut_str = str(unita_tipo) if unita_tipo is not None else ""
594
+ # Canonical US/USM code for the structural decisions below
595
+ # (stratigraphic gating + node-class factory), so localized
596
+ # codes (SU/WSU/SE/…) are recognised as real stratigraphic
597
+ # units. attributes['unita_tipo'] keeps the ORIGINAL code
598
+ # (set further down) for round-trip + the language-aware
599
+ # rapporti dispatch.
600
+ ut_canon = canonical_unita_tipo(ut_str)
589
601
  node = None
590
602
  # Direct hit by composite key (paradata that the bridge
591
603
  # correctly classified OR a stratigraphic node already
@@ -602,14 +614,14 @@ class GraphProjector:
602
614
  # order (e.g. yEd document order interleaves US01 and
603
615
  # DOC.01 — DOC.01 might claim the bridge's '01' placeholder
604
616
  # before US01 row is iterated).
605
- if node is None and ut_str in (
617
+ if node is None and ut_canon in (
606
618
  "US", "USM", "USD", "USV", "USVs", "USVn", "USVc",
607
619
  "SF", "VSF", "RSF",
608
620
  ):
609
621
  node = nodes_by_key.pop((us_name, "__STRAT__"), None)
610
622
  if node is None:
611
623
  node = _create_stratigraphic_node_for_unita_tipo(
612
- ut_str, us_name, node_uuid or us_name,
624
+ ut_canon, us_name, node_uuid or us_name,
613
625
  )
614
626
  if node is not None:
615
627
  try:
@@ -1,7 +1,8 @@
1
1
  """Pure-Python wrapper over s3dgraphy.PyArchInitImporter +
2
2
  s3dgraphy.exporter.graphml.GraphMLExporter.
3
3
 
4
- Public API:
4
+ Public API::
5
+
5
6
  export_graphml(db_path, mapping, output_path,
6
7
  *, site_filter=None, persist_auxiliary=False) -> ExportResult
7
8
 
@@ -1,10 +1,10 @@
1
1
  """Pure-functional helpers for AI06 node grouping.
2
2
 
3
- build_groups_from_sql: scan us_table for the requested grouping
4
- dimensions, emit one GroupSpec per (dim, value) pair.
5
- merge_adhoc_groups: append GroupSpec instances from a GroupStore.
6
- dimensions_with_data: return the subset of 7 grouping columns
7
- that have at least one non-empty value in us_table for sito.
3
+ - ``build_groups_from_sql``: scan us_table for the requested grouping
4
+ dimensions, emit one GroupSpec per (dim, value) pair.
5
+ - ``merge_adhoc_groups``: append GroupSpec instances from a GroupStore.
6
+ - ``dimensions_with_data``: return the subset of 7 grouping columns
7
+ that have at least one non-empty value in us_table for sito.
8
8
 
9
9
  UUID generation: deterministic UUID5 from (sito, group_kind, name)
10
10
  so re-export with the same SQL state produces identical UUIDs
@@ -2,9 +2,10 @@
2
2
 
3
3
  AI05 Phase 2 closure. Manages the 3 node types without an SQL
4
4
  counterpart in pyarchinit:
5
- - AuthorNode (authorship metadata)
6
- - LicenseNode (rights / SPDX licence)
7
- - EmbargoNode (embargo dates)
5
+
6
+ - AuthorNode (authorship metadata)
7
+ - LicenseNode (rights / SPDX licence)
8
+ - EmbargoNode (embargo dates)
8
9
 
9
10
  File location: {db_path.parent}/paradata_{sito_slug}.graphml
10
11
  where sito_slug is `re.sub(r'\\W+', '_', sito).lower()`.
@@ -186,9 +186,41 @@ EDGE_TYPE_DIRECTION_FORWARD: dict[str, bool] = {
186
186
  # ---------------------------------------------------------------------------
187
187
  # Unit-type frozensets driving the verbose-vs-shorthand dispatch
188
188
  # ---------------------------------------------------------------------------
189
- #: Unit types where both endpoints get the verbose Italian dispatch
190
- #: ("Copre", "Coperto da", ...). Stratigraphic Harris atoms only.
191
- CANONICAL_UNIT_TYPES: frozenset[str] = frozenset({"US", "USM"})
189
+ #: Localized US / USM ``unita_tipo`` code → canonical code. pyArchInit
190
+ #: localizes ONLY the US / USM abbreviations per UI language (its
191
+ #: ``pyarchinit_i18n_stratigraphic.UNIT_TYPE_ABBREV`` is the source of
192
+ #: truth). This module is the pyArchInit↔canonical bridge, and the
193
+ #: prefix-strip regex above already enumerates SU|SE|WSU|MSE|UE|…, so the
194
+ #: gating set lives here too. The mapping doubles as the normalization
195
+ #: source: any code path that needs the canonical form calls
196
+ #: :func:`canonical_unita_tipo`. ``attributes['unita_tipo']`` is kept
197
+ #: VERBATIM (original code) elsewhere so round-trip stays byte-identical;
198
+ #: only the verbose/shorthand dispatch and the projector's stratigraphic
199
+ #: gating read through this alias map.
200
+ #:
201
+ #: US → US (it/fr/ro) · SU (en/ar) · SE (de) · UE (es/ca/pt) · ΣΜ (el)
202
+ #: USM → USM (it/fr) · WSU (en/ar) · MSE (de) · UEM (es/ca/pt) ·
203
+ #: USZ (ro) · ΤΣΜ (el)
204
+ UNITA_TIPO_CANONICAL: dict[str, str] = {
205
+ "US": "US", "SU": "US", "SE": "US", "UE": "US", "ΣΜ": "US",
206
+ "USM": "USM", "WSU": "USM", "MSE": "USM", "UEM": "USM",
207
+ "USZ": "USM", "ΤΣΜ": "USM",
208
+ }
209
+
210
+
211
+ def canonical_unita_tipo(unita_tipo) -> str:
212
+ """Map a (possibly localized) US/USM code to its canonical form.
213
+
214
+ Non-US/USM codes (USV*, SF, CON, DOC, …) and unknown values pass
215
+ through unchanged.
216
+ """
217
+ return UNITA_TIPO_CANONICAL.get(unita_tipo, unita_tipo)
218
+
219
+
220
+ #: Unit types where both endpoints get the verbose dispatch ("Copre"/
221
+ #: "Covers"/…, "Coperto da"/"Covered by"/…). All language variants of the
222
+ #: Harris US/USM atoms, derived from the alias map so the two never drift.
223
+ CANONICAL_UNIT_TYPES: frozenset[str] = frozenset(UNITA_TIPO_CANONICAL)
192
224
 
193
225
 
194
226
  #: Continuity unit type. Single-arrow shorthand ``>`` / ``<`` is
@@ -464,6 +496,49 @@ def _coerce_to_list(value):
464
496
  return []
465
497
 
466
498
 
499
+ #: Arrow tokens emitted by :func:`select_rapporti_label` for
500
+ #: non-canonical endpoints. When the dispatch returns one of these we do
501
+ #: NOT override it with a verbose row term (virtual units keep ``>>`` /
502
+ #: ``<<``, continuity keeps ``>`` / ``<``).
503
+ _SHORTHAND_TOKENS: frozenset[str] = frozenset({">", "<", ">>", "<<"})
504
+
505
+
506
+ def _source_rapporti_label(src_node, target_us: str, edge_type: str):
507
+ """Original pyArchInit ``rapporti`` term on *src_node* for *target_us*.
508
+
509
+ The d13 packed string is wire format that should byte-match the
510
+ originating ``us_table.rapporti``, so for a verbose relation we anchor
511
+ the label on the source row's own stored term (in the site's UI
512
+ language — "Covers" / "Couvre" / "Copre" / …) rather than the canonical
513
+ Italian. The label language can't be reconstructed from ``edge_type``
514
+ alone (e.g. "US" is shared by it / fr / ro), so the node's own term is
515
+ the only reliable source.
516
+
517
+ Returned in the canonical display casing (first letter upper, rest
518
+ lower — the form pyArchInit shows). Matching prefers the entry whose
519
+ label maps to the SAME canonical ``edge_type`` (disambiguates multiple
520
+ relations to one target), falling back to any verbose entry pointing at
521
+ ``target_us``. Returns ``None`` when the node carries no usable
522
+ ``rapporti`` attribute (e.g. a yEd-imported graph) — the caller then
523
+ keeps the canonical dispatch label.
524
+ """
525
+ attrs = getattr(src_node, "attributes", None) or {}
526
+ fallback = None
527
+ for entry in _coerce_to_list(attrs.get("rapporti")):
528
+ if not isinstance(entry, (list, tuple)) or len(entry) < 2:
529
+ continue
530
+ lbl = str(entry[0]).strip()
531
+ tgt = str(entry[1]).strip()
532
+ if tgt != str(target_us) or not lbl or lbl in _SHORTHAND_TOKENS:
533
+ continue
534
+ lbl = lbl.capitalize()
535
+ if RAPPORTI_TO_EDGE_TYPE.get(lbl.lower()) == edge_type:
536
+ return lbl
537
+ if fallback is None:
538
+ fallback = lbl
539
+ return fallback
540
+
541
+
467
542
  def serialize_rapporti_from_edges(graph, default_sito: str):
468
543
  """Walk *graph*'s edges and produce per-US rapporti lists ready
469
544
  for the pyarchinit ``us_table.rapporti`` column.
@@ -512,8 +587,6 @@ def serialize_rapporti_from_edges(graph, default_sito: str):
512
587
  continue
513
588
  src_unita_tipo = resolve_unita_tipo_for_dispatch(src_node)
514
589
  tgt_unita_tipo = resolve_unita_tipo_for_dispatch(tgt_node)
515
- rapporti_label = select_rapporti_label(
516
- et, src_unita_tipo, tgt_unita_tipo)
517
590
  tgt_attrs = getattr(tgt_node, "attributes", None) or {}
518
591
  tgt_us = tgt_attrs.get("us")
519
592
  if not tgt_us:
@@ -521,6 +594,18 @@ def serialize_rapporti_from_edges(graph, default_sito: str):
521
594
  if not tgt_name:
522
595
  continue
523
596
  tgt_us = strip_us_prefix(str(tgt_name))
597
+ rapporti_label = select_rapporti_label(
598
+ et, src_unita_tipo, tgt_unita_tipo)
599
+ # For a verbose relation (both endpoints real US/USM, any language)
600
+ # anchor the term on the source row's own rapporti column so the
601
+ # packed string byte-matches the DB in the site's UI language;
602
+ # fall back to the canonical label when the source carries no
603
+ # rapporti attribute (e.g. yEd-imported graphs). Virtual units
604
+ # (``>>`` / ``<<``) and continuity (``>`` / ``<``) keep shorthand.
605
+ if rapporti_label not in _SHORTHAND_TOKENS:
606
+ original = _source_rapporti_label(src_node, str(tgt_us), et)
607
+ if original:
608
+ rapporti_label = original
524
609
  tgt_area = str(tgt_attrs.get("area") or "1")
525
610
  tgt_sito = default_sito
526
611
  rapporto = [rapporti_label, str(tgt_us), tgt_area, tgt_sito]
@@ -536,6 +621,8 @@ __all__ = [
536
621
  "EDGE_TYPE_TO_RAPPORTI_IT",
537
622
  "RAPPORTI_SHORTHAND",
538
623
  "EDGE_TYPE_DIRECTION_FORWARD",
624
+ "UNITA_TIPO_CANONICAL",
625
+ "canonical_unita_tipo",
539
626
  "CANONICAL_UNIT_TYPES",
540
627
  "CONTINUITY_UNIT_TYPES",
541
628
  "NON_RAPPORTI_EDGE_TYPES",
@@ -6,12 +6,12 @@ SQLite and PostgreSQL backends through the `DbHandle` abstraction
6
6
  (Foundation 5.6.2-alpha) — all SQL is expressed as SQLAlchemy
7
7
  ``text()`` statements with named bind parameters.
8
8
 
9
- Public API:
9
+ Public API::
10
10
 
11
11
  import_yed_raw(handle, graphml_path, sito, drafts, *,
12
12
  policy=SKIP, dry_run=False) -> IngestResult
13
13
 
14
- Internal helpers (testable in isolation):
14
+ Internal helpers (testable in isolation)::
15
15
 
16
16
  _classify_destination(classified)
17
17
  _flatten_members(folder, all_folders)
@@ -16,7 +16,7 @@ Self-loop folder edges (source == target) are filtered out of ALL
16
16
  policies before policy application — they arise from nested folder
17
17
  member edges authored in yEd and would otherwise produce noise.
18
18
 
19
- Public API:
19
+ Public API::
20
20
 
21
21
  FolderEdgePolicy (StrEnum: skip / fan_out / representative / synthetic)
22
22
  FolderEdge (dataclass: src, tgt, src_is_folder, tgt_is_folder, edge_type)
@@ -26,6 +26,7 @@ Public API:
26
26
  apply_policy(report, policy, *, all_folders, classified) -> ExpandedRapporti
27
27
 
28
28
  Implementation notes:
29
+
29
30
  * `analyze_edges` parses <edge> elements via lxml (falling back to
30
31
  stdlib `xml.etree.ElementTree`) and classifies each endpoint as a
31
32
  folder or a leaf based on the dataclass lookups passed in.
@@ -3,11 +3,12 @@
3
3
  Reads the top-level <y:TableNode configuration="YED_TABLE_NODE"> of a
4
4
  yEd-raw graphml and extracts archaeological period candidates from
5
5
  its swimlane rows. Each row produces a PeriodCandidate with:
6
- - auto_label from <y:NodeLabel> text
7
- - auto_periodo from 1-based row ordinal
8
- - auto_fase always 1 (yEd table rows don't encode phases)
9
- - member_yed_ids from leaf nodes whose Y-coordinate falls in the
10
- row's Y-range
6
+
7
+ - auto_label from <y:NodeLabel> text
8
+ - auto_periodo from 1-based row ordinal
9
+ - auto_fase always 1 (yEd table rows don't encode phases)
10
+ - member_yed_ids from leaf nodes whose Y-coordinate falls in the
11
+ row's Y-range
11
12
 
12
13
  datazione_iniziale / datazione_finale are NOT extracted (yEd doesn't
13
14
  encode dates on table rows) — user fills them later in the
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: s3dgraphy
3
- Version: 1.6.0.dev7
3
+ Version: 1.6.0.dev8
4
4
  Summary: 3D Stratigraphic Graph Management Library for archaeological and heritage applications
5
5
  Author-email: Emanuel Demetrescu <emanuel.demetrescu@cnr.it>
6
6
  Maintainer-email: Emanuel Demetrescu <emanuel.demetrescu@cnr.it>
@@ -97,30 +97,47 @@ pip install s3dgraphy[full] # All optional dependencies
97
97
  ## 🔧 Quick Start
98
98
 
99
99
  ```python
100
- import s3dgraphy
100
+ from s3dgraphy import Graph
101
+ from s3dgraphy.nodes import StratigraphicUnit, DocumentNode
101
102
 
102
- # Create a new stratigraphic graph
103
- graph = s3dgraphy.Graph()
103
+ # Create a new stratigraphic graph (graph_id is required)
104
+ graph = Graph("my_excavation")
104
105
 
105
- # Add stratigraphic units
106
- us1 = graph.add_node("US001", node_type="US",
107
- properties={"period": "Roman", "material": "pottery"})
108
- us2 = graph.add_node("US002", node_type="US",
109
- properties={"period": "Medieval", "material": "stone"})
106
+ # Build node objects, then add them with add_node()
107
+ wall = StratigraphicUnit("US001", name="US001", description="Stone wall foundation")
108
+ floor = StratigraphicUnit("US002", name="US002", description="Mosaic floor")
109
+ graph.add_node(wall)
110
+ graph.add_node(floor)
110
111
 
111
- # Add stratigraphic relationships
112
- graph.add_edge(us1, us2, edge_type="ABOVE",
113
- properties={"certainty": "high"})
112
+ # Add a stratigraphic relationship.
113
+ # Canonical direction is recent -> ancient: the floor (US002) is more
114
+ # recent than the wall (US001), so US002 is_after US001.
115
+ graph.add_edge("e1", "US002", "US001", "is_after")
116
+
117
+ # Attach documentation
118
+ doc = DocumentNode("DOC001", name="DOC001", description="Field photo")
119
+ graph.add_node(doc)
120
+ graph.add_edge("e2", "US001", "DOC001", "has_documentation")
114
121
 
115
122
  # Query the graph
116
- print(f"Graph contains {len(graph.nodes)} stratigraphic units")
117
- print(f"Relationships: {len(graph.edges)}")
123
+ print(f"Graph contains {len(graph.nodes)} nodes and {len(graph.edges)} edges")
124
+ us_units = graph.get_nodes_by_type("US")
118
125
 
119
- # Export to different formats
120
- graph.export_graphml("stratigraphy.graphml")
121
- graph.export_json("stratigraphy.json")
126
+ # Export to GraphML (yEd round-trip) — the exporter takes the graph directly
127
+ from s3dgraphy.exporter.graphml import GraphMLExporter
128
+ GraphMLExporter(graph).export("my_excavation.graphml")
122
129
  ```
123
130
 
131
+ > **Note on the API.** Nodes are *objects* (`StratigraphicUnit`,
132
+ > `DocumentNode`, …) created first and then added with `graph.add_node()`.
133
+ > Edges are created with `graph.add_edge(edge_id, source_id, target_id,
134
+ > edge_type)` using a **canonical** edge type from the connections
135
+ > datamodel (e.g. `is_after`, `has_property`, `has_documentation`). Invalid
136
+ > connections are downgraded to `generic_connection` with a warning rather
137
+ > than silently accepted. See the
138
+ > [API reference](https://docs.extendedmatrix.org/projects/s3dgraphy/) for
139
+ > the full node and edge catalogs.
140
+
124
141
  ## 📚 Core Features
125
142
 
126
143
  ### 🏛️ Archaeological Stratigraphic Modeling
@@ -328,12 +345,12 @@ The GPL-3.0 license ensures that s3dgraphy remains free and open source, promoti
328
345
  If you use s3dgraphy in your research, please cite:
329
346
 
330
347
  ```bibtex
331
- @software{s3dgraphy2024,
348
+ @software{s3dgraphy,
332
349
  title={s3dgraphy: 3D Stratigraphic Graph Management Library},
333
350
  author={Demetrescu, Emanuel},
334
- year={2024},
351
+ year={2026},
335
352
  url={https://github.com/zalmoxes-laran/s3dgraphy},
336
- version={0.1.1},
353
+ version={1.6.0},
337
354
  institution={CNR-ISPC (National Research Council - Institute of Heritage Science)}
338
355
  }
339
356
  ```
File without changes
File without changes