Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2173 +/- ##
==========================================
+ Coverage 99.33% 99.35% +0.01%
==========================================
Files 367 378 +11
Lines 14379 14623 +244
==========================================
+ Hits 14284 14528 +244
Misses 95 95 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
4cf081e to
13c130e
Compare
736f148 to
9da488d
Compare
DominicOram
left a comment
There was a problem hiding this comment.
Great, I think the main question is around why we have SystemAspectBaseParser when we could use standard pydantic tools instead?
Additionally, are the wedges mounted on the lateral_motors? In which case why are they separate things in the json structure? Why not have something like:
"wedges": {
"y": {
"material" : "aluminium",
"geometry": {
"taper_cotangent" : 9.3985,
"tip" : 5.06,
"voids": []
"motion": {
"units": "mm",
"out" : 5.0,
"threshold": 8.9,
"max": 98.0,
"tolerance": 5.0e-3
}
}
},
}
This would remove a bunch of edge cases about one not being defined when the other is or the names not matching
I haven't looked at the tests yet, I think once we resolve the discussion on SystemAspectBaseParser they might change a bit anyway.
| upper: The upper end of the energy interval (range) for specific absorption fit curve. | ||
| """ | ||
|
|
||
| units: str = Field(..., pattern=r"^(keV|kiloelectronvolts)$") |
There was a problem hiding this comment.
Should:
| units: str = Field(..., pattern=r"^(keV|kiloelectronvolts)$") | |
| units: Literal["keV", "kiloelectronvolts"] |
is more concise and readable. It also means the type system will enforce it later if we ever use the value
There was a problem hiding this comment.
I didn't know You could enforce a choice of two strings by means of a Literal list...
| Optional residuals correction, zeroth order parameter first. | ||
| """ | ||
|
|
||
| photon_absorption: StrictFloat |
There was a problem hiding this comment.
Could: As above,
| photon_absorption: StrictFloat | |
| photon_absorption: StrictFloat= Field(gt=0) |
There was a problem hiding this comment.
Here it probably makes sense
| """ | ||
|
|
||
| photon_absorption: StrictFloat | ||
| roll_off: StrictFloat |
There was a problem hiding this comment.
Could:
| roll_off: StrictFloat | |
| roll_off: StrictFloat = Field(lt=-2, gt=-4) |
(probably with -2 and -4 pulled into constants). Let's pydantic do all the checking for you. With this and above you can remove the validate_attributes entirely
There was a problem hiding this comment.
a) I wasn't aware Field would work with constants - although it seems reasonable that it can
b) there's no good name for the bounds as they are arbitrary and probably too wide and too "3-centric"
I just don't want +2.67 to be accepted
and accepting -4.2 would imply accepting a typo
but yes it could be better explained - how it is somewhat vague and that vagueness is reflected in the code
There was a problem hiding this comment.
They could just be named something like REALISTIC_PHYSICAL_LOWER_BOUND?
| f"Absorption roll off {self.roll_off} does not seem likely on physics grounds." | ||
| if self.roll_off < 0 |
There was a problem hiding this comment.
Should: Why have a separate check on the positive case? Then have a cryptic message that doesn't tell the user how to fix the issue? I think better to remove this case and just check that it's around -3
There was a problem hiding this comment.
I'll look again - I'm sure bits of it made sense as I was tweaking it
| cls._VALIDATOR.validate_name(name_to_check=axis_name) | ||
|
|
||
|
|
||
| class MaterialNameValidation: |
There was a problem hiding this comment.
Could: Why does it matter what someone wants to name their material?
There was a problem hiding this comment.
It doesn't - but there's every advantage in picking up typos from edits to JSON.
You can't catch them all - but does that really mean You should catch no categories at all?
There was a problem hiding this comment.
I just don't want material 1234_iron. - Why would I allow ints at the start?
There was a problem hiding this comment.
Ok, can we at least add a comment to the affect that it's actually just convention/preference? Otherwise I worry that someone will ask for it in 5 years for a legitimate reason and we'll be worried we can't change it as it might break something
| - Each absorber wedge has a motor to drive it sideways across the x-ray beam: | ||
| - expected sideways motions are pure horizontal or pure vertical | ||
| - but that's a detail, azimuthal orientation around the beam should not matter. | ||
| - The wedge motor scale has | ||
| - an **out** position | ||
| - and then a range of "active" positions, ( where the mathematical assumption of a linear taper is reasonable ). |
There was a problem hiding this comment.
Should: None of this is actually matched by anything in the Spec so it's not clear why it's here and I need to think about it at this point?
There was a problem hiding this comment.
Looking at it from the "I understand the transmission system" end of the telescope - the reader WILL be wondering where's the "move to the absorber OUT the way" gubbins?
There was a problem hiding this comment.
Every attenuating element has a "range" of positions which are absorbing
( sometimes - ie for a foil, range = 1 place only )
and a singular location for OUT
( in principle - even if not in practice - lateral motor +/- margin of readout error is roughly a singular location )
OUT is an almost canonical addendum to the "range" of permitted positions for an absorber.
It's a very inhomogenous logical smush together of range + OUT but I couldn't see any way round it
There was a problem hiding this comment.
Looking at it from the "I understand the transmission system" end of the telescope - the reader WILL be wondering where's the "move to the absorber OUT the way" gubbins?
Yes, exactly and they're not here. Ok, so happy to leave the description here if we have a note to see LateralMotorSpec?
| permissions: Those slot numbers which are permitted to be in use. | ||
| """ | ||
|
|
||
| foils: dict[str, FoilSpec] |
There was a problem hiding this comment.
Nit: These are always numbers, right?
| foils: dict[str, FoilSpec] | |
| foils: dict[int, FoilSpec] |
There was a problem hiding this comment.
so no - they are never integers and always "integers"
There was a problem hiding this comment.
Sure, the JSON dict key must be a string but the python dict key doesn't have to be so you could do the conversion here to enforce it to an integer and stop the user putting something in that isn't an integer
| raise ValueError(_msg) | ||
|
|
||
|
|
||
| class WheelsConfig(SystemAspectBaseParser[WheelSpec]): |
There was a problem hiding this comment.
Must: As above re SystemAspectBaseParser
DominicOram
left a comment
There was a problem hiding this comment.
Sorry, meant the above as a request changes, not a comment
* Start with adding JSON validation for system specification JSON dict-like structure expectations * Pydantic BaseModel classes map sub-structures ( sub-dicts ) within the system description structure here adding JSON validation for energy_interval [ the range of x-ray energies (in keV ) over which an absorption curve is valid ] JSON validation for absorption fit curve parameters [ the scaling constant, roll-off vs energy and an optional residuals polynomial ]
* Use pydantic BaseModel classes to capture blobs from Transmission System specification config JSON files for I19 beamlines EH-1 / EH-2
Contributes to #2172
Instructions to reviewer on how to test:
N.B. Voids in an i19 absorber wedge are bubbles in the absorber material ( 3-D printer output )
and therefore motor positions to avoid:
Nothing to do with the software
voidtype.Checks for reviewer
dodal connect ${BEAMLINE}