Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert magnet to use pydantic model #104

Merged

Conversation

MattKing06
Copy link
Collaborator

@MattKing06 MattKing06 commented Nov 7, 2023

Summary of Changes

Device and Magnet classes were originally constructed via dictionary loaded from yaml files. The majority of initialisation code was associated with type-checking, and ensuring that the correct information was defined inside the dictionary passed to the constructor.

It was found that Pydantic models can achieve the same effect and do better at type-enforcement/field-enforcement as well as simplifying the code that defines the class architecture for our devices.

  • Magnet and Device class now use Pydantic models
  • ControlInformation and Metadata pydantic models define the required information at the base level
  • PVSet pydantic model define what PV information is required per-device
  • We now have a MagnetCollection class defined as a pydantic model to perform/manage group-operations on magnets.

Tests

  • Unit tests for Magnet, MagnetCollection, Device, and magnet reader functions have been redefined to take account of the pydantic model changes.

The user-facing side of these changes now allow us to write code for interfacing with devices like below:

from lcls_tools.common.devices.magnet.reader import create_magnet

def take_data():
  print('taking some data...')

gunb_magnets = create_magnet(area='GUNB')
settings = [{'SOL1B' : 0.1, 'SOL2B' : 0.2}, {'SOL1B' : 0.15, 'SOL2B' : 0.25}, {'SOL1B' : 0.2, 'SOL2B' : 0.3}] 
gunb_magnets.scan(scan_settings=settings, function=take_data)

closes #100

MattKing06 and others added 30 commits October 20, 2023 00:48
@MattKing06 MattKing06 marked this pull request as ready for review November 7, 2023 19:46
This was referenced Nov 7, 2023
Copy link
Member

@nneveu nneveu left a comment

Choose a reason for hiding this comment

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

Looks great, thanks!

frozen=True,
)
...

Copy link
Member

Choose a reason for hiding this comment

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

Three dots here?

Copy link
Member

Choose a reason for hiding this comment

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

Comment here on the ...

)
with open(location, "r") as device_file:
config_data = yaml.safe_load(device_file)
if name:
Copy link
Member

Choose a reason for hiding this comment

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

Add comments here on default behavior and naming issue.

metadata:
b_tolerance : 0.002 # in Tesla?
length : 0.135 # in meters?
Copy link
Member

Choose a reason for hiding this comment

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

Move comments to doc strings.

def test_set_bdes_with_args(self, mock_trim, mock_bdes_put):
bdes_settings = {
"SOL1B": 0.1,
}
Copy link
Member

Choose a reason for hiding this comment

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

What happens if someone passes a dict with SOL1B not as a string/in quotes?

self.assertIsNone(create_magnet(self.bad_config, "SOL1B"))
self.assertIsNone(create_magnet(area="GUNB", name="BAD-MAGNET-NAME"))

@patch(
Copy link
Member

Choose a reason for hiding this comment

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

Some comments around here?

@nneveu nneveu merged commit 151a2cb into slaclab:main Nov 8, 2023
1 check passed
@MattKing06 MattKing06 deleted the 100_convert_magnet_to_use_pydantic_model branch November 27, 2023 20:51
Derikka pushed a commit to Derikka/lcls-tools that referenced this pull request Mar 17, 2024
* magnets and screen conversion from csv to dictionary structures working. Can extract by area

* add functionality for extracting multiple areas at once

* add PVs to yaml magnets extraction

* removing unneeded file

* working on adding image pvs to yaml files

* working on image device code

* flake8 and black formatting

* make construction function self, add error handling for MEME timeout

* formatting

* make area a list in screens

* add pv_info to screen construction

* restrict wildcard search in meme

* added models for magnet and associated fields

* start to move magnet functions over to pydantic model

* magnet pydantic model working with reader now

* updated yaml test files to reflect new yaml for devices

* magnet and reader tests up to date with pydantic changes, minimal functional changes to tests

* make MagnetPVSet have frozen attributes.#

* make MagnetPVSet have frozen attributes.

* frozen for controls_information base class

* missed return for area property!

* add setter for bdes

* working on being able to set bdes values for several mags

* find file by area in reader

* use area over location for scope

* change yaml path.

* remove path

* first attempt at function to scan mags

* magnet and device now using pydantic model

* tests reflect model changes, need to check coverage

* add check for function in scan

* remove custom exception, pydantic handles mandatory information now

* coverage up to 100% for each new class now

* formatting

* add pydantic to requirements

* remove superceeded yaml

* add comments for units in tolerance/length

* add comment explaining adding name for device here

---------

Co-authored-by: Neveu <[email protected]>
Co-authored-by: Neveu <[email protected]>
Co-authored-by: matt <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Convert Magnet class to use pydantic model
2 participants