Skip to content

Plotting

pytao.plotting.plot

Classes

pytao.plotting.plot.GraphBase
Functions
pytao.plotting.plot.GraphBase.update
update(manager, *, error_on_new_type=True, raise_if_invalid=False)

Ask Tao to update the plot region. Returns a new Graph instance.

Raises:

Type Description
GraphInvalidError

If raise_if_invalid is set and Tao reports the graph data as invalid.

ValueError

If error_on_new_type is set and the graph type changes after the update.

RuntimeError

If the same graph is no longer found after the update.

Source code in pytao/plotting/plot.py
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
def update(
    self,
    manager: GraphManager,
    *,
    error_on_new_type: bool = True,
    raise_if_invalid: bool = False,
):
    """
    Ask Tao to update the plot region. Returns a new Graph instance.

    Raises
    ------
    GraphInvalidError
        If `raise_if_invalid` is set and Tao reports the graph data as
        invalid.
    ValueError
        If `error_on_new_type` is set and the graph type changes after the
        update.
    RuntimeError
        If the same graph is no longer found after the update.
    """
    try:
        graphs = manager.prepare_graphs_by_name(
            region_name=self.region_name,
            template_name=self.template_name or self.graph_name,
            ignore_invalid=False,
            place=False,
        )
    except GraphInvalidError:
        if raise_if_invalid:
            raise
        return self

    if self.template_graph_index is not None:
        return graphs[self.template_graph_index]

    for graph in graphs:
        if graph.graph_name == self.graph_name:
            if error_on_new_type and not isinstance(graph, type(self)):
                raise ValueError(
                    f"Graph type changed from {type(self).__name__} to {type(graph).__name__}"
                )
            return graph
    raise RuntimeError("Plot not found after update?")
pytao.plotting.plot.GraphManager
GraphManager(tao)

Bases: ABC

Graph backend manager base class.

Source code in pytao/plotting/plot.py
1223
1224
1225
1226
def __init__(self, tao: Tao) -> None:
    self.tao = tao
    self.regions = {}
    self._to_place = {}
Attributes
pytao.plotting.plot.GraphManager.floor_plan_graph property
floor_plan_graph

The floor plan graph. Placed if not already available.

pytao.plotting.plot.GraphManager.lattice_layout_graph property
lattice_layout_graph

The lattice layout graph. Placed if not already available.

pytao.plotting.plot.GraphManager.to_place property
to_place

Graphs to place - region name to graph name.

Functions
pytao.plotting.plot.GraphManager.clear
clear(region_name='*')

Clear a single region or all regions.

Parameters:

Name Type Description Default
region_name str

Defaults to '*', which is all regions.

'*'
Source code in pytao/plotting/plot.py
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
def clear(self, region_name: str = "*"):
    """
    Clear a single region or all regions.

    Parameters
    ----------
    region_name : str, optional
        Defaults to '*', which is all regions.
    """
    try:
        self.tao.cmd(f"place -no_buffer {region_name} none")
    except RuntimeError as ex:
        logger.warning(f"Region clear failed: {ex}")

    self._clear_region(region_name)
pytao.plotting.plot.GraphManager.configure_curves
configure_curves(region_name, settings, *, graph_name=None)

Configure curves in a region.

Parameters:

Name Type Description Default
region_name str

Already-placed region name.

required
settings Dict[int, TaoCurveSettings]

Per-curve settings, keyed by integer curve index (starting at 1).

required
graph_name str

The graph name, if available. If unspecified, settings will be applied to all plots in the region.

None
Source code in pytao/plotting/plot.py
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
def configure_curves(
    self,
    region_name: str,
    settings: Dict[int, TaoCurveSettings],
    *,
    graph_name: Optional[str] = None,
):
    """
    Configure curves in a region.

    Parameters
    ----------
    region_name : str
        Already-placed region name.
    settings : Dict[int, TaoCurveSettings]
        Per-curve settings, keyed by integer curve index (starting at 1).
    graph_name : str, optional
        The graph name, if available.  If unspecified, settings will be
        applied to all plots in the region.
    """
    if not graph_name:
        for plot_name in get_plots_in_region(self.tao, region_name):
            self.configure_curves(region_name, settings=settings, graph_name=plot_name)
        return

    for curve_idx, curve in settings.items():
        for command in curve.get_commands(
            region_name,
            graph_name,
            curve_index=curve_idx,
        ):
            self.tao.cmd(command)
pytao.plotting.plot.GraphManager.configure_graph
configure_graph(region_name, settings, *, graph_name=None)

Configure graph settings for a region.

Parameters:

Name Type Description Default
region_name str

Already-placed region name.

required
settings TaoGraphSettings

Graph customization settings.

required
graph_name str

The graph name, if available. If unspecified, settings will be applied to all plots in the region.

None
Source code in pytao/plotting/plot.py
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
def configure_graph(
    self,
    region_name: str,
    settings: TaoGraphSettings,
    *,
    graph_name: Optional[str] = None,
):
    """
    Configure graph settings for a region.

    Parameters
    ----------
    region_name : str
        Already-placed region name.
    settings : TaoGraphSettings
        Graph customization settings.
    graph_name : str, optional
        The graph name, if available.  If unspecified, settings will be
        applied to all plots in the region.
    """
    if not graph_name:
        for plot_name in get_plots_in_region(self.tao, region_name):
            self.configure_graph(region_name, settings=settings, graph_name=plot_name)
        return

    graph_info = get_plot_graph_info(self.tao, region_name, graph_name)
    graph_type = graph_info["graph^type"]
    for command in settings.get_commands(
        region_name,
        graph_name,
        graph_type=graph_type,
    ):
        self.tao.cmd(command)
