1- from ..control .abstract import ReadWriteFloatArray
1+ from ..common .abstract import ReadWriteFloatArray
22from ..magnet .magnet import Magnet
3+ from ..common .abstract_aggregator import ScalarAggregator
4+
35import numpy as np
4- from ..control .deviceaccesslist import DeviceAccessList
56
67class RWMagnetStrength (ReadWriteFloatArray ):
78
89 def __init__ (self , name :str , magnets :list [Magnet ]):
9- self .__magnets = magnets
1010 self .__name = name
11- self .aggregator :DeviceAccessList = None
11+ self .__magnets = magnets
12+ self .__nb = len (self .__magnets )
13+ self .__aggregator :ScalarAggregator = None
1214
1315 # Gets the values
1416 def get (self ) -> np .array :
15- if not self .aggregator :
17+ if not self .__aggregator :
1618 return np .array ([m .strength .get () for m in self .__magnets ])
1719 else :
18- allHardwareValues = self .aggregator .get () # Read all hardware setpoints
19- allStrength = np .zeros (len (self .__magnets ))
20- mIdx = 0
21- idx = 0
22- for m in self .__magnets :
23- nbDev = len (m .model .get_devices ())
24- allStrength [idx ] = m .model .compute_strengths (allHardwareValues [idx :idx + nbDev ])[m .strength .index ()]
25- mIdx += 1
26- idx += nbDev
27- return allStrength
20+ return self .__aggregator .get ()
2821
2922 # Sets the values
3023 def set (self , value :np .array ):
31- if not self .aggregator :
24+ nvalue = np .ones (self .__nb ) * value if isinstance (value ,float ) else value
25+ if not self .__aggregator :
3226 for idx ,m in enumerate (self .__magnets ):
33- m .strength .set (value [idx ])
27+ m .strength .set (nvalue [idx ])
3428 else :
35- # TODO: if the array does not contains mappings to combined function
36- # magnets, the algorithm below can be optimized
37- allHardwareValues = self .aggregator .get () # Read all hardware setpoints
38- newHardwareValues = np .zeros (len (self .aggregator ))
39- mIdx = 0
40- idx = 0
41- for m in self .__magnets :
42- # m is a single function magnet or a mapping to a
43- # combined function magnet (RWMapper)
44- nbDev = len (m .model .get_devices ())
45- mStrengths = m .model .compute_strengths ( allHardwareValues [idx :idx + nbDev ] )
46- mStrengths [m .strength .index ()] = value [mIdx ]
47- newHardwareValues [idx :idx + nbDev ] = m .model .compute_hardware_values (mStrengths )
48- mIdx += 1
49- idx += nbDev
50- self .aggregator .set (newHardwareValues )
29+ self .__aggregator .set (nvalue )
5130
5231 # Sets the values and waits that the read values reach their setpoint
5332 def set_and_wait (self , value :np .array ):
@@ -58,37 +37,32 @@ def unit(self) -> list[str]:
5837 return [m .strength .unit () for m in self .__magnets ]
5938
6039 # Set the aggregator (Control system only)
61- def set_aggregator (self ,agg :DeviceAccessList ):
62- self .aggregator = agg
40+ def set_aggregator (self ,agg :ScalarAggregator ):
41+ self .__aggregator = agg
6342
6443class RWMagnetHardware (ReadWriteFloatArray ):
6544
6645 def __init__ (self , name :str , magnets :list [Magnet ]):
6746 self .__name = name
6847 self .__magnets = magnets
69- self .aggregator : DeviceAccessList = None
70- self .hasHardwareMapping = True
48+ self .__nb = len ( self . __magnets )
49+ self .__aggregator : ScalarAggregator = None
7150
7251 # Gets the values
7352 def get (self ) -> np .array :
74- if not self .aggregator :
53+ if not self .__aggregator :
7554 return np .array ([m .hardware .get () for m in self .__magnets ])
7655 else :
77- if not self .hasHardwareMapping :
78- raise Exception (f"Array { self .__name } contains elements that that do not support hardware units" )
79- else :
80- return self .aggregator .get ()
56+ return self .__aggregator .get ()
8157
8258 # Sets the values
8359 def set (self , value :np .array ):
84- if not self .aggregator :
60+ nvalue = np .ones (self .__nb ) * value if isinstance (value ,float ) else value
61+ if not self .__aggregator :
8562 for idx ,m in enumerate (self .__magnets ):
8663 m .hardware .set (value [idx ])
8764 else :
88- if not self .hasHardwareMapping :
89- raise Exception (f"Array { self .__name } contains elements that that do not support hardware units" )
90- else :
91- self .aggregator .set (value )
65+ self .__aggregator .set (value )
9266
9367 # Sets the values and waits that the read values reach their setpoint
9468 def set_and_wait (self , value :np .array ):
@@ -98,44 +72,38 @@ def set_and_wait(self, value:np.array):
9872 def unit (self ) -> list [str ]:
9973 return [m .hardware .unit () for m in self .__magnets ]
10074
101- # Set the aggregator (Control system only)
102- def set_aggregator (self ,agg :DeviceAccessList ):
103- self .aggregator = agg
104- for m in self .__magnets :
105- self .hasHardwareMapping |= m .model .has_hardware ()
75+ # Set the aggregator
76+ def set_aggregator (self ,agg :ScalarAggregator ):
77+ self .__aggregator = agg
10678
10779class MagnetArray (list [Magnet ]):
10880 """
10981 Class that implements access to a magnet array
11082 """
11183
112- def __init__ (self ,arrayName :str ,iterable ):
84+ def __init__ (self ,arrayName :str ,magnets : list [ Magnet ], holder = None ):
11385 """
11486 Construct a magnet array
11587
11688 Parameters
11789 ----------
118- iterable
90+ arrayName : str
91+ Array name
92+ magnets: list[Magnet]
11993 Magnet iterator
94+ holder : Element holder
95+ Holder (Simulator or Control System) that contains element of this array used for aggregator
12096 """
121- super ().__init__ (i for i in iterable )
97+ super ().__init__ (i for i in magnets )
12298 self .__name = arrayName
123- self .__rwstrengths = RWMagnetStrength (arrayName ,iterable )
124- self .__rwhardwares = RWMagnetHardware (arrayName ,iterable )
125-
126- def set_aggregator (self ,agg :DeviceAccessList ):
127- """
128- Set an aggregator for this array.
129- Aggregator allow fast control system access by parallelizing
130- call to underlying hardware.
131-
132- Parameters
133- ----------
134- agg : DeviceAccessList
135- List of device access
136- """
137- self .__rwstrengths .set_aggregator (agg )
138- self .__rwhardwares .set_aggregator (agg )
99+ self .__rwstrengths = RWMagnetStrength (arrayName ,magnets )
100+ self .__rwhardwares = RWMagnetHardware (arrayName ,magnets )
101+
102+ if holder is not None :
103+ aggs = holder .create_magnet_strength_aggregator (magnets )
104+ aggh = holder .create_magnet_harddware_aggregator (magnets )
105+ self .__rwstrengths .set_aggregator (aggs )
106+ self .__rwhardwares .set_aggregator (aggh )
139107
140108 @property
141109 def strengths (self ) -> RWMagnetStrength :
0 commit comments