PyMAD-NG Architecture Overview

This section explains the internal architecture of PyMAD-NG, outlining how Python interacts with MAD-NG.

Note

Understanding the architecture will help advanced users contribute to development, extend functionality, and debug issues more effectively.


High-Level Overview

PyMAD-NG is a Python wrapper for MAD-NG, using standard UNIX pipes to manage two-way communication between Python and the MAD-NG subprocess. It provides both:

  • A low-level string-based API (like scripting MAD-NG manually)

  • A high-level object-based API that emulates Pythonic behaviour

At the heart of PyMAD-NG is the MAD class, which:

  • Spawns the MAD-NG binary as a subprocess

  • Manages sending commands and receiving data

  • Handles variable binding, temporary variables, and object references


Communication Pipeline

The communication between Python and MAD-NG follows this pipeline:

+-----------+        send()        +---------+
|  Python   | -------------------> | MAD-NG  |
|  Script   | <------------------- | Process |
+-----------+        recv()        +---------+

This is implemented using os.pipe() and select.select() to manage reads and writes asynchronously.

Communication Protocol

  • Commands are sent as strings to MAD-NG (e.g., mad.send("a = 1 + 2"))

  • Responses are requested explicitly via {func}MAD.recv`

  • Data can be sent and received in binary or string formats, depending on the type


Core Components

MAD Class (madp_object)

  • Main interface for users

  • Automatically loads common MAD-NG modules (e.g. twiss, element, sequence)

  • Handles naming of Python process in MAD-NG via py_name

  • Configures subprocess behaviour (debug mode, stdout redirection)

madp_pymad.MadProcess

  • Manages low-level pipe setup and subprocess launch

  • Provides send, recv, and close methods

  • Serialises and deserialises Python <-> MAD data

madp_classes

  • Wraps MAD-NG references returned to Python

  • Allows chained method calls like mad.math.sin(1)

  • Supports .eval() to convert a MAD value into a native Python object

  • Implements __getattr__, __getitem__, __call__ to emulate Lua table behaviour

madp_last

  • Implements _last[] variable management for symbolic return values

  • Ensures unique temporary variable usage

  • Used in constructing expression chains

madp_strings

  • Contains helpers for quoting strings for MAD-NG consumption

  • Supports quote-conversion for use in file writing and table exporting


Data Types and Serialization

PyMAD-NG supports a wide range of Python-native and NumPy types, which are automatically serialised and mapped to MAD-NG equivalents.

Python Type

MAD-NG Type

Transport Format

int, float, str

number, string

text or binary

bool

bool

text

complex

complex

binary

list

table

serialised list

numpy.ndarray

matrix, cmatrix

binary

range, np.geomspace

range types

encoded structure

Conversion is handled by MAD.send() and {func}MAD.recv, both methods on the {class}MAD` class.


Dynamic Attributes & Autocompletion

Because MAD-NG entities are only known at runtime, PyMAD-NG uses dynamic attribute access via __getattr__. This means:

  • Tab completion (dir(mad)) only works for preloaded or cached attributes

  • Use MAD.globals() to list current MAD-NG global variables

  • madp_classes.high_level_MadRef objects will not show introspectable properties until evaluated


Protected Execution

All sends are “protected” by default:

  • If MAD-NG returns an error, PyMAD-NG raises a Python RuntimeError

  • The return type err_ is automatically detected and escalated

  • This avoids crashes and lets users handle exceptions gracefully


Summary

Component

Role

MAD class

Main interface and environment for interacting with MAD-NG

madp_pymad.MadProcess

Launches and communicates with MAD-NG subprocess

madp_classes.high_level_MadRef

Wraps MAD objects for Pythonic access

madp_last

Tracks temporary intermediate results from MAD-NG

Type dispatch

Maps Python objects to MAD-NG-compatible messages

This modular, pipe-based architecture ensures PyMAD-NG remains flexible, efficient, and closely integrated with MAD-NG’s scripting model.