pytao.plotting.plot.GraphManager.get_region_to_place_template
get_region_to_place_template(template_name)

Get a region for placing the graph.

Source code in pytao/plotting/plot.py
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
def get_region_to_place_template(self, template_name: str) -> str:
    """Get a region for placing the graph."""
    for region_name, to_place in self.to_place.items():
        if to_place == template_name:
            logger.debug("Graph %s found in region %s", template_name, region_name)
            return region_name

    try:
        region_name = find_unused_plot_region(self.tao, set(self.to_place))
    except AllPlotRegionsInUseError:
        region_name = list(self.regions)[0]
        plots_in_region = list(graph.template_name for graph in self.regions[region_name])
        if plots_in_region:
            logger.warning(
                f"All plot regions are in use; reusing plot region {region_name} which has graphs: {plots_in_region}"
            )
    else:
        logger.debug("New region for graph %s: %s", template_name, region_name)
    return region_name
pytao.plotting.plot.GraphManager.make_graph
make_graph(region_name, graph_name, template_name=None, template_graph_index=None)

Create a graph instance from an already-placed graph.

Parameters:

Name Type Description Default
region_name str

The region name of the graph.

required
graph_name str

The placed graph name (tao_template_graph graph%name).

required
template_name str

The graph template name.

None
template_graph_index str

The zero-based graph index of those placed for template_name.

None

Returns:

Type Description
AnyGraph
Source code in pytao/plotting/plot.py
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
def make_graph(
    self,
    region_name: str,
    graph_name: str,
    template_name: Optional[str] = None,
    template_graph_index: Optional[int] = None,
) -> AnyGraph:
    """
    Create a graph instance from an already-placed graph.

    Parameters
    ----------
    region_name : str
        The region name of the graph.
    graph_name : str
        The placed graph name (tao_template_graph graph%name).
    template_name : str, optional
        The graph template name.
    template_graph_index : str, optional
        The zero-based graph index of those placed for `template_name`.

    Returns
    -------
    AnyGraph
    """
    return make_graph(
        self.tao,
        region_name=region_name,
        graph_name=graph_name,
        template_name=template_name,
        template_graph_index=template_graph_index,
    )
pytao.plotting.plot.GraphManager.place
place(template_name, *, region_name=None, ignore_invalid=True)

Place template_name in region_name.

Parameters:

Name Type Description Default
template_name str

The graph template name.

required
region_name str

The region name to place it. Determined automatically if unspecified.

None
ignore_invalid bool

Ignore graphs marked as invalid by bmad.

True

Returns:

Type Description
list of graphs

The type of each graph is backend-dependent.

Source code in pytao/plotting/plot.py
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
def place(
    self,
    template_name: str,
    *,
    region_name: Optional[str] = None,
    ignore_invalid: bool = True,
) -> List[AnyGraph]:
    """
    Place `template_name` in `region_name`.

    Parameters
    ----------
    template_name : str
        The graph template name.
    region_name : str, optional
        The region name to place it.  Determined automatically if unspecified.
    ignore_invalid : bool
        Ignore graphs marked as invalid by bmad.

    Returns
    -------
    list of graphs
        The type of each graph is backend-dependent.
    """
    region_name = self._place(template_name, region_name)
    return self.update_region(
        region_name=region_name,
        template_name=template_name,
        ignore_invalid=ignore_invalid,
    )
pytao.plotting.plot.GraphManager.place_all
place_all(*, ignore_invalid=True, ignore_unsupported=True)

Place all graphs in the place buffer.

Side effect: clears to_place.

Parameters:

Name Type Description Default
ignore_invalid bool

Ignore graphs marked as invalid by bmad.

True
ignore_unsupported bool

Ignore unsupported graph types (e.g., key tables).

True

Returns:

Type Description
Dict[str, List[AnyGraph]]

Region to list of graphs.

Source code in pytao/plotting/plot.py
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
def place_all(
    self,
    *,
    ignore_invalid: bool = True,
    ignore_unsupported: bool = True,
) -> Dict[str, List[AnyGraph]]:
    """
    Place all graphs in the place buffer.

    Side effect: clears `to_place`.

    Parameters
    ----------
    ignore_invalid : bool
        Ignore graphs marked as invalid by bmad.
    ignore_unsupported : bool
        Ignore unsupported graph types (e.g., key tables).

    Returns
    -------
    Dict[str, List[AnyGraph]]
        Region to list of graphs.
    """
    to_place = list(self.to_place.items())
    self.to_place.clear()

    logger.debug("Placing all plots: %s", to_place)
    result = {}
    for region_name, template_name in to_place:
        try:
            result[region_name] = self.place(
                template_name=template_name,
                region_name=region_name,
                ignore_invalid=ignore_invalid,
            )
        except UnsupportedGraphError:
            if not ignore_unsupported:
                raise

    return result
pytao.plotting.plot.GraphManager.plot_all
plot_all(grid=None, include_layout=False, **kwargs)

Plot all "placed" graphs.

Parameters:

Name Type Description Default
grid Tuple[int, int]

Grid plots into this shape - (rows, cols).

None
include_layout bool

Include a layout plot.

