@@ -548,18 +548,21 @@ def __init__(
548
548
bpmtarget: Target orbit position. Must be broadcastable to the number of
549
549
observation points.
550
550
cavdelta: Step on RF frequency for matrix computation [Hz]. This
551
- is also the cavity weight
551
+ is also the cavity weight. Default: automatically computed.
552
552
steerdelta: Step on steerers for matrix computation [rad]. This is
553
553
also the steerer weight. Must be broadcastable to the number of steerers.
554
554
cavdelta: Step on RF frequency for matrix computation [Hz]. This
555
555
is also the cavity weight
556
556
steersum: If :py:obj:`True`, the sum of steerers is appended to the
557
557
Observables.
558
- stsumweight: Weight on steerer summation. Default 1.0 .
558
+ stsumweight: Weight on steerer summation. Default: automatically computed .
559
559
560
560
:ivar VariableList variables: matrix variables
561
561
:ivar ObservableList observables: matrix observables
562
562
563
+ By default, the weights of cavities and steerers summation are set to give
564
+ a factor 2 more efficiency than steerers and BPMs
565
+
563
566
"""
564
567
565
568
def steerer (ik , delta ):
@@ -581,9 +584,9 @@ def set_norm():
581
584
vv = np .mean (np .linalg .norm (nr , axis = 0 ))
582
585
vo = np .mean (np .linalg .norm (nr , axis = 1 ))
583
586
korb = 0.25 * math .sqrt (2.0 ) / math .sin (math .pi * result [3 ])
584
- cavd = vv * korb * alpha * freq / np .linalg .norm (result [2 ] / bpmweight )
585
- stsw = np .linalg .norm (deltas ) / vo / korb
586
- return cavd , stsw
587
+ cd = vv * korb * alpha * freq / np .linalg .norm (result [2 ] / bpmweight )
588
+ sw = np .linalg .norm (deltas ) / vo / korb
589
+ return cd , sw
587
590
588
591
pl = plane_ (plane , "index" )
589
592
plcode = plane_ (plane , "code" )
@@ -600,13 +603,14 @@ def set_norm():
600
603
)
601
604
observables = ObservableList ([bpms ])
602
605
if steersum :
606
+ # noinspection PyUnboundLocalVariable
603
607
sumobs = LatticeObservable (
604
608
steerrefs ,
605
609
"KickAngle" ,
606
610
name = f"{ plcode } _kicks" ,
607
611
target = 0.0 ,
608
612
index = pl ,
609
- weight = stsumweight if stsumweight else stsw ,
613
+ weight = stsumweight if stsumweight else stsw / 2.0 ,
610
614
statfun = np .sum ,
611
615
)
612
616
observables .append (sumobs )
@@ -617,18 +621,49 @@ def set_norm():
617
621
active = (el .longt_motion for el in ring .select (cavrefs ))
618
622
if not all (active ):
619
623
raise ValueError ("Cavities are not active" )
624
+ # noinspection PyUnboundLocalVariable
620
625
cavvar = RefptsVariable (
621
626
cavrefs ,
622
627
"Frequency" ,
623
628
name = "RF frequency" ,
624
- delta = cavdelta if cavdelta else cavd ,
629
+ delta = cavdelta if cavdelta else 2.0 * cavd ,
625
630
)
626
631
variables .append (cavvar )
627
632
628
633
self .nbsteers = nbsteers
629
634
630
635
super ().__init__ (ring , variables , observables )
631
636
637
+ def normalise (
638
+ self , cav_ampl : float | None = 2.0 , stsum_ampl : float | None = 2.0
639
+ ) -> None :
640
+ """Normalise the response matrix
641
+
642
+ Adjust the RF cavity delta and/or the weight of steerer summation so that the
643
+ weighted response matrix is normalised.
644
+
645
+ Args:
646
+ cav_ampl: Desired ratio between the cavity response and the average of
647
+ steerer responses. If :py:obj:`None`, do not normalise.
648
+ stsum_ampl: Desired inverse ratio between the weight of the steerer
649
+ summation and the average of Monitor responses. If :py:obj:`None`,
650
+ do not normalise.
651
+
652
+ By default, the normalisation gives to the RF frequency and steerer summation
653
+ a factor 2 more efficiency than steerers and BPMs
654
+ """
655
+ resp = self .weighted_response
656
+ if resp is None :
657
+ raise AtError ("No response matrix: run build() first" )
658
+ normvar = np .linalg .norm (resp , axis = 0 )
659
+ normobs = np .linalg .norm (resp , axis = 1 )
660
+ if len (self .variables ) > self .nbsteers and cav_ampl is not None :
661
+ self .cavdelta *= np .mean (normvar [:- 1 ]) / normvar [- 1 ] * cav_ampl
662
+ if len (self .observables ) > 1 and stsum_ampl is not None :
663
+ self .stsumweight = (
664
+ self .stsumweight * normobs [- 1 ] / np .mean (normobs [:- 1 ]) / stsum_ampl
665
+ )
666
+
632
667
@property
633
668
def bpmweight (self ):
634
669
"""Weight of position readings."""
0 commit comments