PALSParserJ API Reference

Complete reference for every documented function and type, generated automatically from the package docstrings.

For installation, tutorials, and the lattice/translation guides, see the main documentation.

Index

Public API

PALSParserJ.PALSParserJModule
PALSParserJ

A Julia wrapper around the PALSParserCpp C library (rapidyaml backend).

The C API is tree+nodeId-centric: every operation takes a YAMLTreeHandle (opaque pointer to a parsed tree) and a YAMLNodeId (index within that tree).

On the Julia side:

  • YAMLTree owns the C tree handle and frees it via a finalizer.
  • YAMLNode is a lightweight value type holding a reference to its parent tree (keeping it alive) and the integer node id.
source
PALSParserJ.ProblemType

One 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; message already names the file where the file is the point.
  • severity — a ProblemSeverity: can the trees still be trusted?
  • origin — a ProblemOrigin: whose problem is it?

Only a PROBLEM_INPUT can 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.

source
PALSParserJ.ProblemOriginType

Who has to act on a problem.

  • PROBLEM_INPUT — the document is wrong; the lattice author can fix it.
  • PROBLEM_UNSUPPORTED — valid PALS that PALSParserCpp does not implement yet. Editing the lattice will not clear it.
  • PROBLEM_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_origin in PALSParserCpp.h.

source
PALSParserJ.ProblemSeverityType

Whether a problem leaves the expanded trees trustworthy.

  • PROBLEM_ERROR — the document is wrong here and expansion could not work around it. Do not trust the affected part of the trees.
  • PROBLEM_WARNING — expansion produced a usable result; something was assumed or skipped, but the trees are still sound.

Mirrors enum problem_severity in PALSParserCpp.h.

source
PALSParserJ.evaluate_pals_expressionMethod
evaluate_pals_expression(expr::AbstractString) -> Float64

Evaluate a single PALS mathematical expression to a Float64.

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 functions mass_of, charge_of, and anomalous_moment_of (backed by AtomicAndPhysicalConstantsCLib), whose species-name argument must be quoted, e.g. mass_of("#3He") (a mass number carries a leading #). A leading expr(...) 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. Throws ArgumentError if expr is not evaluable: a parse error, an unknown identifier or species, a random()/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…
source
PALSParserJ.export_manipulatorsMethod
export_manipulators()

Export the public functions from parser_wrapper.jl (Base/Core method extensions such as getindex, length, keys, ... are intentionally omitted).

source
PALSParserJ.match_namesMethod
match_names(node, match_string) -> Vector{YAMLNode}

Return every named construct in node's tree that is matched by match_string, following PALS Name Matching. node may be any node of the tree to search (typically a lattice-view root such as lat.full_expanded); the whole tree is searched and the returned nodes belong to that same tree.

match_string has 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 PALS or facility node (both the full kind: constant/kind: variable and the compact constants:/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 in lat.adjunct. Searching lat.full_expanded for a constant matches nothing, since the PALS/facility node it would be defined under is not part of that tree.

Not yet implemented from Element Name Matching: #N instance selection, {e1}:{e2} ranges, , unions, and & intersections.

Results are de-duplicated and returned in document order. A malformed pattern yields an empty vector.

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 element
match_names(lat.full_expanded, "inj>>>arc>>Q.*>length")  # length of arc's Q… in lattice inj
match_names(lat.adjunct, "a_.*")                # constants/variables named a_…
source
PALSParserJ.node_correspondenceMethod
node_correspondence(lat::Lattices) -> Dict{YAMLNode, NodeCorrespondence}

Map every node of a Lattices to the nodes it corresponds to across the original, combined, full_expanded and adjunct trees.

The correspondence is exact: it is computed from provenance recorded while the trees were derived from one another (originalcombinedfull_expanded and adjunct), 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 single combined/original node can map to several full_expanded copies — so each field of the returned value is a Vector{YAMLNode}.

Expansion splits the document, so a node of combined may land in full_expanded, in adjunct, 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 the combined node they came from.

The expanded view takes no part in the correspondence: it is a pruned copy of full_expanded rather 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 Dict keyed by YAMLNode. For any node that participates in the correspondence, map[node] is a named tuple (; original, combined, full_expanded, adjunct) of Vector{YAMLNode}, listing every corresponding node grouped by tree. The queried node appears in its own tree's vector, so the four vectors together are the full equivalence class of node. A vector is empty when a tree has no corresponding node (e.g. the synthesised destination_pointer scalar exists only in full_expanded, and a constant that the lattice never references exists only in adjunct).

Example

lat = parse_and_expand_pals("lattice.pals.yaml")
corr = node_correspondence(lat)

a_const = lat.combined["PALS"]["facility"][1]["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, so they land here
corr[a_const].full_expanded  # empty unless the lattice referenced it
source
PALSParserJ.pals_to_bmadMethod
pals_to_bmad(yaml::YAMLNode)

Translate a parsed PALS lattice yaml (as returned by parse_file) into a BmadLattice.

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 with pals_to_bmad, then emit the Bmad lattice file with write_bmad_file:

yaml = parse_file(file_dir)
write_bmad_file(pals_to_bmad(yaml), filename)
source
PALSParserJ.pals_to_madxMethod
pals_to_madx(yaml::YAMLNode)

Translate a parsed PALS lattice yaml (as returned by parse_file) into a MadxLattice.

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 with pals_to_madx, then emit the MAD-X lattice file with write_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: RELATIVE controller 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.

source
PALSParserJ.pals_to_scibmadMethod
pals_to_scibmad(yaml::YAMLNode)

Translate a parsed PALS lattice yaml (as returned by parse_file) into a SciBmadLattice.

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 with pals_to_scibmad, then emit the SciBmad lattice file with write_scibmad_file:

yaml = parse_file(file_dir)
write_scibmad_file(pals_to_scibmad(yaml), filename)
source
PALSParserJ.parse_and_expand_palsFunction
parse_and_expand_pals(filename, root_lattice=""; problems=:print) -> Lattices

Parse a PALS lattice file and return its original, combined, expanded, full_expanded and adjunct views, together with the list of expansion problems, as a Lattices.

Arguments

  • filename: Path to the top-level YAML lattice file.
  • root_lattice: Name of the lattice to expand. If empty (the default), the lattice to expand is chosen with the following priority:
    1. the lattice named by the last use statement, or
    2. the last lattice defined in the file if no use statement is present.
  • problems: What to do with the list of problems found while expanding (undefined lattice, dangling element/line references, undefined inherit/repeat/Fork targets, and expressions that could not be evaluated). One of:
    • :print (the default) — print the problems to stderr (nothing is printed when there are none);
    • a filename String — write the problems to that file, printing nothing;
    • :none — do nothing (no printing, no file).

Returns

A Lattices with five independent tree views and a problems list. The same problems handed to problems are also returned in the problems field (a Vector{Problem}, empty when expansion was clean) regardless of the reporting mode, so :none still lets the caller inspect them programmatically. Each entry carries a message, the path it was found at, a severity and an origin; only a PROBLEM_INPUT can be cleared by editing the lattice.

The five tree views are:

  • original: the tree as read in, mapping each file (including any included or loaded files) to its unparsed contents.
  • combined: the tree with all include directives resolved and spliced inline, and all loaded files merged in subnode by subnode.
  • full_expanded: the selected lattice fully expanded, and nothing else — scalars substituted with their full definitions, repeated beamlines unrolled, inherited ancestors merged in, forks resolved, set commands executed and ABSOLUTE controllers applied. It is rooted at a map holding the single name => Lattice entry, without the PALS/facility scaffolding the lattice was defined under, so the lattice is reached as lat.full_expanded["lat1"] rather than through ["PALS"]["facility"]. Its branches entries are branches, not the BeamLines they were built from, and so carry no kind; a BeamLine referenced inside a line is a sub-line whose contents are spliced directly into the enclosing line, so no nested BeamLine survives in the expanded tree. Elements of a multipass line carry a multipass_index giving 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 enclosing multipass line wins when they nest). Every dependent parameter is computed and present: each element carries its element_index (its position, counting from one, in the branch line that holds it), its ReferenceP, FloorP and s_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 a branch_end Placeholder holding 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 is full_expanded with 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 its PALS/facility scaffolding: element and beamline definitions, use statements, constants and variables, Controllers, set commands, and any Lattice that 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 (see evaluate_pals_expression; random()/random_gauss() are left as text). Controller elements are evaluated against their own scoped variable tables, with each control expression computed and stored back in its control entry; controllers are facility-level, so they are found in adjunct.

Each view is backed by its own YAMLNode; all five are freed independently when their nodes are garbage collected.

source
PALSParserJ.write_bmad_fileMethod
write_bmad_file(lat::BmadLattice, filename::String)

Serialize the BmadLattice lat to filename as a Bmad lattice file.

Write the constant and variable definitions, the global, beginning-Twiss and particle-start parameters, the element definitions, the overlay/group definitions, 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.

source
PALSParserJ.write_madx_fileMethod
write_madx_file(lat::MadxLattice, filename::String)

Serialize the MadxLattice lat to filename as a MAD-X lattice file.

Write the constant and variable definitions, the BEAM command and initial conditions, the element definitions, the controller variables and their deferred assignments, the line definitions, the use statement, and the EALIGN misalignments, 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, BEAM has to come before USE, and the SELECT/EALIGN pairs have to come after it, because there is no sequence to apply an error to until one has been expanded.

source
PALSParserJ.write_scibmad_fileMethod
write_scibmad_file(lat::SciBmadLattice, filename::String)

Serialize the SciBmadLattice lat to filename as a SciBmad lattice file.

Write the particle-start block, the @elements block of LineElements, the Controller definitions, the Beamline definitions, and the lattice lists.

source

Internals

Core.BoolMethod
Bool(node) -> Bool

Parse the scalar value of node as a Bool. Accepts exactly the text "true" or "false"; any other value (or a non-scalar node) throws an error.

source
Core.Float64Method
Float64(node) -> Float64

Parse the scalar value of node as a Float64. Throws if node is not a scalar or if its text is not a valid floating-point number.

source
Core.IntMethod
Int(node) -> Int

Parse the scalar value of node as an Int. Throws if node is not a scalar or if its text is not a valid integer.

source
Core.StringMethod
String(node) -> String

Return the scalar value of node as a String. Throws an error if node is not a scalar (i.e. it is a MAP or sequence); guard with is_scalar(node) if unsure. This is the raw text; use Int, Float64, or Bool for typed values.

source
PALSParserJ.ABRepresentationMethod
ABRepresentation(full::FullRepresentation)

Down-convert a FullRepresentation to A/B field integrals.

Combine each multipole's magnitude, length, and tilt into complex field integrals and store their imaginary/real parts as the A/B coefficient dictionaries.

source
PALSParserJ.BmadControllerType
BmadController

A Bmad overlay or group element: what a PALS Controller becomes.

Fields:

  • name : the controller name.
  • type : "overlay" for control_type: ABSOLUTE, "group" for RELATIVE. 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.
source
PALSParserJ.BmadEleDefType
BmadEleDef

A single Bmad element definition.

Fields:

  • name : the element name.
  • type : the Bmad element-type name (e.g. Drift, Quadrupole).
  • attrs : already-translated attribute fragments, each an "attribute = value" string.
source
PALSParserJ.BmadLatticeType
BmadLattice

An in-memory model of a Bmad lattice.

Produced by pals_to_bmad and serialized to a file by write_bmad_file. The fields mirror the sections of a Bmad lattice file:

  • constants : name = value definitions, in definition order.
  • parameters : global parameter[...] = ... 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/group definitions (BmadController).
  • beamlines : line definitions (BmadBeamline).
  • use : branch names for the final use, ... statement.
source
PALSParserJ.FullRepresentationType
FullRepresentation <: MultipoleRepresentation

Raw, over-parametrized multipole form filled directly from PALS-YAML.

Holds, keyed by multipole order, whether each coefficient is normalized (K vs. B) and integrated (field integral vs. field strength), its magnitude (normal/skew pair), and its tilt, together with the element length L. It is down-converted to whichever element-specific representation the element kind requires.

FullRepresentation()

Construct an empty representation with unit length L.

source
PALSParserJ.LatticesType

Five representations of a lattice, each as a root YAMLNode, plus the list of problems found while expanding it.

expanded and full_expanded are the same expanded lattice holding the same values; full_expanded additionally carries every parameter the bookkeeper computed, while expanded keeps only what the author wrote. See parse_and_expand_pals for what each view holds.

problems is a Vector{Problem} — one entry per problem encountered during expansion (undefined lattice, dangling element/line references, undefined inherit/repeat/Fork targets, misspelled names, and expressions that could not be evaluated). It is empty when expansion was clean. Filter it on severity or origin to decide what is worth acting on:

lat = parse_and_expand_pals("ex.pals.yaml"; problems = :none)
mine = filter(p -> p.origin === PROBLEM_INPUT, lat.problems)
source
PALSParserJ.MadxAlignmentType
MadxAlignment

The misalignment of one element: what a PALS BodyShiftP becomes.

MAD-X keeps a misalignment apart from the element definition, in an EALIGN command applied to whatever the preceding SELECT, FLAG=ERROR picked out. name is the element the errors belong to and attrs the EALIGN attribute fragments.

source
PALSParserJ.MadxControllerType
MadxController

A 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.

Fields:

  • 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's MetaP.
source
PALSParserJ.MadxEleDefType
MadxEleDef

A single MAD-X element definition.

Fields:

  • 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 PALS MetaP becomes a comment here, as does anything else worth saying about the element in the file it is written to.
source
PALSParserJ.MadxLatticeType
MadxLattice

An in-memory model of a MAD-X lattice.

Produced by pals_to_madx and serialized to a file by write_madx_file. The fields mirror the sections of a MAD-X lattice file:

  • constants : name = value; definitions, in definition order.
  • beam : the attributes of the BEAM command (species and energy).
  • beta0 : the attributes of the initial-conditions BETA0 block (Twiss and dispersion).
  • particle_start : initial particle coordinates, which MAD-X takes in the TRACK module 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 : EALIGN misalignments (MadxAlignment).
  • beamlines : line definitions (MadxBeamline).
  • use : the branches, each a name => periodic pair, for the use statement.
  • rigidity : whether anything written refers to _MADX_RIGIDITY, which then has to be defined ahead of it.
source
PALSParserJ.SciBmadBeamlineType
SciBmadBeamline

A SciBmad Beamline: its name, the ordered member element members (by name), and the reference-parameter fragments ref taken from the line's first entry.

source
PALSParserJ.SciBmadControllerType
SciBmadController

A SciBmad Controller: what a PALS Controller becomes.

Fields:

  • 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.
source
PALSParserJ.SciBmadEleType
SciBmadEle

A single SciBmad LineElement: its name and the already-translated keyword-argument fragments (attrs, each a "keyword = value" string).

source
PALSParserJ.YAMLNodeType
YAMLNode

A reference to a single node within a YAMLTree. Holding a YAMLNode keeps its parent tree alive. Node ids are invalidated if the tree is deleted.

source
PALSParserJ.YAMLTreeType
YAMLTree

Owns a C YAMLTreeHandle. Freed automatically when the object is GC'd. Do not use the handle after the tree has been freed.

source
Base.copyMethod
Base.copy(node) -> YAMLNode

Return an independent deep copy of node in a new tree.

source
Base.getindexMethod
node[index] -> YAMLNode

Return the index-th direct child of a MAP or sequence node. Indexing is 1-based, matching Julia convention (the underlying C API is 0-based). Throws an error if index is out of bounds.

source
Base.getindexMethod
node[key] -> YAMLNode

Look up a direct child of a MAP node by its string key and return that child node. Only direct children are searched (the lookup is not recursive). Throws an error if no child has the given key; call haskey(node, key) first if the key may be absent.

source
Base.haskeyMethod
haskey(node, key) -> Bool

Return true if the MAP node has a direct child stored under the string key, false otherwise. Only direct children are checked; the search is not recursive. Useful as a guard before node[key], which errors on a missing key.

source
Base.iterateFunction
iterate(node[, state])

Iterate over the children of node, enabling for loops, comprehensions, and collect. Sequences yield successive YAMLNode elements; maps yield (key, YAMLNode) pairs (with key::String). Scalar nodes yield nothing.

source
Base.keysMethod
keys(node) -> Vector{String}

Return the keys of a MAP node, in document order, as a Vector{String}. Returns an empty vector for sequence or scalar nodes. Pair with node[key] to retrieve each value, or iterate the node directly to get (key, value) pairs.

source
Base.lengthMethod
length(node) -> Int

Return the number of direct children of node: the number of key/value pairs in a MAP, or the number of elements in a sequence. Scalar nodes report 0. Only direct children are counted (the count is not recursive).

source
Base.setindex!Method
node[key] = value

Set or update a scalar value in a MAP node. If key already exists its value is updated with set_scalar; otherwise a new scalar child is appended.

source
PALSParserJ._KindMapMethod
_KindMap(ele_kind)

Return the multipole representation type used for a given element kind.

Elements that carry field multipoles map to ABRepresentation; kinds that have no multipole attributes, or are unrecognized, raise an error.

source
PALSParserJ._add_bmad_branches!Method
_add_bmad_branches!(lat::BmadLattice, branches)

Translate a PALS Lattice's branches sequence into lat.

Append each branch name to lat.use and its geometry to lat.parameters (parameter[geometry] for a single branch, <name>[geometry] when several branches are present).

source
PALSParserJ._add_madx_branches!Method
_add_madx_branches!(lat::MadxLattice, branches)

Translate a PALS Lattice's branches sequence into lat.

Append each branch to lat.use as a name => periodic pair. MAD-X has no geometry attribute of its own: whether a branch closes on itself is decided by how it is used – a TWISS given no initial conditions looks for the periodic solution – so the flag is carried through to the comment write_madx_file writes beside the use statement.

source
PALSParserJ._bend_referenceMethod
_bend_reference(props::YAMLNode, name::String, normalized::Bool)

Return the reference bend strength a Bend's order-0 normal multipole is measured against.

PALS states the field of a bend outright, as MagneticMultipoleP.Kn0 (or Bn0). Bmad states it as DG (or DB_FIELD), the departure of the field from the reference bend the element geometry is built on, so the reference has to come off the PALS value: dg = Kn0 - g_ref. The reference is BendP.g_ref – or the curvature 1/radius_ref of that same bend – for a normalized multipole, and BendP.Bn0_ref for an unnormalized one. A bend with no reference of its own does not bend, and the offset is zero.

The two flavors cannot be mixed: going from one to the other takes the reference momentum, which belongs to the branch and not to the element, so a normalized field measured against an unnormalized reference (or the reverse) raises an error.

source
PALSParserJ._bmad_constantMethod
_bmad_constant(props::YAMLNode, pals_kind::String)

Translate a full-form (kind: constant, kind: variable) definition into a Bmad name = value definition.

A definition whose value is a structure rather than a single value has no Bmad equivalent and raises an error; one with no value at all takes PALS' default of zero.

source
PALSParserJ._bmad_constantsMethod
_bmad_constants(node::YAMLNode)

Translate a compact-form constants:/variables: list into Bmad name = value definitions.

Bmad draws no distinction between the two: both become a named value the rest of the lattice file may use in an expression, so both lists translate the same way.

source
PALSParserJ._bmad_control_targetMethod
_bmad_control_target(cname::String, param::String, facility::YAMLNode)

Translate a controller's parameter target into a Bmad slave reference.

Return (target, factor, offset) where target is the "ele[attribute]" Bmad reference and the control expression must be multiplied by factor and have offset subtracted from it to hold the same physics. Neither is trivial in general because the element translation does not carry PALS parameters across unchanged: a multipole that is not the element's own becomes Bmad's normalized integrated strength An/Bn, so a controller driving a non-integrated one has to pick up the slave's length (and the 1/n! of the multipole convention) here. A multipole that is the element's own strength becomes K1, K2, K3 or a bend's DG (see _native_strength!), which is not length integrated, so there an integrated PALS parameter is the one that needs the length; and DG, alone among them, is measured from the reference bend rather than from zero, which is the offset (see _bend_reference). A bend's added K1 and K2 are used only when that order has no skew part, so a controller driving one of those has to look at the skew component to know which attribute it will find.

A target may name its element by kind as well as by name, as {kind}::{name}; the qualifier is checked against the element found and then dropped, the Bmad file naming each element once.

Targets Bmad cannot express – a pattern matching several elements, a >> or >>> qualifier naming the BeamLine or Lattice an element is reached through, or a parameter with no Bmad attribute – raise an error.

source
PALSParserJ._bmad_kindMethod
_bmad_kind(ele_kind::String)

Map a PALS element kind to its Bmad counterpart.

Return (bmad_kind, args) where bmad_kind is the Bmad element-type name for the PALS ele_kind. Kinds with no Bmad equivalent (e.g. UnionEle, Feedback) raise an error.

source
PALSParserJ._bmad_quoteMethod
_bmad_quote(str::String)

Return str as a quoted Bmad string constant, or nothing if it cannot be quoted.

Bmad accepts either quote character but has no escape for one inside a string, so a str holding a double quote is wrapped in single quotes. A str holding both is unrepresentable.

source
PALSParserJ._check_madx_variablesMethod
_check_madx_variables(lat::MadxLattice)

Report two MAD-X definitions that would claim the one name.

_madx_variable_names prefixes a controller variable that another controller's variable or a constant already claims, which settles every collision a PALS lattice can have honestly. This is the backstop for the one it cannot: a constant named after the prefixed form itself.

source
PALSParserJ._ele_to_bmad_strMethod
_ele_to_bmad_str(ele::YAMLNode)

Translate a BeginningEle element into Bmad global-parameter settings.

Return (params, beginning, particle_start) where params holds parameter[...] strings from the element's ReferenceP (species and energy), beginning holds beginning[...] strings from its TwissP (initial Twiss, coupling and dispersion), and particle_start holds particle_start[...] strings from its ParticleP (initial phase-space coordinates and spin).

source
PALSParserJ._ele_to_madx_strMethod
_ele_to_madx_str(ele::YAMLNode)

Translate a BeginningEle element into the MAD-X beam and initial-condition settings.

Return (beam, beta0, particle) where beam holds the BEAM attributes from the element's ReferenceP (species and energy), beta0 holds the BETA0 attributes from its TwissP (initial Twiss and dispersion), and particle holds the START attributes from its ParticleP (initial phase-space coordinates).

Three PALS quantities do not survive the crossing:

  • PALS states the Twiss parameters in the a/b normal modes and MAD-X in the x/y planes, which are the same thing only when the lattice is uncoupled.
  • The coupling itself is stated as Bmad's C matrix here and as MAD-X's R matrix there, which are different parametrizations, so cmat11 and its fellows are not translated.
  • MAD-X has no dispersion derivative, only the momentum dispersion, so deta_x_ds is not translated either.
source
PALSParserJ._ele_to_scibmad_strMethod
_ele_to_scibmad_str(ele::YAMLNode)

Translate a BeginningEle element into SciBmad reference and particle fragments.

Return (ref, particle) where ref holds the reference-parameter fragments from the element's ReferenceP (species and energy) and particle holds the coordinate lines from its ParticleP (followed by the v = [...] phase-space vector).

source
PALSParserJ._facility_entryMethod
_facility_entry(facility::YAMLNode, name::String)

Return the facility entry named name, or nothing if there is none. The entry is the single-key map the translators take as an element; _facility_props gives its properties.

source
PALSParserJ._facility_propsMethod
_facility_props(facility::YAMLNode, name::String)

Return the property map of the facility entry named name, or nothing if there is none.

source
PALSParserJ._fill_multipoles!Method
_fill_multipoles!(full::FullRepresentation, mmP, name)

Populate full from a PALS MagneticMultipoleP map.

Parse each key of mmP into a multipole order and store its magnitude, normalized, integrated, and tilt attributes in full; name is used in error messages. Return full.

source
PALSParserJ._format_bmad_controllerMethod
_format_bmad_controller(ctrl::BmadController)

Render a BmadController as a Bmad name: overlay = {...}, var = {...}, v = init definition.

A control expression is a line's worth of text on its own, so each slave, the variable list and each variable's initial value get a tab-indented continuation line of their own. Every broken line ends in the comma that continues it.

source
PALSParserJ._format_bmad_lineMethod
_format_bmad_line(bl::BmadBeamline)

Render a BmadBeamline as a Bmad name: line = (...) definition, wrapping the member list with tab-indented continuation lines to keep rows under ~80 columns.

source
PALSParserJ._format_madx_alignmentMethod
_format_madx_alignment(align::MadxAlignment)

Render a MadxAlignment as the SELECT/EALIGN pair that applies it.

The element is picked out by an anchored pattern rather than by a range so that a name which is a prefix of another one does not take its neighbour's errors with it. A MAD-X label may hold a decimal point, which a MAD-X pattern reads as "any character", so the name is escaped.

source
PALSParserJ._format_madx_eleMethod
_format_madx_ele(ele::MadxEleDef)

Render a MadxEleDef as a name: type, attr = val, ...; MAD-X element definition, with each attribute on its own tab-indented continuation line and each note on a comment line above.

source
PALSParserJ._format_madx_lineMethod
_format_madx_line(bl::MadxBeamline)

Render a MadxBeamline as a MAD-X name: line = (...); definition, wrapping the member list with tab-indented continuation lines to keep rows under ~80 columns.

source
PALSParserJ._has_skewMethod
_has_skew(props::YAMLNode, order::Int)

Return whether the element has a nonzero skew multipole of the given order.

Which Bmad attribute an order lands in can depend on it: a bend's K1 and K2 are used only for a field with no skew part (see _native_strength!), so a controller driving one has to ask. Any of the four spellings of the component – normalized or not, integrated or not – counts.

source
PALSParserJ._madx_aperture_attrsMethod
_madx_aperture_attrs(apertureP::YAMLNode, name::String, madx_kind::String)

Return the apertype/aperture/aper_offset attribute fragments of a PALS ApertureP.

MAD-X states an aperture as a half width and a half height about the element's axis, with the offset of the aperture's centre given separately; PALS states the two edges, or a full width and a centre. Both forms come to the same half-extent and centre, which is what is written out.

The shape decides which of the components describe the aperture: a RECTANGULAR or ELLIPTICAL one is bounded by its limits and ignores any vertices, and a VERTICES one is bounded by its vertex list and ignores any limits. MAD-X can only take a vertex outline from a file of its own, so a VERTICES aperture is reported rather than written out.

Shape, location and the rest describe an aperture; they do not put one there. Writing them out for a group that sets no limit would hand MAD-X an aperture the PALS lattice does not have, so a group that bounds nothing is skipped entirely. A group that bounds one plane and not the other still has to state both, MAD-X's aperture values being positional; the unbounded plane is left wide open and reported.

What MAD-X has no room for is reported: it puts an aperture at the entrance of an element and nowhere else, so location is lost, and it has no aperture at all on a drift.

source
PALSParserJ._madx_base_valueMethod
_madx_base_value(lat::MadxLattice, target::String)

Return the value target already holds, as written by the element translation.

A control_type: RELATIVE controller varies a parameter rather than setting it, and a MAD-X deferred assignment can only set one: ele->k1 := ele->k1 + dk is the circular definition MAD-X forbids. So the value being varied has to be written into the assignment, and the one place it is written down is the definition this reads it back out of.

source
PALSParserJ._madx_bend_facesMethod
_madx_bend_faces(bendP::YAMLNode, name::String, angle)

Return the e1/e2 attribute fragments of a bend's pole faces.

MAD-X measures the pole-face rotations of an sbend against the sector geometry, which is what PALS' own e1 and e2 are measured against, so those two come straight across. PALS also has e1_rect and e2_rect, measured against fiducial lines parallel to each other, and what separates the two pairs depends on the bend's ref_geometry:

ARC, CHORD        e1 = e1_rect + angle/2,   e2 = e2_rect + angle/2
ENTRANCE_COORDS   e1 = e1_rect,             e2 = e2_rect + angle
EXIT_COORDS       e1 = e1_rect + angle,     e2 = e2_rect

A face given both ways is contradictory and raises an error; one given the rectangular way on a bend whose angle is unknown cannot be converted, and raises one too.

source
PALSParserJ._madx_bend_geometryMethod
_madx_bend_geometry(props::YAMLNode, name::String)

Return the reference geometry of a Bend as (angle, angle_value, arc_length), or nothing if the element states none.

PALS states a bend's geometry with any two of three sets of mutually dependent parameters – a curvature (g_ref, radius_ref or the reference field Bn0_ref), a length (length, L_chord or L_rectangle), and the angle (angle_ref) – one parameter from each of two different sets, from which every other parameter follows. MAD-X states it with exactly two, the angle and the arc length l, so whichever pair the PALS file used has to be turned into that pair here.

Only the field-valued curvature needs the reference rigidity, the others being pure geometry. angle_value is the angle as a number when everything it was derived from is one, and nothing when it is an expression only MAD-X can evaluate. A bend that states too little for the pair to be worked out is reported, and comes back with whichever of the two is known.

source
PALSParserJ._madx_check_expressionMethod
_madx_check_expression(where::String, text::AbstractString)

Report a PALS expression MAD-X has no way to evaluate, and return text unchanged.

An expression is carried across as it stands, MAD-X's arithmetic and its ordinary functions being PALS' as well. Two things in one are not: PALS' particle-data functions, which look up a species in a table MAD-X does not carry, and most of PALS' predefined constants, which MAD-X either spells differently or does not have. Both are reported rather than rewritten – as they are for the other translators, expression translation being an open item for all of them.

source
PALSParserJ._madx_check_nameMethod
_madx_check_name(name::String)

Report a name MAD-X cannot hold, and warn about one it would quietly truncate.

A MAD-X label is at most sixteen characters – the rest are dropped, which can turn two elements into one – and may not be one of MAD-X's own keywords, which is a fatal error there.

source
PALSParserJ._madx_constantMethod
_madx_constant(props::YAMLNode, pals_kind::String)

Translate a full-form (kind: constant, kind: variable) definition into a MAD-X name = value definition.

A definition whose value is a structure rather than a single value has no MAD-X equivalent and raises an error; one with no value at all takes PALS' default of zero. A MAD-X variable is a value and nothing else, so the error bars a PALS definition may carry are reported.

source
PALSParserJ._madx_constantsMethod
_madx_constants(node::YAMLNode)

Translate a compact-form constants:/variables: list into MAD-X name = value definitions.

MAD-X draws no distinction between the two: both become a named value the rest of the lattice file may use in an expression, so both lists translate the same way.

source
PALSParserJ._madx_control_targetMethod
_madx_control_target(cname::String, param::String, facility::YAMLNode)

Translate a controller's parameter target into a MAD-X attribute reference.

Return (target, factor, rigidity) where target is the "ele->attribute" MAD-X reference, the control expression must be multiplied by factor, and rigidity says whether it must also be divided by the reference rigidity to hold the same physics. Neither is trivial in general because the element translation does not carry PALS parameters across unchanged: the attribute a multipole lands in may be length integrated where the PALS parameter was not, or the other way round, and a stated field has to be normalized because MAD-X has no field-valued attribute.

A target may name its element by kind as well as by name, as {kind}::{name}; the qualifier is checked against the element found and then dropped, MAD-X having one namespace for all of them.

Targets MAD-X cannot express – a pattern matching several elements, a >> or >>> qualifier naming the BeamLine or Lattice an element is reached through, a parameter with no MAD-X attribute, or an order that only a multipole array could hold, MAD-X having no way to name one entry of one – raise an error.

source
PALSParserJ._madx_divideMethod
_madx_divide(text::AbstractString, divisor::AbstractString)

Return text divided by the MAD-X expression divisor, which is not a number here and so cannot be worked out during translation.

source
PALSParserJ._madx_foldMethod
_madx_fold(text::AbstractString, f, args::AbstractString...)

Return text, or the number it comes to when every one of args is a number.

A PALS parameter may be written as an expression, which only MAD-X can evaluate, or as a plain number, which the translation can work with. Where a MAD-X value has to be derived from several PALS ones, text is that derivation written as a MAD-X expression and f is the same derivation as a function, applied here when all of its inputs parse.

source
PALSParserJ._madx_kindMethod
_madx_kind(ele_kind::String)

Map a PALS element kind to its MAD-X counterpart.

Return the MAD-X element-type keyword for the PALS ele_kind. Kinds with no MAD-X equivalent raise an error: MAD-X has no branching (Fork), no support structures (Girder), no element that changes the reference energy in mid-line (ReferenceChange), and no way to build one element out of several (UnionEle).

source
PALSParserJ._madx_multipoleMethod
_madx_multipole(full::FullRepresentation, order::Int)

Return the normal and skew components of multipole order, with the multipole's own tilt rotated into them.

A tilt of T on an order-N multipole rotates it by (N+1) T in the normal/skew plane. MAD-X has one tilt for the whole element rather than one per order, so the rotation is worked out here and what comes out is a plain normal/skew pair. The components keep whatever units the PALS file gave them: normalized or not, integrated or not.

source
PALSParserJ._madx_multipole_attrsMethod
_madx_multipole_attrs(full::FullRepresentation, name::String)

Return the knl/ksl attribute fragments of a MAD-X multipole.

MAD-X states a thin multipole as two arrays of integrated coefficients indexed by order from zero up, so an order that is not there still needs its zero written in. A component given as a field is divided by the reference rigidity, which makes the array entry an expression rather than a number – which MAD-X is happy with, the entries being expressions in general.

source
PALSParserJ._madx_native_strength!Function
_madx_native_strength!(full::FullRepresentation, ele_kind::String, name::String, ref_angle)

Take the multipoles that are an element's own strength out of full and return their MAD-X attribute fragments.

The strength of a MAD-X quadrupole is its k1, so that is where a PALS Kn1 belongs. Unlike Bmad, MAD-X has an attribute for the skew component of each of these – k1s, k2s, k3s – so a tilted multipole of the element's own order needs nothing left over, and unlike Bmad it has no field-valued attribute, so an unnormalized component is divided by the reference rigidity.

The length is put in or taken out to match the attribute: k1 is a strength per unit length and angle and the kicker's hkick are integrated. An element of zero length whose PALS value is not integrated has no strength to state, and neither has one whose integrated value cannot be spread over a length of zero; both are reported.

Two of these attributes are not simply the multipole they come from:

  • A bend's order-0 field is its angle. Bmad states the departure of the field from the reference bend and can hold the two apart; MAD-X cannot, because it builds the bend's geometry out of the same angle it tracks through (k0 is in its database but not in its map). So ref_angle, the angle the BendP geometry has already been written out as (see _madx_bend_angle), is what the field is checked against: a Kn0 that agrees with it has nothing left to state, and one that disagrees is reported and dropped, because the alternative – writing the field out as the angle – would move every element downstream of the bend.
  • A kicker's deflection is measured the opposite way round from a bend's, in both MAD-X and PALS: a positive hkick bends towards positive x and a positive Kn0 towards negative x, so the horizontal one changes sign.
source
PALSParserJ._madx_scaleMethod
_madx_scale(text::AbstractString, factor::Real)

Return text scaled by factor, as a MAD-X value.

PALS and MAD-X differ in the units of nearly every quantity that is not a length or an angle: energies are eV against GeV, voltages V against MV, frequencies Hz against MHz. A value written as a number is scaled here and comes out a number; one written as an expression – a constant, say – is left for MAD-X to evaluate and comes out an expression.

source
PALSParserJ._madx_shiftMethod
_madx_shift(text::AbstractString, offset::Real)

Return text with offset added, as a MAD-X value. As with _madx_scale, a number comes out a number and an expression comes out an expression.

source
PALSParserJ._madx_speciesMethod
_madx_species(species::String)

Map a PALS reference species onto a MAD-X PARTICLE.

MAD-X knows the mass and charge of a fixed handful of species and nothing else; anything outside that set has to be given its mass and charge outright, which PALS does not state and which the translation therefore cannot supply.

source
PALSParserJ._madx_strengthMethod
_madx_strength(value::Real, normalized::Bool)

Return a magnet strength as a MAD-X value.

Every MAD-X strength attribute is normalized, so a PALS component given as a field is divided by the reference rigidity (see _MADX_RIGIDITY) instead of being written out as it stands.

source
PALSParserJ._madx_substituteMethod
_madx_substitute(expr::AbstractString, replacements::Dict{String,String})

Return expr with each name in replacements replaced by what it maps to.

Used to put a controller's variables into an expression under whatever MAD-X calls them (see _madx_variable_names), and to put their initial values in place of them. The match is on whole identifiers, and a name reached through a dot is left alone, so a variable cur does not rewrite current nor SELF.cur. Every name is replaced in one pass, so a replacement is never itself replaced.

source
PALSParserJ._madx_timesMethod
_madx_times(a::AbstractString, b::AbstractString)

Return the product of two MAD-X values, without the clutter of a factor of one.

Two numbers are multiplied out here; a unit factor – which is what an element of unit length gives, and what several of the bend derivations reduce to – comes back as the other operand alone rather than as a product with nothing in it.

source
PALSParserJ._madx_variable_namesMethod
_madx_variable_names(controllers::Vector{YAMLNode}, constants::Vector{String})

Decide what each controller variable is called in the MAD-X file.

Return (names, initials) where names maps a (controller, variable) pair to its MAD-X name and initials maps that MAD-X name to the variable's initial value.

A PALS controller owns its variables: ps1>cur and ps2>cur are two independent knobs, and the standard's own example uses exactly that. A MAD-X variable is a name in the one namespace the whole file shares, so a variable whose bare name is claimed by another controller, or by a constant, is prefixed with the controller that owns it. One that is claimed by nobody else keeps its bare name, which is what nearly every lattice will have and is far the easier to read.

source
PALSParserJ._make_bmad_eleMethod
_make_bmad_ele(ele::YAMLNode)

Translate a single PALS element into a BmadEleDef.

Dispatch on the element kind and its parameter groups (aperture, bend, body shift, multipoles, patch, RF, solenoid, reference change, ...) to build the Bmad element type and its attribute fragments. Unsupported parameter groups emit a message or raise an error.

source
PALSParserJ._make_bmad_lineMethod
_make_bmad_line(ele::YAMLNode)

Translate a BeamLine element into a BmadBeamline.

Collect the member element names (dropping the leading reference entry, line[1], by design) into the returned beamline.

source
PALSParserJ._make_madx_controllerMethod
_make_madx_controller(ele, facility, lat, varmap, initials)

Translate a Controller element into a MadxController.

facility is needed to reach the slave elements: what a control expression must be scaled by depends on the element it drives (see _madx_control_target). varmap and initials carry what each controller variable is called in the MAD-X file and what it starts at (see _madx_variable_names). lat is needed for a RELATIVE controller, whose slaves keep the value their element definitions already gave them.

The two control types part company here. An ABSOLUTE controller sets its slaves outright, and a deferred assignment does the same. A RELATIVE one is a knob: its slaves keep the value the lattice gave them and move by however far the knob has been turned from where it started, so the assignment is the element's own value, plus the expression, less the expression at the variables' initial settings. That last term is what a Bmad group keeps track of by itself and MAD-X has nothing for; it is left out only when it can be shown to come to zero, which for a knob resting at zero it does.

source
PALSParserJ._make_madx_eleMethod
_make_madx_ele(ele::YAMLNode)

Translate a single PALS element into a MadxEleDef and its MadxAlignment.

Dispatch on the element kind and its parameter groups (aperture, bend, body shift, multipoles, patch, RF, solenoid, ...) to build the MAD-X element type and its attribute fragments. A BodyShiftP comes back separately because MAD-X keeps a misalignment out of the element definition and in an EALIGN command of its own. Unsupported parameter groups emit a message or raise an error.

source
PALSParserJ._make_madx_lineMethod
_make_madx_line(ele::YAMLNode, facility::YAMLNode)

Translate a BeamLine element into a MadxBeamline.

Collect the member element names into the returned beamline. A leading BeginningEle is dropped – it carries the reference parameters, which become the BEAM command, and MAD-X has no element for it – whether it is spelled out in the line or named there and defined in the facility. A line that does not begin with one, which is a branch forked into with its reference parameters propagated, keeps every element it has.

source
PALSParserJ._make_scibmad_beamlineMethod
_make_scibmad_beamline(ele::YAMLNode, facility::YAMLNode)

Translate a BeamLine element into a SciBmadBeamline.

Collect the member element names (dropping the leading reference entry, line[1]) and the reference parameters read from that first entry. A line may also name its beginning element instead of spelling it out, in which case the reference parameters are on that element's facility definition.

source
PALSParserJ._make_scibmad_controllerMethod
_make_scibmad_controller(ele::YAMLNode, facility::YAMLNode)

Translate a Controller element into a SciBmadController.

Each control becomes a function of the controller's variables, which SciBmad passes as keyword arguments. control_type: RELATIVE adds its expression to the value the element already carries – that is what makes it relative – while ABSOLUTE replaces it.

source
PALSParserJ._make_scibmad_eleMethod
_make_scibmad_ele(ele::YAMLNode)

Translate a single PALS element into a SciBmadEle.

Dispatch on the element's parameter groups (aperture, bend, body shift, multipoles, patch, RF, solenoid, tracking, reference change, ...) to build the keyword-argument fragments of a LineElement. Unsupported parameters emit a message.

source
PALSParserJ._mp_keyMethod
_mp_key(rep::ABRepresentation)

Return the Bmad attribute fragments for A/B field-integral multipoles.

Emit an An = ... / Bn = ... fragment for each nonzero coefficient in rep.

source
PALSParserJ._mp_keyMethod
_mp_key(rep::FullRepresentation)

Return the Bmad attribute fragments for the raw multipole representation.

Emit Kn...L, Kn...SL, and tilt fragments for each multipole in rep.

source
PALSParserJ._name_value_pairsMethod
_name_value_pairs(node::YAMLNode)

Return a PALS name/value list as name => value-text pairs, in definition order.

Accepts both forms the standard allows for such a list: a map (vv: 0.3) and a sequence of single-key maps (- vv: 0.3). An entry written with no value takes PALS' default of zero, and one whose value is a structure rather than a single value is skipped.

source
PALSParserJ._native_strength!Function
_native_strength!(full::FullRepresentation, ele_kind::String, offset::Real = 0.0)

Take the multipoles that are an element's own strength out of full and return their Bmad attribute fragments.

The strength of a Bmad quadrupole is its K1, so that is where a PALS Kn1 belongs: leaving it in a B1 multipole would give an element whose nominal strength is zero and whose field comes entirely from a multipole slot. A bend has a K1 and a K2 of its own on top of its bending field, so a bend's Kn1 and Kn2 land there in the same way. A native attribute is not length integrated, so an integrated PALS value is divided by the element length; a tilted one is rotated first, and whatever lands in the skew part is left behind in full as an ordinary multipole. That rotation is why the tilt does not simply become the Bmad element tilt, which is already spoken for by BodyShiftP.z_rot.

offset is subtracted from the order-0 value written, for the one native attribute Bmad does not measure from zero: a bend's DG is the departure of the field from the reference bend (see _bend_reference).

An order is left in full untouched, to be written in the multipole form, when it has no native attribute for this kind; when an integrated multipole sits on a zero-length element, which no non-integrated attribute can express; and, for a bend's added K1 and K2, when the field has a skew part. As elsewhere in this conversion, an element with no length is taken to be one metre long.

source
PALSParserJ._scibmad_control_targetMethod
_scibmad_control_target(cname::String, param::String, facility::YAMLNode)

Translate a controller's parameter target into a SciBmad (element, :property) pair.

Return (element, property). SciBmad keeps the PALS parameter names, so a group-qualified target such as q>MagneticMultipoleP.Kn1 needs only its group prefix dropped.

A target may name its element by kind as well as by name, as {kind}::{name}; the qualifier is checked against the element found and then dropped, SciBmad naming each element once.

Targets SciBmad cannot express – a pattern matching several elements, or a >> or >>> qualifier naming the BeamLine or Lattice an element is reached through – raise an error.

source
PALSParserJ._tilt_rotationMethod
_tilt_rotation(order::Int, tilt::Real)

Return the factor that rotates an order multipole of the given tilt into normal and skew parts.

A tilt of T rotates an order-N field by (N+1) * T in the normal/skew plane: both PALS and Bmad write the field as (1/N!) (normal + i * skew) exp(-i (N+1) T).

source
PALSParserJ._value_textMethod
_value_text(node::YAMLNode)

Return the text of a value node, with a value left unwritten taken as PALS' default of zero.

source
PALSParserJ.add_map!Method
add_map!(parent; key=nothing, index=nothing) -> YAMLNode

Add an empty MAP child to parent. Pass key for MAP parents; omit it (or pass nothing) for sequence elements. index selects the 1-based position among parent's existing children; the default index=nothing appends at the end.

source
PALSParserJ.add_scalar!Method
add_scalar!(parent, value; key=nothing, index=nothing) -> YAMLNode

Add a scalar child to parent. Pass key for MAP parents; omit it (or pass nothing) for sequence elements. index selects the 1-based position among parent's existing children; the default index=nothing appends at the end.

source
PALSParserJ.add_sequence!Method
add_sequence!(parent; key=nothing, index=nothing) -> YAMLNode

Add an empty sequence child to parent. Pass key for MAP parents; omit it (or pass nothing) for sequence elements. index selects the 1-based position among parent's existing children; the default index=nothing appends at the end.

source
PALSParserJ.deep_copy_children!Method
deep_copy_children!(dst, src; index=nothing)

Copy all children of src into dst at the 1-based position index among dst's existing children; the default index=nothing appends them at the end. Works across different trees.

source
PALSParserJ.deep_copy_node!Method
deep_copy_node!(dst, src)

Copy the type, key, value, and all descendants of src into dst, overwriting whatever dst previously held. Works across different trees.

source
PALSParserJ.get_parentMethod
get_parent(node) -> YAMLNode

Return the parent of node, or error if node is the root (which has no parent).

source
PALSParserJ.is_mapMethod
is_map(node) -> Bool

Return true if node is a MAP (a collection of key/value pairs), false otherwise. A node is exactly one of MAP, sequence, or scalar; use this to decide before accessing children by key.

source
PALSParserJ.is_scalarMethod
is_scalar(node) -> Bool

Return true if node is a scalar (a leaf holding a single string, number, or boolean value), false otherwise. A node is exactly one of MAP, sequence, or scalar; scalar nodes have no children and their value is read with String, Int, Float64, or Bool.

source
PALSParserJ.is_sequenceMethod
is_sequence(node) -> Bool

Return true if node is a sequence (an ordered list of elements), false otherwise. A node is exactly one of MAP, sequence, or scalar; use this to decide before accessing children by index.

source
PALSParserJ.libparserMethod
PALSParserJ.libparser() -> String

Absolute path to the PALSParserCpp shared library every @ccall here targets, resolved on first use and cached thereafter. Throws a descriptive error listing every path tried if the library cannot be found.

Resolution is deliberately lazy rather than done in __init__: using PALSParserJ must succeed without the C library present, so that documentation and other tooling can read the package without a C++ toolchain. The cost is that a missing library is reported at the first call rather than at load.

source
PALSParserJ.node_keyMethod
node_key(node) -> Union{String,Nothing}

Return the key under which node is stored in its parent MAP, as a String, or nothing if node has no key. Sequence elements and the tree root have no key and return nothing.

source
PALSParserJ.parameter_valueMethod
parameter_value(lat::Lattices, match_string) -> Float64 | String | Missing

Return the value of the lattice parameter named by match_string, looked up in the expanded lattice lat.

match_string uses the same PALS Name Matching syntax as match_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 constructs match_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 raw lat.original and lat.combined views are not searched — they carry unevaluated, pre-expansion text. lat.expanded is not searched either: a dependent parameter is a legitimate thing to ask for, and only full_expanded carries one.

Because both searched views are post-expansion, values come back already evaluated: a numeric value as a Float64, and a non-numeric one (e.g. a species name like "#3He", or an expression expansion left unevaluated such as one using random()) verbatim as a String.

The value is resolved as follows:

  • Element parameter, set: its value — a Float64, or a String when non-numeric.
  • Element parameter, not set: the parameter's default is returned (0.0 for every parameter, for now — real per-parameter defaults come later).
  • Constant or variable (bare name): its value, the same way.
  • Nothing identified: missing, 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        (from full_expanded)
parameter_value(lat, "quad1>BendP.g")                 # 0.0        (unset → default)
parameter_value(lat, "a_const")                       # a constant (from adjunct)
parameter_value(lat, "quad1>nope.nope")               # missing
source
PALSParserJ.parse_fileMethod
parse_file(filename) -> YAMLNode

Parse a YAML file from disk. Returns a node pointing to the tree root.

source
PALSParserJ.remove!Method
remove!(node)

Remove node, together with all of its descendants, from its parent. After removal the YAMLNode handle is stale and must not be used again. Intended for non-root nodes; the root has no parent to be removed from.

source
PALSParserJ.set_key!Method
set_key!(node, key)

Set or replace the key under which node is stored in its parent MAP to the string key. Only meaningful for nodes that live inside a MAP; sequence elements are keyless.

source
PALSParserJ.set_scalar!Method
set_scalar!(node, value)

Set or replace the scalar value of node with the string value. Operates on an existing node in place; to set a value by key within a MAP (adding the key if absent), use node[key] = value instead.

source
PALSParserJ.to_yaml_stringMethod
to_yaml_string(node; exclude=String[]) -> String

Emit node and its descendants as a YAML string.

exclude is 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 – node itself is never modified. For example, to print a lattice without the floor and reference subtrees:

println(to_yaml_string(lat, exclude = ["FloorP", "ReferenceP"]))
source
PALSParserJ.write_yamlMethod
write_yaml(node, filename; exclude=String[]) -> Bool

Write the entire tree that contains node to a YAML file. Returns true on success.

exclude is 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, to write a lattice without the floor and reference subtrees:

write_yaml(lat, "out.pals.yaml", exclude = ["FloorP", "ReferenceP"])
source