False
**kwargs

Keyword arguments are passed to .plot_grid().

{}
Source code in pytao/plotting/plot.py
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
def plot_all(
    self,
    grid: Optional[Tuple[int, int]] = None,
    include_layout: bool = False,
    **kwargs,
):
    """
    Plot all "placed" graphs.

    Parameters
    ----------
    grid : Tuple[int, int], optional
        Grid plots into this shape - (rows, cols).
    include_layout : bool, default=False
        Include a layout plot.
    **kwargs
        Keyword arguments are passed to `.plot_grid()`.
    """
    template_names = list(self.to_place.values())
    if not grid:
        grid = (len(template_names), 1)
    return self.plot_grid(
        template_names,
        grid=grid,
        include_layout=include_layout,
        **kwargs,
    )
pytao.plotting.plot.GraphManager.prepare_graphs_by_name
prepare_graphs_by_name(template_name, *, region_name=None, settings=None, curves=None, ignore_unsupported=True, ignore_invalid=True, place=True, xlim=None, ylim=None)

Prepare a graph for plotting.

Parameters:

Name Type Description Default
template_name str

The graph template name.

required
region_name str

The region name to place it. Determined automatically if unspecified.

None
settings TaoGraphSettings

Graph customization settings.

None
curves Dict[int, TaoCurveSettings]

Curve settings, keyed by curve number.

None
ignore_unsupported bool

Ignore unsupported graph types (e.g., key tables).

True
ignore_invalid bool

Ignore graphs marked as invalid by bmad.

True
place bool

Tell Tao to place the template first.

True
xlim (float, float)

X axis limits.

None
ylim (float, float)

Y axis limits.

None

Returns:

Type Description
list of graphs

The type of each graph is backend-dependent.

Source code in pytao/plotting/plot.py
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
def prepare_graphs_by_name(
    self,
    template_name: str,
    *,
    region_name: Optional[str] = None,
    settings: Optional[TaoGraphSettings] = None,
    curves: Optional[Dict[int, TaoCurveSettings]] = None,
    ignore_unsupported: bool = True,
    ignore_invalid: bool = True,
    place: bool = True,
    xlim: Optional[Limit] = None,
    ylim: Optional[Limit] = None,
) -> List[AnyGraph]:
    """
    Prepare a graph for plotting.

    Parameters
    ----------
    template_name : str
        The graph template name.
    region_name : str, optional
        The region name to place it.  Determined automatically if unspecified.
    settings : TaoGraphSettings, optional
        Graph customization settings.
    curves : Dict[int, TaoCurveSettings], optional
        Curve settings, keyed by curve number.
    ignore_unsupported : bool
        Ignore unsupported graph types (e.g., key tables).
    ignore_invalid : bool
        Ignore graphs marked as invalid by bmad.
    place : bool, default=True
        Tell Tao to place the template first.
    xlim : (float, float), optional
        X axis limits.
    ylim : (float, float), optional
        Y axis limits.

    Returns
    -------
    list of graphs
        The type of each graph is backend-dependent.
    """
    if place:
        region_name = self._place(template_name=template_name, region_name=region_name)
    elif not region_name:
        region_name = self.get_region_to_place_template(template_name)

    if settings is None:
        settings = TaoGraphSettings()
    if xlim is not None:
        settings.xlim = xlim
    if ylim is not None:
        settings.ylim = ylim

    self.configure_graph(region_name, settings)

    if curves is not None:
        self.configure_curves(region_name, curves)

    return self.update_region(
        region_name=region_name,
        template_name=template_name,
        ignore_unsupported=ignore_unsupported,
        ignore_invalid=ignore_invalid,
    )
pytao.plotting.plot.GraphManager.prepare_grid_by_names
prepare_grid_by_names(template_names, curves=None, settings=None, xlim=None, ylim=None)

Prepare multiple graphs for a grid plot.

Applies per-graph curve settings and also region/graph settings.

Parameters:

Name Type Description Default
template_names list of str

Graph names.

required
curves list of Dict[int, TaoCurveSettings]

One dictionary per graph, with each dictionary mapping the curve index to curve settings. These settings will be applied to the placed graphs prior to plotting.

None
settings list of TaoGraphSettings

Graph customization settings.

None
xlim list of (float, float)

X axis limits for each graph.

None
ylim list of (float, float)

Y axis limits for each graph.

None

Returns:

