From e381778bbbf3ac6077d6aaf13b8e7d2ff84ade27 Mon Sep 17 00:00:00 2001 From: Roman Mankowsky Date: Sat, 1 May 2021 15:16:40 +0200 Subject: [PATCH] fixes to many thing, kb eco based bender comb motions --- eco/acquisition/scan_nd.py | 29 ++++--- eco/bernina/bernina.py | 28 +++++++ eco/bernina/config.py | 32 +++----- eco/devices_general/detectors.py | 18 ++-- eco/devices_general/motors.py | 14 +++- eco/elements/assembly.py | 5 +- eco/fel/swissfel.py | 28 +++++++ eco/loptics/bernina_laser.py | 10 +++ eco/utilities/config.py | 16 +++- eco/xdiagnostics/dsd.py | 2 + eco/xdiagnostics/intensity_monitors.py | 109 ++++++++++++++++++++++++- eco/xdiagnostics/profile_monitors.py | 14 +++- eco/xoptics/kb_mirrors.py | 51 +++++++++++- eco/xoptics/offsetMirrors_new.py | 4 +- eco/xoptics/reflaser_new.py | 19 +++-- eco/xoptics/shutters.py | 5 +- 16 files changed, 317 insertions(+), 67 deletions(-) diff --git a/eco/acquisition/scan_nd.py b/eco/acquisition/scan_nd.py index 6a5b732..f7dffe5 100644 --- a/eco/acquisition/scan_nd.py +++ b/eco/acquisition/scan_nd.py @@ -43,7 +43,7 @@ class ScanND: return_at_end="question", run_table=None, elog=None, - ): + ): scan_array = [] scan_adjustables = [] for n_dim, (adj_tdim, arr_tdim) in enumerate(zip(adjustables, arrays)): @@ -69,20 +69,27 @@ class ScanND: @property def steps_total(self): - return np.prod([len(ta[0]) for ta in self.scan_array]) + return np.prod([len(ta[0]) for ta in self.scan_array]) @property def shape(self): - return tuple([len(ta[0]) for ta in self.scan_array]) + return tuple([len(ta[0]) for ta in self.scan_array]) - def create_stepping_order(self,order='C'): - return [tuple(te) for te in np.vstack(np.unravel_index(np.arange(self.steps_total),self.shape,order=order)).T] + def create_stepping_order(self, order="C"): + return [ + tuple(te) + for te in np.vstack( + np.unravel_index(np.arange(self.steps_total), self.shape, order=order) + ).T + ] - def create_random_selection(self,N_elements=None,scan_percentage=None,random_type=equal,sort_dimensions=False): + def create_random_selection( + self, + N_elements=None, + scan_percentage=None, + random_type=equal, + sort_dimensions=False, + ): rs = RandomState(seed=0) - rs.choice(a,5,p=np.exp(-a)/sum(np.exp(-a)),replace=False) - - - - + rs.choice(a, 5, p=np.exp(-a) / sum(np.exp(-a)), replace=False) diff --git a/eco/bernina/bernina.py b/eco/bernina/bernina.py index 1e0101c..bce03d6 100644 --- a/eco/bernina/bernina.py +++ b/eco/bernina/bernina.py @@ -36,6 +36,32 @@ for tk in components: # module_name="eco.devices_general.cameras_ptz", # ) +namespace.append_obj( + "GasDetector", + name="mon_und_gas", + module_name="eco.xdiagnostics.intensity_monitors", + lazy=True, +) +namespace.append_obj( + "RefLaser_Aramis", + "SAROP21-OLAS136", + module_name = "eco.xoptics.reflaser_new", + name='reflaser', + lazy=True, +) +namespace.append_obj( + "SolidTargetDetectorPBPS_assi", + "SAROP21-PBPS133", + pvname_fedigitizerchannels=dict( + up="SAROP21-CVME-PBPS1:Lnk9Ch0", + down="SAROP21-CVME-PBPS1:Lnk9Ch12", + left="SAROP21-CVME-PBPS1:Lnk9Ch15", + right="SAROP21-CVME-PBPS1:Lnk9Ch13", + ), + name="mon_opt_dev", + module_name="eco.xdiagnostics.intensity_monitors", + lazy=True, +) namespace.append_obj( "CTA_sequencer", "SAR-CCTA-ESB", @@ -61,11 +87,13 @@ namespace.append_obj( "ProfKbBernina", module_name="eco.xdiagnostics.profile_monitors", name="prof_kb", + pvname_mirror="SARES23-LIC11", lazy=True, ) namespace.append_obj( "TimetoolBerninaUSD", module_name="eco.timing.timing_diag", + pvname_mirror="SARES23-LIC11", name="tt_kb", lazy=True, ) diff --git a/eco/bernina/config.py b/eco/bernina/config.py index 9da053a..9794337 100755 --- a/eco/bernina/config.py +++ b/eco/bernina/config.py @@ -323,14 +323,6 @@ components = [ "desc": "Attenuator Bernina", "type": "eco.xoptics.attenuator_aramis:AttenuatorAramis", }, - { - "name": "ref_laser", - "args": ["SAROP21-OLAS136"], - "kwargs": {}, - "z_und": 136, - "desc": "Bernina beamline reference laser before KBs", - "type": "eco.xoptics.reflaser_new:RefLaser_Aramis", - }, { "name": "slit_att", "args": ["SAROP21-OAPU136"], @@ -446,18 +438,18 @@ components = [ # "type": "eco.endstations.bernina_diffractometers:XRD_old", # "kwargs": {"Id": "SARES21-XRD", "configuration": config["xrd_config"]}, # }, - { - "args": [], - "name": "xrd", - "z_und": 142, - "desc": "Xray diffractometer", - "type": "eco.endstations.bernina_diffractometers:XRD", - "kwargs": { - "Id": "SARES21-XRD", - "configuration": config["xrd_config"], - "diff_detector": {"jf_id": "JF01T03V01"}, - }, - }, + # { + # "args": [], + # "name": "xrd", + # "z_und": 142, + # "desc": "Xray diffractometer", + # "type": "eco.endstations.bernina_diffractometers:XRD", + # "kwargs": { + # "Id": "SARES21-XRD", + # "configuration": config["xrd_config"], + # "diff_detector": {"jf_id": "JF01T03V01"}, + # }, + # }, { "args": [], "name": "vonHamos", diff --git a/eco/devices_general/detectors.py b/eco/devices_general/detectors.py index 4d18bbf..912ddee 100755 --- a/eco/devices_general/detectors.py +++ b/eco/devices_general/detectors.py @@ -15,6 +15,7 @@ from datetime import datetime from ..acquisition.utilities import Acquisition from ..aliases import Alias from ..elements import Assembly +from ..devices_general.adjustable import PvString class PvData(Assembly): @@ -32,12 +33,17 @@ class PvData(Assembly): return self.get_current_value() -class PvDataStream: - def __init__(self, Id, name=None): - self.Id = Id - self._pv = PV(Id) - self.name = name - self.alias = Alias(self.name, channel=self.Id, channeltype="CA") +class PvDataStream(Assembly): + def __init__(self, pvname, name=None): + super().__init__(name=name) + self.Id = pvname + self.pvname = pvname + self._pv = PV(pvname) + self.alias = Alias(self.name, channel=self.pvname, channeltype="CA") + self._append(PvString, self.pvname + ".EGU", name="unit", is_setting=False) + # self._append( + # PvString, self.pvname + ".DESC", name="description", is_setting=False + # ) def collect(self, seconds=None, samples=None): if (not seconds) and (not samples): diff --git a/eco/devices_general/motors.py b/eco/devices_general/motors.py index 2f69966..4ea5b4a 100755 --- a/eco/devices_general/motors.py +++ b/eco/devices_general/motors.py @@ -156,8 +156,18 @@ class SmaractStreamdevice(Assembly): name="sensor_type", is_setting=True, ) - self._append(PvRecord, self.pvname + ":GET_SENSOR_TYPE", name="sensor_type_getter_number", is_setting=False) - self._append(PvRecord, self.pvname + ":SET_SENSOR_TYPE", name="sensor_type_setter_number", is_setting=False) + self._append( + PvRecord, + self.pvname + ":GET_SENSOR_TYPE", + name="sensor_type_getter_number", + is_setting=False, + ) + self._append( + PvRecord, + self.pvname + ":SET_SENSOR_TYPE", + name="sensor_type_setter_number", + is_setting=False, + ) self._append(PvRecord, self.pvname + ":LLM", name="limit_low", is_setting=False) self._append( PvRecord, self.pvname + ":HLM", name="limit_high", is_setting=False diff --git a/eco/elements/assembly.py b/eco/elements/assembly.py index a98acd2..1d11b60 100644 --- a/eco/elements/assembly.py +++ b/eco/elements/assembly.py @@ -68,7 +68,7 @@ class Assembly: view_toplevel_only=True, call_obj=True, **kwargs, - ): + ): if call_obj and callable(foo_obj_init): self.__dict__[name] = foo_obj_init(*args, **kwargs, name=name) else: @@ -164,7 +164,8 @@ class Assembly: return s def __repr__(self): - return self.get_status_indicator_str() + label = self.alias.get_full_name() + " status\n" + return label + self.get_status_indicator_str() def _run_cmd(self, line): print(f"Starting following commandline silently:\n" + line) diff --git a/eco/fel/swissfel.py b/eco/fel/swissfel.py index dc008b6..80ff8d2 100644 --- a/eco/fel/swissfel.py +++ b/eco/fel/swissfel.py @@ -55,6 +55,34 @@ class SwissFel(Assembly): is_status=True, is_setting=True, ) + self._append( + PvEnum, + "SFB_PSICO_AR:ONOFF1", + name="psico_running", + is_status=True, + is_setting=False, + ) + self._append( + PvEnum, + "SFB_POINTING_AR:ONOFF1", + name="pointing_feedback_running", + is_status=True, + is_setting=False, + ) + self._append( + PvRecord, + "SFB_POINTING_AR:SP1", + name="pointing_feedback_setpoint_x", + is_status=True, + is_setting=False, + ) + self._append( + PvRecord, + "SFB_POINTING_AR:SP2", + name="pointing_feedback_setpoint_y", + is_status=True, + is_setting=False, + ) class MessageBoard(Assembly): diff --git a/eco/loptics/bernina_laser.py b/eco/loptics/bernina_laser.py index 6be5b0e..1e5f908 100644 --- a/eco/loptics/bernina_laser.py +++ b/eco/loptics/bernina_laser.py @@ -44,6 +44,16 @@ class LaserBernina(Assembly): DelayTime, self.delaystage_pump, name="delay_pump", is_setting=True ) self._append(XltEpics, name="xlt", is_setting=True, is_status="recursive") + # Upstairs, Laser 1 LAM + self._append( + MotorRecord, + "SLAAR01-LMOT-M252:MOT", + name="delaystage_lam_upstairs", + is_setting=True, + ) + self._append( + DelayTime, self.delaystage_lam_upstairs, name="delay_lam_upstairs", is_setting=True + ) class DelayTime(AdjustableVirtual): diff --git a/eco/utilities/config.py b/eco/utilities/config.py index aad99cc..3cd7dfc 100644 --- a/eco/utilities/config.py +++ b/eco/utilities/config.py @@ -353,7 +353,13 @@ class Namespace(Assembly): self.initialized_items[name] = self.lazy_items.pop(name) if hasattr(obj_initialized, "alias"): - self._append(obj_initialized,name=name,is_setting=True,is_status='recursive',call_obj=False) + self._append( + obj_initialized, + name=name, + is_setting=True, + is_status="recursive", + call_obj=False, + ) if self.alias_namespace and hasattr(obj_initialized, "alias"): for ta in obj_initialized.alias.get_all(): try: @@ -387,7 +393,13 @@ class Namespace(Assembly): if self.root_module: sys.modules[self.root_module].__dict__[name] = obj if hasattr(obj, "alias"): - self._append(obj,name=name,is_setting=True,is_status='recursive',call_obj=False) + self._append( + obj, + name=name, + is_setting=True, + is_status="recursive", + call_obj=False, + ) if self.alias_namespace and hasattr(obj, "alias"): for ta in obj.alias.get_all(): try: diff --git a/eco/xdiagnostics/dsd.py b/eco/xdiagnostics/dsd.py index f6efed9..0277798 100644 --- a/eco/xdiagnostics/dsd.py +++ b/eco/xdiagnostics/dsd.py @@ -30,6 +30,7 @@ class DownstreamDiagnostic(Assembly): "SARES20-DSDPPRM", name="prof_dsd", is_setting=True, + is_status='recursive', view_toplevel_only=False, ) self._append( @@ -37,6 +38,7 @@ class DownstreamDiagnostic(Assembly): pvname="SARES20-DSDPBPS", name="mon_dsd", is_setting=True, + is_status='recursive', view_toplevel_only=False, ) diff --git a/eco/xdiagnostics/intensity_monitors.py b/eco/xdiagnostics/intensity_monitors.py index e1123fa..84e6776 100755 --- a/eco/xdiagnostics/intensity_monitors.py +++ b/eco/xdiagnostics/intensity_monitors.py @@ -1,15 +1,116 @@ from ..devices_general.motors import MotorRecord from ..eco_epics.utilities_epics import EnumWrapper from ..devices_general.detectors import FeDigitizer, PvDataStream -from ..devices_general.adjustable import PvEnum +from ..devices_general.adjustable import PvEnum, PvRecord, AdjustableVirtual from ..aliases import Alias, append_object_to_object +from ..elements import Assembly from epics import PV import numpy as np -class GasDetector: - def __init__(self): - pass +class GasDetector(Assembly): + def __init__(self, name=None): + super().__init__(name=name) + self._append( + PvDataStream, + "SARFE10-PBPG050:HAMP-INTENSITY-CAL", + name="fast_calibrated", + is_status=True, + ) + + +class FeDigitiza(Assembly): + def __init__(self, pvname, name=None): + super().__init__(name=name) + self.pvname = pvname + self._append( + PvEnum, pvname + "-WD-gain", name="gain", is_setting=True, is_status=True + ) + self._append( + PvRecord, pvname + "-HV_SET", name="bias", is_setting=True, is_status=True + ) + + # self.channels = [ + # Id + "-BG-DATA", + # Id + "-BG-DRS_TC", + # Id + "-BG-PULSEID-valid", + # Id + "-DATA", + # Id + "-DRS_TC", + # Id + "-PULSEID-valid", + # ] + + +class SolidTargetDetectorPBPS_assi(Assembly): + def __init__( + self, + pvname, + pvname_fedigitizerchannels=dict( + up="SAROP21-CVME-PBPS1:Lnk9Ch0", + down="SAROP21-CVME-PBPS1:Lnk9Ch12", + left="SAROP21-CVME-PBPS1:Lnk9Ch15", + right="SAROP21-CVME-PBPS1:Lnk9Ch13", + ), + name=None, + ): + print("hia----->", name) + super().__init__(name=name) + self.pvname = pvname + self._append( + PvEnum, + pvname + ":PROBE_SP", + name="target", + is_setting=True, + is_status=True, + ) + self._append( + MotorRecord, + pvname + ":MOTOR_X1", + name="x_diodes", + is_setting=True, + is_status=True, + ) + self._append( + MotorRecord, + pvname + ":MOTOR_Y1", + name="y_diodes", + is_setting=True, + is_status=True, + ) + self._append( + MotorRecord, + pvname + ":MOTOR_PROBE", + name="y_targets", + is_setting=True, + is_status=False, + ) + for chdigi, tp in pvname_fedigitizerchannels.items(): + self._append( + FeDigitiza, tp, name="diode_" + chdigi, is_setting=True, is_status=False + ) + self._append( + AdjustableVirtual, + [ + self.__dict__["diode_" + chdigi].bias + for chdigi in pvname_fedigitizerchannels.keys() + ], + lambda a, b, c, d: all([x == a for x in [b, c, d]]) * a, + lambda x: (x, x, x, x), + name="bias", + is_setting=False, + is_status=True, + ) + self._append( + AdjustableVirtual, + [ + self.__dict__["diode_" + chdigi].gain + for chdigi in pvname_fedigitizerchannels.keys() + ], + lambda a, b, c, d: all([x == a for x in [b, c, d]]) * a, + lambda x: (x, x, x, x), + name="gain", + is_setting=False, + is_status=True, + ) class SolidTargetDetectorPBPS_new: diff --git a/eco/xdiagnostics/profile_monitors.py b/eco/xdiagnostics/profile_monitors.py index 2544ad1..204c572 100755 --- a/eco/xdiagnostics/profile_monitors.py +++ b/eco/xdiagnostics/profile_monitors.py @@ -148,7 +148,7 @@ class ProfKbBernina(Assembly): if wait: ch.wait() - def moveout(self): + def moveout(self,wait=False): ch = self.mirror_in.set_target_value(0) if wait: ch.wait() @@ -165,7 +165,7 @@ class Pprm_dsd(Assembly): is_setting=True, ) self.camCA = CameraCA(pvname_camera) - self._append(CameraBasler, pvname_camera, name="camera", is_setting=False) + self._append(CameraBasler, pvname_camera, name="camera", is_setting=False, is_status='recursive') self._append( MotorRecord, self.pvname + ":MOTOR_ZOOM", name="zoom", is_setting=True ) @@ -211,10 +211,16 @@ class Bernina_XEYE(Assembly): ): super().__init__(name=name) if zoomstage_pv: - self._append(MotorRecord, zoomstage_pv, name="zoom",is_setting=True) + self._append(MotorRecord, zoomstage_pv, name="zoom", is_setting=True) try: self.cam = CameraCA(camera_pv) - self._append(CameraBasler,camera_pv,name='camera',is_setting=True,is_status='recursive') + self._append( + CameraBasler, + camera_pv, + name="camera", + is_setting=True, + is_status="recursive", + ) except: print("X-Ray eye Cam not found") pass diff --git a/eco/xoptics/kb_mirrors.py b/eco/xoptics/kb_mirrors.py index 756d2f3..fa2ff86 100644 --- a/eco/xoptics/kb_mirrors.py +++ b/eco/xoptics/kb_mirrors.py @@ -1,7 +1,7 @@ from ..elements.assembly import Assembly from ..devices_general.motors import MotorRecord -from ..devices_general.adjustable import PvRecord, PvEnum - +from ..devices_general.adjustable import PvRecord, PvEnum, AdjustableVirtual +import numpy as np class KbVer(Assembly): def __init__(self, pvname, name=None): @@ -28,6 +28,14 @@ class KbVer(Assembly): ) self._append(MotorRecord, pvname + ":BU", name="bend1", is_setting=True) self._append(MotorRecord, pvname + ":BD", name="bend2", is_setting=True) + self._append(AdjustableVirtual, + [self.bend1,self.bend2], + lambda b1,b2: float(np.mean([b1,b2])), + lambda mn: self._get_benders_set_mean(mn) , name="bender_mean", is_setting=False, is_status=True) + self._append(AdjustableVirtual, + [self.bend1,self.bend2], + lambda b1,b2: float(np.diff([b1,b2])), + lambda mn: self._get_benders_set_diff(mn) , name="bender_diff", is_setting=False, is_status=True) self._append( PvRecord, pvname + ":CURV_SP", @@ -50,6 +58,22 @@ class KbVer(Assembly): self._append(MotorRecord, pvname + ":TX1", name="_X1", is_setting=True) self._append(MotorRecord, pvname + ":TX2", name="_X2", is_setting=True) + def _get_bend_mean(self): + return float(np.mean([self.bend1.get_current_value(),self.bend2.get_current_value()])) + + def _get_benders_set_mean(self,val): + mn = self._get_bend_mean() + df = val-mn + return self.bend1.get_current_value()+df, self.bend2.get_current_value()+df + + def _get_bend_diff(self): + return float(np.diff([self.bend1.get_current_value(),self.bend2.get_current_value()])) + + def _get_benders_set_diff(self,val): + df = val-self._get_bend_diff() + return self.bend1.get_current_value()-df/2, self.bend2.get_current_value()+df/2 + + class KbHor(Assembly): def __init__(self, pvname, name=None): @@ -76,6 +100,14 @@ class KbHor(Assembly): ) self._append(MotorRecord, pvname + ":BU", name="bend1", is_setting=True) self._append(MotorRecord, pvname + ":BD", name="bend2", is_setting=True) + self._append(AdjustableVirtual, + [self.bend1,self.bend2], + lambda b1,b2: float(np.mean([b1,b2])), + lambda mn: self._get_benders_set_mean(mn) , name="bender_mean", is_setting=False, is_status=True) + self._append(AdjustableVirtual, + [self.bend1,self.bend2], + lambda b1,b2: float(np.diff([b1,b2])), + lambda mn: self._get_benders_set_diff(mn) , name="bender_diff", is_setting=False, is_status=True) self._append( PvRecord, pvname + ":CURV_SP", @@ -97,3 +129,18 @@ class KbHor(Assembly): self._append(MotorRecord, pvname + ":TY3", name="_Y3", is_setting=True) self._append(MotorRecord, pvname + ":TX1", name="_X1", is_setting=True) self._append(MotorRecord, pvname + ":TX2", name="_X2", is_setting=True) + + def _get_bend_mean(self): + return float(np.mean([self.bend1.get_current_value(),self.bend2.get_current_value()])) + + def _get_benders_set_mean(self,val): + mn = self._get_bend_mean() + df = val-mn + return self.bend1.get_current_value()+df, self.bend2.get_current_value()+df + + def _get_bend_diff(self): + return float(np.diff([self.bend1.get_current_value(),self.bend2.get_current_value()])) + + def _get_benders_set_diff(self,val): + df = val-self._get_bend_diff() + return self.bend1.get_current_value()-df/2, self.bend2.get_current_value()+df/2 diff --git a/eco/xoptics/offsetMirrors_new.py b/eco/xoptics/offsetMirrors_new.py index ef77c2c..c2a4039 100644 --- a/eco/xoptics/offsetMirrors_new.py +++ b/eco/xoptics/offsetMirrors_new.py @@ -37,12 +37,12 @@ class OffsetMirrorsBernina(Assembly): "SAROP21-OOMV092", name="mirr1", is_setting=True, - view_toplevel_only=False, + is_status='recursive', ) self._append( OffsetMirror, "SAROP21-OOMV096", name="mirr2", is_setting=True, - view_toplevel_only=False, + is_status='recursive', ) diff --git a/eco/xoptics/reflaser_new.py b/eco/xoptics/reflaser_new.py index 9d4b4f0..5274109 100644 --- a/eco/xoptics/reflaser_new.py +++ b/eco/xoptics/reflaser_new.py @@ -1,20 +1,20 @@ from ..devices_general.motors import MotorRecord from epics import PV from ..aliases import Alias, append_object_to_object +from ..elements import Assembly -class RefLaser_Aramis: +class RefLaser_Aramis(Assembly): def __init__(self, Id, elog=None, name=None, inpos=-18.818, outpos=-5): + super().__init__(name=name) self.Id = Id self.elog = elog - self.name = name - self.alias = Alias(name) # append_object_to_object(self, self._inpos = inpos self._outpos = outpos - self.mirrmotortest = MotorRecord(self.Id + ":MOTOR_1") - self.mirrmotortest.set_limits(-20, 0) + self._append(MotorRecord,self.Id + ":MOTOR_1",name='mirror',is_setting=True) + self.mirror.set_limits(-20, 0) def __call__(self, *args, **kwargs): self.set(*args, **kwargs) @@ -29,7 +29,7 @@ class RefLaser_Aramis: return "Reflaser status not defined." def get_status(self): - v = self.mirrmotortest.get_current_value() + v = self.mirror.get_current_value() if abs(v - self._inpos) < 0.2: isin = True elif abs(v - self._outpos) < 0.2: @@ -47,9 +47,9 @@ class RefLaser_Aramis: else: print("String %s not recognized!" % value) if value: - self.mirrmotortest.set_target_value(self._inpos) + self.mirror.set_target_value(self._inpos) else: - self.mirrmotortest.set_target_value(self._outpos) + self.mirror.set_target_value(self._outpos) def movein(self): self.set("in") @@ -58,4 +58,5 @@ class RefLaser_Aramis: self.set("out") def __repr__(self): - return self.__str__() + return self.__str__() + super().__repr__() + diff --git a/eco/xoptics/shutters.py b/eco/xoptics/shutters.py index 3d2d355..fd2f0f7 100644 --- a/eco/xoptics/shutters.py +++ b/eco/xoptics/shutters.py @@ -7,7 +7,7 @@ from ..devices_general.adjustable import PvEnum class PhotonShutter(Assembly): def __init__(self, pvname, name=None): super().__init__(name=name) - self._append(PvEnum,pvname,name='request') + self._append(PvEnum, pvname, name="request") def open(self): self.request(1) @@ -15,14 +15,13 @@ class PhotonShutter(Assembly): def close(self): self.request(0) - def __call__(self,*args): + def __call__(self, *args): if args: self.request.set_target_value(args[0]) else: return self.request.get_current_value() - class SafetyShutter: def __init__(self, pvname, name=None): self.name = name