Skip to content

Fix BeamLine name attribute#16

Merged
ax3l merged 7 commits into
pals-project:mainfrom
EZoni:beamline_name
Oct 15, 2025
Merged

Fix BeamLine name attribute#16
ax3l merged 7 commits into
pals-project:mainfrom
EZoni:beamline_name

Conversation

@EZoni

@EZoni EZoni commented Jul 23, 2025

Copy link
Copy Markdown
Member

Overview

With the implementation in the main branch, if we add a name attribute to the line object created in the FODO example, the attribute is ignored and the output is

kind: Line
line:
- drift1:
    kind: Drift
    length: 0.25
- quad1:
    MagneticMultipoleP:
      Bn1: 1.0
    kind: Quadrupole
    length: 1.0
- drift2:
    kind: Drift
    length: 0.5
- quad2:
    MagneticMultipoleP:
      Bn1: -1.0
    kind: Quadrupole
    length: 1.0
- drift3:
    kind: Drift
    length: 0.5

This is not consistent with the example in https://github.com/campa-consortium/pals/blob/main/examples/fodo.pals.yaml.

With the implementation in this branch, if we add a name attribute to the line object created in the FODO example, the attribute is stored and the output is

fodo_cell:
  kind: BeamLine
  line:
  - drift1:
      kind: Drift
      length: 0.25
  - quad1:
      MagneticMultipoleP:
        Bn1: 1.0
      kind: Quadrupole
      length: 1.0
  - drift2:
      kind: Drift
      length: 0.5
  - quad2:
      MagneticMultipoleP:
        Bn1: -1.0
      kind: Quadrupole
      length: 1.0
  - drift3:
      kind: Drift
      length: 0.5

which is consistent with the example in https://github.com/campa-consortium/pals/blob/main/examples/fodo.pals.yaml.

This is achieved primarily by deriving the Line (BeamLine after #15) class from the base element class BaseElement instead of deriving it from Pydantic's base model class BaseModel.

I also merged the custom field validation of the line field with the custom model validation, since we needed one anyways to fix the deserialization. I don't see why they should be separate.

I wonder if the right way to do this is using @model_serializer instead of @model_validator...

To do

  • Serialization (fixed with c391e43, very few lines changed)
  • Deserialization (fixed with the custom model validator, many more lines changed)
  • Cleaning

@EZoni EZoni changed the title Fix (Beam)Line name attribute [WIP] Fix (Beam)Line name attribute Jul 23, 2025
Comment thread examples/fodo.py
Comment thread examples/fodo.py Outdated
yaml_data = yaml.safe_load(file)
# Parse YAML data
loaded_line = Line(**yaml_data)
loaded_line = Line(**yaml_data[0])

@EZoni EZoni Jul 23, 2025

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yaml_data was a dictionary before, now it's a one-element list. Keeping the previous API for the Line constructor requires more work, which could be done in this PR or in a separate PR. I have not tried it yet (i.e., I don't know yet if I can find a way to make it work).

@EZoni EZoni changed the title [WIP] Fix (Beam)Line name attribute Fix (Beam)Line name attribute Jul 23, 2025
@EZoni EZoni mentioned this pull request Jul 24, 2025
@EZoni EZoni requested a review from ax3l July 24, 2025 00:12
@ax3l

ax3l commented Aug 7, 2025

Copy link
Copy Markdown
Member

@EZoni does this need a rebase?

@EZoni

EZoni commented Aug 7, 2025

Copy link
Copy Markdown
Member Author

Probably yes, after the last few commits in main. I will get to it asap.

@EZoni

EZoni commented Aug 7, 2025

Copy link
Copy Markdown
Member Author

@ax3l

Conflicts fixed.

@ax3l ax3l self-assigned this Aug 18, 2025
Comment thread examples/fodo.py Outdated
yaml_data = yaml.safe_load(file)
# Parse YAML data
loaded_line = BeamLine(**yaml_data)
loaded_line = BeamLine(**yaml_data[0])

@ax3l ax3l Aug 18, 2025

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me think, also for our current layout/draft:

  • should a PALS file support having multiple beamlines (segments: yes)?
  • if not, which one is the "entry point" to use by default? The 0-th element might be a lattice element and not a kind: BeamLine once we support inheritance

Ignoring the entry point question, we might need a "wrapping" LatticeElements class here in Python that can load a list of elements (instead of only loading [0] and assuming it is of kind BeamLine)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a change in 464020d to return a dict instead of a single-element list.

I cannot remember where the single-element list came from, but the new change seems to avoid the API issue. Am I overlooking something?

I'm not sure I understand what the LatticeElements class should be, but maybe it could be done in a separate PR, unless it turns out that it's necessary here.

@EZoni EZoni Oct 3, 2025

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the problem was with the serialization of single elements, maybe it should be fixed separately as well.

@EZoni EZoni changed the title Fix (Beam)Line name attribute Fix BeamLine name attribute Oct 3, 2025
@ax3l

ax3l commented Oct 15, 2025

Copy link
Copy Markdown
Member

From the PR description:

I wonder if the right way to do this is using @model_serializer instead of @model_validator...

This is what I found:

The pydantic serializer is how we go from pydantic classes to dicts / json and back. This is needed when we want to rename fields or do custom conversions that are serialized slightly different than the internal representation. It looks to me like this is primarily for output formatting changes, not input.

The pydantic validator is used for custom validation logic, e.g., when someone sets a field/value/property, and can optionally modify values. But it seems this is also used for input changes...

@ax3l ax3l left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent, thank you!

@ax3l ax3l added bug Something isn't working breaking and removed bug Something isn't working labels Oct 15, 2025
@ax3l ax3l merged commit 0bc4878 into pals-project:main Oct 15, 2025
11 checks passed
@EZoni EZoni deleted the beamline_name branch October 15, 2025 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants