API Reference¶
Everything below is exported from the top-level palsparserpy package, so
pp.parse_and_expand_pals(...) reaches it after import palsparserpy as pp.
The tree objects¶
- class palsparserpy.YAMLNode(tree, node_id)[source]¶
Bases:
objectA reference to a single node within a
YAMLTree.Holding a
YAMLNodekeeps its tree alive. Node ids are invalidated if the tree is deleted.- tree¶
- id¶
- is_map()[source]¶
Whether this node is a MAP (a collection of key/value pairs).
A node is exactly one of MAP, sequence, or scalar; use this to decide before accessing children by key.
- Return type:
- is_sequence()[source]¶
Whether this node is a sequence (an ordered list of elements).
A node is exactly one of MAP, sequence, or scalar; use this to decide before accessing children by index.
- Return type:
- is_scalar()[source]¶
Whether this node is a scalar (a leaf holding a single string, number or boolean value).
Scalar nodes have no children and their value is read with
value,as_int(),as_float()oras_bool().- Return type:
- parent()[source]¶
The parent of this node. Raises
ValueErrorfor the root, which has no parent.- Return type:
- root()[source]¶
The root of the tree this node belongs to (this node itself if it is the root).
- Return type:
- child(index)[source]¶
The
index-th direct child of a MAP or sequence node, 0-based.Unlike
node[key], this reaches a MAP’s children by position, which is how a single-key map entry is opened without knowing its key.
- get(key, default=None)[source]¶
The child stored under
key, ordefaultif there is none.- Parameters:
key (str)
- __getitem__(key)[source]¶
node[key]looks up a direct child of a MAP by its string key;node[i]returns thei-th direct child of a MAP or sequence.Only direct children are searched (the lookup is not recursive). Raises
KeyErrorif no child has the given key – test withkey in nodeif it may be absent – andIndexErrorif the index is out of bounds.
- __contains__(key)[source]¶
Whether the MAP node has a direct child stored under
key. Only direct children are checked; the search is not recursive.
- __len__()[source]¶
The number of direct children: the number of key/value pairs in a MAP, or the number of elements in a sequence. Scalar nodes report 0.
- Return type:
- __iter__()[source]¶
Iterate the node’s children: a sequence yields its elements, a MAP yields its keys (as
dictdoes; useitems()for pairs), and a scalar yields nothing.- Return type:
- node_key()[source]¶
The key under which this node is stored in its parent MAP, or
Noneif it has none. Sequence elements and the tree root have no key.- Return type:
str | None
- property value: str¶
The scalar value of this node, as raw text.
Raises
ValueErrorif the node has no value (i.e. it is a MAP or a bare sequence). Useas_int(),as_float()oras_bool()for typed values.
- as_int()[source]¶
The scalar value parsed as an
int. Raises if the node is not a scalar or its text is not a valid integer.- Return type:
- as_float()[source]¶
The scalar value parsed as a
float. Raises if the node is not a scalar or its text is not a valid floating-point number.- Return type:
- as_bool()[source]¶
The scalar value parsed as a
bool.Accepts exactly the text
trueorfalse; any other value (or a non-scalar node) raisesValueError.- Return type:
- add_scalar(value, key=None, index=None)[source]¶
Add a scalar child to this node.
Pass
keyfor MAP parents; omit it for sequence elements.indexselects the 0-based position among the existing children; the default appends at the end.
- add_map(key=None, index=None)[source]¶
Add an empty MAP child to this node.
Pass
keyfor MAP parents; omit it for sequence elements.indexselects the 0-based position among the existing children; the default appends at the end.
- add_sequence(key=None, index=None)[source]¶
Add an empty sequence child to this node.
Pass
keyfor MAP parents; omit it for sequence elements.indexselects the 0-based position among the existing children; the default appends at the end.
- __setitem__(key, value)[source]¶
node[key] = valuesets or updates a scalar value in a MAP node.If
keyalready exists its value is updated; otherwise a new scalar child is appended.
- set_scalar(value)[source]¶
Set or replace the scalar value of this node.
Operates on an existing node in place; to set a value by key within a MAP (adding the key if absent), use
node[key] = valueinstead.- Parameters:
value (str)
- Return type:
None
- set_key(key)[source]¶
Set or replace the key under which this node is stored in its parent MAP. Only meaningful inside a MAP; sequence elements are keyless.
- Parameters:
key (str)
- Return type:
None
- remove()[source]¶
Remove this node, together with all of its descendants, from its parent.
After removal the
YAMLNodeis stale and must not be used again. Intended for non-root nodes; the root has no parent to be removed from.- Return type:
None
- deep_copy_node(src)[source]¶
Copy the type, key, value and all descendants of
srcinto this node, overwriting whatever it previously held. Works across trees.- Parameters:
src (YAMLNode)
- Return type:
None
- deep_copy_children(src, index=None)[source]¶
Copy all children of
srcinto this node at the 0-based positionindexamong the existing children; the default appends them at the end. Works across trees.
- to_yaml_string(exclude=())[source]¶
Emit this node and its descendants as a YAML string.
excludeis a key name, or a collection of key names, to be left out of the output: every MAP entry whose key matches, at any depth, is omitted along with its whole subtree. This is a display filter only – the node itself is never modified. For example, to print a lattice without the floor and reference subtrees:print(lat.to_yaml_string(exclude=["FloorP", "ReferenceP"]))
- write_yaml(filename, exclude=())[source]¶
Write the entire tree that contains this node to a YAML file.
Returns
Trueon success.excludeis a key name, or a collection of key names, to be left out of the file: every MAP entry whose key matches, at any depth, is omitted along with its whole subtree. The tree in memory is not modified. For example:lat.write_yaml("out.pals.yaml", exclude=["FloorP", "ReferenceP"])
- class palsparserpy.YAMLTree(handle)[source]¶
Bases:
objectOwns a C
YAMLTreeHandle. Freed automatically when the object is garbage collected. Do not use the handle after the tree has been freed.- handle¶
- exception palsparserpy.PALSParseError[source]¶
Bases:
ValueErrorA YAML document could not be parsed.
The message carries what the C library reported – for a syntax error, prefixed with the offending
line L, column C:– so the fault can be pinpointed instead of reported as a bare failure.
Parsing and building¶
- palsparserpy.parse_file(filename)[source]¶
Parse a YAML file from disk. Returns a node pointing to the tree root.
- Return type:
Function forms of the node operations¶
Each of these is the free-function spelling of the like-named
YAMLNode method above.
- palsparserpy.is_map(node)[source]¶
Whether
nodeis a MAP. SeeYAMLNode.is_map().
- palsparserpy.is_sequence(node)[source]¶
Whether
nodeis a sequence. SeeYAMLNode.is_sequence().
- palsparserpy.is_scalar(node)[source]¶
Whether
nodeis a scalar. SeeYAMLNode.is_scalar().
- palsparserpy.get_parent(node)[source]¶
The parent of
node. SeeYAMLNode.parent().
- palsparserpy.node_key(node)[source]¶
The key
nodeis stored under. SeeYAMLNode.node_key().
- palsparserpy.add_scalar(parent, value, key=None, index=None)[source]¶
Add a scalar child to
parent. SeeYAMLNode.add_scalar().
- palsparserpy.add_map(parent, key=None, index=None)[source]¶
Add an empty MAP child to
parent. SeeYAMLNode.add_map().
- palsparserpy.add_sequence(parent, key=None, index=None)[source]¶
Add an empty sequence child to
parent. SeeYAMLNode.add_sequence().
- palsparserpy.set_scalar(node, value)[source]¶
Set the scalar value of
node. SeeYAMLNode.set_scalar().
- palsparserpy.set_key(node, key)[source]¶
Set the key of
node. SeeYAMLNode.set_key().
- palsparserpy.remove(node)[source]¶
Remove
nodefrom its parent. SeeYAMLNode.remove().- Parameters:
node (YAMLNode)
- Return type:
None
- palsparserpy.deep_copy_node(dst, src)[source]¶
Copy
srcintodst. SeeYAMLNode.deep_copy_node().
- palsparserpy.deep_copy_children(dst, src, index=None)[source]¶
Copy the children of
srcintodst. SeeYAMLNode.deep_copy_children().
- palsparserpy.to_yaml_string(node, exclude=())[source]¶
Emit
nodeas YAML. SeeYAMLNode.to_yaml_string().
Lattices¶
- palsparserpy.parse_and_expand_pals(filename, root_lattice='', *, problems='print')[source]¶
Parse a PALS lattice file and return its five views.
Returns a
Latticesholding theoriginal,combined,expanded,full_expandedandadjunctviews together with the list of expansionproblems.- Parameters:
filename – Path to the top-level YAML lattice file.
root_lattice (str) –
Name of the lattice to expand. If empty (the default), the lattice to expand is chosen with the following priority:
the lattice named by the last
usestatement, orthe last lattice defined in the file if no
usestatement is present.
What to do with the list of problems found while expanding (undefined lattice, dangling element/line references, undefined
inherit/repeat/Forktargets, and expressions that could not be evaluated). One of:"print"(the default) – print the problems tostderr(nothing is printed when there are none);"none"– do nothing (no printing, no file);any other path – write the problems to that file, printing nothing. Those two names are reserved, so a report cannot be written to a file called
printornone.
- Return type:
The same problems handed to
problemsare also returned in theproblemsfield regardless of the reporting mode, so"none"still lets the caller inspect them programmatically. Each entry carries amessage, thepathit was found at, aseverityand anorigin; only aPROBLEM_INPUTcan be cleared by editing the lattice.The five tree views are:
original: the tree as read in, mapping each file (including any file it includes or loads) to its unparsed contents.combined: the tree with allincludedirectives resolved and spliced inline, and everyloadmerged in subnode by subnode.full_expanded: the selected lattice fully expanded, and nothing else – scalars substituted with their full definitions, everyrepeatunrolled, everyinheritmerged in, forks resolved,setcommands executed and ABSOLUTE controllers applied. It is rooted at a map holding the singlename -> Latticeentry, without thePALS/facilityscaffolding the lattice was defined under, so the lattice is reached aslat.full_expanded["lat1"]rather than through["PALS"]["facility"]. Itsbranchesentries are branches, not theBeamLine``s they were built from, and so carry no ``kind; aBeamLinereferenced inside alineis a sub-line whose contents are spliced directly into the enclosing line, so no nestedBeamLinesurvives in the expanded tree. Elements of amultipassline carry amultipass_indexgiving their pass number – how many times a particle will have travelled through that physical element by that point – so every element of one traversal shares an index (the nearest enclosingmultipassline wins when they nest). Every dependent parameter is computed and present: each element carries itselement_index(its position, counting from one, in the branch line that holds it), itsReferenceP,FloorPands_position, the derived members of every parameter family it uses, and the non-zero defaults of the groups it carries; each branch is capped with abranch_endPlaceholderholding its final reference and floor, numbered with the rest.expanded: the same lattice with all of that removed – what the author wrote decides which parameters stay. It isfull_expandedwith nodes pruned rather than an earlier snapshot, so a parameter present in both views holds the same value in both. Use it to see the inputs rather than their consequences, or to write a lattice back out without the computed values.adjunct: everything the expanded views do not carry, keeping itsPALS/facilityscaffolding: element and beamline definitions,usestatements, constants and variables,Controller``s, ``setcommands, and anyLatticethat was not the one expanded. A definition that expansion substituted into the lattice is copied, so it appears in both trees.
Every mathematical expression is evaluated to a number across the expanded views and
adjunct(seeevaluate_pals_expression();random()/random_gauss()are left as text).Controllerelements are evaluated against their own scoped variable tables, with each controlexpressioncomputed and stored back in its control entry; controllers are facility-level, so they are found inadjunct.Each view is backed by its own tree; all five are freed independently when their nodes are garbage collected.
- palsparserpy.evaluate_pals_expression(expr)[source]¶
Evaluate a single PALS mathematical expression to a
float.Supports the full PALS expression grammar: arithmetic (
+ - * / ^), unary signs, parentheses, the built-in constants (pi,c_light,r_electron, …), the math functions (sqrt,log,sin,floor,modulo, …), and the particle-data functionsmass_of,charge_ofandanomalous_moment_of(backed by AtomicAndPhysicalConstantsCLib), whose species-name argument must be quoted, e.g.mass_of("#3He")(a mass number carries a leading#). A leadingexpr(...)wrapper is accepted and unwrapped.This evaluates a standalone string, so user-defined constants and variables are not in scope – use
parse_and_expand_pals()for whole-lattice evaluation, whose expanded trees already have every expression resolved to a number. RaisesValueErrorifexpris not evaluable: a parse error, an unknown identifier or species, arandom()/random_gauss()expression (which is intentionally deferred), or a non-finite result.Example
>>> evaluate_pals_expression("3.75e7 / c_light^2") # 4.172...e-10 >>> evaluate_pals_expression('mass_of("electron")') # 510998.95069... >>> evaluate_pals_expression("expr(2 * pi)") # 6.283...
- palsparserpy.node_correspondence(lat)[source]¶
Map every node of a lattice to the nodes it corresponds to across the
original,combined,full_expandedandadjuncttrees.The correspondence is exact: it is computed from provenance recorded while the trees were derived from one another (
original->combined->full_expandedandadjunct), not by re-matching after the fact. Because expansion can duplicate a node (scalar substitution,repeat,inherit, forks), the correspondence is one-to-many – a singlecombined/originalnode can map to severalfull_expandedcopies – so each field of the returned value is a list of nodes.Expansion splits the document, so a node of
combinedmay land infull_expanded, inadjunct, or in both: a definition that was substituted into the lattice is copied there while its definition stays behind. Those copies share one equivalence class, tied together through thecombinednode they came from.The
expandedview takes no part in the correspondence: it is a pruned copy offull_expandedrather than a step in the derivation chain, so a node in it is found by the path it sits at, not by a recorded link.- Returns:
A
dictkeyed by node. For any node that participates in the correspondence,corr[node]is aNodeCorrespondence–(original, combined, full_expanded, adjunct)– listing every corresponding node grouped by tree. The queried node appears in its own tree’s list, so the four lists together are the full equivalence class ofnode. A list is empty when a tree has no corresponding node (e.g. the synthesiseddestination_pointerscalar exists only infull_expanded, and a constant that the lattice never references exists only inadjunct).- Parameters:
lat (Lattices)
- Return type:
Example
>>> lat = parse_and_expand_pals("lattice.pals.yaml") >>> corr = node_correspondence(lat) >>> a_const = lat.combined["PALS"]["facility"][0]["constants"]["a_const"] >>> corr[a_const].original # the same constant in the original tree >>> corr[a_const].adjunct # constants are not part of the lattice >>> corr[a_const].full_expanded # empty unless the lattice referenced it
- palsparserpy.match_names(node, match_string)[source]¶
Every named construct in
node’s tree that is matched bymatch_string, following PALS Name Matching.nodemay be any node of the tree to search (typically a lattice-view root such aslat.full_expanded); the whole tree is searched and the returned nodes belong to that same tree.match_stringhas the form:[{lattice}>>>][{branch}>>][{kind}::]{name}[>{group}.{sub}. ... .{parameter}]
{lattice},{branch}and{name}are PCRE2 patterns matched against the whole name (anchored at both ends);{kind}is matched exactly; the parameter path after the single>is matched exactly, key by key. An omitted or empty pattern matches any name at that level.{branch}matches an element if any enclosing BeamLine/Branch name matches, so elements in sub-lines are included.The node returned for each match is whatever the string resolves to: the element node (no parameter path), the parameter-group or parameter node (with a path), or – for a bare name (no lattice/branch/kind qualifier and no parameter path) – additionally each matching constant and variable defined directly under the
PALSorfacilitynode (both the fullkind: constant/kind: variableand the compactconstants:/variables:forms). Lattice parameters therefore include constant and variable names.Which tree to search follows from that: elements are in
lat.full_expanded, while constants and variables are defined at facility level and so are found inlat.adjunct. Searchinglat.full_expandedfor a constant matches nothing, since thePALS/facilitynode it would be defined under is not part of that tree.Not yet implemented from Element Name Matching:
#Ninstance selection,{e1}:{e2}ranges,,unions, and&intersections.Results are de-duplicated and returned in document order. A malformed pattern yields an empty list.
Example
>>> lat = parse_and_expand_pals("lattice.pals.yaml") >>> match_names(lat.full_expanded, "B1.*>BendP.e1") # e1 of every B1... bend >>> match_names(lat.full_expanded, "Quadrupole::.*") # every quadrupole >>> match_names(lat.full_expanded, "inj>>>arc>>Q.*>length") >>> match_names(lat.adjunct, "a_.*") # constants/variables
- palsparserpy.parameter_value(lat, match_string)[source]¶
The value of the lattice parameter named by
match_string, looked up in the expanded latticelat.match_stringuses the same PALS Name Matching syntax asmatch_names(). It names either an element parameter (with a>{group}.{sub}. ... .{parameter}path) or, as a bare name (no lattice/branch/kind qualifier and no path), a constant or variable – the same constructsmatch_names()resolves.Only two of
lat’s five views are searched:lat.full_expanded, which holds the element parameters, and then, if the name is not found there,lat.adjunct, which holds the facility-level constants, variables, and any definitions not spliced into the lattice. The rawlat.originalandlat.combinedviews are not searched – they carry unevaluated, pre-expansion text.lat.expandedis not searched either: a dependent parameter is a legitimate thing to ask for, and onlyfull_expandedcarries one.Because both searched views are post-expansion, values come back already evaluated: a numeric value as a
float, and a non-numeric one (e.g. a species name like"#3He", or an expression expansion left unevaluated such as one usingrandom()) verbatim as astr.The value is resolved as follows:
Element parameter, set: its value – a
float, or astrwhen non-numeric.Element parameter, not set: the parameter’s default is returned (
0.0for every parameter, for now – real per-parameter defaults come later).Constant or variable (bare name): its value, the same way.
Nothing identified:
None, when the name matches nothing in either view, names a bare element (an element has no single scalar value), stops on a whole parameter group, or several matches carry conflicting values.
Example
>>> lat = parse_and_expand_pals("lattice.pals.yaml") >>> parameter_value(lat, "quad1>MagneticMultipoleP.Bn1") # 1.0 >>> parameter_value(lat, "quad1>BendP.g") # 0.0 (unset) >>> parameter_value(lat, "a_const") # from adjunct >>> parameter_value(lat, "quad1>nope.nope") # None
What expansion hands back¶
- class palsparserpy.Lattices(original, combined, expanded, full_expanded, adjunct, problems=<factory>)[source]¶
Bases:
objectFive representations of a lattice, each as a root
YAMLNode, plus the list of problems found while expanding it.expandedandfull_expandedare the same expanded lattice holding the same values;full_expandedadditionally carries every parameter the bookkeeper computed, whileexpandedkeeps only what the author wrote. Seepalsparserpy.parse_and_expand_pals()for what each view holds.problemsis a list ofProblem– one entry per problem encountered during expansion (undefined lattice, dangling element/line references, undefinedinherit/repeat/Forktargets, misspelled names, and expressions that could not be evaluated). It is empty when expansion was clean. Filter it onseverityororiginto decide what is worth acting on:lat = parse_and_expand_pals("ex.pals.yaml", problems="none") mine = [p for p in lat.problems if p.origin is PROBLEM_INPUT]
- Parameters:
- class palsparserpy.Problem(message, path, severity, origin)[source]¶
Bases:
objectOne problem found while reading or expanding a document.
message– human-readable description, always present.path– the logical spot it was found at, such as"q1>ApertureP.shape". Empty when the problem is not tied to one place. This is a location within the document, not a file name or a line number;messagealready names the file where the file is the point.severity– aProblemSeverity: can the trees still be trusted?origin– aProblemOrigin: whose problem is it?
Only a
PROBLEM_INPUTcan be cleared by editing the lattice, which is what makes the last field worth reading: a tool that fails on any problem at all will fail on lattices whose author has nothing left to fix.- Parameters:
message (str)
path (str)
severity (ProblemSeverity)
origin (ProblemOrigin)
- severity: ProblemSeverity¶
- origin: ProblemOrigin¶
- class palsparserpy.ProblemSeverity(*values)[source]¶
Bases:
IntEnumWhether a problem leaves the expanded trees trustworthy.
ERROR– the document is wrong here and expansion could not work around it. Do not trust the affected part of the trees.WARNING– expansion produced a usable result; something was assumed or skipped, but the trees are still sound.
Mirrors
enum problem_severityin PALSParserCpp.h.- ERROR = 0¶
- WARNING = 1¶
- class palsparserpy.ProblemOrigin(*values)[source]¶
Bases:
IntEnumWho has to act on a problem.
INPUT– the document is wrong; the lattice author can fix it.UNSUPPORTED– valid PALS that PALSParserCpp does not implement yet. Editing the lattice will not clear it.UNSPECIFIED– the PALS standard does not define the case, so nothing was invented. Neither the author nor the library is in the wrong.
Mirrors
enum problem_originin PALSParserCpp.h.- INPUT = 0¶
- UNSUPPORTED = 1¶
- UNSPECIFIED = 2¶
- class palsparserpy.NodeCorrespondence(original, combined, full_expanded, adjunct)[source]¶
Bases:
NamedTupleThe nodes one logical entity maps to in each of the four derivation-chain trees, grouped by tree.
expandedtakes no part – it is a pruned copy offull_expanded, not a step in the chain. A field is empty when a tree has no corresponding node.- Parameters:
Translation¶
- palsparserpy.pals_to_bmad(yaml)[source]¶
Translate a parsed PALS lattice
yaml(as returned byparse_file()) into aBmadLattice.The returned structure is an in-memory model of the Bmad lattice (elements, beamlines, parameters), not the input PALS tree. Translation is a three-step process: parse the PALS file with
parse_file, build the target model withpals_to_bmad, then emit the Bmad lattice file withwrite_bmad_file():yaml = parse_file(file_dir) write_bmad_file(pals_to_bmad(yaml), filename)
- Parameters:
yaml (YAMLNode)
- Return type:
- palsparserpy.write_bmad_file(lat, filename)[source]¶
Serialize the
BmadLatticelattofilenameas a Bmad lattice file.Write the constant and variable definitions, the global, beginning-Twiss and particle-start parameters, the element definitions, the
overlay/groupdefinitions, the beamline (line) definitions, and the branch (use) statement, each in its own labelled section. The constants come first because Bmad, unlike PALS, resolves a name against what the file has defined above the point of use.- Parameters:
lat (BmadLattice)
- Return type:
None
- class palsparserpy.BmadLattice(constants=<factory>, parameters=<factory>, beginning=<factory>, particle_start=<factory>, elements=<factory>, controllers=<factory>, beamlines=<factory>, use=<factory>)[source]¶
Bases:
objectAn in-memory model of a Bmad lattice.
Produced by
pals_to_bmad()and serialized to a file bywrite_bmad_file(). The fields mirror the sections of a Bmad lattice file:constants:name = valuedefinitions, in definition order.parameters: globalparameter[...] = ...settings (species, energy, geometry).beginning:beginning[...] = ...initial Twiss, coupling and dispersion settings.particle_start:particle_start[...] = ...initial-coordinate settings.elements: element definitions (BmadEleDef).controllers:overlay/groupdefinitions (BmadController).beamlines:linedefinitions (BmadBeamline).use: branch names for the finaluse, ...statement.
- Parameters:
- elements: List[BmadEleDef]¶
- controllers: List[BmadController]¶
- beamlines: List[BmadBeamline]¶
- class palsparserpy.BmadEleDef(name, type, attrs=<factory>)[source]¶
Bases:
objectA single Bmad element definition.
name: the element name.type: the Bmad element-type name (e.g.Drift,Quadrupole).attrs: already-translated attribute fragments, each an"attribute = value"string.
- class palsparserpy.BmadBeamline(name, members=<factory>)[source]¶
Bases:
objectA Bmad
linedefinition: itsnameand the ordered list of member elementmembers(by name).
- class palsparserpy.BmadController(name, type, slaves=<factory>, vars=<factory>, inits=<factory>)[source]¶
Bases:
objectA Bmad
overlayorgroupelement: what a PALSControllerbecomes.name: the controller name.type:"overlay"forcontrol_type: ABSOLUTE,"group"forRELATIVE. Bmad’s overlay sets the slave parameter and its group adds to it, which is the same split PALS makes.slaves: the controlled parameters, each an"ele[attribute]: expression"string.vars: the variable names, in definition order.inits: the variables’ initial values, each a"name = value"string.
- palsparserpy.pals_to_madx(yaml)[source]¶
Translate a parsed PALS lattice
yaml(as returned byparse_file()) into aMadxLattice.The returned structure is an in-memory model of the MAD-X lattice (elements, lines, beam), not the input PALS tree. Translation is a three-step process: parse the PALS file with
parse_file, build the target model withpals_to_madx, then emit the MAD-X lattice file withwrite_madx_file():yaml = parse_file(file_dir) write_madx_file(pals_to_madx(yaml), filename)
Controllers are translated after the elements, in a second pass: a
control_type: RELATIVEcontroller adds to the value the element already carries, and the only place that value is written down is the element definition this pass has just built.- Parameters:
yaml (YAMLNode)
- Return type:
- palsparserpy.write_madx_file(lat, filename)[source]¶
Serialize the
MadxLatticelattofilenameas a MAD-X lattice file.Write the constant and variable definitions, the
BEAMcommand and initial conditions, the element definitions, the controller variables and their deferred assignments, thelinedefinitions, theusestatement, and theEALIGNmisalignments, each in its own labelled section.The order of the sections is the order MAD-X needs them in, which is stricter than Bmad’s: a name has to be defined above the point of use,
BEAMhas to come beforeUSE, and theSELECT/EALIGNpairs have to come after it, because there is no sequence to apply an error to until one has been expanded.- Parameters:
lat (MadxLattice)
- Return type:
None
- class palsparserpy.MadxLattice(constants=<factory>, beam=<factory>, beta0=<factory>, particle_start=<factory>, elements=<factory>, controllers=<factory>, alignments=<factory>, beamlines=<factory>, use=<factory>, rigidity=False)[source]¶
Bases:
objectAn in-memory model of a MAD-X lattice.
Produced by
pals_to_madx()and serialized to a file bywrite_madx_file(). The fields mirror the sections of a MAD-X lattice file:constants:name = value;definitions, in definition order.beam: the attributes of theBEAMcommand (species and energy).beta0: the attributes of the initial-conditionsBETA0block (Twiss and dispersion).particle_start: initial particle coordinates, which MAD-X takes in theTRACKmodule rather than in a lattice file, and which are written out as a comment.elements: element definitions (MadxEleDef).controllers: variables and deferred assignments (MadxController).alignments:EALIGNmisalignments (MadxAlignment).beamlines:linedefinitions (MadxBeamline).use: the branches, each a(name, periodic)pair, for theusestatement.rigidity: whether anything written refers to the rigidity variable, which then has to be defined ahead of it.
- Parameters:
- elements: List[MadxEleDef]¶
- controllers: List[MadxController]¶
- alignments: List[MadxAlignment]¶
- beamlines: List[MadxBeamline]¶
- class palsparserpy.MadxEleDef(name, type, attrs=<factory>, notes=<factory>)[source]¶
Bases:
objectA single MAD-X element definition.
name: the element name.type: the MAD-X element-type keyword (e.g.drift,quadrupole).attrs: already-translated attribute fragments, each an"attribute = value"string.notes: comment lines to write above the definition. MAD-X elements carry no metadata strings of their own, so a PALSMetaPbecomes a comment here, as does anything else worth saying about the element in the file it is written to.
- class palsparserpy.MadxBeamline(name, members=<factory>)[source]¶
Bases:
objectA MAD-X
linedefinition: itsnameand the ordered list of member elementmembers(by name).
- class palsparserpy.MadxController(name, vars=<factory>, controls=<factory>, notes=<factory>)[source]¶
Bases:
objectA MAD-X rendering of a PALS
Controller.MAD-X has no controller element. What it has instead is the deferred assignment
:=, which makes an element attribute depend on a variable rather than take its value once, and that is what a controller becomes: its variables become ordinary MAD-X variables and each of its controls becomes a deferred assignment to the attribute it drives.name: the controller name, written out as a comment heading.vars: the variables’ initial values, each a"name = value"string.controls: the deferred assignments, each an"ele->attribute := expression"string.notes: comment lines to write above the definitions, holding the controller’sMetaP.
- class palsparserpy.MadxAlignment(name, attrs=<factory>)[source]¶
Bases:
objectThe misalignment of one element: what a PALS
BodyShiftPbecomes.MAD-X keeps a misalignment apart from the element definition, in an
EALIGNcommand applied to whatever the precedingSELECT, FLAG=ERRORpicked out.nameis the element the errors belong to andattrstheEALIGNattribute fragments.
- palsparserpy.pals_to_scibmad(yaml)[source]¶
Translate a parsed PALS lattice
yaml(as returned byparse_file()) into aSciBmadLattice.The returned structure is an in-memory model of the SciBmad lattice (elements, beamlines, lattice lists), not the input PALS tree. Translation is a three-step process: parse the PALS file with
parse_file, build the target model withpals_to_scibmad, then emit the SciBmad lattice file withwrite_scibmad_file():yaml = parse_file(file_dir) write_scibmad_file(pals_to_scibmad(yaml), filename)
- Parameters:
yaml (YAMLNode)
- Return type:
- palsparserpy.write_scibmad_file(lat, filename)[source]¶
Serialize the
SciBmadLatticelattofilenameas a SciBmad lattice file.Write the particle-start block, the
@elementsblock ofLineElement``s, the ``Controllerdefinitions, theBeamlinedefinitions, and the lattice lists.- Parameters:
lat (SciBmadLattice)
- Return type:
None
- class palsparserpy.SciBmadLattice(particle=<factory>, elements=<factory>, controllers=<factory>, beamlines=<factory>, lattices=<factory>)[source]¶
Bases:
objectAn in-memory model of a SciBmad lattice.
Produced by
pals_to_scibmad()and serialized to a file bywrite_scibmad_file():particle:BeginningEleparticle-coordinate lines (including thev = [...]vector).elements:LineElementdefinitions (SciBmadEle).controllers:Controllerdefinitions (SciBmadController).beamlines:Beamlinedefinitions (SciBmadBeamline).lattices: lattice lists (SciBmadLatticeList).
- Parameters:
elements (List[SciBmadEle])
controllers (List[SciBmadController])
beamlines (List[SciBmadBeamline])
lattices (List[SciBmadLatticeList])
- elements: List[SciBmadEle]¶
- controllers: List[SciBmadController]¶
- beamlines: List[SciBmadBeamline]¶
- lattices: List[SciBmadLatticeList]¶
- class palsparserpy.SciBmadEle(name, attrs=<factory>)[source]¶
Bases:
objectA single SciBmad
LineElement: itsnameand the already-translated keyword-argument fragments (attrs, each a"keyword = value"string).
- class palsparserpy.SciBmadBeamline(name, members=<factory>, ref=<factory>)[source]¶
Bases:
objectA SciBmad
Beamline: itsname, the ordered member elementmembers(by name), and the reference-parameter fragmentsreftaken from the line’s first entry.
- class palsparserpy.SciBmadLatticeList(name, branches=<factory>)[source]¶
Bases:
objectA SciBmad lattice list: its
nameand the ordered branch/beamlinebranches(by name).
- class palsparserpy.SciBmadController(name, slaves=<factory>, vars=<factory>)[source]¶
Bases:
objectA SciBmad
Controller: what a PALSControllerbecomes.name: the controller name.slaves: the controlled properties, each a"(ele, :prop) => (ele; vars...) -> expr"pair-and-function string.vars: the variables’ initial values, each a"name = value"string.