Skip to content
12 changes: 12 additions & 0 deletions src/genie_python/genie.py
Original file line number Diff line number Diff line change
Expand Up @@ -2554,3 +2554,15 @@ def get_detector_table() -> str | None:
"""
assert _genie_api.dae is not None
return _genie_api.dae.get_table_path("Detector")


@usercommand
@log_command_and_handle_exception
def change_autosave(freq: float) -> None:
"""Change the rate of ICP autosave

Args:
freq (float): frequency of autosave
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The units are actually "Frames" (as in isis pulses) as opposed to Hz and are an integer

assert _genie_api.dae is not None
_genie_api.dae.change_autosave_freq(freq)
40 changes: 25 additions & 15 deletions src/genie_python/genie_change_cache.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import xml.etree.ElementTree as ET
from builtins import object, str
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from genie_python.genie import PVValue


class ChangeCache(object):
def __init__(self):
def __init__(self) -> None:
self.wiring = None
self.detector = None
self.spectra = None
self.mon_spect = None
self.mon_from = None
self.mon_to = None
self.mon_spect: int | None = None
self.mon_from: float | None = None
self.mon_to: float | None = None
self.dae_sync = None
self.tcb_file = None
self.tcb_tables = []
Expand All @@ -30,13 +35,14 @@
self.periods_seq = None
self.periods_delay = None
self.periods_settings = []
self.autosave_freq = None

def set_monitor(self, spec, low, high):
def set_monitor(self, spec: int | None, low: float | None, high: float | None) -> None:
self.mon_spect = spec
self.mon_from = low
self.mon_to = high

def clear_vetos(self):
def clear_vetos(self) -> None:
self.smp_veto = 0
self.ts2_veto = 0
self.hz50_veto = 0
Expand All @@ -45,12 +51,12 @@
self.ext2_veto = 0
self.ext3_veto = 0

def set_fermi(self, enable, delay=1.0, width=1.0):
def set_fermi(self, enable: int | bool, delay: float = 1.0, width: float = 1.0) -> None:
self.fermi_veto = 1 if enable else 0
self.fermi_delay = delay
self.fermi_width = width

def change_dae_settings(self, root):
def change_dae_settings(self, root: ET) -> bool:
changed = self._change_xml(root, "String", "Wiring Table", self.wiring)
changed |= self._change_xml(root, "String", "Detector Table", self.detector)
changed |= self._change_xml(root, "String", "Spectra Table", self.spectra)
Expand All @@ -68,7 +74,7 @@
changed |= self._change_vetos(root)
return changed

def _change_vetos(self, root):
def _change_vetos(self, root: ET.Element) -> bool:
changed = self._change_xml(root, "EW", "SMP (Chopper) Veto", self.smp_veto)
changed |= self._change_xml(root, "EW", " TS2 Pulse Veto", self.ts2_veto)
changed |= self._change_xml(root, "EW", " ISIS 50Hz Veto", self.hz50_veto)
Expand All @@ -78,17 +84,17 @@
changed |= self._change_xml(root, "EW", "Veto 3", self.ext3_veto)
return changed

def change_tcb_calculation_method(self, root):
def change_tcb_calculation_method(self, root: ET.Element) -> bool:
changed = self._change_xml(root, "U16", "Calculation Method", self.tcb_calculation_method)
return changed

def change_tcb_settings(self, root):
def change_tcb_settings(self, root: ET.Element) -> bool:
changed = self._change_xml(root, "String", "Time Channel File", self.tcb_file)
changed |= self.change_tcb_calculation_method(root)
changed |= self._change_tcb_table(root)
return changed

def _change_tcb_table(self, root):
def _change_tcb_table(self, root: ET.Element) -> bool:
changed = False
for row in self.tcb_tables:
regime = str(row[0])
Expand All @@ -101,7 +107,7 @@
changed |= self.change_tcb_calculation_method(root)
return changed

def change_period_settings(self, root):
def change_period_settings(self, root: ET.Element) -> bool:
changed = self._change_xml(root, "EW", "Period Type", self.periods_type)
changed |= self._change_xml(
root, "I32", "Number Of Software Periods", self.periods_soft_num
Expand All @@ -113,7 +119,7 @@
changed |= self._change_period_table(root)
return changed

def _change_period_table(self, root):
def _change_period_table(self, root: ET.Element) -> bool:
changed = False
for row in self.periods_settings:
period = row[0]
Expand All @@ -127,7 +133,11 @@
changed |= self._change_xml(root, "String", "Label %s" % period, label)
return changed

def _change_xml(self, xml, node, name, value):
def change_autosave_settings(self, root: ET.Element) -> bool:
changed = self._change_xml(root, "U32", " Frequency", self.autosave_freq)
return changed

def _change_xml(self, xml: ET.Element, node: str, name: str, value: PVValue) -> bool:
"""
Helper func to change the xml.
Will not be set if the input is None.
Expand Down
28 changes: 28 additions & 0 deletions src/genie_python/genie_dae.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from caffi.ca import AlarmCondition, AlarmSeverity # type: ignore[reportMissingImports]

from genie_python.genie_cachannel_wrapper import CaChannelWrapper
from genie_python.genie_change_cache import ChangeCache

Check failure

Code scanning / CodeQL

Module-level cyclic import Error

'ChangeCache' may not be defined if module
genie_python.genie_change_cache
is imported before module
genie_python.genie_dae
, as the
definition
of ChangeCache occurs after the cyclic
import
of genie_python.genie_dae.
from genie_python.utilities import (
compress_and_hex,
dehex_and_decompress,
Expand Down Expand Up @@ -1201,6 +1201,7 @@
self._change_dae_settings()
self._change_tcb_settings()
self._change_period_settings()
self._change_autosave_freq()
self.change_cache = ChangeCache()

def change_tables(
Expand Down Expand Up @@ -1884,6 +1885,17 @@
"set a number that is too large for the DAE memory. Try a smaller number!"
)

def _change_autosave_freq(self) -> None:
root = ET.fromstring(
self._get_pv_value(self._get_dae_pv_name("updatesettings"), to_string=True)
)
changed = self.change_cache.change_autosave_settings(root)
if changed:
self._set_pv_value(
self._get_dae_pv_name("updatesettings_sp"),
ET.tostring(root),
)

def get_spectrum(
self, spectrum: int, period: int = 1, dist: bool = True, use_numpy: bool | None = None
) -> "_GetspectrumReturn":
Expand Down Expand Up @@ -2234,3 +2246,19 @@
# run sum of terms, note in the case that the high and low partials
# are in the same bin this still works
return full_count + partial_count_high - partial_count_low

def change_autosave_freq(self, freq: float) -> None:
"""Change the rate of ICP autosave

Args:
freq (float): frequency of autosave
"""
did_change = False
if not self.in_change:
self.change_start()
did_change = True

self.change_cache.autosave_freq = freq

if did_change:
self.change_finish()
Loading