Type Description
list of graphs
Source code in pytao/plotting/plot.py
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
def prepare_grid_by_names(
    self,
    template_names: List[str],
    curves: Optional[List[CurveIndexToCurve]] = None,
    settings: Optional[List[TaoGraphSettings]] = None,
    xlim: Union[OptionalLimit, Sequence[OptionalLimit]] = None,
    ylim: Union[OptionalLimit, Sequence[OptionalLimit]] = None,
):
    """
    Prepare multiple graphs for a grid plot.

    Applies per-graph curve settings and also region/graph settings.

    Parameters
    ----------
    template_names : list of str
        Graph names.
    curves : list of Dict[int, TaoCurveSettings], optional
        One dictionary per graph, with each dictionary mapping the curve
        index to curve settings. These settings will be applied to the
        placed graphs prior to plotting.
    settings : list of TaoGraphSettings, optional
        Graph customization settings.
    xlim : list of (float, float), optional
        X axis limits for each graph.
    ylim : list of (float, float), optional
        Y axis limits for each graph.

    Returns
    -------
    list of graphs
    """
    num_graphs = len(template_names)
    if not curves:
        curves = [{}] * num_graphs
    elif len(curves) < num_graphs:
        assert len(curves)
        curves = list(curves) + [{}] * (num_graphs - len(curves))

    if not settings:
        settings = [TaoGraphSettings()] * num_graphs
    elif len(settings) < num_graphs:
        settings = list(settings) + [TaoGraphSettings()] * (num_graphs - len(settings))

    xlim = fix_grid_limits(xlim, num_graphs=num_graphs)
    ylim = fix_grid_limits(ylim, num_graphs=num_graphs)
    for setting, xl, yl in zip(settings, xlim, ylim):
        setting.xlim = xl
        setting.ylim = yl

    graphs = sum(
        (
            self.prepare_graphs_by_name(
                template_name=template_name,
                curves=graph_curves,
                settings=graph_settings,
            )
            for template_name, graph_curves, graph_settings in zip(
                template_names,
                curves,
                settings,
            )
        ),
        [],
    )

    if not graphs:
        raise UnsupportedGraphError(
            f"No supported plots from these templates: {template_names}"
        )
    return graphs
pytao.plotting.plot.GraphManager.tao_init_hook
tao_init_hook()

Tao has reinitialized; clear our state.

Source code in pytao/plotting/plot.py
1228
1229
1230
1231
def tao_init_hook(self) -> None:
    """Tao has reinitialized; clear our state."""
    self.regions.clear()
    self._to_place.clear()
pytao.plotting.plot.GraphManager.update_region
update_region(region_name, template_name, ignore_invalid=True, ignore_unsupported=True)

Query information about already-placed graphs in a given region.

Parameters:

Name Type Description Default
region_name str

The region name where the graph was placed.

required
template_name str

The template name the user placed.

required
ignore_invalid bool

Ignore graphs marked as invalid by bmad.

True
ignore_unsupported bool

Ignore unsupported graph types (e.g., key tables).

True

Returns:

Type Description
list of graphs

The type of each graph is backend-dependent.

Source code in pytao/plotting/plot.py
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
def update_region(
    self,
    region_name: str,
    template_name: str,
    ignore_invalid: bool = True,
    ignore_unsupported: bool = True,
) -> List[AnyGraph]:
    """
    Query information about already-placed graphs in a given region.

    Parameters
    ----------
    region_name : str, optional
        The region name where the graph was placed.
    template_name : str
        The template name the user placed.
    ignore_invalid : bool
        Ignore graphs marked as invalid by bmad.
    ignore_unsupported : bool
        Ignore unsupported graph types (e.g., key tables).

    Returns
    -------
    list of graphs
        The type of each graph is backend-dependent.
    """
    self._clear_region(region_name)

    result = []
    plot_names = get_plots_in_region(self.tao, region_name)
    for idx, plot_name in enumerate(plot_names):
        try:
            result.append(
                self.make_graph(
                    region_name=region_name,
                    graph_name=plot_name,
                    template_name=template_name,
                    template_graph_index=idx,
                )
            )
        except UnsupportedGraphError as ex:
            if ignore_unsupported:
                logger.debug(f"Unsupported graph in region {region_name}: {ex}")
                continue
            raise
        except GraphInvalidError as ex:
            if ignore_invalid:
                logger.warning(f"Invalid graph in region {region_name}: {ex}")
                continue
            raise

    self.regions[region_name] = result
    logger.debug(
        "Updating region: %s template: %s generated %d plots",
        region_name,
        template_name,
        len(result),
    )
    return result
pytao.plotting.plot.LatticeLayoutElement
Functions
pytao.plotting.plot.LatticeLayoutElement.wrapped_shape classmethod
wrapped_shape(s1, s2, y1, y2, color, shape, name, x_min, x_max, y2_floor)

Element is wrapped around the lattice ends, and s1 >= s2.

$ACC_ROOT_DIR/regression_tests/pipe_test/tao.init_wake shows off this functionality.

Source code in pytao/plotting/plot.py
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
@classmethod
def wrapped_shape(
    cls,
    s1: float,
    s2: float,
    y1: float,
    y2: float,
    color: str,
    shape: str,
    name: str,
    x_min: float,
    x_max: float,
    y2_floor: float,
) -> Tuple[Optional[layout_shapes.AnyWrappedLayoutShape], List[PlotAnnotation]]:
    """
    Element is wrapped around the lattice ends, and s1 >= s2.

    `$ACC_ROOT_DIR/regression_tests/pipe_test/tao.init_wake` shows off
    this functionality.
    """
    assert s1 >= s2
    s_min = max((x_min, s1 + (s1 + s2) / 2.0))
    s_max = min((x_max, s1 - (s1 + s2) / 2.0))

    try:
        shape_cls = layout_shapes.wrapped_shape_to_class[shape]
    except KeyError:
        logger.debug(f"Unsupported wrappedlayout shape type: {shape}")
        shape_instance = None
    else:
        shape_instance = shape_cls(
            s1=s1,
            s2=s2,
            y1=y1,
            y2=y2,
            color=color,
            s_min=s_min,
            s_max=s_max,
            name=name,
            fill=False,
        )

    annotations = [
        PlotAnnotation(
            x=s_max,
            y=1.1 * y2_floor,
            text=name,
            horizontalalignment="right",
            verticalalignment="top",
            clip_on=True,
            color=color,
        ),
        PlotAnnotation(
            x=s_min,
            y=1.1 * y2_floor,
            text=name,
            horizontalalignment="left",
            verticalalignment="top",
            clip_on=True,
            color=color,
        ),
    ]

    return shape_instance, annotations

