diff --git a/siriuspy/Makefile b/siriuspy/Makefile index b898a63f5..8c6a4ff0d 100644 --- a/siriuspy/Makefile +++ b/siriuspy/Makefile @@ -1,37 +1,29 @@ -DISTPATH=$(shell python-sirius -c "import site; print(site.getsitepackages())" | cut -f2 -d"'") PACKAGE:=$(shell basename $(shell pwd)) -ISINST=$(shell sudo pip-sirius show $(PACKAGE) | wc -l ) -EGGLINK=$(DISTPATH)/$(PACKAGE).egg-link -TMPFOLDER=/tmp/install-$(PACKAGE) +PREFIX= +PIP=pip +ifeq ($(CONDA_PREFIX),) + PREFIX=sudo -H + PIP=pip-sirius +endif clean: git clean -fdX -develop: uninstall - pip-sirius install --no-deps -e ./ +install: clean uninstall + $(PREFIX) $(PIP) install --no-deps ./ -install: uninstall -ifneq (, $(wildcard $(TMPFOLDER))) - rm -rf /tmp/install-$(PACKAGE) -endif - cp -rRL ../$(PACKAGE) /tmp/install-$(PACKAGE) - cd /tmp/install-$(PACKAGE)/; sudo -H pip-sirius install --no-deps ./ - rm -rf /tmp/install-$(PACKAGE) +uninstall: + $(PREFIX) $(PIP) uninstall -y $(PACKAGE) + +develop-install: clean develop-uninstall + $(PIP) install --no-deps -e ./ # known issue: It will fail to uninstall scripts # if they were installed in develop mode -uninstall: clean -ifneq (,$(wildcard $(EGGLINK))) - rm -r $(EGGLINK) -endif -ifneq ($(ISINST),0) - pip-sirius uninstall -y $(PACKAGE) - sed -i '/$(PACKAGE)/d' $(DISTPATH)/easy-install.pth -else - echo 'already uninstalled $(PACKAGE)' -endif +develop-uninstall: + $(PIP) uninstall -y $(PACKAGE) -test: +test: pytest tests/ dist: clean ## Build setuptools dist diff --git a/siriuspy/siriuspy/clientarch/client.py b/siriuspy/siriuspy/clientarch/client.py index 3aac0861b..5fbd54cef 100644 --- a/siriuspy/siriuspy/clientarch/client.py +++ b/siriuspy/siriuspy/clientarch/client.py @@ -17,19 +17,18 @@ from . import exceptions as _exceptions -_TIMEOUT = 5.0 # [seconds] - - class ClientArchiver: """Archiver Data Fetcher class.""" + DEFAULT_TIMEOUT = 5.0 # [s] SERVER_URL = _envars.SRVURL_ARCHIVER ENDPOINT = '/mgmt/bpl' - def __init__(self, server_url=None): + def __init__(self, server_url=None, timeout=None): """Initialize.""" + timeout = timeout or ClientArchiver.DEFAULT_TIMEOUT self.session = None - self.timeout = _TIMEOUT + self._timeout = timeout self._url = server_url or self.SERVER_URL self._ret = None # print('urllib3 InsecureRequestWarning disabled!') @@ -40,12 +39,22 @@ def connected(self): """Connected.""" try: status = _urllib.request.urlopen( - self._url, timeout=self.timeout, + self._url, timeout=self._timeout, context=_ssl.SSLContext()).status return status == 200 except _urllib.error.URLError: return False + @property + def timeout(self): + """Connection timeout.""" + return self._timeout + + @timeout.setter + def timeout(self, value): + """Set connection timeout.""" + self._timeout = float(value) + @property def server_url(self): """Return URL of the Archiver server. @@ -215,7 +224,7 @@ def getData(self, pvname, timestamp_start, timestamp_stop, pvn2resp = dict() for pvn, idcs in pvn2idcs.items(): - _ts, _vs = _np.array([]), _np.array([]) + _ts, _vs = _np.array([]), list() _st, _sv = _np.array([]), _np.array([]) for idx in idcs: resp = resps[idx] @@ -223,15 +232,17 @@ def getData(self, pvname, timestamp_start, timestamp_stop, continue data = resp[0]['data'] _ts = _np.r_[_ts, [v['secs'] + v['nanos']/1.0e9 for v in data]] - _vs = _np.r_[_vs, [v['val'] for v in data]] + for val in data: + _vs.append(val['val']) _st = _np.r_[_st, [v['status'] for v in data]] _sv = _np.r_[_sv, [v['severity'] for v in data]] if not _ts.size: timestamp, value, status, severity = [None, None, None, None] else: _, _tsidx = _np.unique(_ts, return_index=True) - timestamp, value, status, severity = \ - _ts[_tsidx], _vs[_tsidx], _st[_tsidx], _sv[_tsidx] + timestamp, status, severity = \ + _ts[_tsidx], _st[_tsidx], _sv[_tsidx] + value = [_vs[i] for i in _tsidx] pvn2resp[pvn] = dict( timestamp=timestamp, value=value, status=status, @@ -286,18 +297,23 @@ def _run_async_event_loop(self, *args, **kwargs): def _thread_run_async_event_loop(self, func, *args, **kwargs): """Get event loop.""" + close = False try: loop = _asyncio.get_event_loop() except RuntimeError as error: if 'no current event loop' in str(error): loop = _asyncio.new_event_loop() _asyncio.set_event_loop(loop) + close = True else: raise error try: self._ret = loop.run_until_complete(func(*args, **kwargs)) except _asyncio.TimeoutError: - self._ret = None + raise _exceptions.TimeoutError + + if close: + loop.close() async def _handle_request( self, url, return_json=False, need_login=False): @@ -318,7 +334,7 @@ async def _get_request_response(self, url, session, return_json): try: if isinstance(url, list): response = await _asyncio.gather( - *[session.get(u, ssl=False, timeout=self.timeout) + *[session.get(u, ssl=False, timeout=self._timeout) for u in url]) if any([not r.ok for r in response]): return None @@ -327,7 +343,7 @@ async def _get_request_response(self, url, session, return_json): *[r.json() for r in response]) else: response = await session.get( - url, ssl=False, timeout=self.timeout) + url, ssl=False, timeout=self._timeout) if not response.ok: return None if return_json: @@ -341,7 +357,7 @@ async def _create_session(self, url, headers, payload, ssl): session = _ClientSession() async with session.post( url, headers=headers, data=payload, ssl=ssl, - timeout=self.timeout) as response: + timeout=self._timeout) as response: content = await response.content.read() authenticated = b"authenticated" in content return session, authenticated diff --git a/siriuspy/siriuspy/clientarch/pvarch.py b/siriuspy/siriuspy/clientarch/pvarch.py index b74ca7bc5..bbefea955 100644 --- a/siriuspy/siriuspy/clientarch/pvarch.py +++ b/siriuspy/siriuspy/clientarch/pvarch.py @@ -296,10 +296,12 @@ def update(self, mean_sec=None, parallel=True): def set_data(self, timestamp, value, status, severity): """Auxiliary method to set data. Used by PVDataSet.""" - self._timestamp = _np.asarray(timestamp) - self._value = _np.asarray(value) - self._status = _np.asarray(status) - self._severity = _np.asarray(severity) + self._timestamp = self._value = self._status = self._severity = None + if timestamp is not None: + self._timestamp = _np.asarray(timestamp) + self._value = _np.asarray(value) + self._status = _np.asarray(status) + self._severity = _np.asarray(severity) def to_dict(self): """Return dictionary with PV properties. diff --git a/siriuspy/siriuspy/clientconfigdb/types/as_rf.py b/siriuspy/siriuspy/clientconfigdb/types/as_rf.py index b20ef9992..51a578752 100644 --- a/siriuspy/siriuspy/clientconfigdb/types/as_rf.py +++ b/siriuspy/siriuspy/clientconfigdb/types/as_rf.py @@ -3,7 +3,8 @@ # NOTE: absolute imports are necessary here due to how # CONFIG_TYPES in __init__.py is built. -from siriuspy.clientconfigdb.types.global_config import _pvs_as_rf +from siriuspy.clientconfigdb.types.global_config import _pvs_as_rf, \ + _pvs_li_llrf def get_dict(): @@ -22,7 +23,6 @@ def get_dict(): # in the configuration. The second numeric parameter in the pair is the # delay [s] the client should wait before setting the next PV. - _pvs_bo_llrf = [ ['BR-RF-DLLRF-01:ILK:REVSSA1:S', 0.0, 0.0], # Interlock disable ['BR-RF-DLLRF-01:ILK:REVSSA2:S', 0, 0.0], @@ -134,7 +134,7 @@ def get_dict(): ['BR-RF-DLLRF-01:TUNE:FILT:S', 0, 0.0], ['BR-RF-DLLRF-01:TUNE:TRIG:S', 0, 0.0], ['BR-RF-DLLRF-01:TUNE:TOPRAMP:S', 0, 0.0], - ['BR-RF-DLLRF-01:FF:POS:S', 0, 0.0], # Field Flatness loop config + ['BR-RF-DLLRF-01:FF:POS:S', 0, 0.0], # Field Flatness loop config ['BR-RF-DLLRF-01:FF:DEADBAND:S', 0, 0.0], # [%] ['BR-RF-DLLRF-01:FF:GAIN:CELL2:S', 0, 0.0], ['BR-RF-DLLRF-01:FF:GAIN:CELL4:S', 0, 0.0], @@ -438,10 +438,10 @@ def get_dict(): ['SR-RF-DLLRF-01:RmpTs2-SP', 0, 0.0], # [ms] ['SR-RF-DLLRF-01:RmpTs3-SP', 0, 0.0], # [ms] ['SR-RF-DLLRF-01:RmpTs4-SP', 0, 0.0], # [ms] - ['SR-RF-DLLRF-01:mV:RAMP:AMP:BOT-SP', 0, 0.0], # [mV] - ['SR-RF-DLLRF-01:RmpPhsBot-SP', 0, 0.0], # [°] ['SR-RF-DLLRF-01:mV:RAMP:AMP:TOP-SP', 0, 0.0], # [mV] ['SR-RF-DLLRF-01:RmpPhsTop-SP', 0, 0.0], # [°] + ['SR-RF-DLLRF-01:mV:RAMP:AMP:BOT-SP', 0, 0.0], # [mV] + ['SR-RF-DLLRF-01:RmpPhsBot-SP', 0, 0.0], # [°] ['SR-RF-DLLRF-01:RmpIncTs-SP', 0, 0.0], # [min] ['SR-RF-DLLRF-01:DisableRampDown:S', 0, 0.0], ['SR-RF-DLLRF-01:FDL:FrameQty-SP', 0, 0.0], @@ -452,7 +452,7 @@ def get_dict(): _pvs_si_rfssa = [ - ['RA-ToSIA01:OffsetConfig:UpperIncidentPower', 0, 0.0], # Offsets SSA Twr 1 + ['RA-ToSIA01:OffsetConfig:UpperIncidentPower', 0, 0.0], # Offsets SSA Twr1 ['RA-ToSIA01:OffsetConfig:UpperReflectedPower', 0, 0.0], ['RA-ToSIA01:OffsetConfig:LowerIncidentPower', 0, 0.0], ['RA-ToSIA01:OffsetConfig:LowerReflectedPower', 0, 0.0], @@ -474,7 +474,7 @@ def get_dict(): ['RA-ToSIA01:AlarmConfig:CurrentLimHigh', 0, 0.0], ['RA-ToSIA01:AlarmConfig:CurrentLimLow', 0, 0.0], ['RA-ToSIA01:AlarmConfig:CurrentLimLoLo', 0, 0.0], - ['RA-ToSIA02:OffsetConfig:UpperIncidentPower', 0, 0.0], # Offsets SSA Twr 2 + ['RA-ToSIA02:OffsetConfig:UpperIncidentPower', 0, 0.0], # Offsets SSA Twr2 ['RA-ToSIA02:OffsetConfig:UpperReflectedPower', 0, 0.0], ['RA-ToSIA02:OffsetConfig:LowerIncidentPower', 0, 0.0], ['RA-ToSIA02:OffsetConfig:LowerReflectedPower', 0, 0.0], @@ -652,6 +652,6 @@ def get_dict(): _template_dict = { 'pvs': _pvs_as_rf + - _pvs_bo_llrf + _pvs_bo_rfssa + _pvs_bo_rfcal + + _pvs_li_llrf + _pvs_bo_llrf + _pvs_bo_rfssa + _pvs_bo_rfcal + _pvs_si_llrf + _pvs_si_rfssa + _pvs_si_rfcav + _pvs_si_rfcal } diff --git a/siriuspy/siriuspy/clientconfigdb/types/global_config.py b/siriuspy/siriuspy/clientconfigdb/types/global_config.py index a37d929e1..f8b6aee35 100644 --- a/siriuspy/siriuspy/clientconfigdb/types/global_config.py +++ b/siriuspy/siriuspy/clientconfigdb/types/global_config.py @@ -1040,10 +1040,10 @@ def get_dict(): ['BR-RF-DLLRF-01:RmpTs2-SP', 0, 0.0], # ms ['BR-RF-DLLRF-01:RmpTs3-SP', 0, 0.0], # ms ['BR-RF-DLLRF-01:RmpTs4-SP', 0, 0.0], # ms - ['BR-RF-DLLRF-01:RmpPhsBot-SP', 0, 0.0], # Deg ['BR-RF-DLLRF-01:RmpPhsTop-SP', 0, 0.0], # Deg - ['BR-RF-DLLRF-01:mV:RAMP:AMP:BOT-SP', 0, 0.0], # mV + ['BR-RF-DLLRF-01:RmpPhsBot-SP', 0, 0.0], # Deg ['BR-RF-DLLRF-01:mV:RAMP:AMP:TOP-SP', 0, 0.0], # mV + ['BR-RF-DLLRF-01:mV:RAMP:AMP:BOT-SP', 0, 0.0], # mV ] diff --git a/siriuspy/siriuspy/devices/egun.py b/siriuspy/siriuspy/devices/egun.py index e710b1ad9..f50ba9ca5 100644 --- a/siriuspy/siriuspy/devices/egun.py +++ b/siriuspy/siriuspy/devices/egun.py @@ -1,10 +1,13 @@ """E-Gun devices.""" import time as _time +from datetime import timedelta as _timedelta +import numpy as _np from ..pwrsupply.psctrl.pscstatus import PSCStatus as _PSCStatus -from .device import Device as _Device, Devices as _Devices +from .device import Device as _Device, Devices as _Devices, \ + DeviceNC as _DeviceNC from .timing import Trigger @@ -132,6 +135,15 @@ def is_on(self): """.""" return self['swstatus'] == self.PWRSTATE.On + def wait_current(self, value, tol=0.20, timeout=DEF_TIMEOUT): + """Wait current to reach value with tolerance 'tol'.""" + _t0 = _time.time() + while _time.time() - _t0 < timeout: + if abs(self.current - value) < tol: + return True + _time.sleep(0.1) + return False + class EGHVPS(_Device): """Egun High-Voltage Power Supply Device.""" @@ -204,6 +216,15 @@ def is_on(self): ison &= self['swstatus'] == self.PWRSTATE.On return ison + def wait_voltage(self, value, tol=1, timeout=DEF_TIMEOUT): + """Wait voltage to reach value with tolerance 'tol'.""" + _t0 = _time.time() + while _time.time() - _t0 < timeout: + if abs(self.voltage - value) < tol: + return True + _time.sleep(0.1) + return False + class EGTriggerPS(_Device): """Egun Trigger Power Supply Device.""" @@ -404,10 +425,17 @@ class EGun(_Devices): BIAS_MULTI_BUNCH = -46.0 # [V] BIAS_SINGLE_BUNCH = -80.0 # [V] BIAS_TOLERANCE = 1.0 # [V] - HV_OPVALUE = 90.0 # [V] - HV_TOLERANCE = 1.0 # [V] + HV_OPVALUE = 90.0 # [kV] + HV_TOLERANCE = 1.0 # [kV] + HV_LEAKCURR_OPVALUE = 0.015 # [mA] + HV_MAXVALUE = 90.0 # [kV] + HV_RAMP_NRPTS = 15 + HV_RAMP_DURATION = 5*60 # [s] FILACURR_OPVALUE = 1.34 # [A] FILACURR_TOLERANCE = 0.20 # [A] + FILACURR_MAXVALUE = 1.40 # [A] + FILACURR_RAMP_NRPTS = 10 + FILACURR_RAMP_DURATION = 5*60 # [s] def __init__(self): """Init.""" @@ -420,17 +448,29 @@ def __init__(self): self.trigmulti = Trigger('LI-01:TI-EGun-MultBun') self.trigmultipre = Trigger('LI-01:TI-EGun-MultBunPre') + self.sys_ext = _DeviceNC('LI-01:EG-External', ('status', )) + self.sys_vlv = _DeviceNC('LI-01:EG-Valve', ('status', )) + self.sys_gat = _DeviceNC('LI-01:EG-Gate', ('status', )) + self.sys_vac = _DeviceNC('LI-01:EG-Vacuum', ('status', )) + self.mps_ccg = _DeviceNC( + 'LA-CN:H1MPS-1', ('CCG1Warn_L', 'CCG2Warn_L')) + self.mps_gun = _DeviceNC('LA-CN:H1MPS-1', ('GunPermit', )) + devices = ( self.bias, self.fila, self.hvps, self.trigps, self.pulse, - self.trigsingle, self.trigmulti, self.trigmultipre) + self.trigsingle, self.trigmulti, self.trigmultipre, + self.sys_ext, self.sys_vlv, self.sys_gat, self.sys_vac, + self.mps_ccg, self.mps_gun) self._bias_mb = EGun.BIAS_MULTI_BUNCH self._bias_sb = EGun.BIAS_SINGLE_BUNCH self._bias_tol = EGun.BIAS_TOLERANCE self._hv_opval = EGun.HV_OPVALUE self._hv_tol = EGun.HV_TOLERANCE + self._hv_leakcurr = EGun.HV_LEAKCURR_OPVALUE self._filacurr_opval = EGun.FILACURR_OPVALUE self._filacurr_tol = EGun.FILACURR_TOLERANCE + self._last_status = '' super().__init__('', devices) @@ -531,6 +571,11 @@ def is_multi_bunch(self): sts &= self.pulse.multi_bunch_switch return sts + @property + def last_status(self): + """Return last status log.""" + return self._last_status + @property def high_voltage_opvalue(self): """High voltage operation value.""" @@ -540,6 +585,16 @@ def high_voltage_opvalue(self): def high_voltage_opvalue(self, value): self._hv_opval = value + @property + def high_voltage_leakcurr(self): + """High voltage leakage current value.""" + return self._hv_leakcurr + + @high_voltage_leakcurr.setter + def high_voltage_leakcurr(self, value): + self._hv_leakcurr = value + self.hvps.current = value + @property def is_hv_on(self): """Indicate whether high voltage is on and in operational value.""" @@ -547,6 +602,67 @@ def is_hv_on(self): is_op = abs(self.hvps.voltage - self._hv_opval) < self._hv_tol return is_on and is_op + def set_hv_voltage(self, value=None, duration=None, timeout=DEF_TIMEOUT): + """Set HVPS voltage.""" + if not self._check_status_ok(): + self._update_last_status('ERR:MPS or LI Status not ok. Aborted.') + return False + if not self.hvps.is_on(): + self._update_last_status('ERR:HVPS voltage is not on.') + return False + if value is None: + value = self._hv_opval + + # if voltage already satisfies value + cond = abs(self.hvps['voltinsoft'] - value) < self._hv_tol + cond &= abs(self.hvps['voltoutsoft'] - value) < 1e-4 + if cond: + self._update_last_status( + f'HVPS Voltage is already at {value:.3f}kV.') + self.hvps.voltage = value + return True + + # before voltage setpoints, set leakage current to suitable value + self._update_last_status( + f'Setting leakage current to {self._hv_leakcurr:.3f}mA.') + self.hvps.current = self._hv_leakcurr + + # if value is lower, do only one setpoint + if value < self.hvps.voltage: + self._update_last_status(f'Setting voltage to {value:.3f}kV.') + self.hvps.voltage = value + return self.hvps.wait_voltage(value, self._hv_tol) + + # else, do a ramp up + duration = duration if duration is not None else EGun.HV_RAMP_DURATION + nrpts = EGun.HV_RAMP_NRPTS + max_value = EGun.HV_MAXVALUE + ydata = self._get_ramp(self.hvps.voltage, value, nrpts, max_value) + t_inter = duration / (nrpts-1) + + self._update_last_status(f'Starting HVPS ramp to {value:.3f}kV.') + self.hvps.voltage = ydata[0] + for volt in ydata[1:]: + self.hvps.voltage = volt + self._update_last_status(f'Sent HV: {volt:.3f}kV...') + _time.sleep(t_inter) + _t0 = _time.time() + while _time.time() - _t0 < timeout: + if not self._check_status_ok(): + self._update_last_status( + 'ERR:MPS or LI Status not ok. Aborted.') + return False + if self.hvps.voltage - volt < self._hv_tol: + break + _time.sleep(0.1) + else: + self._update_last_status( + 'ERR:HVPS Voltage is taking too' + ' long to increase. Aborted.') + return False + self._update_last_status('HVPS Ready!') + return True + @property def fila_current_opvalue(self): """Filament current operation value.""" @@ -563,3 +679,81 @@ def is_fila_on(self): is_op = abs(self.fila.current - self._filacurr_opval) < \ self._filacurr_tol return is_on and is_op + + def set_fila_current(self, value=None): + """Set filament current.""" + if not self._check_status_ok(): + self._update_last_status('ERR:MPS or LI Status not ok. Aborted.') + return False + if not self.fila.is_on(): + self._update_last_status('ERR:FilaPS is not on.') + return False + if value is None: + value = self._filacurr_opval + + # if current already satisfies value + cond = abs(self.fila['currentinsoft'] - value) < self._filacurr_tol + cond &= abs(self.fila['currentoutsoft'] - value) < 1e-4 + if cond: + self._update_last_status( + 'FilaPS current is already at {0:.3f}A.'.format(value)) + self.fila.current = value + return True + + # elif value is lower, do only one setpoint + if value < self.fila.current: + self._update_last_status(f'Setting current to {value:.3f}A.') + self.fila.current = value + return self.fila.wait_current(value, self._filacurr_tol) + + # else, do a ramp up + duration = EGun.FILACURR_RAMP_DURATION + nrpts = EGun.FILACURR_RAMP_NRPTS + max_value = EGun.FILACURR_MAXVALUE + ydata = self._get_ramp(self.fila.current, value, nrpts, max_value) + t_inter = duration / (nrpts-1) + total_steps_duration = (len(ydata)-1)*t_inter + + self._update_last_status(f'Starting filament ramp to {value:.3f}.') + self.fila.current = ydata[0] + for i, cur in enumerate(ydata[1:]): + self.fila.current = cur + dur = str(_timedelta( + seconds=total_steps_duration - i*t_inter)).split('.')[0] + self._update_last_status( + 'Remaining Time: {0:s} Curr: {1:.3f} A'.format(dur, cur)) + _time.sleep(t_inter) + + if not self._check_status_ok(): + self._update_last_status( + 'ERR:MPS or LI Status not ok. Aborted.') + return False + self._update_last_status('FilaPS Ready!') + + def _get_ramp(self, curr_val, goal, nrpts, max_val): + xdata = _np.linspace(0, 1, nrpts) + ydata = 1 - (1-xdata)**3 + # ydata = 1 - (1-xdata)**2 + # ydata = _np.sqrt(1 - (1-xdata)**2) + # ydata = _np.sin(2*np.pi * xdata/4) + + ydata *= max_val + ydata = ydata[ydata > curr_val] + ydata = ydata[ydata < goal] + ydata = _np.r_[curr_val, ydata, goal] + return ydata + + def _check_status_ok(self): + """Check if interlock signals are ok.""" + isok = [self.mps_ccg[ppty] == 0 for ppty in self.mps_ccg.properties] + allok = all(isok) + allok &= self.mps_gun['GunPermit'] == 1 + allok &= self.sys_ext['status'] == 1 + allok &= self.sys_vlv['status'] == 1 + allok &= self.sys_gat['status'] == 1 + allok &= self.sys_vac['status'] == 1 + return allok + + def _update_last_status(self, status): + self._last_status = status + print(status) diff --git a/siriuspy/siriuspy/machshift/macreport.py b/siriuspy/siriuspy/machshift/macreport.py index f655894fd..105d4bfc4 100644 --- a/siriuspy/siriuspy/machshift/macreport.py +++ b/siriuspy/siriuspy/machshift/macreport.py @@ -1065,73 +1065,85 @@ def plot_raw_data(self): fig.subplots_adjust(top=0.96, left=0.08, bottom=0.05, right=0.96) axs[0].set_title('Raw data', fontsize=12) - axs[0].plot_date( + axs[0].xaxis.axis_date() + axs[0].plot( datetimes, self._raw_data['Current'], '-', color='blue', label='Current') axs[0].legend(loc='upper left', fontsize=9) axs[0].grid() - axs[1].plot_date( + axs[1].xaxis.axis_date() + axs[1].plot( datetimes, self._raw_data['UserShiftInitCurr'], '-', color='blue', label='User Shifts - Initial Current') axs[1].legend(loc='upper left', fontsize=9) axs[1].grid() - axs[2].plot_date( + axs[2].xaxis.axis_date() + axs[2].plot( datetimes, self._raw_data['UserShiftProgmd'], '-', color='gold', label='User Shifts - Programmed') axs[2].legend(loc='upper left', fontsize=9) axs[2].grid() - axs[3].plot_date( + axs[3].xaxis.axis_date() + axs[3].plot( datetimes, self._raw_data['UserShiftDelivd'], '-', color='gold', label='User Shifts - Delivered') axs[3].legend(loc='upper left', fontsize=9) axs[3].grid() - axs[4].plot_date( + axs[4].xaxis.axis_date() + axs[4].plot( datetimes, self._raw_data['UserShiftStable'], '-', color='gold', label='User Shifts - Delivered Without Distortions') axs[4].legend(loc='upper left', fontsize=9) axs[4].grid() - axs[5].plot_date( + axs[5].xaxis.axis_date() + axs[5].plot( datetimes, self._raw_data['UserShiftTotal'], '-', color='gold', label='User Shifts - Total') axs[5].legend(loc='upper left', fontsize=9) axs[5].grid() - axs[6].plot_date( + axs[6].xaxis.axis_date() + axs[6].plot( datetimes, self._raw_data['Failures']['NoEBeam'], '-', color='red', label='Failures - NoEBeam') axs[6].legend(loc='upper left', fontsize=9) axs[6].grid() - axs[7].plot_date( + axs[7].xaxis.axis_date() + axs[7].plot( datetimes, self._raw_data['GammaShutter'], '-', color='red', label='Failures - Gamma Shutter Closed') axs[7].legend(loc='upper left', fontsize=9) axs[7].grid() - axs[8].plot_date( + axs[8].xaxis.axis_date() + axs[8].plot( datetimes, self._raw_data['Failures']['WrongShift'], '-', color='red', label='Failures - WrongShift') axs[8].legend(loc='upper left', fontsize=9) axs[8].grid() - axs[9].plot_date( + axs[9].xaxis.axis_date() + axs[9].plot( datetimes, self._raw_data['Failures']['SubsystemsNOk'], '-', color='red', label='Failures - PS, RF and MPS') axs[9].legend(loc='upper left', fontsize=9) axs[9].grid() - axs[10].plot_date( + axs[10].xaxis.axis_date() + axs[10].plot( datetimes, self._raw_data['Distortions']['SOFBLoop'], '-', color='orangered', label='Distortions - SOFB Loop Open') axs[10].legend(loc='upper left', fontsize=9) axs[10].grid() - axs[11].plot_date( + axs[11].xaxis.axis_date() + axs[11].plot( datetimes, self._raw_data['Shift']['Injection'], '-', color='lightsalmon', label='Injection Shifts') axs[11].legend(loc='upper left', fontsize=9) @@ -1145,7 +1157,8 @@ def plot_raw_data(self): for shift, auxdata in shift2color.items(): ydata = self._raw_data['Shift'][shift] - axs[12].plot_date( + axs[12].xaxis.axis_date() + axs[12].plot( datetimes, ydata, '-', color=auxdata[1], label=auxdata[0]) axs[12].legend(loc='upper left', ncol=4, fontsize=9) @@ -1157,7 +1170,8 @@ def plot_raw_data(self): for egmode, color in egmodes2color.items(): ydata = self._raw_data['EgunModes'][egmode] - axs[13].plot_date( + axs[13].xaxis.axis_date() + axs[13].plot( datetimes, ydata, '-', color=color, label=egmode) axs[13].legend(loc='upper left', ncol=2, fontsize=9) @@ -1185,8 +1199,9 @@ def plot_progmd_vs_delivd_hours(self): fig = _plt.figure() axs = _plt.gca() - axs.plot_date(datetimes, cum_progmd, '-', label='Programmed') - axs.plot_date(datetimes, cum_deliv, '-', label='Delivered') + axs.xaxis.axis_date() + axs.plot(datetimes, cum_progmd, '-', label='Programmed') + axs.plot(datetimes, cum_deliv, '-', label='Delivered') axs.grid() axs.set_ylabel('Integrated Hours') _plt.legend(loc=4) diff --git a/siriuspy/siriuspy/machshift/macschedule.py b/siriuspy/siriuspy/machshift/macschedule.py index 77658fa96..2f88453c5 100644 --- a/siriuspy/siriuspy/machshift/macschedule.py +++ b/siriuspy/siriuspy/machshift/macschedule.py @@ -93,7 +93,8 @@ def plot_mac_schedule(year): new_tags = _interp1d_previous(times, tags, new_timestamp) fig = _plt.figure() - _plt.plot_date(new_datetimes, new_tags, '-') + _plt.gca().xaxis.axis_date() + _plt.plot(new_datetimes, new_tags, '-') _plt.title('Machine Schedule - ' + str(year)) return fig diff --git a/siriuspy/siriuspy/machshift/test_macreport.py b/siriuspy/siriuspy/machshift/test_macreport.py index 79254685a..9142b1eeb 100644 --- a/siriuspy/siriuspy/machshift/test_macreport.py +++ b/siriuspy/siriuspy/machshift/test_macreport.py @@ -45,16 +45,19 @@ fig, axs = plt.subplots(3, 1, sharex=True) fig.set_size_inches(9, 6) fig.subplots_adjust(top=0.96, left=0.08, bottom=0.05, right=0.96) -axs[0].plot_date(mtbfs.keys(), mtbfs.values(), '-b') -axs[0].plot_date(mtbfs.keys(), mtbfs.values(), 'ob') +axs[0].xaxis.axis_date() +axs[0].plot(mtbfs.keys(), mtbfs.values(), '-b') +axs[0].plot(mtbfs.keys(), mtbfs.values(), 'ob') axs[0].set_title('MTBF') axs[0].grid() -axs[1].plot_date(mttrs.keys(), mttrs.values(), '-r') -axs[1].plot_date(mttrs.keys(), mttrs.values(), 'or') +axs[1].xaxis.axis_date() +axs[1].plot(mttrs.keys(), mttrs.values(), '-r') +axs[1].plot(mttrs.keys(), mttrs.values(), 'or') axs[1].set_title('MTTR') axs[1].grid() -axs[2].plot_date(reliabs.keys(), reliabs.values(), '-g') -axs[2].plot_date(reliabs.keys(), reliabs.values(), 'og') +axs[2].xaxis.axis_date() +axs[2].plot(reliabs.keys(), reliabs.values(), '-g') +axs[2].plot(reliabs.keys(), reliabs.values(), 'og') axs[2].set_title('Reliability') axs[2].grid() fig.show() @@ -80,8 +83,9 @@ fig = plt.figure() axs = plt.gca() -axs.plot_date(dates, cum_progmd, '-', label='Programmed') -axs.plot_date(dates, cum_deliv, '-', label='Delivered') +axs.xaxis.axis_date() +axs.plot(dates, cum_progmd, '-', label='Programmed') +axs.plot(dates, cum_deliv, '-', label='Delivered') axs.grid() axs.set_ylabel('Integrated Hours') plt.legend(loc=4) @@ -102,8 +106,9 @@ fig = plt.figure() axs = plt.gca() -axs.plot_date(new_dates, new_cum_progmd, '-', label='Programmed') -axs.plot_date(new_dates, new_cum_deliv, '-', label='Delivered') +axs.xaxis.axis_date() +axs.plot(new_dates, new_cum_progmd, '-', label='Programmed') +axs.plot(new_dates, new_cum_deliv, '-', label='Delivered') axs.grid() axs.set_ylabel('Integrated Hours') plt.legend(loc=4)