Skip to content

Commit 0617b4f

Browse files
committed
Added a normalise method
1 parent e5adff2 commit 0617b4f

File tree

2 files changed

+43
-8
lines changed

2 files changed

+43
-8
lines changed

docs/p/notebooks/observables.ipynb

+1-1
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@
936936
"name": "python",
937937
"nbconvert_exporter": "python",
938938
"pygments_lexer": "ipython3",
939-
"version": "3.9.20"
939+
"version": "3.11.11"
940940
}
941941
},
942942
"nbformat": 4,

pyat/at/latticetools/response_matrix.py

+42-7
Original file line numberDiff line numberDiff line change
@@ -548,18 +548,21 @@ def __init__(
548548
bpmtarget: Target orbit position. Must be broadcastable to the number of
549549
observation points.
550550
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.
552552
steerdelta: Step on steerers for matrix computation [rad]. This is
553553
also the steerer weight. Must be broadcastable to the number of steerers.
554554
cavdelta: Step on RF frequency for matrix computation [Hz]. This
555555
is also the cavity weight
556556
steersum: If :py:obj:`True`, the sum of steerers is appended to the
557557
Observables.
558-
stsumweight: Weight on steerer summation. Default 1.0.
558+
stsumweight: Weight on steerer summation. Default: automatically computed.
559559
560560
:ivar VariableList variables: matrix variables
561561
:ivar ObservableList observables: matrix observables
562562
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+
563566
"""
564567

565568
def steerer(ik, delta):
@@ -581,9 +584,9 @@ def set_norm():
581584
vv = np.mean(np.linalg.norm(nr, axis=0))
582585
vo = np.mean(np.linalg.norm(nr, axis=1))
583586
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
587590

588591
pl = plane_(plane, "index")
589592
plcode = plane_(plane, "code")
@@ -600,13 +603,14 @@ def set_norm():
600603
)
601604
observables = ObservableList([bpms])
602605
if steersum:
606+
# noinspection PyUnboundLocalVariable
603607
sumobs = LatticeObservable(
604608
steerrefs,
605609
"KickAngle",
606610
name=f"{plcode}_kicks",
607611
target=0.0,
608612
index=pl,
609-
weight=stsumweight if stsumweight else stsw,
613+
weight=stsumweight if stsumweight else stsw / 2.0,
610614
statfun=np.sum,
611615
)
612616
observables.append(sumobs)
@@ -617,18 +621,49 @@ def set_norm():
617621
active = (el.longt_motion for el in ring.select(cavrefs))
618622
if not all(active):
619623
raise ValueError("Cavities are not active")
624+
# noinspection PyUnboundLocalVariable
620625
cavvar = RefptsVariable(
621626
cavrefs,
622627
"Frequency",
623628
name="RF frequency",
624-
delta=cavdelta if cavdelta else cavd,
629+
delta=cavdelta if cavdelta else 2.0 * cavd,
625630
)
626631
variables.append(cavvar)
627632

628633
self.nbsteers = nbsteers
629634

630635
super().__init__(ring, variables, observables)
631636

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+
632667
@property
633668
def bpmweight(self):
634669
"""Weight of position readings."""

0 commit comments

Comments
 (0)