pytao.plotting.curves

Classes

pytao.plotting.curves.TaoCurveSettings

Bases: BaseModel

TaoCurveSettings are per-curve settings for Tao's set curve command.

All parameters are None by default and will only be applied if user-specified.

Attributes:

Name Type Description
ele_ref_name str

Name or index or the reference element. An empty string means no reference element.

ix_ele_ref int

Same as setting ele_ref_name. -1 = No reference element.

component str

Who to plot. Eg: 'meas - design' A "data" graph is used to draw lattice parameters such as orbits, or Tao data, or variable values such as quadrupole strengths. The data values will depend upon where the data comes from. This is determined, in part, by the setting of the component parameter in the tao_template_graph namelist. The component may be one of:

"model", for model values. This is the default.
"design", for design values.
"base", for base values.
"meas", for data values.
"ref", for reference data values.
"beam_chamber_wall", for beam chamber wall data.

Additionally, component may be set to plot a linear combination of the above. For example: "model - design" This will plot the difference between the model and design values.

ix_branch int

Branch index.

ix_bunch int

Bunch index.

ix_universe int

Universe index.

symbol_every int

Symbol skip number.

y_axis_scale_factor int

Scaling of y axis

draw_line bool

Draw a line through the data points?

draw_symbols bool

Draw a symbol at the data points?

draw_symbol_index bool

Draw the symbol index number curve%ix_symb?

pytao.plotting.fields

Classes

pytao.plotting.pgplot

Functions

pytao.plotting.pgplot.mathjax_string
mathjax_string(value)

Takes string with pgplot characters and returns string with characters replaced with MathJax equivalent.

Source code in pytao/plotting/pgplot.py
112
113
114
115
116
117
118
119
120
def mathjax_string(value: str) -> str:
    """
    Takes string with pgplot characters and returns string with characters replaced with MathJax equivalent.
    """
    res = mpl_string(value)
    if res.startswith("$") and res.endswith("$"):
        # MathJAX strings are $$ ... $$ instead of just $ ... $
        return f"${res}$"
    return res
pytao.plotting.pgplot.mpl_color
mpl_color(pgplot_color)

Pgplot color to matplotlib color.

Source code in pytao/plotting/pgplot.py
 9
10
11
12
13
14
15
16
17
18
19
def mpl_color(pgplot_color: str) -> str:
    """Pgplot color to matplotlib color."""
    return {
        "yellow_green": "greenyellow",
        "light_green": "limegreen",
        "navy_blue": "navy",
        "reddish_purple": "mediumvioletred",
        "dark_grey": "gray",
        "light_grey": "lightgray",
        "transparent": "none",
    }.get(pgplot_color.lower(), pgplot_color)
pytao.plotting.pgplot.mpl_string
mpl_string(value)

Takes string with pgplot characters and returns string with characters replaced with matplotlib equivalent.

Source code in pytao/plotting/pgplot.py
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
def mpl_string(value: str) -> str:
    """Takes string with pgplot characters and returns string with characters replaced with matplotlib equivalent."""
    backslash = "\\"
    if backslash not in value:
        return value

    value = value.replace(backslash, r"\\")

    result = f"${value}$"
    while r"\\d" in result and r"\\u" in result:
        d_pos = result.find(r"\\d")
        u_pos = result.find(r"\\u")
        if d_pos < u_pos:
            sx = result[d_pos : u_pos + 3]
            result = result.replace(sx, "_" + sx[3:-3])
        else:
            sx = result[u_pos : d_pos + 3]
            result = result.replace(sx, "^" + sx[3:-3])

    # TODO this is far from performant, but this is unlikely to be called
    # frequently so I'm leaving it for now
    for from_, to in _pgplot_to_mpl_chars:
        result = result.replace(from_, to)

    # Replace any instances of \1 with non-LaTeX equivalents, as these can be
    # used in component names.
    result = re.sub(r"\\\\(\d+)", r"\\backslash\1", result)

    if r"\\" in result:
        logger.debug(f"Unknown pgplot character in string: {result}")

    return result

pytao.plotting.settings

Classes

pytao.plotting.settings.QuickPlotPoint

Tao QuickPlot Point.

Attributes:

Name Type Description
x float
y float
units (str, optional)
Functions
pytao.plotting.settings.QuickPlotPoint.get_commands
get_commands(region_name, graph_name, parent_name)

Get command strings to apply these settings with Tao.

Parameters:

Name Type Description Default
region_name str

Region name.

required
graph_name str

Graph name.

required
parent_name str

Parent item name.

required

Returns:

Type Description
list of str

Commands to send to Tao to apply these settings.

Source code in pytao/plotting/settings.py
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
def get_commands(
    self,
    region_name: str,
    graph_name: str,
    parent_name: str,
) -> List[str]:
    """
    Get command strings to apply these settings with Tao.

    Parameters
    ----------
    region_name : str
        Region name.
    graph_name : str
        Graph name.
    parent_name : str
        Parent item name.

    Returns
    -------
    list of str
        Commands to send to Tao to apply these settings.
    """
    return [
        f"set graph {region_name}.{graph_name} {parent_name}%{key} = {value}"
        for key, value in asdict(self).items()
        if value is not None
    ]
