diff --git a/examples/asc_test/master.py b/examples/asc_test/master.py index de2019588cf5bea43c0ad1b686a93cad351c35f3..9fbec29df01c14cd921053812d245e39bca03ccb 100644 --- a/examples/asc_test/master.py +++ b/examples/asc_test/master.py @@ -124,6 +124,8 @@ def pd_phase(tmpkat): # function for root finding def PD_q_test(x): kat.PDrefl_q.phi1=x + print("\n!!!!!!", kat.PDrefl_q.phi1, x) + out = kat.run() print('\r root finding: function value %g ' % out.y, end=' ') sys.stdout.flush() @@ -131,6 +133,7 @@ def pd_phase(tmpkat): # do root finding xtol=1e-8 + (result, info)=scipy.optimize.bisect(PD_q_test,80.0,100.0, xtol=xtol, maxiter=500, full_output=True) print("") diff --git a/pykat/components.py b/pykat/components.py index a55a09ef30321f2ca9a8476b15a33b4da4a864b8..8caba1b05ee2c379ae0d764774fab5b5c0b65e7b 100644 --- a/pykat/components.py +++ b/pykat/components.py @@ -197,9 +197,6 @@ class Component(object): name = str(ns.node.name) fget = lambda self: self.__get_node_setter(name) - - if name == "nITM1": - print(self.__class__) setattr(self.__class__, name, property(fget)) setattr(self, '__nodesetter_' + name, ns) diff --git a/pykat/detectors.py b/pykat/detectors.py index 42ddc583e11b1115017d078666f0a1de46ab95ed..b13521fce9cd4eb1097d7571a6dd668c3555d4df 100644 --- a/pykat/detectors.py +++ b/pykat/detectors.py @@ -380,6 +380,7 @@ class bp(Detector1): return rtn +id___2 = 0 class pd(Detector1): @@ -387,7 +388,28 @@ class pd(Detector1): # This creates an instance specific class for the component # this enables us to add properties to instances rather than # all classes - return object.__new__(type(cls.__name__, (cls,), {}), *args, **kwargs) + global id___2 + id___2 += 1 + cnew_name = str("%s.%s_%i" % (cls.__module__, cls.__name__, id___2)) + + cnew = type(cnew_name, (cls,), {}) + + return object.__new__(cnew, *args, **kwargs) + + def __deepcopy__(self, memo): + """ + When deep copying a kat object we need to take into account + the instance specific properties. + """ + + # Here we create a copy of this object based of the base class + # of this one, otherwise we're making a copy of a copy of a copy... + result = self.__class__.__new__(self.__class__.__base__) + result.__dict__ = copy.deepcopy(self.__dict__, memo) + + result.__set_demod_attrs() + + return result def __init__(self, name=None, num_demods=1, node_name=None, senstype=None, alternate_beam=False, pdtype=None, **kwargs): BaseDetector.__init__(self, name, node_name) @@ -437,24 +459,6 @@ class pd(Detector1): self.__set_demod_attrs() - - - # def __deepcopy__(self, memo): - # """ - # When deep copying a kat object we need to take into account - # the instance specific properties. - # """ - # result = pd(self.name, self.num_demods, self.node.name) - # memo[id(self)] = result - # result.__dict__ = copy.deepcopy(self.__dict__, memo) - # - # # Find all properties in class we are copying - # # and deep copy these to the new class instance - # for x in self.__class__.__dict__.items(): - # if isinstance(x[1], property): - # setattr(result.__class__, x[0], x[1]) - # - # return result @property def senstype(self): return self.__senstype @@ -486,17 +490,23 @@ class pd(Detector1): return getattr(self, '_pd__' + name) def __set_f(self, num, value): - setattr(self, '_pd__f' + num, value) + value = SIfloat(value) + + p = getattr(self, '_pd__f' + num) + p.value = value def __set_phi(self, num, value): + value = SIfloat(value) + if value == None and num != self.num_demods: # check if we are setting no phase that this is only on the last # demodulation phase. raise pkex.BasePyKatException("Only last demodulation phase can be set to None") elif isinstance(value, six.string_types) and not isinstance(value,float) and value.lower() != "max": raise pkex.BasePyKatException("Demodulation phase can only be set to a 'max' or a number (or None if the last demodulation phase)") - - setattr(self, '_'+ self.__class__.__name__ +'__phi' + num, value) + + p = getattr(self, '_pd__phi' + num) + p.value = value def __set_demod_attrs(self): """ @@ -510,15 +520,20 @@ class pd(Detector1): if self.__num_demods > 0: for i in range(1,6): name = str(i) + if i <= self.num_demods: if not hasattr(self, "f"+name): - setattr(self.__class__, "f"+name, property(fget=lambda self, i=i: self.__get_fphi('f'+str(i)), fset=lambda self, value, i=i: self.__set_f(str(i), value))) + fget = lambda self, i=i: self.__get_fphi('f'+str(i)) + fset = lambda self, value, i=i: self.__set_f(str(i), value) + + setattr(self.__class__, "f"+name, property(fget=fget, fset=fset)) if not hasattr(self, "phi"+name): setattr(self.__class__, "phi"+name, property(fget=lambda self, i=i: self.__get_fphi('phi'+str(i)), fset=lambda self, value, i=i: self.__set_phi(str(i), value))) else: if hasattr(self, "f"+name): delattr(self.__class__, "f"+name) + if hasattr(self, "phi"+name): delattr(self.__class__, "phi"+name) else: diff --git a/test/test_properties.py b/test/test_properties.py new file mode 100644 index 0000000000000000000000000000000000000000..71152bb55df5c2f4c14e97edff328baaf73cb2f7 --- /dev/null +++ b/test/test_properties.py @@ -0,0 +1,33 @@ +import pykat +from copy import deepcopy + +kat = pykat.finesse.kat() + +code_det = """ +m m1 1 0 0 n0 n1 +pd1 pdr 9M 90 n1 +""" + +kat.parseCommands(code_det) + +kat.pdr.f1 = "0.1k" +assert(kat.pdr.f1 == 100) +assert(type(kat.pdr.f1) is pykat.param.Param) + +kat.pdr.phi1 = "10u" +assert(kat.pdr.phi1 == 1e-5) +assert(type(kat.pdr.phi1) is pykat.param.Param) + +kat.m1.R = "10000u" +assert(kat.m1.R == 0.01) + +################################# +kat = deepcopy(kat) + +kat.m1.R = 0.9 +assert(kat.m1.R == 0.9) + +kat.pdr.phi1 = 20 +assert(kat.pdr.phi1 == 20) + +print "PASSED" \ No newline at end of file