Element Selection Syntax
With the introduction of loading purely element layouts without any tracking details of a lattice from PALS #1066, it becomes timely to introduce a lattice element query/selection syntax/API (in Python).
With such a syntax, we can create read/write views into the lattice to manipulate properties like element model approximately to use (linear/paraxial/exact), modeling of collective effects, and numerical parameters.
Many other coded have this feature, and typical afe queries by kind of the element, regex by name, etc.
Examples:
Another pretty common operation we need with respect to selecting elements are transformations (translations & rotations) of element groups. One can imagine this like aligning a lens on an optical table: there is a lot of drift everywhere, and a few optical (beamline: em) elements are placed in drift regions to modify the beam.
For instance, quite often a whole quadrupole triplet as a whole is moved on a beamline as a whole (along all positional axes) or even rotated as a whole. The triplet is kinda "embedded" in drift sections, which need to be increased/reduced proportionally as the whole selection moves. Before/after the drift (selection), ever element stays globally as it is.
A simpler example is a slit aperture that might be positioned/moved before/behind dipole magnets in a drift region. The drift region is cut by the aperture in two, but stays overall the same lengths as the aperture is moved within it.
Kinda duplicated from #884
I wish we could do lattice[kind=..., name=...], but PEP637 was rejected. So we need to use a .select() syntax instead.