pytao.plotting.settings.QuickPlotRectangle

Tao QuickPlot Rectangle.

Attributes:

Name Type Description
x1 float
x2 float
y1 float
y2 float
units (str, optional)
Functions
pytao.plotting.settings.QuickPlotRectangle.get_commands
get_commands(region_name, graph_name, parent_name)

Get command strings to apply these settings with Tao.

Parameters:

Name Type Description Default
region_name str

Region name.

required
graph_name str

Graph name.

required
parent_name str

Parent item name.

required

Returns:

Type Description
list of str

Commands to send to Tao to apply these settings.

Source code in pytao/plotting/settings.py
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
def get_commands(
    self,
    region_name: str,
    graph_name: str,
    parent_name: str,
) -> List[str]:
    """
    Get command strings to apply these settings with Tao.

    Parameters
    ----------
    region_name : str
        Region name.
    graph_name : str
        Graph name.
    parent_name : str
        Parent item name.

    Returns
    -------
    list of str
        Commands to send to Tao to apply these settings.
    """
    return [
        f"set graph {region_name}.{graph_name} {parent_name}%{key} = {value}"
        for key, value in asdict(self).items()
        if value is not None
    ]
pytao.plotting.settings.TaoAxisSettings

Bases: BaseModel

Tao per-axis (x, x2, y, or y2) settings in a graph.

Intended for use with:

tao.plot(..., settings=TaoGraphSettings(y=TaoAxisSettings(...))).

All attributes may be None. A value of None indicates that the setting should not be configured in Tao.

Not all parameters are useful for PyTao plotting. This class intends to support Tao's internal plotting mechanism as well for users who prefer to use it instead.

Attributes:

Name Type Description
bounds One of {"zero_at_end", "zero_symmetric", "general", "exact"}

Axis bounds.

min float

Left or bottom axis number range.

max float

Right or top axis number range.

number_offset float

Offset from the axis line in inches.

label_offset float

Offset from numbers in inches.

major_tick_len float

Major tick length in inches.

minor_tick_len float

Minor tick length in inches.

label_color str

Color of the label string.

major_div int

Number of major divisions.

major_div_nominal int

Major divisions nominal value.

minor_div int

Number of minor divisions, where 0 is automatic.

minor_div_max int

Maximum minor divisions, if minor_div is set to automatic (0).

places int

Number of digits to print.

tick_side -1, 0, or 1
  • 1: draw ticks to the inside
  • 0: draw ticks both inside and outside
  • -1: draw ticks to the outside
number_side -1 or 1
  • 1: draw numbers to the inside
  • -1: draw numbers to the outside
label str

Axis label string.

type log or linear

Axis type.

draw_label bool

Draw the label string.

draw_numbers bool

Draw the numbers.

Functions
pytao.plotting.settings.TaoAxisSettings.get_commands
get_commands(region_name, axis_name)

Get command strings to apply these settings with Tao.

Parameters:

Name Type Description Default
region_name str

Region name.

required
axis_name str

Axis name.

required

Returns:

Type Description
list of str

Commands to send to Tao to apply these settings.

Source code in pytao/plotting/settings.py
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
def get_commands(
    self,
    region_name: str,
    axis_name: str,
) -> List[str]:
    """
    Get command strings to apply these settings with Tao.

    Parameters
    ----------
    region_name : str
        Region name.
    axis_name : str
        Axis name.

    Returns
    -------
    list of str
        Commands to send to Tao to apply these settings.
    """
    items = {key: value for key, value in self.model_dump().items() if value is not None}
    scale = items.pop("scale", None)
    scale_gang = items.pop("scale_gang", None)

    commands = []
    if scale is not None:
        scale_low, scale_high = scale
        scale_cmd = {
            "x": "x_scale",
            "x2": "x_scale",
            "y": "scale -y",
            "y2": "scale -y2",
        }[axis_name]
        if scale_gang:
            scale_cmd = f"{scale_cmd} -gang"
        elif scale_gang is False:  # note: may be None
            scale_cmd = f"{scale_cmd} -nogang"
        commands.append(f"{scale_cmd} {region_name} {scale_low} {scale_high}")

    return commands + [
        f"set graph {region_name} {axis_name}%{key} = {value}"
        for key, value in items.items()
    ]
pytao.plotting.settings.TaoFloorPlanSettings

Bases: BaseModel

Tao graph settings specifically for floor plans.

Intended for use with:

tao.plot(..., settings=TaoGraphSettings(floor_plan=TaoFloorPlanSettings(...))).

All attributes may be None. A value of None indicates that the setting should not be configured in Tao.

Not all parameters are useful for PyTao plotting. This class intends to support Tao's internal plotting mechanism as well for users who prefer to use it instead.

Attributes:

Name Type Description
correct_distortion bool

Correct distortion. By default, the horizontal or vertical margins of the graph will be increased so that the horizontal scale (meters per plotting inch) is equal to the vertical scale. If correct_distortion is set to False, this scaling will not be done.

size_is_absolute bool

Shape sizes scaled to absolute dimensions. The size_is_absolute logical is combined with the setting for a shape to determine the size transverse to the center line curve of the drawn shape. If size_is_absolute is False (the default), is taken to be the size of the shape in points (72 points is approximately 1 inch). If size_is_absolute is True, is taken to be the size in meters. That is, if size_is_absolute is False, zooming in or out will not affect the size of an element shape while if size_is_absolute is True, the size of an element will scale when zooming.

