s3dgraphy Edges Reference
This document provides comprehensive documentation for all edge types in s3dgraphy, including their semantic meanings, CIDOC-CRM mappings, and usage patterns.
Overview
Edges in s3dgraphy represent relationships between nodes in the archaeological knowledge graph. Each edge type has specific semantic meaning and follows archaeological documentation standards.
Edge Types Classification
Temporal Relationships
is_before
- Label:
Chronological Sequence
- Description:
Indicates a temporal sequence where one item occurs before another
- CIDOC-CRM:
P120_occurs_before
- Visual Style:
Solid line
- Usage:
Primary stratigraphic relationships
# Stratigraphic sequence: US003 is earlier than US002
graph.add_edge("rel001", "US003", "US002", "is_before")
- Allowed Connections:
StratigraphicNode → StratigraphicNode
StratigraphicEventNode → StratigraphicEventNode
EpochNode → EpochNode
has_same_time
- Label:
Contemporaneous Elements
- Description:
Indicates that two elements are contemporaneous
- CIDOC-CRM:
P114_is_equal_in_time_to
- Visual Style:
Double line
- Usage:
Contemporary archaeological features
# Contemporary features: wall and floor built at same time
graph.add_edge("rel002", "US001_wall", "US002_floor", "has_same_time")
- Allowed Connections:
StratigraphicNode → StratigraphicNode
SpecialFindUnit → SpecialFindUnit
changed_from
- Label:
Temporal Transformation
- Description:
Represents an object that changes over time
- CIDOC-CRM:
P123_resulted_from
- Visual Style:
Dotted line
- Usage:
Transformation processes, reconstruction phases
# Building transformation: medieval wall reuses Roman foundation
graph.add_edge("trans001", "US005_medieval_wall", "US010_roman_foundation", "changed_from")
- Allowed Connections:
StratigraphicNode → StratigraphicNode (any subtype, including container nodes)
TransformationStratigraphicUnit → StratigraphicNode
Note
When multiple nodes are linked by changed_from edges, they form an instance chain –
a connected component representing the complete biography of a single physical object
through time. The chain is traversed transitively via BFS. Instance chains can link
any combination of stratigraphic node types (US, USD, SF, VSF, etc.).
Containment Relationships
is_part_of
- Label:
Is Part Of
- Description:
Physical containment – a node is part of a container stratigraphic unit
- CIDOC-CRM:
P46_is_composed_of
- Visual Style:
Not represented as a visual edge in GraphML (expressed via group nesting)
- Usage:
Mereological (part–whole) relationships
# Special find contained in a wall
graph.add_edge("part001", "SF10102", "US10101", "is_part_of")
- Allowed Connections:
SpecialFindUnit → StratigraphicUnit
SpecialFindUnit → DocumentaryStratigraphicUnit
SpecialFindUnit → VirtualSpecialFindUnit
VirtualSpecialFindUnit → StratigraphicUnit
VirtualSpecialFindUnit → DocumentaryStratigraphicUnit
VirtualSpecialFindUnit → VirtualSpecialFindUnit
Note
The reverse edge has_part is automatically generated by s3dgraphy.
In the GraphML representation, containment is expressed through group nodes –
the container is a yEd group node with a specific background colour (US: #9B3333,
USD: #D86400, VSF: #B19F61), and children are placed inside it.
has_visual_reference
- Label:
Has Visual Reference
- Description:
Links a node to a visual reference document
- CIDOC-CRM:
P138i_has_representation
- Visual Style:
Solid line
- Usage:
Visual documentation links (added in datamodel v1.5.4)
# Link to visual reference
graph.add_edge("vis001", "US001", "DOC005_photo", "has_visual_reference")
Documentation Relationships
has_data_provenance
- Label:
Data Provenance
- Description:
Indicates the provenance of data, often linking to source nodes
- CIDOC-CRM:
P70i_is_documented_in
- Visual Style:
Dashed line
- Usage:
Links interpretations to their sources
# Property supported by documentation
graph.add_edge("prov001", "PROP001_material", "DOC001_analysis", "has_data_provenance")
- Allowed Connections:
PropertyNode → DocumentNode
PropertyNode → ExtractorNode
CombinerNode → ExtractorNode
extracted_from
- Label:
Extracted From
- Description:
Indicates that information is derived from a particular source
- CIDOC-CRM:
P67_refers_to
- Visual Style:
Dashed line
- Usage:
Information extraction processes
# Information extracted from document
graph.add_edge("ext001", "EXT001_typology", "DOC005_corpus", "extracted_from")
- Allowed Connections:
ExtractorNode → DocumentNode
PropertyNode → DocumentNode
SpecialFindUnit → StratigraphicNode (findspot)
combines
- Label:
Combines
- Description:
Indicates that a node combines information from various sources
- CIDOC-CRM:
P16_used_specific_object
- Visual Style:
Dashed line
- Usage:
Information synthesis processes
# Combiner synthesizes multiple sources
graph.add_edge("comb001", "COMB001_synthesis", "EXT001_dating", "combines")
graph.add_edge("comb002", "COMB001_synthesis", "EXT002_material", "combines")
- Allowed Connections:
CombinerNode → ExtractorNode
CombinerNode → PropertyNode
Property and Attribution Relationships
has_property
- Label:
Has Property
- Description:
Connects a node to one of its properties
- CIDOC-CRM:
P2_has_type
- Visual Style:
Solid line
- Usage:
Attribute assignment
# Stratigraphic unit has material property
graph.add_edge("prop001", "US001", "PROP001_material_stone", "has_property")
- Allowed Connections:
StratigraphicNode → PropertyNode
SpecialFindUnit → PropertyNode
Any Node → PropertyNode
contrasts_with
- Label:
Contrasting Properties
- Description:
Represents contrasting or mutually exclusive properties
- CIDOC-CRM:
P69_has_association_with
- Visual Style:
Dashed-dotted line
- Usage:
Alternative interpretations, conflicting evidence
# Alternative dating interpretations
graph.add_edge("contrast001", "PROP001_dating_early", "PROP002_dating_late", "contrasts_with")
- Allowed Connections:
PropertyNode → PropertyNode
ExtractorNode → ExtractorNode
CombinerNode → CombinerNode
Temporal and Epochal Relationships
has_first_epoch
- Label:
Has First Epoch
- Description:
Indicates the initial epoch associated with a node
- CIDOC-CRM:
P82a_begin_of_the_begin
- Visual Style:
Solid line
- Usage:
Temporal assignment to periods
# Unit belongs to Roman period
graph.add_edge("epoch001", "US001", "EPOCH_ROMAN", "has_first_epoch")
- Allowed Connections:
StratigraphicNode → EpochNode
SpecialFindUnit → EpochNode
survive_in_epoch
- Label:
Survives In Epoch
- Description:
Indicates that a node continues to exist in a given epoch
- CIDOC-CRM:
P10_falls_within
- Visual Style:
Solid line
- Usage:
Long-duration features
# Wall continues through multiple periods
graph.add_edge("surv001", "US001_wall", "EPOCH_MEDIEVAL", "survive_in_epoch")
- Allowed Connections:
StratigraphicNode → EpochNode
ContinuityNode → EpochNode
Organizational Relationships
is_in_activity
- Label:
Part of Activity
- Description:
Indicates that a node is part of a specific activity
- CIDOC-CRM:
P9_consists_of
- Visual Style:
Solid line
- Usage:
Activity-based grouping
# Units part of construction activity
graph.add_edge("act001", "US001", "ACT001_construction", "is_in_activity")
- Allowed Connections:
Any Node → ActivityNodeGroup
has_timebranch / is_in_timebranch
- Label:
Connected to a Timebranch / Included in Timebranch
- Description:
Indicates connection to alternative temporal interpretations
- CIDOC-CRM:
P67_refers_to
- Visual Style:
Solid line
- Usage:
Alternative chronological hypotheses
# Alternative interpretation branch
graph.add_edge("branch001", "US001", "BRANCH001_early_dating", "has_timebranch")
- Allowed Connections:
Any Node → TimeBranchNodeGroup
is_in_paradata_nodegroup / has_paradata_nodegroup
- Label:
Belongs to Paradata Group / Has Paradata Group
- Description:
Organizational relationships for paradata management
- CIDOC-CRM:
P106_is_composed_of
- Visual Style:
Solid line
- Usage:
Documentation organization
# Group paradata by excavation area
graph.add_edge("para001", "DOC001", "PARAGROUP_AREA_A", "is_in_paradata_nodegroup")
- Allowed Connections:
DocumentNode → ParadataNodeGroup
ExtractorNode → ParadataNodeGroup
CombinerNode → ParadataNodeGroup
ParadataNodeGroup → ActivityNodeGroup
Specialized Relationships
has_linked_resource
- Label:
Has Link
- Description:
Connects a node to its linked resource(s)
- CIDOC-CRM:
P67_refers_to
- Visual Style:
Solid line
- Usage:
External resource links
# Link to external resource
graph.add_edge("link001", "US001", "LINK001_3d_model", "has_linked_resource")
- Allowed Connections:
Any Node → LinkNode
has_semantic_shape
- Label:
Has Semantic Shape
- Description:
Connects any node to its semantic shape representation in 3D space
- CIDOC-CRM:
E36_Visual_Item
- Visual Style:
Solid line
- Usage:
3D visualization links
# Link to 3D semantic representation
graph.add_edge("shape001", "US001", "SHAPE001_wall_3d", "has_semantic_shape")
- Allowed Connections:
Any Node → SemanticShapeNode
has_representation_model
- Label:
Has Representation Model
- Description:
Connects any node to its representation model in 3D space
- CIDOC-CRM:
E36_Visual_Item
- Visual Style:
Solid line
- Usage:
3D model connections
# Link to 3D representation model
graph.add_edge("model001", "US001", "MODEL001_wall", "has_representation_model")
- Allowed Connections:
Any Node → RepresentationModelNode
Licensing and Legal Relationships
has_license
- Label:
Has License
- Description:
Indicates that a resource is subject to a specific licence
- CIDOC-CRM:
P104_is_subject_to
- Visual Style:
Solid line
- Usage:
Legal and copyright information
# Document has specific license
graph.add_edge("lic001", "DOC001", "LICENSE_CC_BY", "has_license")
has_embargo
- Label:
Has Embargo
- Description:
Indicates that a licence has an associated time embargo
- CIDOC-CRM:
P4_has_time-span
- Visual Style:
Solid line
- Usage:
Temporal access restrictions
# License has embargo period
graph.add_edge("emb001", "LICENSE_CC_BY", "EMBARGO_2025", "has_embargo")
Generic Relationships
generic_connection
- Label:
Generic Connection
- Description:
Represents a non-specific connection between two nodes
- CIDOC-CRM:
P67_refers_to
- Visual Style:
Solid line
- Usage:
Placeholder for unspecified relationships
# Generic connection (should be enhanced to specific type)
graph.add_edge("gen001", "NODE001", "NODE002", "generic_connection")
Note: Generic connections are often enhanced to more specific types during import processing.
Connection Validation Rules
Node Type Compatibility Matrix
s3dgraphy enforces strict validation rules for edge connections based on archaeological logic:
# Validation example
source_node = graph.find_node_by_id("US001")
target_node = graph.find_node_by_id("DOC001")
if Graph.validate_connection(source_node.node_type, target_node.node_type, "has_data_provenance"):
graph.add_edge("valid_edge", "US001", "DOC001", "has_data_provenance")
else:
print("Invalid connection type")
Common Valid Patterns:
Stratigraphic Relationships
US → US (is_before, has_same_time)
US → SF (extracted_from - findspot)
US → EpochNode (has_first_epoch, survive_in_epoch)
Documentation Chains
DocumentNode → ExtractorNode (extracted_from)
ExtractorNode → CombinerNode (combines)
PropertyNode → DocumentNode (has_data_provenance)
US/SF → PropertyNode (has_property)
Organizational Structures
Any Node → ActivityNodeGroup (is_in_activity)
ParadataNode → ParadataNodeGroup (is_in_paradata_nodegroup)
Any Node → TimeBranchNodeGroup (has_timebranch)
Best Practices for Edge Usage
Temporal Relationships
Use consistent direction: Later units point to earlier units with “is_after” (canonical direction from recent to ancient)
Document contemporaneity: Use “has_same_time” for features built together
Model transformations: Use “changed_from” for reuse and modification
# Good: Consistent temporal direction (canonical "is_after")
graph.add_edge("temp1", "US002_wall", "US003_foundation", "is_after") # wall is more recent than foundation
graph.add_edge("temp2", "US001_roof", "US002_wall", "is_after") # roof is more recent than wall
# Good: Contemporary features
graph.add_edge("cont1", "US002_wall", "US004_floor", "has_same_time")
Documentation Chains
Complete paradata chains: Link properties through extractors to documents
Use specific edge types: Avoid generic_connection when possible
Document conflicting interpretations: Use contrasts_with for alternatives
# Complete documentation chain
graph.add_edge("prop1", "US001", "PROP001_material", "has_property")
graph.add_edge("ext1", "EXT001_analysis", "DOC001_lab_report", "extracted_from")
graph.add_edge("prov1", "PROP001_material", "EXT001_analysis", "has_data_provenance")
Organizational Structure
Group related elements: Use node groups for logical organization
Separate activity phases: Use activity groups for excavation phases
Model alternative interpretations: Use time branches for competing hypotheses
# Organizational grouping
graph.add_edge("org1", "US001", "ACT001_phase1", "is_in_activity")
graph.add_edge("org2", "DOC001", "PARA001_area_a", "is_in_paradata_nodegroup")
Error Handling and Validation
Common Edge Validation Errors
Invalid Node Types
# This will fail validation
try:
graph.add_edge("invalid", "US001", "US002", "has_license")
except ValueError as e:
print(f"Invalid connection: {e}")
# US nodes cannot have license relationships
Missing Nodes
# Check nodes exist before creating edges
if (graph.find_node_by_id("US001") and
graph.find_node_by_id("US002")):
graph.add_edge("rel1", "US001", "US002", "is_before")
else:
graph.add_warning("Cannot create edge: missing nodes")
Circular Dependencies
# Detect circular temporal relationships
def check_temporal_cycles(graph):
temporal_edges = [e for e in graph.edges if e.edge_type == "is_before"]
# Implementation of cycle detection algorithm
return has_cycles
Edge Enhancement During Import
GraphML Import Processing
The GraphMLImporter automatically enhances edge types based on connected node types:
def enhance_edge_type(self, source_node, target_node, edge_type):
"""Enhance generic connections to specific types"""
if edge_type == "generic_connection":
# DocumentNode → ExtractorNode becomes "extracted_from"
if (source_node.node_type == "document" and
target_node.node_type == "extractor"):
return "extracted_from"
# ExtractorNode → CombinerNode becomes "combines"
elif (source_node.node_type == "extractor" and
target_node.node_type == "combiner"):
return "combines"
return edge_type
Export Considerations
GraphML Export
Edge types are preserved with their semantic meaning and visual styling:
# Export preserves edge semantics
exporter = GraphMLExporter()
exporter.export_graph(graph, "output.graphml",
preserve_edge_styles=True)
JSON Export
Edges include full metadata and CIDOC-CRM mappings:
# JSON export includes semantic information
{
"edge_id": "rel001",
"source": "US001",
"target": "US002",
"edge_type": "is_before",
"label": "Chronological Sequence",
"description": "Indicates a temporal sequence where one item occurs before another",
"cidoc_mapping": "P120_occurs_before",
"visual_style": "solid_line"
}
This comprehensive edge reference provides the foundation for creating semantically rich archaeological graphs in s3dgraphy.