scanspec.specs
#
Spec
and its subclasses.
Members
A serializable representation of the type and parameters of a scan. |
|
Step scan, with num frames of given duration at each frame in the spec. |
|
Flyscan, zipping with fixed duration for every frame. |
|
A string returned from |
- pydantic model scanspec.specs.ConstantDuration[source]#
Apply a constant duration to every point in a Spec.
Typically applied with the
@
modifier.# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Line spec = 0.1 @ Line("x", 1, 2, 3) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)Show JSON schema
{ "title": "ConstantDuration", "description": "Apply a constant duration to every point in a Spec.\n\nTypically applied with the ``@`` modifier.\n\n.. example_spec::\n\n from scanspec.specs import Line\n\n spec = 0.1 @ Line(\"x\", 1, 2, 3)", "type": "object", "properties": { "constant_duration": { "description": "The value at each point", "title": "Constant Duration", "type": "number" }, "spec": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "null" } ], "default": null, "description": "Spec contaning the path to be followed" }, "type": { "const": "ConstantDuration", "default": "ConstantDuration", "title": "Type", "type": "string" } }, "$defs": { "Circle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy circle of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Circle(\"x\", \"y\", 1, 2, 0.9)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the circle", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the circle", "title": "Y Middle", "type": "number" }, "radius": { "description": "Radius of the circle", "exclusiveMinimum": 0.0, "title": "Radius", "type": "number" }, "type": { "const": "Circle", "default": "Circle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "radius" ], "title": "Circle", "type": "object" }, "CombinationOf__Axis_": { "additionalProperties": false, "description": "Abstract baseclass for a combination of two regions, left and right.", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "CombinationOf", "default": "CombinationOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "CombinationOf", "type": "object" }, "Concat__Axis_": { "additionalProperties": false, "description": "Concatenate two Specs together, running one after the other.\n\nEach Dimension of left and right must contain the same axes. Typically\nformed using `Spec.concat`.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 3, 3).concat(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Concat, midpoints will appear earlier" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Concat, midpoints will appear later" }, "gap": { "default": false, "description": "If True, force a gap in the output at the join", "title": "Gap", "type": "boolean" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Concat", "default": "Concat", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Concat", "type": "object" }, "ConstantDuration__Axis_": { "additionalProperties": false, "description": "Apply a constant duration to every point in a Spec.\n\nTypically applied with the ``@`` modifier.\n\n.. example_spec::\n\n from scanspec.specs import Line\n\n spec = 0.1 @ Line(\"x\", 1, 2, 3)", "properties": { "constant_duration": { "description": "The value at each point", "title": "Constant Duration", "type": "number" }, "spec": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "null" } ], "default": null, "description": "Spec contaning the path to be followed" }, "type": { "const": "ConstantDuration", "default": "ConstantDuration", "title": "Type", "type": "string" } }, "required": [ "constant_duration" ], "title": "ConstantDuration", "type": "object" }, "DifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in DifferenceOf(a, b) if in a and not in b.\n\nTypically created with the ``-`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) - Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "DifferenceOf", "default": "DifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "DifferenceOf", "type": "object" }, "Ellipse__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy ellipse of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Ellipse\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Ellipse(\"x\", \"y\", 5, 5, 2, 3, 75)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the ellipse", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the ellipse", "title": "Y Middle", "type": "number" }, "x_radius": { "description": "The radius along the x axis of the ellipse", "exclusiveMinimum": 0.0, "title": "X Radius", "type": "number" }, "y_radius": { "description": "The radius along the y axis of the ellipse", "exclusiveMinimum": 0.0, "title": "Y Radius", "type": "number" }, "angle": { "default": 0.0, "description": "The angle of the ellipse (degrees)", "title": "Angle", "type": "number" }, "type": { "const": "Ellipse", "default": "Ellipse", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "x_radius", "y_radius" ], "title": "Ellipse", "type": "object" }, "Fly__Axis_": { "additionalProperties": false, "description": "Move through lower to upper bounds of the Spec rather than stopping.\n\nThis is commonly termed a \"fly scan\" rather than a \"step scan\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 3))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "Spec contaning the path to be followed" }, "type": { "const": "Fly", "default": "Fly", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Fly", "type": "object" }, "IntersectionOf__Axis_": { "additionalProperties": false, "description": "A point is in IntersectionOf(a, b) if in both a and b.\n\nTypically created with the ``&`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) & Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, False, True, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "IntersectionOf", "default": "IntersectionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "IntersectionOf", "type": "object" }, "Line__Axis_": { "additionalProperties": false, "description": "Linearly spaced frames with start and stop as first and last midpoints.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 5))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "start": { "description": "Midpoint of the first point of the line", "title": "Start", "type": "number" }, "stop": { "description": "Midpoint of the last point of the line", "title": "Stop", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Line", "default": "Line", "title": "Type", "type": "string" } }, "required": [ "axis", "start", "stop", "num" ], "title": "Line", "type": "object" }, "Mask__Axis_": { "additionalProperties": false, "description": "Restrict Spec to only midpoints that fall inside the given Region.\n\nTypically created with the ``&`` operator. It also pushes down the\n``& | ^ -`` operators to its `Region` to avoid the need for brackets on\ncombinations of Regions.\n\nIf a Region spans multiple Dimension objects, they will be squashed together.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Fly, Line\n\n region = Circle(\"x\", \"y\", 4, 2, 1.2)\n spec = Fly(Line(\"y\", 1, 3, 3) * Line(\"x\", 3, 5, 5) & region)\n\nSee Also: `why-squash-can-change-path`", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec containing the source midpoints" }, "region": { "$ref": "#/$defs/Region", "description": "The Region that midpoints will be inside" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Mask", "default": "Mask", "title": "Type", "type": "string" } }, "required": [ "spec", "region" ], "title": "Mask", "type": "object" }, "Polygon__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy polygon.\n\n.. example_spec::\n\n from scanspec.regions import Polygon\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Polygon(\"x\", \"y\", [1.0, 6.0, 8.0, 2.0], [4.0, 10.0, 6.0, 1.0])", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_verts": { "description": "The Nx1 x coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "X Verts", "type": "array" }, "y_verts": { "description": "The Nx1 y coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "Y Verts", "type": "array" }, "type": { "const": "Polygon", "default": "Polygon", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_verts", "y_verts" ], "title": "Polygon", "type": "object" }, "Product__Axis_": { "additionalProperties": false, "description": "Outer product of two Specs, nesting inner within outer.\n\nThis means that inner will run in its entirety at each point in outer.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * Line(\"x\", 3, 4, 12))\n\nAn inner integer can be used to repeat the same point many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * 2)\n\nAn outer integer can be used to repeat the same scan many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(2 * ~Line.bounded(\"x\", 3, 4, 1))\n\nIf you want snaked axes to have no gap between iterations you can do:\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Product\n\n spec = Fly(Product(2, ~Line.bounded(\"x\", 3, 4, 1), gap=False))\n\n.. note:: There is no turnaround arrow at x=4", "properties": { "outer": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed once", "title": "Outer" }, "inner": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed len(outer) times", "title": "Inner" }, "gap": { "default": true, "description": "If False and the outer spec is an integer and the inner spec is snaked then the end and start of consecutive iterations of inner will have no gap", "title": "Gap", "type": "boolean" }, "type": { "const": "Product", "default": "Product", "title": "Type", "type": "string" } }, "required": [ "outer", "inner" ], "title": "Product", "type": "object" }, "Range__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis >= min and <= max.\n\n>>> r = Range(\"x\", 1, 2)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, False, False])", "properties": { "axis": { "description": "The name matching the axis to mask in spec", "title": "Axis" }, "min": { "description": "The minimum inclusive value in the region", "title": "Min", "type": "number" }, "max": { "description": "The minimum inclusive value in the region", "title": "Max", "type": "number" }, "type": { "const": "Range", "default": "Range", "title": "Type", "type": "string" } }, "required": [ "axis", "min", "max" ], "title": "Range", "type": "object" }, "Rectangle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy rectangle.\n\n.. example_spec::\n\n from scanspec.regions import Rectangle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Rectangle(\"x\", \"y\", 0, 1.1, 1.5, 2.1, 30)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_min": { "description": "Minimum inclusive x value in the region", "title": "X Min", "type": "number" }, "y_min": { "description": "Minimum inclusive y value in the region", "title": "Y Min", "type": "number" }, "x_max": { "description": "Maximum inclusive x value in the region", "title": "X Max", "type": "number" }, "y_max": { "description": "Maximum inclusive y value in the region", "title": "Y Max", "type": "number" }, "angle": { "default": 0.0, "description": "Clockwise rotation angle of the rectangle", "title": "Angle", "type": "number" }, "type": { "const": "Rectangle", "default": "Rectangle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_min", "y_min", "x_max", "y_max" ], "title": "Rectangle", "type": "object" }, "Region": { "discriminator": { "mapping": { "Circle": "#/$defs/Circle__Axis_", "CombinationOf": "#/$defs/CombinationOf__Axis_", "DifferenceOf": "#/$defs/DifferenceOf__Axis_", "Ellipse": "#/$defs/Ellipse__Axis_", "IntersectionOf": "#/$defs/IntersectionOf__Axis_", "Polygon": "#/$defs/Polygon__Axis_", "Range": "#/$defs/Range__Axis_", "Rectangle": "#/$defs/Rectangle__Axis_", "SymmetricDifferenceOf": "#/$defs/SymmetricDifferenceOf__Axis_", "UnionOf": "#/$defs/UnionOf__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/CombinationOf__Axis_" }, { "$ref": "#/$defs/UnionOf__Axis_" }, { "$ref": "#/$defs/IntersectionOf__Axis_" }, { "$ref": "#/$defs/DifferenceOf__Axis_" }, { "$ref": "#/$defs/SymmetricDifferenceOf__Axis_" }, { "$ref": "#/$defs/Range__Axis_" }, { "$ref": "#/$defs/Rectangle__Axis_" }, { "$ref": "#/$defs/Polygon__Axis_" }, { "$ref": "#/$defs/Circle__Axis_" }, { "$ref": "#/$defs/Ellipse__Axis_" } ] }, "Snake__Axis_": { "additionalProperties": false, "description": "Run the Spec in reverse on every other iteration when nested.\n\nTypically created with the ``~`` operator.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 3, 3) * ~Line(\"x\", 3, 5, 5))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to run in reverse every other iteration" }, "type": { "const": "Snake", "default": "Snake", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Snake", "type": "object" }, "Spec": { "discriminator": { "mapping": { "Concat": "#/$defs/Concat__Axis_", "ConstantDuration": "#/$defs/ConstantDuration__Axis_", "Fly": "#/$defs/Fly__Axis_", "Line": "#/$defs/Line__Axis_", "Mask": "#/$defs/Mask__Axis_", "Product": "#/$defs/Product__Axis_", "Snake": "#/$defs/Snake__Axis_", "Spiral": "#/$defs/Spiral__Axis_", "Squash": "#/$defs/Squash__Axis_", "Static": "#/$defs/Static__Axis_", "Zip": "#/$defs/Zip__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/Product__Axis_" }, { "$ref": "#/$defs/Zip__Axis_" }, { "$ref": "#/$defs/Mask__Axis_" }, { "$ref": "#/$defs/Snake__Axis_" }, { "$ref": "#/$defs/Concat__Axis_" }, { "$ref": "#/$defs/Squash__Axis_" }, { "$ref": "#/$defs/Line__Axis_" }, { "$ref": "#/$defs/Fly__Axis_" }, { "$ref": "#/$defs/ConstantDuration__Axis_" }, { "$ref": "#/$defs/Static__Axis_" }, { "$ref": "#/$defs/Spiral__Axis_" } ] }, "Spiral__Axis_": { "additionalProperties": false, "description": "Archimedean spiral of \"x_axis\" and \"y_axis\".\n\nStarts at centre point (\"x_start\", \"y_start\") with angle \"rotate\". Produces\n\"num\" points in a spiral spanning width of \"x_range\" and height of \"y_range\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Spiral\n\n spec = Fly(Spiral(\"x\", \"y\", 1, 5, 10, 50, 30))", "properties": { "x_axis": { "description": "An identifier for what to move for x", "title": "X Axis" }, "y_axis": { "description": "An identifier for what to move for y", "title": "Y Axis" }, "x_start": { "description": "x centre of the spiral", "title": "X Start", "type": "number" }, "y_start": { "description": "y centre of the spiral", "title": "Y Start", "type": "number" }, "x_range": { "description": "x width of the spiral", "title": "X Range", "type": "number" }, "y_range": { "description": "y width of the spiral", "title": "Y Range", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "rotate": { "default": 0.0, "description": "How much to rotate the angle of the spiral", "title": "Rotate", "type": "number" }, "type": { "const": "Spiral", "default": "Spiral", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_start", "y_start", "x_range", "y_range", "num" ], "title": "Spiral", "type": "object" }, "Squash__Axis_": { "additionalProperties": false, "description": "Squash a stack of Dimension together into a single expanded Dimension object.\n\nSee Also:\n `why-squash-can-change-path`\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Squash\n\n spec = Fly(Squash(Line(\"y\", 1, 2, 3) * Line(\"x\", 0, 1, 4)))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to squash the dimensions of" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Squash", "default": "Squash", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Squash", "type": "object" }, "Static__Axis_": { "additionalProperties": false, "description": "A static frame, repeated num times, with axis at value.\n\nCan be used to set axis=value at every point in a scan.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Static\n\n spec = Fly(Line(\"y\", 1, 2, 3).zip(Static(\"x\", 3)))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "value": { "description": "The value at each point", "title": "Value", "type": "number" }, "num": { "default": 1, "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Static", "default": "Static", "title": "Type", "type": "string" } }, "required": [ "axis", "value" ], "title": "Static", "type": "object" }, "SymmetricDifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in SymmetricDifferenceOf(a, b) if in either a or b, but not both.\n\nTypically created with the ``^`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) ^ Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "SymmetricDifferenceOf", "default": "SymmetricDifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "SymmetricDifferenceOf", "type": "object" }, "UnionOf__Axis_": { "additionalProperties": false, "description": "A point is in UnionOf(a, b) if in either a or b.\n\nTypically created with the ``|`` operator\n\n>>> r = Range(\"x\", 0.5, 2.5) | Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "UnionOf", "default": "UnionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "UnionOf", "type": "object" }, "Zip__Axis_": { "additionalProperties": false, "description": "Run two Specs in parallel, merging their midpoints together.\n\nTypically formed using `Spec.zip`.\n\nStacks of Dimension are merged by:\n\n- If right creates a stack of a single Dimension object of size 1, expand it to\n the size of the fastest Dimension object created by left\n- Merge individual Dimension objects together from fastest to slowest\n\nThis means that Zipping a Spec producing stack [l2, l1] with a Spec\nproducing stack [r1] will assert len(l1)==len(r1), and produce\nstack [l2, l1.zip(r1)].\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"z\", 1, 2, 3) * Line(\"y\", 3, 4, 5).zip(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Zip, will appear earlier in axes" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Zip, will appear later in axes" }, "type": { "const": "Zip", "default": "Zip", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Zip", "type": "object" } }, "additionalProperties": false, "required": [ "constant_duration" ] }
- Fields:
- axes() list[Axis] [source]#
Return the list of axes that are present in the scan.
Ordered from slowest moving to fastest moving.
- class scanspec.specs.Spec[source]#
A serializable representation of the type and parameters of a scan.
Abstract baseclass for the specification of a scan. Supports operators:
*
: OuterProduct
of two Specs or ints, nesting the second within the first.@
:ConstantDuration
of the Spec, setting a constant duration for each point.&
:Mask
the Spec with aRegion
, excluding midpoints outside of it~
:Snake
the Spec, reversing every other iteration of it
- axes() list[Axis] [source]#
Return the list of axes that are present in the scan.
Ordered from slowest moving to fastest moving.
- duration() float | None | Literal['VARIABLE_DURATION'] [source]#
Returns the duration of each scan point.
Return value will be one of: -
None
: No duration defined -float
: A constant duration for each point -VARIABLE_DURATION
: A different duration for each point
- calculate(bounds: bool = False, nested: bool = False) list[Dimension[Axis]] [source]#
Produce a stack of nested
Dimension
that form the scan.Ordered from slowest moving to fastest moving.
- frames(bounds: bool = False) Dimension[Axis] [source]#
Expand all the scan
Dimension
and return them.
- zip(other: Spec[OtherAxis]) Zip[Axis | OtherAxis] [source]#
Zip
the Spec with another, iterating in tandem.
- pydantic model scanspec.specs.Product[source]#
Outer product of two Specs, nesting inner within outer.
This means that inner will run in its entirety at each point in outer.
# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Line spec = Fly(Line("y", 1, 2, 3) * Line("x", 3, 4, 12)) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)An inner integer can be used to repeat the same point many times.
# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Line spec = Fly(Line("y", 1, 2, 3) * 2) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)An outer integer can be used to repeat the same scan many times.
# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Line spec = Fly(2 * ~Line.bounded("x", 3, 4, 1)) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)If you want snaked axes to have no gap between iterations you can do:
# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Line, Product spec = Fly(Product(2, ~Line.bounded("x", 3, 4, 1), gap=False)) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)Note
There is no turnaround arrow at x=4
Show JSON schema
{ "title": "Product", "description": "Outer product of two Specs, nesting inner within outer.\n\nThis means that inner will run in its entirety at each point in outer.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * Line(\"x\", 3, 4, 12))\n\nAn inner integer can be used to repeat the same point many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * 2)\n\nAn outer integer can be used to repeat the same scan many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(2 * ~Line.bounded(\"x\", 3, 4, 1))\n\nIf you want snaked axes to have no gap between iterations you can do:\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Product\n\n spec = Fly(Product(2, ~Line.bounded(\"x\", 3, 4, 1), gap=False))\n\n.. note:: There is no turnaround arrow at x=4", "type": "object", "properties": { "outer": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed once", "title": "Outer" }, "inner": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed len(outer) times", "title": "Inner" }, "gap": { "default": true, "description": "If False and the outer spec is an integer and the inner spec is snaked then the end and start of consecutive iterations of inner will have no gap", "title": "Gap", "type": "boolean" }, "type": { "const": "Product", "default": "Product", "title": "Type", "type": "string" } }, "$defs": { "Circle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy circle of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Circle(\"x\", \"y\", 1, 2, 0.9)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the circle", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the circle", "title": "Y Middle", "type": "number" }, "radius": { "description": "Radius of the circle", "exclusiveMinimum": 0.0, "title": "Radius", "type": "number" }, "type": { "const": "Circle", "default": "Circle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "radius" ], "title": "Circle", "type": "object" }, "CombinationOf__Axis_": { "additionalProperties": false, "description": "Abstract baseclass for a combination of two regions, left and right.", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "CombinationOf", "default": "CombinationOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "CombinationOf", "type": "object" }, "Concat__Axis_": { "additionalProperties": false, "description": "Concatenate two Specs together, running one after the other.\n\nEach Dimension of left and right must contain the same axes. Typically\nformed using `Spec.concat`.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 3, 3).concat(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Concat, midpoints will appear earlier" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Concat, midpoints will appear later" }, "gap": { "default": false, "description": "If True, force a gap in the output at the join", "title": "Gap", "type": "boolean" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Concat", "default": "Concat", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Concat", "type": "object" }, "ConstantDuration__Axis_": { "additionalProperties": false, "description": "Apply a constant duration to every point in a Spec.\n\nTypically applied with the ``@`` modifier.\n\n.. example_spec::\n\n from scanspec.specs import Line\n\n spec = 0.1 @ Line(\"x\", 1, 2, 3)", "properties": { "constant_duration": { "description": "The value at each point", "title": "Constant Duration", "type": "number" }, "spec": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "null" } ], "default": null, "description": "Spec contaning the path to be followed" }, "type": { "const": "ConstantDuration", "default": "ConstantDuration", "title": "Type", "type": "string" } }, "required": [ "constant_duration" ], "title": "ConstantDuration", "type": "object" }, "DifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in DifferenceOf(a, b) if in a and not in b.\n\nTypically created with the ``-`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) - Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "DifferenceOf", "default": "DifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "DifferenceOf", "type": "object" }, "Ellipse__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy ellipse of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Ellipse\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Ellipse(\"x\", \"y\", 5, 5, 2, 3, 75)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the ellipse", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the ellipse", "title": "Y Middle", "type": "number" }, "x_radius": { "description": "The radius along the x axis of the ellipse", "exclusiveMinimum": 0.0, "title": "X Radius", "type": "number" }, "y_radius": { "description": "The radius along the y axis of the ellipse", "exclusiveMinimum": 0.0, "title": "Y Radius", "type": "number" }, "angle": { "default": 0.0, "description": "The angle of the ellipse (degrees)", "title": "Angle", "type": "number" }, "type": { "const": "Ellipse", "default": "Ellipse", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "x_radius", "y_radius" ], "title": "Ellipse", "type": "object" }, "Fly__Axis_": { "additionalProperties": false, "description": "Move through lower to upper bounds of the Spec rather than stopping.\n\nThis is commonly termed a \"fly scan\" rather than a \"step scan\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 3))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "Spec contaning the path to be followed" }, "type": { "const": "Fly", "default": "Fly", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Fly", "type": "object" }, "IntersectionOf__Axis_": { "additionalProperties": false, "description": "A point is in IntersectionOf(a, b) if in both a and b.\n\nTypically created with the ``&`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) & Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, False, True, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "IntersectionOf", "default": "IntersectionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "IntersectionOf", "type": "object" }, "Line__Axis_": { "additionalProperties": false, "description": "Linearly spaced frames with start and stop as first and last midpoints.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 5))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "start": { "description": "Midpoint of the first point of the line", "title": "Start", "type": "number" }, "stop": { "description": "Midpoint of the last point of the line", "title": "Stop", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Line", "default": "Line", "title": "Type", "type": "string" } }, "required": [ "axis", "start", "stop", "num" ], "title": "Line", "type": "object" }, "Mask__Axis_": { "additionalProperties": false, "description": "Restrict Spec to only midpoints that fall inside the given Region.\n\nTypically created with the ``&`` operator. It also pushes down the\n``& | ^ -`` operators to its `Region` to avoid the need for brackets on\ncombinations of Regions.\n\nIf a Region spans multiple Dimension objects, they will be squashed together.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Fly, Line\n\n region = Circle(\"x\", \"y\", 4, 2, 1.2)\n spec = Fly(Line(\"y\", 1, 3, 3) * Line(\"x\", 3, 5, 5) & region)\n\nSee Also: `why-squash-can-change-path`", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec containing the source midpoints" }, "region": { "$ref": "#/$defs/Region", "description": "The Region that midpoints will be inside" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Mask", "default": "Mask", "title": "Type", "type": "string" } }, "required": [ "spec", "region" ], "title": "Mask", "type": "object" }, "Polygon__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy polygon.\n\n.. example_spec::\n\n from scanspec.regions import Polygon\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Polygon(\"x\", \"y\", [1.0, 6.0, 8.0, 2.0], [4.0, 10.0, 6.0, 1.0])", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_verts": { "description": "The Nx1 x coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "X Verts", "type": "array" }, "y_verts": { "description": "The Nx1 y coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "Y Verts", "type": "array" }, "type": { "const": "Polygon", "default": "Polygon", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_verts", "y_verts" ], "title": "Polygon", "type": "object" }, "Product__Axis_": { "additionalProperties": false, "description": "Outer product of two Specs, nesting inner within outer.\n\nThis means that inner will run in its entirety at each point in outer.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * Line(\"x\", 3, 4, 12))\n\nAn inner integer can be used to repeat the same point many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * 2)\n\nAn outer integer can be used to repeat the same scan many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(2 * ~Line.bounded(\"x\", 3, 4, 1))\n\nIf you want snaked axes to have no gap between iterations you can do:\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Product\n\n spec = Fly(Product(2, ~Line.bounded(\"x\", 3, 4, 1), gap=False))\n\n.. note:: There is no turnaround arrow at x=4", "properties": { "outer": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed once", "title": "Outer" }, "inner": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed len(outer) times", "title": "Inner" }, "gap": { "default": true, "description": "If False and the outer spec is an integer and the inner spec is snaked then the end and start of consecutive iterations of inner will have no gap", "title": "Gap", "type": "boolean" }, "type": { "const": "Product", "default": "Product", "title": "Type", "type": "string" } }, "required": [ "outer", "inner" ], "title": "Product", "type": "object" }, "Range__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis >= min and <= max.\n\n>>> r = Range(\"x\", 1, 2)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, False, False])", "properties": { "axis": { "description": "The name matching the axis to mask in spec", "title": "Axis" }, "min": { "description": "The minimum inclusive value in the region", "title": "Min", "type": "number" }, "max": { "description": "The minimum inclusive value in the region", "title": "Max", "type": "number" }, "type": { "const": "Range", "default": "Range", "title": "Type", "type": "string" } }, "required": [ "axis", "min", "max" ], "title": "Range", "type": "object" }, "Rectangle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy rectangle.\n\n.. example_spec::\n\n from scanspec.regions import Rectangle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Rectangle(\"x\", \"y\", 0, 1.1, 1.5, 2.1, 30)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_min": { "description": "Minimum inclusive x value in the region", "title": "X Min", "type": "number" }, "y_min": { "description": "Minimum inclusive y value in the region", "title": "Y Min", "type": "number" }, "x_max": { "description": "Maximum inclusive x value in the region", "title": "X Max", "type": "number" }, "y_max": { "description": "Maximum inclusive y value in the region", "title": "Y Max", "type": "number" }, "angle": { "default": 0.0, "description": "Clockwise rotation angle of the rectangle", "title": "Angle", "type": "number" }, "type": { "const": "Rectangle", "default": "Rectangle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_min", "y_min", "x_max", "y_max" ], "title": "Rectangle", "type": "object" }, "Region": { "discriminator": { "mapping": { "Circle": "#/$defs/Circle__Axis_", "CombinationOf": "#/$defs/CombinationOf__Axis_", "DifferenceOf": "#/$defs/DifferenceOf__Axis_", "Ellipse": "#/$defs/Ellipse__Axis_", "IntersectionOf": "#/$defs/IntersectionOf__Axis_", "Polygon": "#/$defs/Polygon__Axis_", "Range": "#/$defs/Range__Axis_", "Rectangle": "#/$defs/Rectangle__Axis_", "SymmetricDifferenceOf": "#/$defs/SymmetricDifferenceOf__Axis_", "UnionOf": "#/$defs/UnionOf__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/CombinationOf__Axis_" }, { "$ref": "#/$defs/UnionOf__Axis_" }, { "$ref": "#/$defs/IntersectionOf__Axis_" }, { "$ref": "#/$defs/DifferenceOf__Axis_" }, { "$ref": "#/$defs/SymmetricDifferenceOf__Axis_" }, { "$ref": "#/$defs/Range__Axis_" }, { "$ref": "#/$defs/Rectangle__Axis_" }, { "$ref": "#/$defs/Polygon__Axis_" }, { "$ref": "#/$defs/Circle__Axis_" }, { "$ref": "#/$defs/Ellipse__Axis_" } ] }, "Snake__Axis_": { "additionalProperties": false, "description": "Run the Spec in reverse on every other iteration when nested.\n\nTypically created with the ``~`` operator.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 3, 3) * ~Line(\"x\", 3, 5, 5))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to run in reverse every other iteration" }, "type": { "const": "Snake", "default": "Snake", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Snake", "type": "object" }, "Spec": { "discriminator": { "mapping": { "Concat": "#/$defs/Concat__Axis_", "ConstantDuration": "#/$defs/ConstantDuration__Axis_", "Fly": "#/$defs/Fly__Axis_", "Line": "#/$defs/Line__Axis_", "Mask": "#/$defs/Mask__Axis_", "Product": "#/$defs/Product__Axis_", "Snake": "#/$defs/Snake__Axis_", "Spiral": "#/$defs/Spiral__Axis_", "Squash": "#/$defs/Squash__Axis_", "Static": "#/$defs/Static__Axis_", "Zip": "#/$defs/Zip__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/Product__Axis_" }, { "$ref": "#/$defs/Zip__Axis_" }, { "$ref": "#/$defs/Mask__Axis_" }, { "$ref": "#/$defs/Snake__Axis_" }, { "$ref": "#/$defs/Concat__Axis_" }, { "$ref": "#/$defs/Squash__Axis_" }, { "$ref": "#/$defs/Line__Axis_" }, { "$ref": "#/$defs/Fly__Axis_" }, { "$ref": "#/$defs/ConstantDuration__Axis_" }, { "$ref": "#/$defs/Static__Axis_" }, { "$ref": "#/$defs/Spiral__Axis_" } ] }, "Spiral__Axis_": { "additionalProperties": false, "description": "Archimedean spiral of \"x_axis\" and \"y_axis\".\n\nStarts at centre point (\"x_start\", \"y_start\") with angle \"rotate\". Produces\n\"num\" points in a spiral spanning width of \"x_range\" and height of \"y_range\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Spiral\n\n spec = Fly(Spiral(\"x\", \"y\", 1, 5, 10, 50, 30))", "properties": { "x_axis": { "description": "An identifier for what to move for x", "title": "X Axis" }, "y_axis": { "description": "An identifier for what to move for y", "title": "Y Axis" }, "x_start": { "description": "x centre of the spiral", "title": "X Start", "type": "number" }, "y_start": { "description": "y centre of the spiral", "title": "Y Start", "type": "number" }, "x_range": { "description": "x width of the spiral", "title": "X Range", "type": "number" }, "y_range": { "description": "y width of the spiral", "title": "Y Range", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "rotate": { "default": 0.0, "description": "How much to rotate the angle of the spiral", "title": "Rotate", "type": "number" }, "type": { "const": "Spiral", "default": "Spiral", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_start", "y_start", "x_range", "y_range", "num" ], "title": "Spiral", "type": "object" }, "Squash__Axis_": { "additionalProperties": false, "description": "Squash a stack of Dimension together into a single expanded Dimension object.\n\nSee Also:\n `why-squash-can-change-path`\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Squash\n\n spec = Fly(Squash(Line(\"y\", 1, 2, 3) * Line(\"x\", 0, 1, 4)))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to squash the dimensions of" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Squash", "default": "Squash", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Squash", "type": "object" }, "Static__Axis_": { "additionalProperties": false, "description": "A static frame, repeated num times, with axis at value.\n\nCan be used to set axis=value at every point in a scan.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Static\n\n spec = Fly(Line(\"y\", 1, 2, 3).zip(Static(\"x\", 3)))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "value": { "description": "The value at each point", "title": "Value", "type": "number" }, "num": { "default": 1, "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Static", "default": "Static", "title": "Type", "type": "string" } }, "required": [ "axis", "value" ], "title": "Static", "type": "object" }, "SymmetricDifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in SymmetricDifferenceOf(a, b) if in either a or b, but not both.\n\nTypically created with the ``^`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) ^ Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "SymmetricDifferenceOf", "default": "SymmetricDifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "SymmetricDifferenceOf", "type": "object" }, "UnionOf__Axis_": { "additionalProperties": false, "description": "A point is in UnionOf(a, b) if in either a or b.\n\nTypically created with the ``|`` operator\n\n>>> r = Range(\"x\", 0.5, 2.5) | Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "UnionOf", "default": "UnionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "UnionOf", "type": "object" }, "Zip__Axis_": { "additionalProperties": false, "description": "Run two Specs in parallel, merging their midpoints together.\n\nTypically formed using `Spec.zip`.\n\nStacks of Dimension are merged by:\n\n- If right creates a stack of a single Dimension object of size 1, expand it to\n the size of the fastest Dimension object created by left\n- Merge individual Dimension objects together from fastest to slowest\n\nThis means that Zipping a Spec producing stack [l2, l1] with a Spec\nproducing stack [r1] will assert len(l1)==len(r1), and produce\nstack [l2, l1.zip(r1)].\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"z\", 1, 2, 3) * Line(\"y\", 3, 4, 5).zip(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Zip, will appear earlier in axes" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Zip, will appear later in axes" }, "type": { "const": "Zip", "default": "Zip", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Zip", "type": "object" } }, "additionalProperties": false, "required": [ "outer", "inner" ] }
- Fields:
- field gap: bool = True#
If False and the outer spec is an integer and the inner spec is snaked then the end and start of consecutive iterations of inner will have no gap
- axes() list[Axis] [source]#
Return the list of axes that are present in the scan.
Ordered from slowest moving to fastest moving.
- pydantic model scanspec.specs.Zip[source]#
Run two Specs in parallel, merging their midpoints together.
Typically formed using
Spec.zip
.Stacks of Dimension are merged by:
If right creates a stack of a single Dimension object of size 1, expand it to the size of the fastest Dimension object created by left
Merge individual Dimension objects together from fastest to slowest
This means that Zipping a Spec producing stack [l2, l1] with a Spec producing stack [r1] will assert len(l1)==len(r1), and produce stack [l2, l1.zip(r1)].
# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Line spec = Fly(Line("z", 1, 2, 3) * Line("y", 3, 4, 5).zip(Line("x", 4, 5, 5))) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)Show JSON schema
{ "title": "Zip", "description": "Run two Specs in parallel, merging their midpoints together.\n\nTypically formed using `Spec.zip`.\n\nStacks of Dimension are merged by:\n\n- If right creates a stack of a single Dimension object of size 1, expand it to\n the size of the fastest Dimension object created by left\n- Merge individual Dimension objects together from fastest to slowest\n\nThis means that Zipping a Spec producing stack [l2, l1] with a Spec\nproducing stack [r1] will assert len(l1)==len(r1), and produce\nstack [l2, l1.zip(r1)].\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"z\", 1, 2, 3) * Line(\"y\", 3, 4, 5).zip(Line(\"x\", 4, 5, 5)))", "type": "object", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Zip, will appear earlier in axes" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Zip, will appear later in axes" }, "type": { "const": "Zip", "default": "Zip", "title": "Type", "type": "string" } }, "$defs": { "Circle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy circle of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Circle(\"x\", \"y\", 1, 2, 0.9)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the circle", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the circle", "title": "Y Middle", "type": "number" }, "radius": { "description": "Radius of the circle", "exclusiveMinimum": 0.0, "title": "Radius", "type": "number" }, "type": { "const": "Circle", "default": "Circle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "radius" ], "title": "Circle", "type": "object" }, "CombinationOf__Axis_": { "additionalProperties": false, "description": "Abstract baseclass for a combination of two regions, left and right.", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "CombinationOf", "default": "CombinationOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "CombinationOf", "type": "object" }, "Concat__Axis_": { "additionalProperties": false, "description": "Concatenate two Specs together, running one after the other.\n\nEach Dimension of left and right must contain the same axes. Typically\nformed using `Spec.concat`.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 3, 3).concat(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Concat, midpoints will appear earlier" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Concat, midpoints will appear later" }, "gap": { "default": false, "description": "If True, force a gap in the output at the join", "title": "Gap", "type": "boolean" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Concat", "default": "Concat", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Concat", "type": "object" }, "ConstantDuration__Axis_": { "additionalProperties": false, "description": "Apply a constant duration to every point in a Spec.\n\nTypically applied with the ``@`` modifier.\n\n.. example_spec::\n\n from scanspec.specs import Line\n\n spec = 0.1 @ Line(\"x\", 1, 2, 3)", "properties": { "constant_duration": { "description": "The value at each point", "title": "Constant Duration", "type": "number" }, "spec": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "null" } ], "default": null, "description": "Spec contaning the path to be followed" }, "type": { "const": "ConstantDuration", "default": "ConstantDuration", "title": "Type", "type": "string" } }, "required": [ "constant_duration" ], "title": "ConstantDuration", "type": "object" }, "DifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in DifferenceOf(a, b) if in a and not in b.\n\nTypically created with the ``-`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) - Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "DifferenceOf", "default": "DifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "DifferenceOf", "type": "object" }, "Ellipse__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy ellipse of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Ellipse\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Ellipse(\"x\", \"y\", 5, 5, 2, 3, 75)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the ellipse", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the ellipse", "title": "Y Middle", "type": "number" }, "x_radius": { "description": "The radius along the x axis of the ellipse", "exclusiveMinimum": 0.0, "title": "X Radius", "type": "number" }, "y_radius": { "description": "The radius along the y axis of the ellipse", "exclusiveMinimum": 0.0, "title": "Y Radius", "type": "number" }, "angle": { "default": 0.0, "description": "The angle of the ellipse (degrees)", "title": "Angle", "type": "number" }, "type": { "const": "Ellipse", "default": "Ellipse", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "x_radius", "y_radius" ], "title": "Ellipse", "type": "object" }, "Fly__Axis_": { "additionalProperties": false, "description": "Move through lower to upper bounds of the Spec rather than stopping.\n\nThis is commonly termed a \"fly scan\" rather than a \"step scan\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 3))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "Spec contaning the path to be followed" }, "type": { "const": "Fly", "default": "Fly", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Fly", "type": "object" }, "IntersectionOf__Axis_": { "additionalProperties": false, "description": "A point is in IntersectionOf(a, b) if in both a and b.\n\nTypically created with the ``&`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) & Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, False, True, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "IntersectionOf", "default": "IntersectionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "IntersectionOf", "type": "object" }, "Line__Axis_": { "additionalProperties": false, "description": "Linearly spaced frames with start and stop as first and last midpoints.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 5))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "start": { "description": "Midpoint of the first point of the line", "title": "Start", "type": "number" }, "stop": { "description": "Midpoint of the last point of the line", "title": "Stop", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Line", "default": "Line", "title": "Type", "type": "string" } }, "required": [ "axis", "start", "stop", "num" ], "title": "Line", "type": "object" }, "Mask__Axis_": { "additionalProperties": false, "description": "Restrict Spec to only midpoints that fall inside the given Region.\n\nTypically created with the ``&`` operator. It also pushes down the\n``& | ^ -`` operators to its `Region` to avoid the need for brackets on\ncombinations of Regions.\n\nIf a Region spans multiple Dimension objects, they will be squashed together.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Fly, Line\n\n region = Circle(\"x\", \"y\", 4, 2, 1.2)\n spec = Fly(Line(\"y\", 1, 3, 3) * Line(\"x\", 3, 5, 5) & region)\n\nSee Also: `why-squash-can-change-path`", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec containing the source midpoints" }, "region": { "$ref": "#/$defs/Region", "description": "The Region that midpoints will be inside" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Mask", "default": "Mask", "title": "Type", "type": "string" } }, "required": [ "spec", "region" ], "title": "Mask", "type": "object" }, "Polygon__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy polygon.\n\n.. example_spec::\n\n from scanspec.regions import Polygon\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Polygon(\"x\", \"y\", [1.0, 6.0, 8.0, 2.0], [4.0, 10.0, 6.0, 1.0])", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_verts": { "description": "The Nx1 x coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "X Verts", "type": "array" }, "y_verts": { "description": "The Nx1 y coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "Y Verts", "type": "array" }, "type": { "const": "Polygon", "default": "Polygon", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_verts", "y_verts" ], "title": "Polygon", "type": "object" }, "Product__Axis_": { "additionalProperties": false, "description": "Outer product of two Specs, nesting inner within outer.\n\nThis means that inner will run in its entirety at each point in outer.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * Line(\"x\", 3, 4, 12))\n\nAn inner integer can be used to repeat the same point many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * 2)\n\nAn outer integer can be used to repeat the same scan many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(2 * ~Line.bounded(\"x\", 3, 4, 1))\n\nIf you want snaked axes to have no gap between iterations you can do:\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Product\n\n spec = Fly(Product(2, ~Line.bounded(\"x\", 3, 4, 1), gap=False))\n\n.. note:: There is no turnaround arrow at x=4", "properties": { "outer": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed once", "title": "Outer" }, "inner": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed len(outer) times", "title": "Inner" }, "gap": { "default": true, "description": "If False and the outer spec is an integer and the inner spec is snaked then the end and start of consecutive iterations of inner will have no gap", "title": "Gap", "type": "boolean" }, "type": { "const": "Product", "default": "Product", "title": "Type", "type": "string" } }, "required": [ "outer", "inner" ], "title": "Product", "type": "object" }, "Range__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis >= min and <= max.\n\n>>> r = Range(\"x\", 1, 2)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, False, False])", "properties": { "axis": { "description": "The name matching the axis to mask in spec", "title": "Axis" }, "min": { "description": "The minimum inclusive value in the region", "title": "Min", "type": "number" }, "max": { "description": "The minimum inclusive value in the region", "title": "Max", "type": "number" }, "type": { "const": "Range", "default": "Range", "title": "Type", "type": "string" } }, "required": [ "axis", "min", "max" ], "title": "Range", "type": "object" }, "Rectangle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy rectangle.\n\n.. example_spec::\n\n from scanspec.regions import Rectangle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Rectangle(\"x\", \"y\", 0, 1.1, 1.5, 2.1, 30)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_min": { "description": "Minimum inclusive x value in the region", "title": "X Min", "type": "number" }, "y_min": { "description": "Minimum inclusive y value in the region", "title": "Y Min", "type": "number" }, "x_max": { "description": "Maximum inclusive x value in the region", "title": "X Max", "type": "number" }, "y_max": { "description": "Maximum inclusive y value in the region", "title": "Y Max", "type": "number" }, "angle": { "default": 0.0, "description": "Clockwise rotation angle of the rectangle", "title": "Angle", "type": "number" }, "type": { "const": "Rectangle", "default": "Rectangle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_min", "y_min", "x_max", "y_max" ], "title": "Rectangle", "type": "object" }, "Region": { "discriminator": { "mapping": { "Circle": "#/$defs/Circle__Axis_", "CombinationOf": "#/$defs/CombinationOf__Axis_", "DifferenceOf": "#/$defs/DifferenceOf__Axis_", "Ellipse": "#/$defs/Ellipse__Axis_", "IntersectionOf": "#/$defs/IntersectionOf__Axis_", "Polygon": "#/$defs/Polygon__Axis_", "Range": "#/$defs/Range__Axis_", "Rectangle": "#/$defs/Rectangle__Axis_", "SymmetricDifferenceOf": "#/$defs/SymmetricDifferenceOf__Axis_", "UnionOf": "#/$defs/UnionOf__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/CombinationOf__Axis_" }, { "$ref": "#/$defs/UnionOf__Axis_" }, { "$ref": "#/$defs/IntersectionOf__Axis_" }, { "$ref": "#/$defs/DifferenceOf__Axis_" }, { "$ref": "#/$defs/SymmetricDifferenceOf__Axis_" }, { "$ref": "#/$defs/Range__Axis_" }, { "$ref": "#/$defs/Rectangle__Axis_" }, { "$ref": "#/$defs/Polygon__Axis_" }, { "$ref": "#/$defs/Circle__Axis_" }, { "$ref": "#/$defs/Ellipse__Axis_" } ] }, "Snake__Axis_": { "additionalProperties": false, "description": "Run the Spec in reverse on every other iteration when nested.\n\nTypically created with the ``~`` operator.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 3, 3) * ~Line(\"x\", 3, 5, 5))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to run in reverse every other iteration" }, "type": { "const": "Snake", "default": "Snake", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Snake", "type": "object" }, "Spec": { "discriminator": { "mapping": { "Concat": "#/$defs/Concat__Axis_", "ConstantDuration": "#/$defs/ConstantDuration__Axis_", "Fly": "#/$defs/Fly__Axis_", "Line": "#/$defs/Line__Axis_", "Mask": "#/$defs/Mask__Axis_", "Product": "#/$defs/Product__Axis_", "Snake": "#/$defs/Snake__Axis_", "Spiral": "#/$defs/Spiral__Axis_", "Squash": "#/$defs/Squash__Axis_", "Static": "#/$defs/Static__Axis_", "Zip": "#/$defs/Zip__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/Product__Axis_" }, { "$ref": "#/$defs/Zip__Axis_" }, { "$ref": "#/$defs/Mask__Axis_" }, { "$ref": "#/$defs/Snake__Axis_" }, { "$ref": "#/$defs/Concat__Axis_" }, { "$ref": "#/$defs/Squash__Axis_" }, { "$ref": "#/$defs/Line__Axis_" }, { "$ref": "#/$defs/Fly__Axis_" }, { "$ref": "#/$defs/ConstantDuration__Axis_" }, { "$ref": "#/$defs/Static__Axis_" }, { "$ref": "#/$defs/Spiral__Axis_" } ] }, "Spiral__Axis_": { "additionalProperties": false, "description": "Archimedean spiral of \"x_axis\" and \"y_axis\".\n\nStarts at centre point (\"x_start\", \"y_start\") with angle \"rotate\". Produces\n\"num\" points in a spiral spanning width of \"x_range\" and height of \"y_range\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Spiral\n\n spec = Fly(Spiral(\"x\", \"y\", 1, 5, 10, 50, 30))", "properties": { "x_axis": { "description": "An identifier for what to move for x", "title": "X Axis" }, "y_axis": { "description": "An identifier for what to move for y", "title": "Y Axis" }, "x_start": { "description": "x centre of the spiral", "title": "X Start", "type": "number" }, "y_start": { "description": "y centre of the spiral", "title": "Y Start", "type": "number" }, "x_range": { "description": "x width of the spiral", "title": "X Range", "type": "number" }, "y_range": { "description": "y width of the spiral", "title": "Y Range", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "rotate": { "default": 0.0, "description": "How much to rotate the angle of the spiral", "title": "Rotate", "type": "number" }, "type": { "const": "Spiral", "default": "Spiral", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_start", "y_start", "x_range", "y_range", "num" ], "title": "Spiral", "type": "object" }, "Squash__Axis_": { "additionalProperties": false, "description": "Squash a stack of Dimension together into a single expanded Dimension object.\n\nSee Also:\n `why-squash-can-change-path`\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Squash\n\n spec = Fly(Squash(Line(\"y\", 1, 2, 3) * Line(\"x\", 0, 1, 4)))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to squash the dimensions of" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Squash", "default": "Squash", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Squash", "type": "object" }, "Static__Axis_": { "additionalProperties": false, "description": "A static frame, repeated num times, with axis at value.\n\nCan be used to set axis=value at every point in a scan.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Static\n\n spec = Fly(Line(\"y\", 1, 2, 3).zip(Static(\"x\", 3)))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "value": { "description": "The value at each point", "title": "Value", "type": "number" }, "num": { "default": 1, "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Static", "default": "Static", "title": "Type", "type": "string" } }, "required": [ "axis", "value" ], "title": "Static", "type": "object" }, "SymmetricDifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in SymmetricDifferenceOf(a, b) if in either a or b, but not both.\n\nTypically created with the ``^`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) ^ Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "SymmetricDifferenceOf", "default": "SymmetricDifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "SymmetricDifferenceOf", "type": "object" }, "UnionOf__Axis_": { "additionalProperties": false, "description": "A point is in UnionOf(a, b) if in either a or b.\n\nTypically created with the ``|`` operator\n\n>>> r = Range(\"x\", 0.5, 2.5) | Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "UnionOf", "default": "UnionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "UnionOf", "type": "object" }, "Zip__Axis_": { "additionalProperties": false, "description": "Run two Specs in parallel, merging their midpoints together.\n\nTypically formed using `Spec.zip`.\n\nStacks of Dimension are merged by:\n\n- If right creates a stack of a single Dimension object of size 1, expand it to\n the size of the fastest Dimension object created by left\n- Merge individual Dimension objects together from fastest to slowest\n\nThis means that Zipping a Spec producing stack [l2, l1] with a Spec\nproducing stack [r1] will assert len(l1)==len(r1), and produce\nstack [l2, l1.zip(r1)].\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"z\", 1, 2, 3) * Line(\"y\", 3, 4, 5).zip(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Zip, will appear earlier in axes" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Zip, will appear later in axes" }, "type": { "const": "Zip", "default": "Zip", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Zip", "type": "object" } }, "additionalProperties": false, "required": [ "left", "right" ] }
- Fields:
- axes() list[Axis] [source]#
Return the list of axes that are present in the scan.
Ordered from slowest moving to fastest moving.
- pydantic model scanspec.specs.Mask[source]#
Restrict Spec to only midpoints that fall inside the given Region.
Typically created with the
&
operator. It also pushes down the& | ^ -
operators to itsRegion
to avoid the need for brackets on combinations of Regions.If a Region spans multiple Dimension objects, they will be squashed together.
# Example Spec from scanspec.plot import plot_spec from scanspec.regions import Circle from scanspec.specs import Fly, Line region = Circle("x", "y", 4, 2, 1.2) spec = Fly(Line("y", 1, 3, 3) * Line("x", 3, 5, 5) & region) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)See Also: Why Squash (and Mask) can change the Path
Show JSON schema
{ "title": "Mask", "description": "Restrict Spec to only midpoints that fall inside the given Region.\n\nTypically created with the ``&`` operator. It also pushes down the\n``& | ^ -`` operators to its `Region` to avoid the need for brackets on\ncombinations of Regions.\n\nIf a Region spans multiple Dimension objects, they will be squashed together.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Fly, Line\n\n region = Circle(\"x\", \"y\", 4, 2, 1.2)\n spec = Fly(Line(\"y\", 1, 3, 3) * Line(\"x\", 3, 5, 5) & region)\n\nSee Also: `why-squash-can-change-path`", "type": "object", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec containing the source midpoints" }, "region": { "$ref": "#/$defs/Region", "description": "The Region that midpoints will be inside" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Mask", "default": "Mask", "title": "Type", "type": "string" } }, "$defs": { "Circle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy circle of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Circle(\"x\", \"y\", 1, 2, 0.9)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the circle", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the circle", "title": "Y Middle", "type": "number" }, "radius": { "description": "Radius of the circle", "exclusiveMinimum": 0.0, "title": "Radius", "type": "number" }, "type": { "const": "Circle", "default": "Circle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "radius" ], "title": "Circle", "type": "object" }, "CombinationOf__Axis_": { "additionalProperties": false, "description": "Abstract baseclass for a combination of two regions, left and right.", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "CombinationOf", "default": "CombinationOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "CombinationOf", "type": "object" }, "Concat__Axis_": { "additionalProperties": false, "description": "Concatenate two Specs together, running one after the other.\n\nEach Dimension of left and right must contain the same axes. Typically\nformed using `Spec.concat`.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 3, 3).concat(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Concat, midpoints will appear earlier" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Concat, midpoints will appear later" }, "gap": { "default": false, "description": "If True, force a gap in the output at the join", "title": "Gap", "type": "boolean" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Concat", "default": "Concat", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Concat", "type": "object" }, "ConstantDuration__Axis_": { "additionalProperties": false, "description": "Apply a constant duration to every point in a Spec.\n\nTypically applied with the ``@`` modifier.\n\n.. example_spec::\n\n from scanspec.specs import Line\n\n spec = 0.1 @ Line(\"x\", 1, 2, 3)", "properties": { "constant_duration": { "description": "The value at each point", "title": "Constant Duration", "type": "number" }, "spec": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "null" } ], "default": null, "description": "Spec contaning the path to be followed" }, "type": { "const": "ConstantDuration", "default": "ConstantDuration", "title": "Type", "type": "string" } }, "required": [ "constant_duration" ], "title": "ConstantDuration", "type": "object" }, "DifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in DifferenceOf(a, b) if in a and not in b.\n\nTypically created with the ``-`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) - Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "DifferenceOf", "default": "DifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "DifferenceOf", "type": "object" }, "Ellipse__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy ellipse of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Ellipse\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Ellipse(\"x\", \"y\", 5, 5, 2, 3, 75)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the ellipse", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the ellipse", "title": "Y Middle", "type": "number" }, "x_radius": { "description": "The radius along the x axis of the ellipse", "exclusiveMinimum": 0.0, "title": "X Radius", "type": "number" }, "y_radius": { "description": "The radius along the y axis of the ellipse", "exclusiveMinimum": 0.0, "title": "Y Radius", "type": "number" }, "angle": { "default": 0.0, "description": "The angle of the ellipse (degrees)", "title": "Angle", "type": "number" }, "type": { "const": "Ellipse", "default": "Ellipse", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "x_radius", "y_radius" ], "title": "Ellipse", "type": "object" }, "Fly__Axis_": { "additionalProperties": false, "description": "Move through lower to upper bounds of the Spec rather than stopping.\n\nThis is commonly termed a \"fly scan\" rather than a \"step scan\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 3))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "Spec contaning the path to be followed" }, "type": { "const": "Fly", "default": "Fly", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Fly", "type": "object" }, "IntersectionOf__Axis_": { "additionalProperties": false, "description": "A point is in IntersectionOf(a, b) if in both a and b.\n\nTypically created with the ``&`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) & Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, False, True, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "IntersectionOf", "default": "IntersectionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "IntersectionOf", "type": "object" }, "Line__Axis_": { "additionalProperties": false, "description": "Linearly spaced frames with start and stop as first and last midpoints.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 5))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "start": { "description": "Midpoint of the first point of the line", "title": "Start", "type": "number" }, "stop": { "description": "Midpoint of the last point of the line", "title": "Stop", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Line", "default": "Line", "title": "Type", "type": "string" } }, "required": [ "axis", "start", "stop", "num" ], "title": "Line", "type": "object" }, "Mask__Axis_": { "additionalProperties": false, "description": "Restrict Spec to only midpoints that fall inside the given Region.\n\nTypically created with the ``&`` operator. It also pushes down the\n``& | ^ -`` operators to its `Region` to avoid the need for brackets on\ncombinations of Regions.\n\nIf a Region spans multiple Dimension objects, they will be squashed together.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Fly, Line\n\n region = Circle(\"x\", \"y\", 4, 2, 1.2)\n spec = Fly(Line(\"y\", 1, 3, 3) * Line(\"x\", 3, 5, 5) & region)\n\nSee Also: `why-squash-can-change-path`", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec containing the source midpoints" }, "region": { "$ref": "#/$defs/Region", "description": "The Region that midpoints will be inside" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Mask", "default": "Mask", "title": "Type", "type": "string" } }, "required": [ "spec", "region" ], "title": "Mask", "type": "object" }, "Polygon__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy polygon.\n\n.. example_spec::\n\n from scanspec.regions import Polygon\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Polygon(\"x\", \"y\", [1.0, 6.0, 8.0, 2.0], [4.0, 10.0, 6.0, 1.0])", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_verts": { "description": "The Nx1 x coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "X Verts", "type": "array" }, "y_verts": { "description": "The Nx1 y coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "Y Verts", "type": "array" }, "type": { "const": "Polygon", "default": "Polygon", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_verts", "y_verts" ], "title": "Polygon", "type": "object" }, "Product__Axis_": { "additionalProperties": false, "description": "Outer product of two Specs, nesting inner within outer.\n\nThis means that inner will run in its entirety at each point in outer.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * Line(\"x\", 3, 4, 12))\n\nAn inner integer can be used to repeat the same point many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * 2)\n\nAn outer integer can be used to repeat the same scan many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(2 * ~Line.bounded(\"x\", 3, 4, 1))\n\nIf you want snaked axes to have no gap between iterations you can do:\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Product\n\n spec = Fly(Product(2, ~Line.bounded(\"x\", 3, 4, 1), gap=False))\n\n.. note:: There is no turnaround arrow at x=4", "properties": { "outer": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed once", "title": "Outer" }, "inner": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed len(outer) times", "title": "Inner" }, "gap": { "default": true, "description": "If False and the outer spec is an integer and the inner spec is snaked then the end and start of consecutive iterations of inner will have no gap", "title": "Gap", "type": "boolean" }, "type": { "const": "Product", "default": "Product", "title": "Type", "type": "string" } }, "required": [ "outer", "inner" ], "title": "Product", "type": "object" }, "Range__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis >= min and <= max.\n\n>>> r = Range(\"x\", 1, 2)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, False, False])", "properties": { "axis": { "description": "The name matching the axis to mask in spec", "title": "Axis" }, "min": { "description": "The minimum inclusive value in the region", "title": "Min", "type": "number" }, "max": { "description": "The minimum inclusive value in the region", "title": "Max", "type": "number" }, "type": { "const": "Range", "default": "Range", "title": "Type", "type": "string" } }, "required": [ "axis", "min", "max" ], "title": "Range", "type": "object" }, "Rectangle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy rectangle.\n\n.. example_spec::\n\n from scanspec.regions import Rectangle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Rectangle(\"x\", \"y\", 0, 1.1, 1.5, 2.1, 30)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_min": { "description": "Minimum inclusive x value in the region", "title": "X Min", "type": "number" }, "y_min": { "description": "Minimum inclusive y value in the region", "title": "Y Min", "type": "number" }, "x_max": { "description": "Maximum inclusive x value in the region", "title": "X Max", "type": "number" }, "y_max": { "description": "Maximum inclusive y value in the region", "title": "Y Max", "type": "number" }, "angle": { "default": 0.0, "description": "Clockwise rotation angle of the rectangle", "title": "Angle", "type": "number" }, "type": { "const": "Rectangle", "default": "Rectangle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_min", "y_min", "x_max", "y_max" ], "title": "Rectangle", "type": "object" }, "Region": { "discriminator": { "mapping": { "Circle": "#/$defs/Circle__Axis_", "CombinationOf": "#/$defs/CombinationOf__Axis_", "DifferenceOf": "#/$defs/DifferenceOf__Axis_", "Ellipse": "#/$defs/Ellipse__Axis_", "IntersectionOf": "#/$defs/IntersectionOf__Axis_", "Polygon": "#/$defs/Polygon__Axis_", "Range": "#/$defs/Range__Axis_", "Rectangle": "#/$defs/Rectangle__Axis_", "SymmetricDifferenceOf": "#/$defs/SymmetricDifferenceOf__Axis_", "UnionOf": "#/$defs/UnionOf__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/CombinationOf__Axis_" }, { "$ref": "#/$defs/UnionOf__Axis_" }, { "$ref": "#/$defs/IntersectionOf__Axis_" }, { "$ref": "#/$defs/DifferenceOf__Axis_" }, { "$ref": "#/$defs/SymmetricDifferenceOf__Axis_" }, { "$ref": "#/$defs/Range__Axis_" }, { "$ref": "#/$defs/Rectangle__Axis_" }, { "$ref": "#/$defs/Polygon__Axis_" }, { "$ref": "#/$defs/Circle__Axis_" }, { "$ref": "#/$defs/Ellipse__Axis_" } ] }, "Snake__Axis_": { "additionalProperties": false, "description": "Run the Spec in reverse on every other iteration when nested.\n\nTypically created with the ``~`` operator.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 3, 3) * ~Line(\"x\", 3, 5, 5))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to run in reverse every other iteration" }, "type": { "const": "Snake", "default": "Snake", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Snake", "type": "object" }, "Spec": { "discriminator": { "mapping": { "Concat": "#/$defs/Concat__Axis_", "ConstantDuration": "#/$defs/ConstantDuration__Axis_", "Fly": "#/$defs/Fly__Axis_", "Line": "#/$defs/Line__Axis_", "Mask": "#/$defs/Mask__Axis_", "Product": "#/$defs/Product__Axis_", "Snake": "#/$defs/Snake__Axis_", "Spiral": "#/$defs/Spiral__Axis_", "Squash": "#/$defs/Squash__Axis_", "Static": "#/$defs/Static__Axis_", "Zip": "#/$defs/Zip__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/Product__Axis_" }, { "$ref": "#/$defs/Zip__Axis_" }, { "$ref": "#/$defs/Mask__Axis_" }, { "$ref": "#/$defs/Snake__Axis_" }, { "$ref": "#/$defs/Concat__Axis_" }, { "$ref": "#/$defs/Squash__Axis_" }, { "$ref": "#/$defs/Line__Axis_" }, { "$ref": "#/$defs/Fly__Axis_" }, { "$ref": "#/$defs/ConstantDuration__Axis_" }, { "$ref": "#/$defs/Static__Axis_" }, { "$ref": "#/$defs/Spiral__Axis_" } ] }, "Spiral__Axis_": { "additionalProperties": false, "description": "Archimedean spiral of \"x_axis\" and \"y_axis\".\n\nStarts at centre point (\"x_start\", \"y_start\") with angle \"rotate\". Produces\n\"num\" points in a spiral spanning width of \"x_range\" and height of \"y_range\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Spiral\n\n spec = Fly(Spiral(\"x\", \"y\", 1, 5, 10, 50, 30))", "properties": { "x_axis": { "description": "An identifier for what to move for x", "title": "X Axis" }, "y_axis": { "description": "An identifier for what to move for y", "title": "Y Axis" }, "x_start": { "description": "x centre of the spiral", "title": "X Start", "type": "number" }, "y_start": { "description": "y centre of the spiral", "title": "Y Start", "type": "number" }, "x_range": { "description": "x width of the spiral", "title": "X Range", "type": "number" }, "y_range": { "description": "y width of the spiral", "title": "Y Range", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "rotate": { "default": 0.0, "description": "How much to rotate the angle of the spiral", "title": "Rotate", "type": "number" }, "type": { "const": "Spiral", "default": "Spiral", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_start", "y_start", "x_range", "y_range", "num" ], "title": "Spiral", "type": "object" }, "Squash__Axis_": { "additionalProperties": false, "description": "Squash a stack of Dimension together into a single expanded Dimension object.\n\nSee Also:\n `why-squash-can-change-path`\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Squash\n\n spec = Fly(Squash(Line(\"y\", 1, 2, 3) * Line(\"x\", 0, 1, 4)))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to squash the dimensions of" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Squash", "default": "Squash", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Squash", "type": "object" }, "Static__Axis_": { "additionalProperties": false, "description": "A static frame, repeated num times, with axis at value.\n\nCan be used to set axis=value at every point in a scan.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Static\n\n spec = Fly(Line(\"y\", 1, 2, 3).zip(Static(\"x\", 3)))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "value": { "description": "The value at each point", "title": "Value", "type": "number" }, "num": { "default": 1, "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Static", "default": "Static", "title": "Type", "type": "string" } }, "required": [ "axis", "value" ], "title": "Static", "type": "object" }, "SymmetricDifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in SymmetricDifferenceOf(a, b) if in either a or b, but not both.\n\nTypically created with the ``^`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) ^ Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "SymmetricDifferenceOf", "default": "SymmetricDifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "SymmetricDifferenceOf", "type": "object" }, "UnionOf__Axis_": { "additionalProperties": false, "description": "A point is in UnionOf(a, b) if in either a or b.\n\nTypically created with the ``|`` operator\n\n>>> r = Range(\"x\", 0.5, 2.5) | Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "UnionOf", "default": "UnionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "UnionOf", "type": "object" }, "Zip__Axis_": { "additionalProperties": false, "description": "Run two Specs in parallel, merging their midpoints together.\n\nTypically formed using `Spec.zip`.\n\nStacks of Dimension are merged by:\n\n- If right creates a stack of a single Dimension object of size 1, expand it to\n the size of the fastest Dimension object created by left\n- Merge individual Dimension objects together from fastest to slowest\n\nThis means that Zipping a Spec producing stack [l2, l1] with a Spec\nproducing stack [r1] will assert len(l1)==len(r1), and produce\nstack [l2, l1.zip(r1)].\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"z\", 1, 2, 3) * Line(\"y\", 3, 4, 5).zip(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Zip, will appear earlier in axes" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Zip, will appear later in axes" }, "type": { "const": "Zip", "default": "Zip", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Zip", "type": "object" } }, "additionalProperties": false, "required": [ "spec", "region" ] }
- Fields:
- axes() list[Axis] [source]#
Return the list of axes that are present in the scan.
Ordered from slowest moving to fastest moving.
- pydantic model scanspec.specs.Snake[source]#
Run the Spec in reverse on every other iteration when nested.
Typically created with the
~
operator.# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Line spec = Fly(Line("y", 1, 3, 3) * ~Line("x", 3, 5, 5)) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)Show JSON schema
{ "title": "Snake", "description": "Run the Spec in reverse on every other iteration when nested.\n\nTypically created with the ``~`` operator.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 3, 3) * ~Line(\"x\", 3, 5, 5))", "type": "object", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to run in reverse every other iteration" }, "type": { "const": "Snake", "default": "Snake", "title": "Type", "type": "string" } }, "$defs": { "Circle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy circle of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Circle(\"x\", \"y\", 1, 2, 0.9)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the circle", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the circle", "title": "Y Middle", "type": "number" }, "radius": { "description": "Radius of the circle", "exclusiveMinimum": 0.0, "title": "Radius", "type": "number" }, "type": { "const": "Circle", "default": "Circle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "radius" ], "title": "Circle", "type": "object" }, "CombinationOf__Axis_": { "additionalProperties": false, "description": "Abstract baseclass for a combination of two regions, left and right.", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "CombinationOf", "default": "CombinationOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "CombinationOf", "type": "object" }, "Concat__Axis_": { "additionalProperties": false, "description": "Concatenate two Specs together, running one after the other.\n\nEach Dimension of left and right must contain the same axes. Typically\nformed using `Spec.concat`.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 3, 3).concat(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Concat, midpoints will appear earlier" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Concat, midpoints will appear later" }, "gap": { "default": false, "description": "If True, force a gap in the output at the join", "title": "Gap", "type": "boolean" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Concat", "default": "Concat", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Concat", "type": "object" }, "ConstantDuration__Axis_": { "additionalProperties": false, "description": "Apply a constant duration to every point in a Spec.\n\nTypically applied with the ``@`` modifier.\n\n.. example_spec::\n\n from scanspec.specs import Line\n\n spec = 0.1 @ Line(\"x\", 1, 2, 3)", "properties": { "constant_duration": { "description": "The value at each point", "title": "Constant Duration", "type": "number" }, "spec": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "null" } ], "default": null, "description": "Spec contaning the path to be followed" }, "type": { "const": "ConstantDuration", "default": "ConstantDuration", "title": "Type", "type": "string" } }, "required": [ "constant_duration" ], "title": "ConstantDuration", "type": "object" }, "DifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in DifferenceOf(a, b) if in a and not in b.\n\nTypically created with the ``-`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) - Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "DifferenceOf", "default": "DifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "DifferenceOf", "type": "object" }, "Ellipse__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy ellipse of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Ellipse\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Ellipse(\"x\", \"y\", 5, 5, 2, 3, 75)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the ellipse", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the ellipse", "title": "Y Middle", "type": "number" }, "x_radius": { "description": "The radius along the x axis of the ellipse", "exclusiveMinimum": 0.0, "title": "X Radius", "type": "number" }, "y_radius": { "description": "The radius along the y axis of the ellipse", "exclusiveMinimum": 0.0, "title": "Y Radius", "type": "number" }, "angle": { "default": 0.0, "description": "The angle of the ellipse (degrees)", "title": "Angle", "type": "number" }, "type": { "const": "Ellipse", "default": "Ellipse", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "x_radius", "y_radius" ], "title": "Ellipse", "type": "object" }, "Fly__Axis_": { "additionalProperties": false, "description": "Move through lower to upper bounds of the Spec rather than stopping.\n\nThis is commonly termed a \"fly scan\" rather than a \"step scan\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 3))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "Spec contaning the path to be followed" }, "type": { "const": "Fly", "default": "Fly", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Fly", "type": "object" }, "IntersectionOf__Axis_": { "additionalProperties": false, "description": "A point is in IntersectionOf(a, b) if in both a and b.\n\nTypically created with the ``&`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) & Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, False, True, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "IntersectionOf", "default": "IntersectionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "IntersectionOf", "type": "object" }, "Line__Axis_": { "additionalProperties": false, "description": "Linearly spaced frames with start and stop as first and last midpoints.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 5))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "start": { "description": "Midpoint of the first point of the line", "title": "Start", "type": "number" }, "stop": { "description": "Midpoint of the last point of the line", "title": "Stop", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Line", "default": "Line", "title": "Type", "type": "string" } }, "required": [ "axis", "start", "stop", "num" ], "title": "Line", "type": "object" }, "Mask__Axis_": { "additionalProperties": false, "description": "Restrict Spec to only midpoints that fall inside the given Region.\n\nTypically created with the ``&`` operator. It also pushes down the\n``& | ^ -`` operators to its `Region` to avoid the need for brackets on\ncombinations of Regions.\n\nIf a Region spans multiple Dimension objects, they will be squashed together.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Fly, Line\n\n region = Circle(\"x\", \"y\", 4, 2, 1.2)\n spec = Fly(Line(\"y\", 1, 3, 3) * Line(\"x\", 3, 5, 5) & region)\n\nSee Also: `why-squash-can-change-path`", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec containing the source midpoints" }, "region": { "$ref": "#/$defs/Region", "description": "The Region that midpoints will be inside" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Mask", "default": "Mask", "title": "Type", "type": "string" } }, "required": [ "spec", "region" ], "title": "Mask", "type": "object" }, "Polygon__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy polygon.\n\n.. example_spec::\n\n from scanspec.regions import Polygon\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Polygon(\"x\", \"y\", [1.0, 6.0, 8.0, 2.0], [4.0, 10.0, 6.0, 1.0])", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_verts": { "description": "The Nx1 x coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "X Verts", "type": "array" }, "y_verts": { "description": "The Nx1 y coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "Y Verts", "type": "array" }, "type": { "const": "Polygon", "default": "Polygon", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_verts", "y_verts" ], "title": "Polygon", "type": "object" }, "Product__Axis_": { "additionalProperties": false, "description": "Outer product of two Specs, nesting inner within outer.\n\nThis means that inner will run in its entirety at each point in outer.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * Line(\"x\", 3, 4, 12))\n\nAn inner integer can be used to repeat the same point many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * 2)\n\nAn outer integer can be used to repeat the same scan many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(2 * ~Line.bounded(\"x\", 3, 4, 1))\n\nIf you want snaked axes to have no gap between iterations you can do:\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Product\n\n spec = Fly(Product(2, ~Line.bounded(\"x\", 3, 4, 1), gap=False))\n\n.. note:: There is no turnaround arrow at x=4", "properties": { "outer": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed once", "title": "Outer" }, "inner": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed len(outer) times", "title": "Inner" }, "gap": { "default": true, "description": "If False and the outer spec is an integer and the inner spec is snaked then the end and start of consecutive iterations of inner will have no gap", "title": "Gap", "type": "boolean" }, "type": { "const": "Product", "default": "Product", "title": "Type", "type": "string" } }, "required": [ "outer", "inner" ], "title": "Product", "type": "object" }, "Range__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis >= min and <= max.\n\n>>> r = Range(\"x\", 1, 2)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, False, False])", "properties": { "axis": { "description": "The name matching the axis to mask in spec", "title": "Axis" }, "min": { "description": "The minimum inclusive value in the region", "title": "Min", "type": "number" }, "max": { "description": "The minimum inclusive value in the region", "title": "Max", "type": "number" }, "type": { "const": "Range", "default": "Range", "title": "Type", "type": "string" } }, "required": [ "axis", "min", "max" ], "title": "Range", "type": "object" }, "Rectangle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy rectangle.\n\n.. example_spec::\n\n from scanspec.regions import Rectangle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Rectangle(\"x\", \"y\", 0, 1.1, 1.5, 2.1, 30)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_min": { "description": "Minimum inclusive x value in the region", "title": "X Min", "type": "number" }, "y_min": { "description": "Minimum inclusive y value in the region", "title": "Y Min", "type": "number" }, "x_max": { "description": "Maximum inclusive x value in the region", "title": "X Max", "type": "number" }, "y_max": { "description": "Maximum inclusive y value in the region", "title": "Y Max", "type": "number" }, "angle": { "default": 0.0, "description": "Clockwise rotation angle of the rectangle", "title": "Angle", "type": "number" }, "type": { "const": "Rectangle", "default": "Rectangle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_min", "y_min", "x_max", "y_max" ], "title": "Rectangle", "type": "object" }, "Region": { "discriminator": { "mapping": { "Circle": "#/$defs/Circle__Axis_", "CombinationOf": "#/$defs/CombinationOf__Axis_", "DifferenceOf": "#/$defs/DifferenceOf__Axis_", "Ellipse": "#/$defs/Ellipse__Axis_", "IntersectionOf": "#/$defs/IntersectionOf__Axis_", "Polygon": "#/$defs/Polygon__Axis_", "Range": "#/$defs/Range__Axis_", "Rectangle": "#/$defs/Rectangle__Axis_", "SymmetricDifferenceOf": "#/$defs/SymmetricDifferenceOf__Axis_", "UnionOf": "#/$defs/UnionOf__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/CombinationOf__Axis_" }, { "$ref": "#/$defs/UnionOf__Axis_" }, { "$ref": "#/$defs/IntersectionOf__Axis_" }, { "$ref": "#/$defs/DifferenceOf__Axis_" }, { "$ref": "#/$defs/SymmetricDifferenceOf__Axis_" }, { "$ref": "#/$defs/Range__Axis_" }, { "$ref": "#/$defs/Rectangle__Axis_" }, { "$ref": "#/$defs/Polygon__Axis_" }, { "$ref": "#/$defs/Circle__Axis_" }, { "$ref": "#/$defs/Ellipse__Axis_" } ] }, "Snake__Axis_": { "additionalProperties": false, "description": "Run the Spec in reverse on every other iteration when nested.\n\nTypically created with the ``~`` operator.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 3, 3) * ~Line(\"x\", 3, 5, 5))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to run in reverse every other iteration" }, "type": { "const": "Snake", "default": "Snake", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Snake", "type": "object" }, "Spec": { "discriminator": { "mapping": { "Concat": "#/$defs/Concat__Axis_", "ConstantDuration": "#/$defs/ConstantDuration__Axis_", "Fly": "#/$defs/Fly__Axis_", "Line": "#/$defs/Line__Axis_", "Mask": "#/$defs/Mask__Axis_", "Product": "#/$defs/Product__Axis_", "Snake": "#/$defs/Snake__Axis_", "Spiral": "#/$defs/Spiral__Axis_", "Squash": "#/$defs/Squash__Axis_", "Static": "#/$defs/Static__Axis_", "Zip": "#/$defs/Zip__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/Product__Axis_" }, { "$ref": "#/$defs/Zip__Axis_" }, { "$ref": "#/$defs/Mask__Axis_" }, { "$ref": "#/$defs/Snake__Axis_" }, { "$ref": "#/$defs/Concat__Axis_" }, { "$ref": "#/$defs/Squash__Axis_" }, { "$ref": "#/$defs/Line__Axis_" }, { "$ref": "#/$defs/Fly__Axis_" }, { "$ref": "#/$defs/ConstantDuration__Axis_" }, { "$ref": "#/$defs/Static__Axis_" }, { "$ref": "#/$defs/Spiral__Axis_" } ] }, "Spiral__Axis_": { "additionalProperties": false, "description": "Archimedean spiral of \"x_axis\" and \"y_axis\".\n\nStarts at centre point (\"x_start\", \"y_start\") with angle \"rotate\". Produces\n\"num\" points in a spiral spanning width of \"x_range\" and height of \"y_range\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Spiral\n\n spec = Fly(Spiral(\"x\", \"y\", 1, 5, 10, 50, 30))", "properties": { "x_axis": { "description": "An identifier for what to move for x", "title": "X Axis" }, "y_axis": { "description": "An identifier for what to move for y", "title": "Y Axis" }, "x_start": { "description": "x centre of the spiral", "title": "X Start", "type": "number" }, "y_start": { "description": "y centre of the spiral", "title": "Y Start", "type": "number" }, "x_range": { "description": "x width of the spiral", "title": "X Range", "type": "number" }, "y_range": { "description": "y width of the spiral", "title": "Y Range", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "rotate": { "default": 0.0, "description": "How much to rotate the angle of the spiral", "title": "Rotate", "type": "number" }, "type": { "const": "Spiral", "default": "Spiral", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_start", "y_start", "x_range", "y_range", "num" ], "title": "Spiral", "type": "object" }, "Squash__Axis_": { "additionalProperties": false, "description": "Squash a stack of Dimension together into a single expanded Dimension object.\n\nSee Also:\n `why-squash-can-change-path`\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Squash\n\n spec = Fly(Squash(Line(\"y\", 1, 2, 3) * Line(\"x\", 0, 1, 4)))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to squash the dimensions of" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Squash", "default": "Squash", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Squash", "type": "object" }, "Static__Axis_": { "additionalProperties": false, "description": "A static frame, repeated num times, with axis at value.\n\nCan be used to set axis=value at every point in a scan.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Static\n\n spec = Fly(Line(\"y\", 1, 2, 3).zip(Static(\"x\", 3)))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "value": { "description": "The value at each point", "title": "Value", "type": "number" }, "num": { "default": 1, "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Static", "default": "Static", "title": "Type", "type": "string" } }, "required": [ "axis", "value" ], "title": "Static", "type": "object" }, "SymmetricDifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in SymmetricDifferenceOf(a, b) if in either a or b, but not both.\n\nTypically created with the ``^`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) ^ Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "SymmetricDifferenceOf", "default": "SymmetricDifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "SymmetricDifferenceOf", "type": "object" }, "UnionOf__Axis_": { "additionalProperties": false, "description": "A point is in UnionOf(a, b) if in either a or b.\n\nTypically created with the ``|`` operator\n\n>>> r = Range(\"x\", 0.5, 2.5) | Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "UnionOf", "default": "UnionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "UnionOf", "type": "object" }, "Zip__Axis_": { "additionalProperties": false, "description": "Run two Specs in parallel, merging their midpoints together.\n\nTypically formed using `Spec.zip`.\n\nStacks of Dimension are merged by:\n\n- If right creates a stack of a single Dimension object of size 1, expand it to\n the size of the fastest Dimension object created by left\n- Merge individual Dimension objects together from fastest to slowest\n\nThis means that Zipping a Spec producing stack [l2, l1] with a Spec\nproducing stack [r1] will assert len(l1)==len(r1), and produce\nstack [l2, l1.zip(r1)].\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"z\", 1, 2, 3) * Line(\"y\", 3, 4, 5).zip(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Zip, will appear earlier in axes" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Zip, will appear later in axes" }, "type": { "const": "Zip", "default": "Zip", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Zip", "type": "object" } }, "additionalProperties": false, "required": [ "spec" ] }
- axes() list[Axis] [source]#
Return the list of axes that are present in the scan.
Ordered from slowest moving to fastest moving.
- pydantic model scanspec.specs.Concat[source]#
Concatenate two Specs together, running one after the other.
Each Dimension of left and right must contain the same axes. Typically formed using
Spec.concat
.# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Line spec = Fly(Line("x", 1, 3, 3).concat(Line("x", 4, 5, 5))) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)Show JSON schema
{ "title": "Concat", "description": "Concatenate two Specs together, running one after the other.\n\nEach Dimension of left and right must contain the same axes. Typically\nformed using `Spec.concat`.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 3, 3).concat(Line(\"x\", 4, 5, 5)))", "type": "object", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Concat, midpoints will appear earlier" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Concat, midpoints will appear later" }, "gap": { "default": false, "description": "If True, force a gap in the output at the join", "title": "Gap", "type": "boolean" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Concat", "default": "Concat", "title": "Type", "type": "string" } }, "$defs": { "Circle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy circle of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Circle(\"x\", \"y\", 1, 2, 0.9)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the circle", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the circle", "title": "Y Middle", "type": "number" }, "radius": { "description": "Radius of the circle", "exclusiveMinimum": 0.0, "title": "Radius", "type": "number" }, "type": { "const": "Circle", "default": "Circle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "radius" ], "title": "Circle", "type": "object" }, "CombinationOf__Axis_": { "additionalProperties": false, "description": "Abstract baseclass for a combination of two regions, left and right.", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "CombinationOf", "default": "CombinationOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "CombinationOf", "type": "object" }, "Concat__Axis_": { "additionalProperties": false, "description": "Concatenate two Specs together, running one after the other.\n\nEach Dimension of left and right must contain the same axes. Typically\nformed using `Spec.concat`.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 3, 3).concat(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Concat, midpoints will appear earlier" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Concat, midpoints will appear later" }, "gap": { "default": false, "description": "If True, force a gap in the output at the join", "title": "Gap", "type": "boolean" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Concat", "default": "Concat", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Concat", "type": "object" }, "ConstantDuration__Axis_": { "additionalProperties": false, "description": "Apply a constant duration to every point in a Spec.\n\nTypically applied with the ``@`` modifier.\n\n.. example_spec::\n\n from scanspec.specs import Line\n\n spec = 0.1 @ Line(\"x\", 1, 2, 3)", "properties": { "constant_duration": { "description": "The value at each point", "title": "Constant Duration", "type": "number" }, "spec": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "null" } ], "default": null, "description": "Spec contaning the path to be followed" }, "type": { "const": "ConstantDuration", "default": "ConstantDuration", "title": "Type", "type": "string" } }, "required": [ "constant_duration" ], "title": "ConstantDuration", "type": "object" }, "DifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in DifferenceOf(a, b) if in a and not in b.\n\nTypically created with the ``-`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) - Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "DifferenceOf", "default": "DifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "DifferenceOf", "type": "object" }, "Ellipse__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy ellipse of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Ellipse\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Ellipse(\"x\", \"y\", 5, 5, 2, 3, 75)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the ellipse", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the ellipse", "title": "Y Middle", "type": "number" }, "x_radius": { "description": "The radius along the x axis of the ellipse", "exclusiveMinimum": 0.0, "title": "X Radius", "type": "number" }, "y_radius": { "description": "The radius along the y axis of the ellipse", "exclusiveMinimum": 0.0, "title": "Y Radius", "type": "number" }, "angle": { "default": 0.0, "description": "The angle of the ellipse (degrees)", "title": "Angle", "type": "number" }, "type": { "const": "Ellipse", "default": "Ellipse", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "x_radius", "y_radius" ], "title": "Ellipse", "type": "object" }, "Fly__Axis_": { "additionalProperties": false, "description": "Move through lower to upper bounds of the Spec rather than stopping.\n\nThis is commonly termed a \"fly scan\" rather than a \"step scan\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 3))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "Spec contaning the path to be followed" }, "type": { "const": "Fly", "default": "Fly", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Fly", "type": "object" }, "IntersectionOf__Axis_": { "additionalProperties": false, "description": "A point is in IntersectionOf(a, b) if in both a and b.\n\nTypically created with the ``&`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) & Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, False, True, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "IntersectionOf", "default": "IntersectionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "IntersectionOf", "type": "object" }, "Line__Axis_": { "additionalProperties": false, "description": "Linearly spaced frames with start and stop as first and last midpoints.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 5))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "start": { "description": "Midpoint of the first point of the line", "title": "Start", "type": "number" }, "stop": { "description": "Midpoint of the last point of the line", "title": "Stop", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Line", "default": "Line", "title": "Type", "type": "string" } }, "required": [ "axis", "start", "stop", "num" ], "title": "Line", "type": "object" }, "Mask__Axis_": { "additionalProperties": false, "description": "Restrict Spec to only midpoints that fall inside the given Region.\n\nTypically created with the ``&`` operator. It also pushes down the\n``& | ^ -`` operators to its `Region` to avoid the need for brackets on\ncombinations of Regions.\n\nIf a Region spans multiple Dimension objects, they will be squashed together.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Fly, Line\n\n region = Circle(\"x\", \"y\", 4, 2, 1.2)\n spec = Fly(Line(\"y\", 1, 3, 3) * Line(\"x\", 3, 5, 5) & region)\n\nSee Also: `why-squash-can-change-path`", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec containing the source midpoints" }, "region": { "$ref": "#/$defs/Region", "description": "The Region that midpoints will be inside" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Mask", "default": "Mask", "title": "Type", "type": "string" } }, "required": [ "spec", "region" ], "title": "Mask", "type": "object" }, "Polygon__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy polygon.\n\n.. example_spec::\n\n from scanspec.regions import Polygon\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Polygon(\"x\", \"y\", [1.0, 6.0, 8.0, 2.0], [4.0, 10.0, 6.0, 1.0])", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_verts": { "description": "The Nx1 x coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "X Verts", "type": "array" }, "y_verts": { "description": "The Nx1 y coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "Y Verts", "type": "array" }, "type": { "const": "Polygon", "default": "Polygon", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_verts", "y_verts" ], "title": "Polygon", "type": "object" }, "Product__Axis_": { "additionalProperties": false, "description": "Outer product of two Specs, nesting inner within outer.\n\nThis means that inner will run in its entirety at each point in outer.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * Line(\"x\", 3, 4, 12))\n\nAn inner integer can be used to repeat the same point many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * 2)\n\nAn outer integer can be used to repeat the same scan many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(2 * ~Line.bounded(\"x\", 3, 4, 1))\n\nIf you want snaked axes to have no gap between iterations you can do:\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Product\n\n spec = Fly(Product(2, ~Line.bounded(\"x\", 3, 4, 1), gap=False))\n\n.. note:: There is no turnaround arrow at x=4", "properties": { "outer": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed once", "title": "Outer" }, "inner": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed len(outer) times", "title": "Inner" }, "gap": { "default": true, "description": "If False and the outer spec is an integer and the inner spec is snaked then the end and start of consecutive iterations of inner will have no gap", "title": "Gap", "type": "boolean" }, "type": { "const": "Product", "default": "Product", "title": "Type", "type": "string" } }, "required": [ "outer", "inner" ], "title": "Product", "type": "object" }, "Range__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis >= min and <= max.\n\n>>> r = Range(\"x\", 1, 2)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, False, False])", "properties": { "axis": { "description": "The name matching the axis to mask in spec", "title": "Axis" }, "min": { "description": "The minimum inclusive value in the region", "title": "Min", "type": "number" }, "max": { "description": "The minimum inclusive value in the region", "title": "Max", "type": "number" }, "type": { "const": "Range", "default": "Range", "title": "Type", "type": "string" } }, "required": [ "axis", "min", "max" ], "title": "Range", "type": "object" }, "Rectangle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy rectangle.\n\n.. example_spec::\n\n from scanspec.regions import Rectangle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Rectangle(\"x\", \"y\", 0, 1.1, 1.5, 2.1, 30)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_min": { "description": "Minimum inclusive x value in the region", "title": "X Min", "type": "number" }, "y_min": { "description": "Minimum inclusive y value in the region", "title": "Y Min", "type": "number" }, "x_max": { "description": "Maximum inclusive x value in the region", "title": "X Max", "type": "number" }, "y_max": { "description": "Maximum inclusive y value in the region", "title": "Y Max", "type": "number" }, "angle": { "default": 0.0, "description": "Clockwise rotation angle of the rectangle", "title": "Angle", "type": "number" }, "type": { "const": "Rectangle", "default": "Rectangle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_min", "y_min", "x_max", "y_max" ], "title": "Rectangle", "type": "object" }, "Region": { "discriminator": { "mapping": { "Circle": "#/$defs/Circle__Axis_", "CombinationOf": "#/$defs/CombinationOf__Axis_", "DifferenceOf": "#/$defs/DifferenceOf__Axis_", "Ellipse": "#/$defs/Ellipse__Axis_", "IntersectionOf": "#/$defs/IntersectionOf__Axis_", "Polygon": "#/$defs/Polygon__Axis_", "Range": "#/$defs/Range__Axis_", "Rectangle": "#/$defs/Rectangle__Axis_", "SymmetricDifferenceOf": "#/$defs/SymmetricDifferenceOf__Axis_", "UnionOf": "#/$defs/UnionOf__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/CombinationOf__Axis_" }, { "$ref": "#/$defs/UnionOf__Axis_" }, { "$ref": "#/$defs/IntersectionOf__Axis_" }, { "$ref": "#/$defs/DifferenceOf__Axis_" }, { "$ref": "#/$defs/SymmetricDifferenceOf__Axis_" }, { "$ref": "#/$defs/Range__Axis_" }, { "$ref": "#/$defs/Rectangle__Axis_" }, { "$ref": "#/$defs/Polygon__Axis_" }, { "$ref": "#/$defs/Circle__Axis_" }, { "$ref": "#/$defs/Ellipse__Axis_" } ] }, "Snake__Axis_": { "additionalProperties": false, "description": "Run the Spec in reverse on every other iteration when nested.\n\nTypically created with the ``~`` operator.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 3, 3) * ~Line(\"x\", 3, 5, 5))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to run in reverse every other iteration" }, "type": { "const": "Snake", "default": "Snake", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Snake", "type": "object" }, "Spec": { "discriminator": { "mapping": { "Concat": "#/$defs/Concat__Axis_", "ConstantDuration": "#/$defs/ConstantDuration__Axis_", "Fly": "#/$defs/Fly__Axis_", "Line": "#/$defs/Line__Axis_", "Mask": "#/$defs/Mask__Axis_", "Product": "#/$defs/Product__Axis_", "Snake": "#/$defs/Snake__Axis_", "Spiral": "#/$defs/Spiral__Axis_", "Squash": "#/$defs/Squash__Axis_", "Static": "#/$defs/Static__Axis_", "Zip": "#/$defs/Zip__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/Product__Axis_" }, { "$ref": "#/$defs/Zip__Axis_" }, { "$ref": "#/$defs/Mask__Axis_" }, { "$ref": "#/$defs/Snake__Axis_" }, { "$ref": "#/$defs/Concat__Axis_" }, { "$ref": "#/$defs/Squash__Axis_" }, { "$ref": "#/$defs/Line__Axis_" }, { "$ref": "#/$defs/Fly__Axis_" }, { "$ref": "#/$defs/ConstantDuration__Axis_" }, { "$ref": "#/$defs/Static__Axis_" }, { "$ref": "#/$defs/Spiral__Axis_" } ] }, "Spiral__Axis_": { "additionalProperties": false, "description": "Archimedean spiral of \"x_axis\" and \"y_axis\".\n\nStarts at centre point (\"x_start\", \"y_start\") with angle \"rotate\". Produces\n\"num\" points in a spiral spanning width of \"x_range\" and height of \"y_range\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Spiral\n\n spec = Fly(Spiral(\"x\", \"y\", 1, 5, 10, 50, 30))", "properties": { "x_axis": { "description": "An identifier for what to move for x", "title": "X Axis" }, "y_axis": { "description": "An identifier for what to move for y", "title": "Y Axis" }, "x_start": { "description": "x centre of the spiral", "title": "X Start", "type": "number" }, "y_start": { "description": "y centre of the spiral", "title": "Y Start", "type": "number" }, "x_range": { "description": "x width of the spiral", "title": "X Range", "type": "number" }, "y_range": { "description": "y width of the spiral", "title": "Y Range", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "rotate": { "default": 0.0, "description": "How much to rotate the angle of the spiral", "title": "Rotate", "type": "number" }, "type": { "const": "Spiral", "default": "Spiral", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_start", "y_start", "x_range", "y_range", "num" ], "title": "Spiral", "type": "object" }, "Squash__Axis_": { "additionalProperties": false, "description": "Squash a stack of Dimension together into a single expanded Dimension object.\n\nSee Also:\n `why-squash-can-change-path`\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Squash\n\n spec = Fly(Squash(Line(\"y\", 1, 2, 3) * Line(\"x\", 0, 1, 4)))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to squash the dimensions of" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Squash", "default": "Squash", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Squash", "type": "object" }, "Static__Axis_": { "additionalProperties": false, "description": "A static frame, repeated num times, with axis at value.\n\nCan be used to set axis=value at every point in a scan.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Static\n\n spec = Fly(Line(\"y\", 1, 2, 3).zip(Static(\"x\", 3)))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "value": { "description": "The value at each point", "title": "Value", "type": "number" }, "num": { "default": 1, "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Static", "default": "Static", "title": "Type", "type": "string" } }, "required": [ "axis", "value" ], "title": "Static", "type": "object" }, "SymmetricDifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in SymmetricDifferenceOf(a, b) if in either a or b, but not both.\n\nTypically created with the ``^`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) ^ Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "SymmetricDifferenceOf", "default": "SymmetricDifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "SymmetricDifferenceOf", "type": "object" }, "UnionOf__Axis_": { "additionalProperties": false, "description": "A point is in UnionOf(a, b) if in either a or b.\n\nTypically created with the ``|`` operator\n\n>>> r = Range(\"x\", 0.5, 2.5) | Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "UnionOf", "default": "UnionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "UnionOf", "type": "object" }, "Zip__Axis_": { "additionalProperties": false, "description": "Run two Specs in parallel, merging their midpoints together.\n\nTypically formed using `Spec.zip`.\n\nStacks of Dimension are merged by:\n\n- If right creates a stack of a single Dimension object of size 1, expand it to\n the size of the fastest Dimension object created by left\n- Merge individual Dimension objects together from fastest to slowest\n\nThis means that Zipping a Spec producing stack [l2, l1] with a Spec\nproducing stack [r1] will assert len(l1)==len(r1), and produce\nstack [l2, l1.zip(r1)].\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"z\", 1, 2, 3) * Line(\"y\", 3, 4, 5).zip(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Zip, will appear earlier in axes" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Zip, will appear later in axes" }, "type": { "const": "Zip", "default": "Zip", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Zip", "type": "object" } }, "additionalProperties": false, "required": [ "left", "right" ] }
- Fields:
- axes() list[Axis] [source]#
Return the list of axes that are present in the scan.
Ordered from slowest moving to fastest moving.
- pydantic model scanspec.specs.Squash[source]#
Squash a stack of Dimension together into a single expanded Dimension object.
# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Line, Squash spec = Fly(Squash(Line("y", 1, 2, 3) * Line("x", 0, 1, 4))) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)Show JSON schema
{ "title": "Squash", "description": "Squash a stack of Dimension together into a single expanded Dimension object.\n\nSee Also:\n `why-squash-can-change-path`\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Squash\n\n spec = Fly(Squash(Line(\"y\", 1, 2, 3) * Line(\"x\", 0, 1, 4)))", "type": "object", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to squash the dimensions of" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Squash", "default": "Squash", "title": "Type", "type": "string" } }, "$defs": { "Circle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy circle of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Circle(\"x\", \"y\", 1, 2, 0.9)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the circle", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the circle", "title": "Y Middle", "type": "number" }, "radius": { "description": "Radius of the circle", "exclusiveMinimum": 0.0, "title": "Radius", "type": "number" }, "type": { "const": "Circle", "default": "Circle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "radius" ], "title": "Circle", "type": "object" }, "CombinationOf__Axis_": { "additionalProperties": false, "description": "Abstract baseclass for a combination of two regions, left and right.", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "CombinationOf", "default": "CombinationOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "CombinationOf", "type": "object" }, "Concat__Axis_": { "additionalProperties": false, "description": "Concatenate two Specs together, running one after the other.\n\nEach Dimension of left and right must contain the same axes. Typically\nformed using `Spec.concat`.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 3, 3).concat(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Concat, midpoints will appear earlier" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Concat, midpoints will appear later" }, "gap": { "default": false, "description": "If True, force a gap in the output at the join", "title": "Gap", "type": "boolean" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Concat", "default": "Concat", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Concat", "type": "object" }, "ConstantDuration__Axis_": { "additionalProperties": false, "description": "Apply a constant duration to every point in a Spec.\n\nTypically applied with the ``@`` modifier.\n\n.. example_spec::\n\n from scanspec.specs import Line\n\n spec = 0.1 @ Line(\"x\", 1, 2, 3)", "properties": { "constant_duration": { "description": "The value at each point", "title": "Constant Duration", "type": "number" }, "spec": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "null" } ], "default": null, "description": "Spec contaning the path to be followed" }, "type": { "const": "ConstantDuration", "default": "ConstantDuration", "title": "Type", "type": "string" } }, "required": [ "constant_duration" ], "title": "ConstantDuration", "type": "object" }, "DifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in DifferenceOf(a, b) if in a and not in b.\n\nTypically created with the ``-`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) - Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "DifferenceOf", "default": "DifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "DifferenceOf", "type": "object" }, "Ellipse__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy ellipse of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Ellipse\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Ellipse(\"x\", \"y\", 5, 5, 2, 3, 75)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the ellipse", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the ellipse", "title": "Y Middle", "type": "number" }, "x_radius": { "description": "The radius along the x axis of the ellipse", "exclusiveMinimum": 0.0, "title": "X Radius", "type": "number" }, "y_radius": { "description": "The radius along the y axis of the ellipse", "exclusiveMinimum": 0.0, "title": "Y Radius", "type": "number" }, "angle": { "default": 0.0, "description": "The angle of the ellipse (degrees)", "title": "Angle", "type": "number" }, "type": { "const": "Ellipse", "default": "Ellipse", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "x_radius", "y_radius" ], "title": "Ellipse", "type": "object" }, "Fly__Axis_": { "additionalProperties": false, "description": "Move through lower to upper bounds of the Spec rather than stopping.\n\nThis is commonly termed a \"fly scan\" rather than a \"step scan\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 3))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "Spec contaning the path to be followed" }, "type": { "const": "Fly", "default": "Fly", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Fly", "type": "object" }, "IntersectionOf__Axis_": { "additionalProperties": false, "description": "A point is in IntersectionOf(a, b) if in both a and b.\n\nTypically created with the ``&`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) & Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, False, True, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "IntersectionOf", "default": "IntersectionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "IntersectionOf", "type": "object" }, "Line__Axis_": { "additionalProperties": false, "description": "Linearly spaced frames with start and stop as first and last midpoints.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 5))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "start": { "description": "Midpoint of the first point of the line", "title": "Start", "type": "number" }, "stop": { "description": "Midpoint of the last point of the line", "title": "Stop", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Line", "default": "Line", "title": "Type", "type": "string" } }, "required": [ "axis", "start", "stop", "num" ], "title": "Line", "type": "object" }, "Mask__Axis_": { "additionalProperties": false, "description": "Restrict Spec to only midpoints that fall inside the given Region.\n\nTypically created with the ``&`` operator. It also pushes down the\n``& | ^ -`` operators to its `Region` to avoid the need for brackets on\ncombinations of Regions.\n\nIf a Region spans multiple Dimension objects, they will be squashed together.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Fly, Line\n\n region = Circle(\"x\", \"y\", 4, 2, 1.2)\n spec = Fly(Line(\"y\", 1, 3, 3) * Line(\"x\", 3, 5, 5) & region)\n\nSee Also: `why-squash-can-change-path`", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec containing the source midpoints" }, "region": { "$ref": "#/$defs/Region", "description": "The Region that midpoints will be inside" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Mask", "default": "Mask", "title": "Type", "type": "string" } }, "required": [ "spec", "region" ], "title": "Mask", "type": "object" }, "Polygon__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy polygon.\n\n.. example_spec::\n\n from scanspec.regions import Polygon\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Polygon(\"x\", \"y\", [1.0, 6.0, 8.0, 2.0], [4.0, 10.0, 6.0, 1.0])", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_verts": { "description": "The Nx1 x coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "X Verts", "type": "array" }, "y_verts": { "description": "The Nx1 y coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "Y Verts", "type": "array" }, "type": { "const": "Polygon", "default": "Polygon", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_verts", "y_verts" ], "title": "Polygon", "type": "object" }, "Product__Axis_": { "additionalProperties": false, "description": "Outer product of two Specs, nesting inner within outer.\n\nThis means that inner will run in its entirety at each point in outer.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * Line(\"x\", 3, 4, 12))\n\nAn inner integer can be used to repeat the same point many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * 2)\n\nAn outer integer can be used to repeat the same scan many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(2 * ~Line.bounded(\"x\", 3, 4, 1))\n\nIf you want snaked axes to have no gap between iterations you can do:\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Product\n\n spec = Fly(Product(2, ~Line.bounded(\"x\", 3, 4, 1), gap=False))\n\n.. note:: There is no turnaround arrow at x=4", "properties": { "outer": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed once", "title": "Outer" }, "inner": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed len(outer) times", "title": "Inner" }, "gap": { "default": true, "description": "If False and the outer spec is an integer and the inner spec is snaked then the end and start of consecutive iterations of inner will have no gap", "title": "Gap", "type": "boolean" }, "type": { "const": "Product", "default": "Product", "title": "Type", "type": "string" } }, "required": [ "outer", "inner" ], "title": "Product", "type": "object" }, "Range__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis >= min and <= max.\n\n>>> r = Range(\"x\", 1, 2)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, False, False])", "properties": { "axis": { "description": "The name matching the axis to mask in spec", "title": "Axis" }, "min": { "description": "The minimum inclusive value in the region", "title": "Min", "type": "number" }, "max": { "description": "The minimum inclusive value in the region", "title": "Max", "type": "number" }, "type": { "const": "Range", "default": "Range", "title": "Type", "type": "string" } }, "required": [ "axis", "min", "max" ], "title": "Range", "type": "object" }, "Rectangle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy rectangle.\n\n.. example_spec::\n\n from scanspec.regions import Rectangle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Rectangle(\"x\", \"y\", 0, 1.1, 1.5, 2.1, 30)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_min": { "description": "Minimum inclusive x value in the region", "title": "X Min", "type": "number" }, "y_min": { "description": "Minimum inclusive y value in the region", "title": "Y Min", "type": "number" }, "x_max": { "description": "Maximum inclusive x value in the region", "title": "X Max", "type": "number" }, "y_max": { "description": "Maximum inclusive y value in the region", "title": "Y Max", "type": "number" }, "angle": { "default": 0.0, "description": "Clockwise rotation angle of the rectangle", "title": "Angle", "type": "number" }, "type": { "const": "Rectangle", "default": "Rectangle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_min", "y_min", "x_max", "y_max" ], "title": "Rectangle", "type": "object" }, "Region": { "discriminator": { "mapping": { "Circle": "#/$defs/Circle__Axis_", "CombinationOf": "#/$defs/CombinationOf__Axis_", "DifferenceOf": "#/$defs/DifferenceOf__Axis_", "Ellipse": "#/$defs/Ellipse__Axis_", "IntersectionOf": "#/$defs/IntersectionOf__Axis_", "Polygon": "#/$defs/Polygon__Axis_", "Range": "#/$defs/Range__Axis_", "Rectangle": "#/$defs/Rectangle__Axis_", "SymmetricDifferenceOf": "#/$defs/SymmetricDifferenceOf__Axis_", "UnionOf": "#/$defs/UnionOf__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/CombinationOf__Axis_" }, { "$ref": "#/$defs/UnionOf__Axis_" }, { "$ref": "#/$defs/IntersectionOf__Axis_" }, { "$ref": "#/$defs/DifferenceOf__Axis_" }, { "$ref": "#/$defs/SymmetricDifferenceOf__Axis_" }, { "$ref": "#/$defs/Range__Axis_" }, { "$ref": "#/$defs/Rectangle__Axis_" }, { "$ref": "#/$defs/Polygon__Axis_" }, { "$ref": "#/$defs/Circle__Axis_" }, { "$ref": "#/$defs/Ellipse__Axis_" } ] }, "Snake__Axis_": { "additionalProperties": false, "description": "Run the Spec in reverse on every other iteration when nested.\n\nTypically created with the ``~`` operator.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 3, 3) * ~Line(\"x\", 3, 5, 5))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to run in reverse every other iteration" }, "type": { "const": "Snake", "default": "Snake", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Snake", "type": "object" }, "Spec": { "discriminator": { "mapping": { "Concat": "#/$defs/Concat__Axis_", "ConstantDuration": "#/$defs/ConstantDuration__Axis_", "Fly": "#/$defs/Fly__Axis_", "Line": "#/$defs/Line__Axis_", "Mask": "#/$defs/Mask__Axis_", "Product": "#/$defs/Product__Axis_", "Snake": "#/$defs/Snake__Axis_", "Spiral": "#/$defs/Spiral__Axis_", "Squash": "#/$defs/Squash__Axis_", "Static": "#/$defs/Static__Axis_", "Zip": "#/$defs/Zip__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/Product__Axis_" }, { "$ref": "#/$defs/Zip__Axis_" }, { "$ref": "#/$defs/Mask__Axis_" }, { "$ref": "#/$defs/Snake__Axis_" }, { "$ref": "#/$defs/Concat__Axis_" }, { "$ref": "#/$defs/Squash__Axis_" }, { "$ref": "#/$defs/Line__Axis_" }, { "$ref": "#/$defs/Fly__Axis_" }, { "$ref": "#/$defs/ConstantDuration__Axis_" }, { "$ref": "#/$defs/Static__Axis_" }, { "$ref": "#/$defs/Spiral__Axis_" } ] }, "Spiral__Axis_": { "additionalProperties": false, "description": "Archimedean spiral of \"x_axis\" and \"y_axis\".\n\nStarts at centre point (\"x_start\", \"y_start\") with angle \"rotate\". Produces\n\"num\" points in a spiral spanning width of \"x_range\" and height of \"y_range\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Spiral\n\n spec = Fly(Spiral(\"x\", \"y\", 1, 5, 10, 50, 30))", "properties": { "x_axis": { "description": "An identifier for what to move for x", "title": "X Axis" }, "y_axis": { "description": "An identifier for what to move for y", "title": "Y Axis" }, "x_start": { "description": "x centre of the spiral", "title": "X Start", "type": "number" }, "y_start": { "description": "y centre of the spiral", "title": "Y Start", "type": "number" }, "x_range": { "description": "x width of the spiral", "title": "X Range", "type": "number" }, "y_range": { "description": "y width of the spiral", "title": "Y Range", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "rotate": { "default": 0.0, "description": "How much to rotate the angle of the spiral", "title": "Rotate", "type": "number" }, "type": { "const": "Spiral", "default": "Spiral", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_start", "y_start", "x_range", "y_range", "num" ], "title": "Spiral", "type": "object" }, "Squash__Axis_": { "additionalProperties": false, "description": "Squash a stack of Dimension together into a single expanded Dimension object.\n\nSee Also:\n `why-squash-can-change-path`\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Squash\n\n spec = Fly(Squash(Line(\"y\", 1, 2, 3) * Line(\"x\", 0, 1, 4)))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to squash the dimensions of" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Squash", "default": "Squash", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Squash", "type": "object" }, "Static__Axis_": { "additionalProperties": false, "description": "A static frame, repeated num times, with axis at value.\n\nCan be used to set axis=value at every point in a scan.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Static\n\n spec = Fly(Line(\"y\", 1, 2, 3).zip(Static(\"x\", 3)))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "value": { "description": "The value at each point", "title": "Value", "type": "number" }, "num": { "default": 1, "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Static", "default": "Static", "title": "Type", "type": "string" } }, "required": [ "axis", "value" ], "title": "Static", "type": "object" }, "SymmetricDifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in SymmetricDifferenceOf(a, b) if in either a or b, but not both.\n\nTypically created with the ``^`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) ^ Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "SymmetricDifferenceOf", "default": "SymmetricDifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "SymmetricDifferenceOf", "type": "object" }, "UnionOf__Axis_": { "additionalProperties": false, "description": "A point is in UnionOf(a, b) if in either a or b.\n\nTypically created with the ``|`` operator\n\n>>> r = Range(\"x\", 0.5, 2.5) | Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "UnionOf", "default": "UnionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "UnionOf", "type": "object" }, "Zip__Axis_": { "additionalProperties": false, "description": "Run two Specs in parallel, merging their midpoints together.\n\nTypically formed using `Spec.zip`.\n\nStacks of Dimension are merged by:\n\n- If right creates a stack of a single Dimension object of size 1, expand it to\n the size of the fastest Dimension object created by left\n- Merge individual Dimension objects together from fastest to slowest\n\nThis means that Zipping a Spec producing stack [l2, l1] with a Spec\nproducing stack [r1] will assert len(l1)==len(r1), and produce\nstack [l2, l1.zip(r1)].\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"z\", 1, 2, 3) * Line(\"y\", 3, 4, 5).zip(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Zip, will appear earlier in axes" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Zip, will appear later in axes" }, "type": { "const": "Zip", "default": "Zip", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Zip", "type": "object" } }, "additionalProperties": false, "required": [ "spec" ] }
- Fields:
- axes() list[Axis] [source]#
Return the list of axes that are present in the scan.
Ordered from slowest moving to fastest moving.
- pydantic model scanspec.specs.Line[source]#
Linearly spaced frames with start and stop as first and last midpoints.
# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Line spec = Fly(Line("x", 1, 2, 5)) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)Show JSON schema
{ "title": "Line", "description": "Linearly spaced frames with start and stop as first and last midpoints.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 5))", "type": "object", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "start": { "description": "Midpoint of the first point of the line", "title": "Start", "type": "number" }, "stop": { "description": "Midpoint of the last point of the line", "title": "Stop", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Line", "default": "Line", "title": "Type", "type": "string" } }, "additionalProperties": false, "required": [ "axis", "start", "stop", "num" ] }
- axes() list[Axis] [source]#
Return the list of axes that are present in the scan.
Ordered from slowest moving to fastest moving.
- bounded(lower: float = FieldInfo(annotation=NoneType, required=True, description='Lower bound of the first point of the line'), upper: float = FieldInfo(annotation=NoneType, required=True, description='Upper bound of the last point of the line'), num: int = FieldInfo(annotation=NoneType, required=True, description='Number of frames to produce', metadata=[Ge(ge=1)])) Line[OtherAxis] [source]#
Specify a Line by extreme bounds instead of midpoints.
# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Line spec = Fly(Line.bounded("x", 1, 2, 5)) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)
- pydantic model scanspec.specs.Static[source]#
A static frame, repeated num times, with axis at value.
Can be used to set axis=value at every point in a scan.
# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Line, Static spec = Fly(Line("y", 1, 2, 3).zip(Static("x", 3))) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)Show JSON schema
{ "title": "Static", "description": "A static frame, repeated num times, with axis at value.\n\nCan be used to set axis=value at every point in a scan.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Static\n\n spec = Fly(Line(\"y\", 1, 2, 3).zip(Static(\"x\", 3)))", "type": "object", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "value": { "description": "The value at each point", "title": "Value", "type": "number" }, "num": { "default": 1, "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Static", "default": "Static", "title": "Type", "type": "string" } }, "additionalProperties": false, "required": [ "axis", "value" ] }
- pydantic model scanspec.specs.Spiral[source]#
Archimedean spiral of “x_axis” and “y_axis”.
Starts at centre point (“x_start”, “y_start”) with angle “rotate”. Produces “num” points in a spiral spanning width of “x_range” and height of “y_range”
# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Spiral spec = Fly(Spiral("x", "y", 1, 5, 10, 50, 30)) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)Show JSON schema
{ "title": "Spiral", "description": "Archimedean spiral of \"x_axis\" and \"y_axis\".\n\nStarts at centre point (\"x_start\", \"y_start\") with angle \"rotate\". Produces\n\"num\" points in a spiral spanning width of \"x_range\" and height of \"y_range\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Spiral\n\n spec = Fly(Spiral(\"x\", \"y\", 1, 5, 10, 50, 30))", "type": "object", "properties": { "x_axis": { "description": "An identifier for what to move for x", "title": "X Axis" }, "y_axis": { "description": "An identifier for what to move for y", "title": "Y Axis" }, "x_start": { "description": "x centre of the spiral", "title": "X Start", "type": "number" }, "y_start": { "description": "y centre of the spiral", "title": "Y Start", "type": "number" }, "x_range": { "description": "x width of the spiral", "title": "X Range", "type": "number" }, "y_range": { "description": "y width of the spiral", "title": "Y Range", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "rotate": { "default": 0.0, "description": "How much to rotate the angle of the spiral", "title": "Rotate", "type": "number" }, "type": { "const": "Spiral", "default": "Spiral", "title": "Type", "type": "string" } }, "additionalProperties": false, "required": [ "x_axis", "y_axis", "x_start", "y_start", "x_range", "y_range", "num" ] }
- Fields:
- axes() list[Axis] [source]#
Return the list of axes that are present in the scan.
Ordered from slowest moving to fastest moving.
- calculate(bounds: bool = False, nested: bool = False) list[Dimension[Axis]] [source]#
Produce a stack of nested
Dimension
that form the scan.Ordered from slowest moving to fastest moving.
- spaced(y_axis: OtherAxis = FieldInfo(annotation=NoneType, required=True, description='An identifier for what to move for y'), x_start: float = FieldInfo(annotation=NoneType, required=True, description='x centre of the spiral'), y_start: float = FieldInfo(annotation=NoneType, required=True, description='y centre of the spiral'), radius: float = FieldInfo(annotation=NoneType, required=True, description='radius of the spiral'), dr: float = FieldInfo(annotation=NoneType, required=True, description='difference between each ring'), rotate: float = FieldInfo(annotation=NoneType, required=False, default=0.0, description='How much to rotate the angle of the spiral')) Spiral[OtherAxis] [source]#
Specify a Spiral equally spaced in “x_axis” and “y_axis”.
# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Spiral spec = Fly(Spiral.spaced("x", "y", 0, 0, 10, 3)) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)
- pydantic model scanspec.specs.Fly[source]#
Move through lower to upper bounds of the Spec rather than stopping.
This is commonly termed a “fly scan” rather than a “step scan”
# Example Spec from scanspec.plot import plot_spec from scanspec.specs import Fly, Line spec = Fly(Line("x", 1, 2, 3)) plot_spec(spec)
(
Source code
,png
,hires.png
,pdf
)Show JSON schema
{ "title": "Fly", "description": "Move through lower to upper bounds of the Spec rather than stopping.\n\nThis is commonly termed a \"fly scan\" rather than a \"step scan\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 3))", "type": "object", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "Spec contaning the path to be followed" }, "type": { "const": "Fly", "default": "Fly", "title": "Type", "type": "string" } }, "$defs": { "Circle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy circle of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Circle(\"x\", \"y\", 1, 2, 0.9)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the circle", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the circle", "title": "Y Middle", "type": "number" }, "radius": { "description": "Radius of the circle", "exclusiveMinimum": 0.0, "title": "Radius", "type": "number" }, "type": { "const": "Circle", "default": "Circle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "radius" ], "title": "Circle", "type": "object" }, "CombinationOf__Axis_": { "additionalProperties": false, "description": "Abstract baseclass for a combination of two regions, left and right.", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "CombinationOf", "default": "CombinationOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "CombinationOf", "type": "object" }, "Concat__Axis_": { "additionalProperties": false, "description": "Concatenate two Specs together, running one after the other.\n\nEach Dimension of left and right must contain the same axes. Typically\nformed using `Spec.concat`.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 3, 3).concat(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Concat, midpoints will appear earlier" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Concat, midpoints will appear later" }, "gap": { "default": false, "description": "If True, force a gap in the output at the join", "title": "Gap", "type": "boolean" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Concat", "default": "Concat", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Concat", "type": "object" }, "ConstantDuration__Axis_": { "additionalProperties": false, "description": "Apply a constant duration to every point in a Spec.\n\nTypically applied with the ``@`` modifier.\n\n.. example_spec::\n\n from scanspec.specs import Line\n\n spec = 0.1 @ Line(\"x\", 1, 2, 3)", "properties": { "constant_duration": { "description": "The value at each point", "title": "Constant Duration", "type": "number" }, "spec": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "null" } ], "default": null, "description": "Spec contaning the path to be followed" }, "type": { "const": "ConstantDuration", "default": "ConstantDuration", "title": "Type", "type": "string" } }, "required": [ "constant_duration" ], "title": "ConstantDuration", "type": "object" }, "DifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in DifferenceOf(a, b) if in a and not in b.\n\nTypically created with the ``-`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) - Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "DifferenceOf", "default": "DifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "DifferenceOf", "type": "object" }, "Ellipse__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within an xy ellipse of given radius.\n\n.. example_spec::\n\n from scanspec.regions import Ellipse\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Ellipse(\"x\", \"y\", 5, 5, 2, 3, 75)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_middle": { "description": "The central x point of the ellipse", "title": "X Middle", "type": "number" }, "y_middle": { "description": "The central y point of the ellipse", "title": "Y Middle", "type": "number" }, "x_radius": { "description": "The radius along the x axis of the ellipse", "exclusiveMinimum": 0.0, "title": "X Radius", "type": "number" }, "y_radius": { "description": "The radius along the y axis of the ellipse", "exclusiveMinimum": 0.0, "title": "Y Radius", "type": "number" }, "angle": { "default": 0.0, "description": "The angle of the ellipse (degrees)", "title": "Angle", "type": "number" }, "type": { "const": "Ellipse", "default": "Ellipse", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_middle", "y_middle", "x_radius", "y_radius" ], "title": "Ellipse", "type": "object" }, "Fly__Axis_": { "additionalProperties": false, "description": "Move through lower to upper bounds of the Spec rather than stopping.\n\nThis is commonly termed a \"fly scan\" rather than a \"step scan\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 3))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "Spec contaning the path to be followed" }, "type": { "const": "Fly", "default": "Fly", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Fly", "type": "object" }, "IntersectionOf__Axis_": { "additionalProperties": false, "description": "A point is in IntersectionOf(a, b) if in both a and b.\n\nTypically created with the ``&`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) & Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, False, True, False, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "IntersectionOf", "default": "IntersectionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "IntersectionOf", "type": "object" }, "Line__Axis_": { "additionalProperties": false, "description": "Linearly spaced frames with start and stop as first and last midpoints.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"x\", 1, 2, 5))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "start": { "description": "Midpoint of the first point of the line", "title": "Start", "type": "number" }, "stop": { "description": "Midpoint of the last point of the line", "title": "Stop", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Line", "default": "Line", "title": "Type", "type": "string" } }, "required": [ "axis", "start", "stop", "num" ], "title": "Line", "type": "object" }, "Mask__Axis_": { "additionalProperties": false, "description": "Restrict Spec to only midpoints that fall inside the given Region.\n\nTypically created with the ``&`` operator. It also pushes down the\n``& | ^ -`` operators to its `Region` to avoid the need for brackets on\ncombinations of Regions.\n\nIf a Region spans multiple Dimension objects, they will be squashed together.\n\n.. example_spec::\n\n from scanspec.regions import Circle\n from scanspec.specs import Fly, Line\n\n region = Circle(\"x\", \"y\", 4, 2, 1.2)\n spec = Fly(Line(\"y\", 1, 3, 3) * Line(\"x\", 3, 5, 5) & region)\n\nSee Also: `why-squash-can-change-path`", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec containing the source midpoints" }, "region": { "$ref": "#/$defs/Region", "description": "The Region that midpoints will be inside" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Mask", "default": "Mask", "title": "Type", "type": "string" } }, "required": [ "spec", "region" ], "title": "Mask", "type": "object" }, "Polygon__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy polygon.\n\n.. example_spec::\n\n from scanspec.regions import Polygon\n from scanspec.specs import Line\n\n grid = Line(\"y\", 3, 8, 10) * ~Line(\"x\", 1 ,8, 10)\n spec = grid & Polygon(\"x\", \"y\", [1.0, 6.0, 8.0, 2.0], [4.0, 10.0, 6.0, 1.0])", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_verts": { "description": "The Nx1 x coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "X Verts", "type": "array" }, "y_verts": { "description": "The Nx1 y coordinates of the polygons vertices", "items": { "type": "number" }, "minItems": 3, "title": "Y Verts", "type": "array" }, "type": { "const": "Polygon", "default": "Polygon", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_verts", "y_verts" ], "title": "Polygon", "type": "object" }, "Product__Axis_": { "additionalProperties": false, "description": "Outer product of two Specs, nesting inner within outer.\n\nThis means that inner will run in its entirety at each point in outer.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * Line(\"x\", 3, 4, 12))\n\nAn inner integer can be used to repeat the same point many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 2, 3) * 2)\n\nAn outer integer can be used to repeat the same scan many times.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(2 * ~Line.bounded(\"x\", 3, 4, 1))\n\nIf you want snaked axes to have no gap between iterations you can do:\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Product\n\n spec = Fly(Product(2, ~Line.bounded(\"x\", 3, 4, 1), gap=False))\n\n.. note:: There is no turnaround arrow at x=4", "properties": { "outer": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed once", "title": "Outer" }, "inner": { "anyOf": [ { "$ref": "#/$defs/Spec" }, { "type": "integer" } ], "description": "Will be executed len(outer) times", "title": "Inner" }, "gap": { "default": true, "description": "If False and the outer spec is an integer and the inner spec is snaked then the end and start of consecutive iterations of inner will have no gap", "title": "Gap", "type": "boolean" }, "type": { "const": "Product", "default": "Product", "title": "Type", "type": "string" } }, "required": [ "outer", "inner" ], "title": "Product", "type": "object" }, "Range__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis >= min and <= max.\n\n>>> r = Range(\"x\", 1, 2)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, False, False])", "properties": { "axis": { "description": "The name matching the axis to mask in spec", "title": "Axis" }, "min": { "description": "The minimum inclusive value in the region", "title": "Min", "type": "number" }, "max": { "description": "The minimum inclusive value in the region", "title": "Max", "type": "number" }, "type": { "const": "Range", "default": "Range", "title": "Type", "type": "string" } }, "required": [ "axis", "min", "max" ], "title": "Range", "type": "object" }, "Rectangle__Axis_": { "additionalProperties": false, "description": "Mask contains points of axis within a rotated xy rectangle.\n\n.. example_spec::\n\n from scanspec.regions import Rectangle\n from scanspec.specs import Line\n\n grid = Line(\"y\", 1, 3, 10) * ~Line(\"x\", 0, 2, 10)\n spec = grid & Rectangle(\"x\", \"y\", 0, 1.1, 1.5, 2.1, 30)", "properties": { "x_axis": { "description": "The name matching the x axis of the spec", "title": "X Axis" }, "y_axis": { "description": "The name matching the y axis of the spec", "title": "Y Axis" }, "x_min": { "description": "Minimum inclusive x value in the region", "title": "X Min", "type": "number" }, "y_min": { "description": "Minimum inclusive y value in the region", "title": "Y Min", "type": "number" }, "x_max": { "description": "Maximum inclusive x value in the region", "title": "X Max", "type": "number" }, "y_max": { "description": "Maximum inclusive y value in the region", "title": "Y Max", "type": "number" }, "angle": { "default": 0.0, "description": "Clockwise rotation angle of the rectangle", "title": "Angle", "type": "number" }, "type": { "const": "Rectangle", "default": "Rectangle", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_min", "y_min", "x_max", "y_max" ], "title": "Rectangle", "type": "object" }, "Region": { "discriminator": { "mapping": { "Circle": "#/$defs/Circle__Axis_", "CombinationOf": "#/$defs/CombinationOf__Axis_", "DifferenceOf": "#/$defs/DifferenceOf__Axis_", "Ellipse": "#/$defs/Ellipse__Axis_", "IntersectionOf": "#/$defs/IntersectionOf__Axis_", "Polygon": "#/$defs/Polygon__Axis_", "Range": "#/$defs/Range__Axis_", "Rectangle": "#/$defs/Rectangle__Axis_", "SymmetricDifferenceOf": "#/$defs/SymmetricDifferenceOf__Axis_", "UnionOf": "#/$defs/UnionOf__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/CombinationOf__Axis_" }, { "$ref": "#/$defs/UnionOf__Axis_" }, { "$ref": "#/$defs/IntersectionOf__Axis_" }, { "$ref": "#/$defs/DifferenceOf__Axis_" }, { "$ref": "#/$defs/SymmetricDifferenceOf__Axis_" }, { "$ref": "#/$defs/Range__Axis_" }, { "$ref": "#/$defs/Rectangle__Axis_" }, { "$ref": "#/$defs/Polygon__Axis_" }, { "$ref": "#/$defs/Circle__Axis_" }, { "$ref": "#/$defs/Ellipse__Axis_" } ] }, "Snake__Axis_": { "additionalProperties": false, "description": "Run the Spec in reverse on every other iteration when nested.\n\nTypically created with the ``~`` operator.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"y\", 1, 3, 3) * ~Line(\"x\", 3, 5, 5))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to run in reverse every other iteration" }, "type": { "const": "Snake", "default": "Snake", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Snake", "type": "object" }, "Spec": { "discriminator": { "mapping": { "Concat": "#/$defs/Concat__Axis_", "ConstantDuration": "#/$defs/ConstantDuration__Axis_", "Fly": "#/$defs/Fly__Axis_", "Line": "#/$defs/Line__Axis_", "Mask": "#/$defs/Mask__Axis_", "Product": "#/$defs/Product__Axis_", "Snake": "#/$defs/Snake__Axis_", "Spiral": "#/$defs/Spiral__Axis_", "Squash": "#/$defs/Squash__Axis_", "Static": "#/$defs/Static__Axis_", "Zip": "#/$defs/Zip__Axis_" }, "propertyName": "type" }, "oneOf": [ { "$ref": "#/$defs/Product__Axis_" }, { "$ref": "#/$defs/Zip__Axis_" }, { "$ref": "#/$defs/Mask__Axis_" }, { "$ref": "#/$defs/Snake__Axis_" }, { "$ref": "#/$defs/Concat__Axis_" }, { "$ref": "#/$defs/Squash__Axis_" }, { "$ref": "#/$defs/Line__Axis_" }, { "$ref": "#/$defs/Fly__Axis_" }, { "$ref": "#/$defs/ConstantDuration__Axis_" }, { "$ref": "#/$defs/Static__Axis_" }, { "$ref": "#/$defs/Spiral__Axis_" } ] }, "Spiral__Axis_": { "additionalProperties": false, "description": "Archimedean spiral of \"x_axis\" and \"y_axis\".\n\nStarts at centre point (\"x_start\", \"y_start\") with angle \"rotate\". Produces\n\"num\" points in a spiral spanning width of \"x_range\" and height of \"y_range\"\n\n.. example_spec::\n\n from scanspec.specs import Fly, Spiral\n\n spec = Fly(Spiral(\"x\", \"y\", 1, 5, 10, 50, 30))", "properties": { "x_axis": { "description": "An identifier for what to move for x", "title": "X Axis" }, "y_axis": { "description": "An identifier for what to move for y", "title": "Y Axis" }, "x_start": { "description": "x centre of the spiral", "title": "X Start", "type": "number" }, "y_start": { "description": "y centre of the spiral", "title": "Y Start", "type": "number" }, "x_range": { "description": "x width of the spiral", "title": "X Range", "type": "number" }, "y_range": { "description": "y width of the spiral", "title": "Y Range", "type": "number" }, "num": { "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "rotate": { "default": 0.0, "description": "How much to rotate the angle of the spiral", "title": "Rotate", "type": "number" }, "type": { "const": "Spiral", "default": "Spiral", "title": "Type", "type": "string" } }, "required": [ "x_axis", "y_axis", "x_start", "y_start", "x_range", "y_range", "num" ], "title": "Spiral", "type": "object" }, "Squash__Axis_": { "additionalProperties": false, "description": "Squash a stack of Dimension together into a single expanded Dimension object.\n\nSee Also:\n `why-squash-can-change-path`\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Squash\n\n spec = Fly(Squash(Line(\"y\", 1, 2, 3) * Line(\"x\", 0, 1, 4)))", "properties": { "spec": { "$ref": "#/$defs/Spec", "description": "The Spec to squash the dimensions of" }, "check_path_changes": { "default": true, "description": "If True path through scan will not be modified by squash", "title": "Check Path Changes", "type": "boolean" }, "type": { "const": "Squash", "default": "Squash", "title": "Type", "type": "string" } }, "required": [ "spec" ], "title": "Squash", "type": "object" }, "Static__Axis_": { "additionalProperties": false, "description": "A static frame, repeated num times, with axis at value.\n\nCan be used to set axis=value at every point in a scan.\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line, Static\n\n spec = Fly(Line(\"y\", 1, 2, 3).zip(Static(\"x\", 3)))", "properties": { "axis": { "description": "An identifier for what to move", "title": "Axis" }, "value": { "description": "The value at each point", "title": "Value", "type": "number" }, "num": { "default": 1, "description": "Number of frames to produce", "minimum": 1, "title": "Num", "type": "integer" }, "type": { "const": "Static", "default": "Static", "title": "Type", "type": "string" } }, "required": [ "axis", "value" ], "title": "Static", "type": "object" }, "SymmetricDifferenceOf__Axis_": { "additionalProperties": false, "description": "A point is in SymmetricDifferenceOf(a, b) if in either a or b, but not both.\n\nTypically created with the ``^`` operator.\n\n>>> r = Range(\"x\", 0.5, 2.5) ^ Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, False, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "SymmetricDifferenceOf", "default": "SymmetricDifferenceOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "SymmetricDifferenceOf", "type": "object" }, "UnionOf__Axis_": { "additionalProperties": false, "description": "A point is in UnionOf(a, b) if in either a or b.\n\nTypically created with the ``|`` operator\n\n>>> r = Range(\"x\", 0.5, 2.5) | Range(\"x\", 1.5, 3.5)\n>>> r.mask({\"x\": np.array([0, 1, 2, 3, 4])})\narray([False, True, True, True, False])", "properties": { "left": { "$ref": "#/$defs/Region", "description": "The left-hand Region to combine" }, "right": { "$ref": "#/$defs/Region", "description": "The right-hand Region to combine" }, "type": { "const": "UnionOf", "default": "UnionOf", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "UnionOf", "type": "object" }, "Zip__Axis_": { "additionalProperties": false, "description": "Run two Specs in parallel, merging their midpoints together.\n\nTypically formed using `Spec.zip`.\n\nStacks of Dimension are merged by:\n\n- If right creates a stack of a single Dimension object of size 1, expand it to\n the size of the fastest Dimension object created by left\n- Merge individual Dimension objects together from fastest to slowest\n\nThis means that Zipping a Spec producing stack [l2, l1] with a Spec\nproducing stack [r1] will assert len(l1)==len(r1), and produce\nstack [l2, l1.zip(r1)].\n\n.. example_spec::\n\n from scanspec.specs import Fly, Line\n\n spec = Fly(Line(\"z\", 1, 2, 3) * Line(\"y\", 3, 4, 5).zip(Line(\"x\", 4, 5, 5)))", "properties": { "left": { "$ref": "#/$defs/Spec", "description": "The left-hand Spec to Zip, will appear earlier in axes" }, "right": { "$ref": "#/$defs/Spec", "description": "The right-hand Spec to Zip, will appear later in axes" }, "type": { "const": "Zip", "default": "Zip", "title": "Type", "type": "string" } }, "required": [ "left", "right" ], "title": "Zip", "type": "object" } }, "additionalProperties": false, "required": [ "spec" ] }
- axes() list[Axis] [source]#
Return the list of axes that are present in the scan.
Ordered from slowest moving to fastest moving.
- scanspec.specs.step(spec: Spec[Axis], duration: float, num: int = 1) Spec[Axis] [source]#
Step scan, with num frames of given duration at each frame in the spec.
- Parameters:
spec – The source
Spec
with midpoints to move to and stopduration – The duration of each scan frame
num – Number of frames to produce with given duration at each of frame in the spec
Deprecated since version 1.0.0: You should use
ConstantDuration
instead.
- scanspec.specs.fly(spec: Spec[Axis], duration: float) Spec[Axis | str] [source]#
Flyscan, zipping with fixed duration for every frame.
- Parameters:
spec – The source
Spec
to continuously moveduration – How long to spend at each frame in the spec
Deprecated since version 1.0.0: You should use
Fly
andConstantDuration
instead
- scanspec.specs.VARIABLE_DURATION = 'VARIABLE_DURATION'#
A string returned from
Spec.duration
to signify it produces a different duration for each point