draw_only_first_pass bool

Suppresses drawing of multipass_slave lattice elements that are associated with the second and higher passes. Setting to True is only useful in some extreme circumstances where the plotting of additional passes leads to large pdf/ps file sizes.

flip_label_side bool

Draw element label on other side of element.

rotation float

Rotation of floor plan plot: 1.0 -> 360 deg. An overall rotation of the floor plan can be controlled by setting rotation parameter. A setting of 1.0 corresponds to 360◦. Positive values correspond to counter-clockwise rotations. Alternatively, the global coordinates at the start of the lattice can be defined in the lattice file and this can rotate the floor plan. Unless there is an offset specified in the lattice file, a lattice will start at (x, y) = (0, 0). Assuming that the machine lies in the horizontal plane with no negative bends, the reference orbit will start out pointing in the negative x direction and will circle clockwise in the (x, y) plane.

orbit_scale float

Scale for the orbit. If 0 (the default), no orbit will be drawn.

orbit_color str

Orbit color.

orbit_lattice One of {"model", "design", "base"}

Orbit lattice.

orbit_pattern str

Orbit pattern.

orbit_width int

Orbit width.

view One of {"xy", "xz", "yx", "yz", "zx", "zy"}
Functions
pytao.plotting.settings.TaoFloorPlanSettings.get_commands
get_commands(region_name, graph_name)

Get command strings to apply these settings with Tao.

Parameters:

Name Type Description Default
region_name str

Region name.

required
graph_name str

Graph name.

required

Returns:

Type Description
list of str

Commands to send to Tao to apply these settings.

Source code in pytao/plotting/settings.py
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
def get_commands(
    self,
    region_name: str,
    graph_name: str,
) -> List[str]:
    """
    Get command strings to apply these settings with Tao.

    Parameters
    ----------
    region_name : str
        Region name.
    graph_name : str
        Graph name.

    Returns
    -------
    list of str
        Commands to send to Tao to apply these settings.
    """
    return [
        f"set graph {region_name} floor_plan%{key} = {value}"
        for key, value in self.model_dump().items()
        if value is not None
    ]
pytao.plotting.settings.TaoGraphSettings

Bases: BaseModel

Per-graph settings for Tao.

Intended for use with tao.plot(..., settings=TaoGraphSettings()).

All attributes may be None. A value of None indicates that the setting should not be configured in Tao.

Not all parameters are useful for PyTao plotting. This class intends to support Tao's internal plotting mechanism as well for users who prefer to use it instead.

Attributes:

Name Type Description
text_legend Dict[int, str]

Dictionary of text legend index to legend string. The text legend is a legend that can be setup by either the user or by Tao itself. Tao uses the text legend in conjunction with phase space plotting or histogram displays. The text legend is distinct from the curve legend.

allow_wrap_around bool

If plot%x_axis_type is set to "s", and if the plotted data is from a lattice branch with a closed geometry, and if graph%x%min is negative, then the graph%allow_wrap_around parameter sets if the curves contained in the graph are “wrapped around” the beginning of the lattice so that the curves are not cut off at s = 0. The Tao default is True.

box Dict[int, int]

The graph%box parameter sets the layout of the box which the graph is placed. The Tao default is 1,1,1,1 which scales a graph to cover the entire region the plot is placed in.

commands List[str]

Custom commands to be sent to Tao for this graph. Each string will be formatted with the following keys: * settings - the TaoGraphSettings object itself * region - the region name (e.g., r12) * graph_name - the graph name (e.g., g) * graph_type - the graph type (e.g., lat_layout) * graph - the full graph name (e.g., r12.g)

component str

Who to plot - applied to all curves. For example: 'meas - design' A "data" graph is used to draw lattice parameters such as orbits, or Tao data, or variable values such as quadrupole strengths. The data values will depend upon where the data comes from. This is determined, in part, by the setting of the component parameter in the tao_template_graph namelist. The component may be one of:

"model", for model values. This is the default.
"design", for design values.
"base", for base values.
"meas", for data values.
"ref", for reference data values.
"beam_chamber_wall", for beam chamber wall data.

Additionally, component may be set to plot a linear combination of the above. For example: "model - design" This will plot the difference between the model and design values.

clip bool

Clip curves at the boundary.

curve_legend_origin tuple[float, float, str] or QuickPlotPoint

The curve legend displays which curves are associated with which of the plotted lines and symbols. This defines where the upper left hand corner of the legend is.

draw_axes bool

Draw the graph axes.

draw_title bool

Draw the graph title.

draw_curve_legend bool

Draw the curve legend.

draw_grid bool

Draw the graph grid.

draw_only_good_user_data_or_vars bool

When plotting Tao data or variables, if draw_only_good_user_data_or_vars is set to True (the default), symbol points of curves in the graph associated with data or variables whose good_user parameter is set to False will be ignored. That is, data and variables that will not be used in an optimization will be ignored. If draw_only_good_user_data_or_vars is set to False, data or variables that have a valid value will be plotted.

floor_plan TaoFloorPlanSettings

Settings only for floor plan graphs.

ix_universe int

The default universe for curves of the graph.

ix_branch int

The default branch for curves of the graph.

margin tuple[float, float, float, float, str] or QuickPlotRectangle

Margin between the graph and the box: (x1, x2, y1, y2, units)

