This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
"""
|
||||
cSAXS exposure-box filter transmission utilities.
|
||||
|
||||
This method has been created based on previous spec implementations
|
||||
The translation was mainly done by copilot AI.
|
||||
|
||||
Implements fil_trans physics:
|
||||
- Per-material attenuation-length tables loaded from package 'filter_data/'.
|
||||
- Linear interpolation of attenuation length vs. energy (eV).
|
||||
@@ -137,7 +140,7 @@ class cSAXSFilterTransmission:
|
||||
# -----------------------------
|
||||
# Public API
|
||||
# -----------------------------
|
||||
def fil_trans(
|
||||
def fil_trans_select(
|
||||
self,
|
||||
transmission: float,
|
||||
energy_kev: Optional[float] = None,
|
||||
@@ -498,3 +501,103 @@ class cSAXSFilterTransmission:
|
||||
# Optionally: achieved transmission (approx., using the selected combination value)
|
||||
achieved_T = comb["transmission"]
|
||||
print(f"\nAchieved transmission (approx.): {achieved_T:9.3e} at {energy_kev:.3f} keV")
|
||||
|
||||
|
||||
|
||||
def fil_trans_report(self, tol: float = 0.1) -> None:
|
||||
"""
|
||||
Report the currently active exposure‑box filter combination.
|
||||
Determines stage positions via dev.<axis>.readback.get()
|
||||
with a tolerance window of ±tol relative to nominal positions.
|
||||
"""
|
||||
self._ensure_internal_state()
|
||||
|
||||
# Resolve device object
|
||||
dev = getattr(self.client, "dev", None)
|
||||
if dev is None:
|
||||
dev = self.client.device_manager
|
||||
|
||||
# Try getting current energy
|
||||
try:
|
||||
energy_kev = float(self.client.device_manager.mokev.read())
|
||||
except Exception:
|
||||
print("WARNING: Could not read current beam energy. Assuming 6.2 keV.")
|
||||
energy_kev = 6.2
|
||||
|
||||
print("\nCurrent filter transmission report")
|
||||
print("-" * 60)
|
||||
print(f"Photon energy : {energy_kev:.3f} keV")
|
||||
print(f"Tolerance : ±{tol:.3f}")
|
||||
print("-" * 60)
|
||||
|
||||
indices = [] # 0–5 per unit
|
||||
|
||||
for unit_idx, axis_name in enumerate(self._AXES):
|
||||
axis_obj = getattr(dev, axis_name, None)
|
||||
if axis_obj is None:
|
||||
print(f"ERROR: Device axis '{axis_name}' not found.")
|
||||
return
|
||||
|
||||
# Read readback
|
||||
try:
|
||||
rb = float(axis_obj.readback.get())
|
||||
except Exception:
|
||||
print(f"ERROR: readback unavailable for axis {axis_name}")
|
||||
return
|
||||
|
||||
# Match readback to nearest nominal
|
||||
pos_list = self._POSITIONS_USER[unit_idx]
|
||||
best_idx = None
|
||||
for i, nominal in enumerate(pos_list):
|
||||
if nominal is None:
|
||||
continue
|
||||
if abs(rb - nominal) <= tol:
|
||||
best_idx = i
|
||||
break
|
||||
|
||||
if best_idx is None:
|
||||
print(f"Unit {unit_idx+1}: readback {rb:.3f} does not match any known position.")
|
||||
return
|
||||
|
||||
indices.append(best_idx)
|
||||
|
||||
# Build combination dictionary like internally used ones
|
||||
code = "".join(str(i + 1) for i in indices)
|
||||
print(f"\nMatched filter code: {code}")
|
||||
|
||||
# Build full combination record for transmission calculation
|
||||
units = [
|
||||
self._FILTERS[u * self._PER_UNIT : (u + 1) * self._PER_UNIT]
|
||||
for u in range(self._UNITS)
|
||||
]
|
||||
|
||||
materials = []
|
||||
total_T = 1.0
|
||||
|
||||
for u, pos_idx in enumerate(indices):
|
||||
(m1, t1), (m2, t2), enabled = units[u][pos_idx]
|
||||
T = self._position_transmission(units[u][pos_idx], energy_kev)
|
||||
if T is None:
|
||||
print(f"Unit {u+1}: position disabled")
|
||||
T = 1.0
|
||||
total_T *= T
|
||||
|
||||
if m2 != "none" and t2 > 0:
|
||||
materials.append(((m1, t1), (m2, t2)))
|
||||
else:
|
||||
materials.append(((m1, t1), None))
|
||||
|
||||
# Print detailed report
|
||||
print(f"Total transmission: {total_T:.6e}\n")
|
||||
|
||||
for u, matinfo in enumerate(materials, start=1):
|
||||
(m1, t1), second = matinfo
|
||||
pos = indices[u - 1] + 1
|
||||
if second:
|
||||
m2, t2 = second
|
||||
print(f" unit {u}: #{pos} {t1:4.0f} µm {m1:<4} + {t2:4.0f} µm {m2:<4}")
|
||||
else:
|
||||
if m1 != "none" and t1 > 0:
|
||||
print(f" unit {u}: #{pos} {t1:4.0f} µm {m1:<4}")
|
||||
else:
|
||||
print(f" unit {u}: #{pos} ----- out")
|
||||
|
||||
Reference in New Issue
Block a user