Skip to content

Commit e366c54

Browse files
committed
testing tune and correcting it push values
1 parent 3a48291 commit e366c54

File tree

2 files changed

+131
-6
lines changed

2 files changed

+131
-6
lines changed

src/dt4acc/custom_tango/views/repeated_publishing_view.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def process(self, orbit_data: Orbit):
4444
class LegacyBPMView(ViewInterface):
4545
def __init__(self, prefix):
4646
# For Tango, prefix is like "server_name/instance_name:bpm_pv_name"
47-
# We need to extract the server/instance part and construct the device name
47+
4848
self.prefix = prefix
4949
self.counter = itertools.count()
5050
# Extract base prefix (server_name/instance_name) by splitting on ':'
@@ -144,6 +144,8 @@ async def push(self, data: TuneData):
144144
device_name = f"{self.prefix}/tune_device"
145145
device = DeviceProxy(device_name)
146146

147+
logger.debug(f"TuneView.push: Writing tune X={tune_x:.10f}, Y={tune_y:.10f} to {device_name}")
148+
147149
await asyncio.get_event_loop().run_in_executor(
148150
None,
149151
lambda: device.write_attribute("x", tune_x)
@@ -152,9 +154,11 @@ async def push(self, data: TuneData):
152154
None,
153155
lambda: device.write_attribute("y", tune_y)
154156
)
157+
158+
logger.info(f"TuneView.push: >>>>>>>> Successfully wrote tune X={tune_x:.10f}, Y={tune_y:.10f}")
155159

156160
except Exception as e:
157-
logger.error(f"Error processing tune object data: {e}")
161+
logger.error(f"TuneView.push: ❌ Error writing tune values: {e}")
158162

159163

160164
class RepeatedResultView:
@@ -178,15 +182,23 @@ def set_bpm_mimicry(self, bpm_mimicry):
178182
async def heart_beat(self):
179183
"""
180184
Periodic heartbeat function to push default BPM data.
185+
186+
Note: We do NOT republish tune here because tune values should only
187+
be published when fresh calculations are complete. Republishing cached
188+
tune values would overwrite fresh values with stale ones.
181189
"""
182-
logger.debug(f"{self.__class__.__name__} heartbeat {datetime.now()}, publishing bpm, orbit, twiss")
190+
logger.debug(f"{self.__class__.__name__} heartbeat {datetime.now()}, publishing bpm, orbit")
183191
await self.orbit_object_publisher.publish()
184-
await self.tune_publisher.publish()
192+
# DO NOT publish tune here - it's published by push_twiss() with fresh values
193+
# await self.tune_publisher.publish() # ← REMOVED: This was overwriting fresh tune values with stale cache
185194
await self.legacy_bpm_publisher.publish()
186-
logger.info(f"{self.__class__.__name__} view heartbeat {datetime.now()}, published bpm, orbit, twiss")
195+
logger.info(f"{self.__class__.__name__} view heartbeat {datetime.now()}, published bpm, orbit")
187196

188197
async def push_twiss(self, twiss_result: TwissWithAggregatedKValues):
189-
self.tune_publisher.set_data(TuneData(x=twiss_result.x.tune, y=twiss_result.y.tune))
198+
tune_x = float(twiss_result.x.tune)
199+
tune_y = float(twiss_result.y.tune)
200+
logger.info(f"RepeatedResultView.push_twiss: Publishing FRESH tune values X={tune_x:.10f}, Y={tune_y:.10f}")
201+
self.tune_publisher.set_data(TuneData(x=tune_x, y=tune_y))
190202
await self.tune_publisher.publish()
191203

192204
async def push_orbit(self, orbit_result: Orbit):
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Test script with SMALL, realistic current changes.
4+
5+
This tests whether small current adjustments (±1%, ±5%, ±10%)
6+
produce corresponding small tune changes, which would be expected
7+
in normal accelerator operation.
8+
"""
9+
10+
import time
11+
import sys
12+
from tango import DeviceProxy
13+
14+
def test_small_changes():
15+
"""Test tune response to small current changes."""
16+
17+
print("=" * 80)
18+
print("SMALL CURRENT CHANGES TEST - Realistic operational adjustments")
19+
print("=" * 80)
20+
21+
try:
22+
# Connect to devices
23+
tune_device_name = "SimpleTangoServer/test/tune_device"
24+
pc_device_name = "SimpleTangoServer/test/power_converter_Q3P2T6R"
25+
26+
print(f"\nConnecting to devices...")
27+
tune_device = DeviceProxy(tune_device_name)
28+
pc_device = DeviceProxy(pc_device_name)
29+
print(f" ✓ Tune device: {tune_device_name}")
30+
print(f" ✓ Power converter: {pc_device_name}")
31+
32+
# Get initial values
33+
initial_current = pc_device.read_attribute("current_setpoint").value
34+
initial_tune_x = tune_device.read_attribute("x").value
35+
initial_tune_y = tune_device.read_attribute("y").value
36+
37+
print(f"\n Initial State:")
38+
print(f" Current: {initial_current:.6f} A")
39+
print(f" Tune X: {initial_tune_x:.10f}")
40+
print(f" Tune Y: {initial_tune_y:.10f}")
41+
42+
print("\n" + "=" * 80)
43+
print("TEST SEQUENCE: Small incremental changes")
44+
print("=" * 80)
45+
46+
# Test sequence with small changes
47+
# Format: (percentage, description)
48+
test_changes = [
49+
(1.01, "+1% (very small)"),
50+
(1.02, "+2%"),
51+
(1.05, "+5%"),
52+
(1.10, "+10%"),
53+
(1.15, "+15%"),
54+
(1.00, "Back to initial"),
55+
(0.99, "-1%"),
56+
(0.98, "-2%"),
57+
(0.95, "-5%"),
58+
(0.90, "-10%"),
59+
(0.85, "-15%"),
60+
(1.00, "Restore initial"),
61+
]
62+
63+
results = []
64+
tune_changed_count = 0
65+
66+
for i, (factor, description) in enumerate(test_changes, 1):
67+
test_current = initial_current * factor
68+
69+
print(f"\n--- Test {i}/{len(test_changes)}: {description}{test_current:.4f} A ---")
70+
71+
# Set the new current
72+
pc_device.write_attribute("current_setpoint", test_current)
73+
74+
# Wait for calculations (longer wait to ensure completion)
75+
wait_time = 2.0
76+
time.sleep(wait_time)
77+
78+
# Read values
79+
readback_current = pc_device.read_attribute("current_readback").value
80+
new_tune_x = tune_device.read_attribute("x").value
81+
new_tune_y = tune_device.read_attribute("y").value
82+
83+
84+
85+
return tune_changed_count > 0
86+
87+
except Exception as e:
88+
print(f"\n❌ ERROR: {e}")
89+
import traceback
90+
traceback.print_exc()
91+
return False
92+
93+
finally:
94+
# Restore initial current
95+
try:
96+
if pc_device and initial_current is not None:
97+
print(f"\n Restoring initial current: {initial_current:.6f} A")
98+
pc_device.write_attribute("current_setpoint", initial_current)
99+
time.sleep(2.0)
100+
print("✓ Current restored")
101+
except:
102+
pass
103+
104+
105+
if __name__ == "__main__":
106+
print("\n" + "" * 40)
107+
print("SMALL CURRENT CHANGES → TUNE RESPONSE TEST")
108+
print("" * 40 + "\n")
109+
110+
success = test_small_changes()
111+
112+
113+

0 commit comments

Comments
 (0)