scale_margin Union[QuickPlotRectangle, QuickPlotRectangleTuple]

(x1, x2, y1, y2, units) Used to set the minimum space between what is being drawn and the edges of the graph when a scale, x_scale, or an xy_scale command is issued. Normally this is zero but is useful for floor plan drawings.

symbol_size_scale float

Symbol size scale.

text_legend_origin tuple[float, float, float, float, str] or QuickPlotRectangle

(x1, x2, y1, y2, units) Text legend origin.

title str

The title component is the string printed just above the graph box. The full string will also include information about what is being plotted and the horizontal axis type. To fully suppress the title leave it blank. Note: A graph also has a title_suffix which Tao uses to hold the string which is printed to the right of the graph%title. This string contains information like what curve%component is being plotted. The graph%title_suffix cannot be set by the user.

type str

The type of graph. Tao knows about the following types:

  • "data"

Lattice parameters, data and/or variable plots (default)

With type set to "data", data such as orbits and/or variable values such as quadrupole strengths are plotted. Here “data” can be data from a defined data structure or computed directly from the lattice, beam tracking, etc. A "data" graph type will contain a number of curves and multiple data and variable curves can be drawn in one graph.

  • "floor_plan"

With type set to "floor_plan", the two dimensional layout of the machine is drawn.

  • "dynamic_aperture"

Dynamic aperture plot.

  • "histogram"

With type set to "histogram", such things such as beam densities can be his- togrammed.

  • "lat_layout"

With type set to "lat_layout", the elements of the lattice are symbolical drawn in a one dimensional line as a function of the longitudinal distance along the machine centerline.

  • "phase_space"

With type set to "phase_space", phase space plots are produced.

  • "key_table" - unsupported by PyTao plotting.

With type set to "key_table", the key bindings for use in single mode are displayed. Note: The "key_table" graph type does not have any associated curves.

x TaoAxisSettings

Primary x-axis settings.

x2 TaoAxisSettings

Secondary x-axis settings.

y TaoAxisSettings

Primary y-axis settings.

y2 TaoAxisSettings

Secondary y-axis settings.

y2_mirrors_y bool

Keep y2 min/max the same as y-axis.

x_axis_scale_factor float

Sets the horizontal x-axis scale factor. For a given datum value, the plotted value will be: x(plotted) = scale_factor * x(datum) The default value is 1. For example, a %x_axis_scale_factor of 1000 will draw a 1.0 mm phase space z value at the 1.0 mark on the horizontal scale. That is, the horizontal scale will be in millimeters. Also see curve(N)%y_axis_scale_factor.

Functions
pytao.plotting.settings.TaoGraphSettings.get_commands
get_commands(region_name, graph_name, graph_type)

Get command strings to apply these settings with Tao.

Parameters:

Name Type Description Default
region_name str

Region name.

required
graph_name str

Graph name.

required
graph_type str

Graph type. Required to determine which commands to send - that is, TaoFloorPlanSettings will be skipped for non-floor plan graphs.

required

Returns:

Type Description
list of str

Commands to send to Tao to apply these settings.

Source code in pytao/plotting/settings.py
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
def get_commands(
    self,
    region_name: str,
    graph_name: str,
    graph_type: str,
) -> List[str]:
    """
    Get command strings to apply these settings with Tao.

    Parameters
    ----------
    region_name : str
        Region name.
    graph_name : str
        Graph name.
    graph_type : str
        Graph type.  Required to determine which commands to send - that is,
        `TaoFloorPlanSettings` will be skipped for non-floor plan graphs.

    Returns
    -------
    list of str
        Commands to send to Tao to apply these settings.
    """
    result = []
    for key in self.model_dump().keys():
        value = getattr(self, key)
        if value is None:
            continue

        if key == "commands":
            result.extend(
                [
                    cmd.format(
                        settings=self,
                        region=region_name,
                        graph_name=graph_name,
                        graph_type=graph_type,
                        graph=f"{region_name}.{graph_name}",
                    )
                    for cmd in value
                    if cmd
                ]
            )
            continue
        if key in ("curve_legend_origin",) and isinstance(value, tuple):
            value = QuickPlotPoint(*value)
        elif key in ("scale_margin", "margin", "text_legend_origin") and isinstance(
            value, tuple
        ):
            value = QuickPlotRectangle(*value)

        if isinstance(value, QuickPlotPoint):
            result.extend(value.get_commands(region_name, graph_name, key))
        elif isinstance(value, TaoFloorPlanSettings):
            result.extend(value.get_commands(region_name, graph_name))
        elif isinstance(value, QuickPlotRectangle):
            result.extend(value.get_commands(region_name, graph_name, key))
        elif isinstance(value, TaoAxisSettings):
            result.extend(value.get_commands(region_name, key))
        elif key == "n_curve_points":
            result.append(f"set plot {region_name} n_curve_pts = {value}")
        elif key == "text_legend":
            for legend_index, legend_value in value.items():
                result.append(
                    f"set graph {region_name} text_legend({legend_index}) = {legend_value}"
                )
        elif key == "box":
            for box_index, box_value in value.items():
                result.append(f"set graph {region_name} box({box_index}) = {box_value}")
        elif isinstance(value, TaoFloorPlanSettings):
            if graph_type == "floor_plan":
                result.extend(value.get_commands(region_name, graph_name))
        else:
            result.append(f"set graph {region_name}.{graph_name} {key} = {value}")
    return result