21 from __future__
import annotations
23 __all__ = (
"QuantumNode",
"NodeId",
"BuildId")
25 from dataclasses
import dataclass
26 from typing
import NewType
28 from ..pipeline
import TaskDef
29 from lsst.daf.butler
import Quantum, DatasetRef
31 BuildId = NewType(
"BuildId", str)
34 def _hashDsRef(ref: DatasetRef) -> int:
35 return hash((ref.datasetType, ref.dataId))
38 @dataclass(frozen=
True, eq=
True)
40 """This represents an unique identifier of a node within an individual
41 construction of a `QuantumGraph`. This identifier will stay constant through
42 a pickle, and any `QuantumGraph` methods that return a new `QuantumGraph`.
44 A `NodeId` will not be the same if a new graph is built containing the same
45 information in a `QuantumNode`, or even built from exactly the same inputs.
47 `NodeId`s do not play any role in deciding the equality or identity (hash)
48 of a `QuantumNode`, and are mainly useful in debugging or working with
49 various subsets of the same graph.
51 This interface is a convenance only, and no guarantees on long term
52 stability are made. New implementations might change the `NodeId`, or
53 provide more or less guarantees.
56 """The unique position of the node within the graph assigned at graph
60 """Unique identifier created at the time the originating graph was created
64 @dataclass(frozen=
True)
66 """This class represents a node in the quantum graph.
68 The quantum attribute represents the data that is to be processed at this
72 """The unit of data that is to be processed by this graph node"""
74 """Definition of the task that will process the `Quantum` associated with
78 """The unique position of the node within the graph assigned at graph
82 def __eq__(self, other: object) -> bool:
83 if not isinstance(other, QuantumNode):
85 if self.quantum != other.quantum:
90 """For graphs it is useful to have a more robust hash than provided
91 by the default quantum id based hashing
93 return hash((self.
taskDef, self.quantum))