Skip to content
Snippets Groups Projects
Commit 012e5a23 authored by osherso2's avatar osherso2
Browse files

Models TES object(s) on an island and simulates the thermal and electrical balance equations.

parent ef3ba263
No related branches found
No related tags found
1 merge request!1S4 design
Pipeline #184837 canceled
from detector_lib.TES_model import *
from scipy.optimize import minimize
from scipy.interpolate import interp1d
import pickle
hbar = 6.58212e-16 # eV s
kb = 8.61733e-5 # eV / K
J_eV = 6.2415091e18 # eV / J
class detector:
"""A model of our TES detectors"""
def __init__(self,TESs,Tx,Cx,Gx,betaC,betaG,num_rows,Rsh,Rb,Rl,Rs,L,Vb,Tb,R,I,T,Popt,center_freq,bandwidth):
"""
DEVICE DESCRIPTION
TESs: An array of TES objects. This MUST be in order of first superconducting to last!
Tx [K]: Reference temperature on which to measure heat capacity and thermal conductance.
Cx [J/K]: Heat capacity of the island at Tx.
Gx [W/K]: Thermal conductance of the island at Tx.
betaC: Power law parameter: C(T) = Cx(T/Tx)**betaC.
betaG: Power law parameter: G(T) = Gx(T/Tx)**betaG.
num_rows: Number of detectors in a row (used to compute the load on the bias voltage).
Rsh [Ohms]: Shunt resistor.
Rb [Ohms]: Bias resistor.
Rl [Ohms]: Parasitic resistance on the island.
Rs [Ohms]: Stray resistance off the island.
L [H]: Inductance coupled to the TESs.
DEVICE STATE
Vb [V]: Bias voltage.
Tb [K]: FPU temperature.
R [Ohms]: Resistance on the island.
I [A]: Current through the island.
T [K]: Temperature of the island.
LOADING
Popt [W]: Optical loading.
center_freq [Hz]: Center frequency of the band.
bandwidth [Hz]: Width of the band.
"""
# Thermal
self.Tx=float(Tx) # [K] The temperature at which Cx and Gx are measured.
self.Cx=float(Cx) # [J/K] Island heat capacity at Tx.
self.Gx=float(Gx) # [W/K] Leg heat conductance at Tx.
self.betaC=float(betaC) # Power law describing heat capacity: C = Cx * (T/Tx)**betaC.
self.betaG=float(betaG) # Power law describing leg conductance: G = Gx * (T/Tx)**betaG.
# Electrical
self.num_rows = num_rows # Necessary to know the load on the bias voltage.
self.L=float(L) # [H] Inductance.
self.Rsh=float(Rsh) # [Ohm] Shunt resistor.
self.Rl=float(Rl) # [Ohm] Parasitic resistance on the island.
self.Rs=float(Rs) # [Ohm] Stray resistance NOT on the island.
self.Rb=float(Rb) # [Ohm] Bias resistor.
self.Rn = Rl
for tes in TESs: self.Rn += tes.Rn # Highest possible resistance on the island.
# Environment / Loading
self.Popt=float(Popt) # [W] Optical loading.
self.center_freq = center_freq # [Hz] Center of the band.
self.bandwidth = bandwidth # [Hz] Width of the band.
# State
self.Vb = Vb # [V] Bias of entire row (not the voltage across the TES).
self.Tb = Tb # [K] Temperature of FPU (other side of the legs).
self.R = R # [Ohms] Resistance of the island (Rs of all TESs + Rl).
self.I = I # [A] Current flowing through the TESs.
self.T = T # [K] Temperature of the island.
# Copying each TES onto the island.
self.TESs = []
for tes in TESs:
tes_copy = tes.copy()
tes.set_state(I=I, T=T)
self.TESs.append(tes_copy)
def set_state(self, I=None, T=None):
if I is None: I = self.I
else: self.I = I
if T is None: T = self.T
else: self.T = T
R = self.Rl
for tes in self.TESs:
tes.set_state(I=I, T=T)
R += tes.R_trans(I=I, T=T)
self.R = R
def get_Vb(self, R=None, I=None):
if R is None: R = self.R
if I is None: I = self.I
Rsh = self.Rsh
Rs = self.Rs
Rb = self.Rb
N = self.num_rows
Rc = N*(R + Rs)*Rsh/(R + Rs + Rsh)
Ib = I * (Rsh + Rs + R) / Rsh
return Ib * (Rb + Rc)
def get_Ib(self, Vb=None, R=None):
if Vb is None: Vb = self.Vb
if R is None: R = self.R
Rsh = self.Rsh
Rs = self.Rs
Rb = self.Rb
N = self.num_rows
Rc = N*(R + Rs)*Rsh/(R + Rs + Rsh)
Ib = Vb / (Rb + Rc)
return Ib
def get_R(self, I=None, T=None):
if I is None: I = self.I
if T is None: T = self.T
R = self.Rl
for tes in self.TESs: R += tes.R_trans(I=I, T=T)
return R
def get_I(self, R=None, Vb=None):
if Vb is None: Vb = self.Vb
if R is None: R = self.R
Ib = self.get_Ib(Vb=Vb, R=R)
I = Ib * self.Rsh / (self.Rsh + self.Rs + R)
return I
def get_G(self, T=None):
if T is None: T = self.T
return self.Gx * (self.T/self.Tx)**self.betaG
def get_C(self, T=None):
if T is None: T = self.T
return self.Cx * (self.T/self.Tx)**self.betaC
def get_alpha(self, I=None, T=None):
if I is None: I = self.I
if T is None: T = self.T
alpha = 0
for tes in self.TESs: alpha += tes.get_alpha(I=I, T=T)*(tes.R/self.R)
return alpha
def get_beta(self, I=None, T=None):
if I is None: I = self.I
if T is None: T = self.T
beta = 0
for tes in self.TESs: beta += tes.get_beta(I=I, T=T)*(tes.R/self.R)
return beta
def get_loop_gain(self):
G = self.get_G()
return self.get_alpha() * self.R * self.I**2. / (G * self.T)
def get_Z(self, omega):
R = self.R
beta = self.get_beta()
loop_gain = self.get_loop_gain()
G = self.get_G()
C = self.get_C()
tau_tm = (C/G)/(1. - loop_gain)
return R*(1.+beta)+(R*loop_gain*(2.+beta)/(1.-loop_gain))/(1.+1.j*omega*tau_tm)
def get_taus(self):
R = self.R
I = self.I
T = self.T
L = self.L
Rl = self.Rs + self.Rsh
Tx = self.Tx
alpha = self.get_alpha()
beta = self.get_beta()
loop_gain = self.get_loop_gain()
gamma = Rl/R
G = self.get_G()
C = self.get_C()
tau_CG = C/G
tau_LR = L/R
tau_el = tau_LR / (1 + beta + gamma)
tau_tm = tau_CG / (1. - loop_gain)
disc = ((tau_tm - tau_el)/(tau_tm * tau_el))**2.
disc-= 4.* R * loop_gain * (2. + beta) / (L * tau_CG)
disc = complex(disc)**.5
term = (tau_tm + tau_el)/(tau_tm * tau_el)
tau_p = 2/(term + disc)
tau_m = 2/(term - disc)
return tau_p, tau_m, tau_el, tau_tm
def stability(self):
tau_p, tau_m, _, _ = self.get_taus()
if numpy.isnan(tau_p): return False
if numpy.isnan(tau_m): return False
if tau_p.real <= 0 or tau_m.real <= 0: return False
return True
def over_damped(self):
tau_p, tau_m, _, _ = self.get_taus()
if abs(numpy.imag(tau_p)) > 1e-12: return False
if abs(numpy.imag(tau_m)) > 1e-12: return False
return self.stability()
def get_Lcrits(self):
R = self.R
Rl = self.Rs + self.Rsh
gamma = Rl / R
beta = self.get_beta()
tau = self.get_C() / self.get_G()
loop_gain = self.get_loop_gain()
A = loop_gain*(3. + beta - gamma)
B = 1. + beta + gamma
C = loop_gain*(2. + beta)
D = loop_gain*(1. - gamma)
E = 2.*numpy.sqrt(C*(D + B))
F = R*tau/(loop_gain - 1.)**2.
return F*(A + B + E), F*(A + B - E)
def get_Lthresh(self):
R = self.R
Rl = self.Rs + self.Rsh
gamma = Rl / R
beta = self.get_beta()
tau = self.get_C() / self.get_G()
loop_gain = self.get_loop_gain()
prefactor = (1. + beta + gamma) / (loop_gain - 1.)
return prefactor * R * tau
def P_in(self, R=None, I=None, T=None):
if R is None: R = self.R
if I is None: I = self.I
if T is None: T = self.T
P_J = R*(I**2.)
return P_J + self.Popt
def P_out(self, R=None, I=None, T=None):
if R is None: R = self.R
if I is None: I = self.I
if T is None: T = self.T
eta = self.betaG + 1.
return self.Gx*(T**eta - self.Tb**eta)/(eta * self.Tx**self.betaG)
def P_bal(self, R=None, I=None, T=None):
return self.P_in(R=R, I=I, T=T) - self.P_out(R=R, I=I, T=T)
def delPdelI(self, R=None, I=None, T=None):
if R is None: R = self.R
if I is None: I = self.I
if T is None: T = self.T
derv = 2.*R*I
for tes in self.TESs: derv += tes.delRdelI(I=I, T=T)*(I**2.)
return derv
def delPdelT(self, R=None, I=None, T=None):
if R is None: R = self.R
if I is None: I = self.I
if T is None: T = self.T
derv = -self.Gx*(T**self.betaG)/(self.Tx**self.betaG) # dPlegs/dT
for tes in self.TESs: derv += tes.delRdelT(I=I, T=T)*(I**2.) # dPJoule/dT
return derv
def halfway_finder(self, TES_index=0):
tess = numpy.array(self.TESs)
assert(TES_index < len(tess))
R = self.Rl
if len(tess[:TES_index]) > 1:
for tes in tess[:TES_index]: R += tes.Rn
R += tess[TES_index].Rn/2.
if TES_index == 0: T_arr = numpy.arange(0, tess[0].Tc, 1e-3)
else: T_arr = numpy.arange(tess[TES_index-1].Tc, tess[TES_index].Tc, 1e-3)
bG = self.betaG
Gx = self.Gx
Tx = self.Tx
Tc = self.TESs[TES_index].Tc
Ic = self.TESs[TES_index].Ic
Popt = self.Popt
Tb = self.Tb
p1 = (bG + 1.) * (Tx**bG)/Gx
PJ = lambda T: R * Ic**2. * (1. - T/Tc)**3.
T = (p1*(PJ(T_arr) + Popt) + Tb**(bG + 1.))**(1./(bG + 1.))
ind = numpy.argmin(numpy.abs(T - T_arr))
if ind == 0: ind = 1
if ind == len(T_arr)-1: ind -= 1
T_arr = numpy.linspace(T_arr[ind-1], T_arr[ind+1], 5000)
T = (p1*(PJ(T_arr) + Popt) + Tb**(bG + 1.))**(1./(bG + 1.))
T = T_arr[numpy.argmin(numpy.abs(T - T_arr))]
I = Ic*(1. - T/Tc)**(3./2)
Vb = self.get_Vb(R=R, I=I)
self.Vb = Vb;
self.set_state(I=I, T=T)
self.halfway_point = (Vb, Tb)
def stationary_point(self, R_frac=.65, TES_index=0, method="hybr",
weight=1e3, preserve=False, debug=False):
if TES_index == -1: TES_index = len(self.TESs) - 1
if not preserve: self.halfway_finder(TES_index=TES_index)
tess = self.TESs
assert(TES_index < len(tess))
tes = tess[TES_index]
Rc = self.Rl
if len(tess[:TES_index]) > 1:
for tes in tess[:TES_index]: Rc += tes.Rn
target = R_frac*tes.Rn + Rc
def err(I, T):
R = self.get_R(I,T)
return (R/target - 1.)**2.
def pbal(I, T):
R = self.get_R(I,T)
return self.P_bal(R=R, I=I, T=T)
def Lg(I, T, l):
R = self.get_R(I=I, T=T)
return (R/target - 1.)**2. - l*weight*self.P_bal(R=R, I=I, T=T)
def delLdelI(x):
I, T, l = x
R = tes.R_trans(I=I, T=T)
dEdI = 2.*(R/target - 1.)*tes.delRdelI(I=I, T=T)/target
return dEdI - weight*l*self.delPdelI(R=R, I=I, T=T)
def delLdelT(x):
I, T, l = x
R = tes.R_trans(I=I, T=T)
dEdT = 2.*(R/target - 1.)*tes.delRdelT(I=I, T=T)/target
return dEdT - weight*l*self.delPdelT(R=R, I=I, T=T)
def delLdell(x):
I, T, li = x
R = tes.R_trans(I=I, T=T)
return -weight*self.P_bal(R=R, I=I, T=T)
DeltaT = tes.Tc - self.T
DeltaI = tes.Ic_correction(T=2.*self.T - tes.Tc) - self.I
if R_frac > .5:
I_bound = [self.I, min(self.I + 2.*DeltaI, tes.Ic)]
T_bound = [self.T, tes.Tc]
elif R_frac < .5:
I_bound = [max(0, self.I - 2.*DeltaI), self.I]
T_bound = [max(0, self.T - 2.*DeltaT), self.T]
l_bound = [-numpy.inf, numpy.inf]
from scipy.optimize import root
dL = lambda x: [delLdelI(x), delLdelT(x), delLdell(x)]
res = root(dL, [self.I, self.T, 1.], method=method)
curr_I = res.x[0]; curr_T = res.x[1]; curr_l = res.x[2]
curr_R = tes.R_trans(I=curr_I, T=curr_T)
curr_R = self.get_R(I=curr_I, T=curr_T)
curr_Vb = self.get_Vb(R=curr_R, I=curr_I)
self.Vb = curr_Vb
self.set_state(I=curr_I, T=curr_T)
return res
def iterative_finder(self, R_frac=.65, TES_index=0, preserve=True, N=3, M=4, dt=1e-8):
if TES_index == -1: TES_index = len(self.TESs) - 1
if not preserve: self.halfway_finder(TES_index=TES_index)
tess = self.TESs
assert(TES_index < len(tess))
tes = tess[TES_index]
Rc = self.Rl
if len(tess[:TES_index]) > 1:
for tes in tess[:TES_index]: Rc += tes.Rn
target = R_frac*tes.Rn + Rc
for i in range(N):
time = numpy.arange(dt, dt*M, dt)
self.sim(time=time)
E = target - self.R
dI = self.I * E / (self.R * self.get_beta())
Vb = self.get_Vb(R=target, I=self.I+dI)
self.set_state(I=self.I+dI)
self.Vb = Vb
### SIMULATION ###
def small_sig(self, dt=5e-8, I=None, T=None, Vb=None, Tb=None):
"""
Simulates one step (of size dt) in time.
Input: dt (default 1e-6 seconds)
Output: dI, dT
"""
if I is None: I = self.I
else: self.I = I
if T is None: T = self.T
else: self.T = T
if Vb is None: Vb = self.Vb
if Tb is None: Tb = self.Tb
# Current state
R = self.get_R(I=I, T=T)
# Electrical impulse
Rsh = self.Rsh
Rs = self.Rs
L = self.L
Ib = self.get_Ib(Vb=Vb, R=R)
LdIdt = Ib*Rsh - I*(Rsh + R + Rs)
dI = LdIdt*dt/L
# Thermal impulse
CdTdt = self.P_bal(R=R, I=I, T=T)
dT = CdTdt * dt / self.get_C(T=T)
return dI, dT
def sim(self, time, I=None, T=None, prog=False):
"""
Runs self.small_sig a lot to simulate detector response.
Input: an array for time representing the incremental steps to simulate.
Output: time, R, I, T
"""
Vb = self.Vb
Tb = self.Tb
R_arr = []
I_arr = []
T_arr = []
if I is None: I = self.I
if T is None: T = self.T
curr_p = -1
dtime = numpy.diff(time)
dtime = numpy.append(dtime, dtime[-1])
for i, dt in enumerate(dtime):
if prog:
if (100*i)/len(dtime)>curr_p:
print "%03d%%" % int((100*i)/len(dtime))
curr_p += 10
sig = self.small_sig(I=I,T=T,dt=dt)
dI, dT = sig
I += dI
T += dT
R = self.get_R(I=I, T=T)
self.R = R
R_arr = numpy.append(R_arr, R)
I_arr = numpy.append(I_arr, I)
T_arr = numpy.append(T_arr, T)
R_arr = numpy.array(R_arr)
I_arr = numpy.array(I_arr)
T_arr = numpy.array(T_arr)
return time, R_arr, I_arr, T_arr
def settle(self, prog=False):
"""
Runs self.sim for a time array appropriate to let the detector settle and converge.
Input:
Output: time, R, I, T
"""
time = numpy.append(numpy.ones(50000)*1e-12, numpy.arange(1e-12, 5e-8, 1e-12))
time = numpy.cumsum(time)
return self.sim(time=time, prog=prog)
def Tb_variation(self, arr_t, arr_T, time=None, plot=False):
"""
Simulates detector response to changing FPU temperature (T_base).
Input: A array of FPU temperatures (arr_T) and the corresponding time array (arr_t)
Output: time, T_base, R, I, T
"""
Vb = self.Vb
Tb = interp1d(arr_t, arr_T)
I = self.I
T = self.T
R_arr = []
I_arr = []
T_arr = []
T_bath = []
if time is None:
dt = 1e-6
N = (numpy.max(arr_t) - numpy.min(arr_t))/dt
N = numpy.floor(N)
time = numpy.arange(N)*dt + arr_t[0]
dtime = numpy.diff(time)
dtime = numpy.append(dtime, dtime[-1])
for i, (dt, t) in enumerate(zip(dtime, time)):
self.Tb = Tb(t)
dI, dT = self.small_sig(I=I,T=T,dt=dt)
I += dI
T += dT
R = self.get_R(I=I, T=T)
self.R = R
R_arr.append(R)
I_arr.append(I)
T_arr.append(T)
T_bath.append(Tb(t))
R_arr = numpy.array(R_arr)
I_arr = numpy.array(I_arr)
T_arr = numpy.array(T_arr)
T_bath = numpy.array(T_bath)
return time, T_bath, R_arr, I_arr, T_arr
def Vb_variation(self, arr_t, arr_V, time=None, plot=False):
"""
Simulates detector response to changing biasing voltage, V_bias.
Input: A array of voltage biases (arr_V) and the corresponding time array (arr_t)
Output: time, V_bias, R, I, T
"""
Vb = interp1d(arr_t, arr_V)
Tb = self.Tb
I = self.I
T = self.T
R_arr = []
I_arr = []
T_arr = []
V_bias = []
if time is None:
dt = 1e-6
N = (numpy.max(arr_t) - numpy.min(arr_t))/dt
N = numpy.floor(N)
time = numpy.arange(N)*dt + arr_t[0]
dtime = numpy.diff(time)
dtime = numpy.append(dtime, dtime[-1])
for i, (dt, t) in enumerate(zip(dtime, time)):
self.Vb = Vb(t)
dI, dT = self.small_sig(I=I,T=T,dt=dt)
I += dI
T += dT
R = self.get_R(I=I, T=T)
self.R = R
R_arr.append(R)
I_arr.append(I)
T_arr.append(T)
V_bias.append(Vb(t))
R_arr = numpy.array(R_arr)
I_arr = numpy.array(I_arr)
T_arr = numpy.array(T_arr)
V_bias = numpy.array(V_bias)
return time, V_bias, R_arr, I_arr, T_arr
def Edep(self, E):
"""
Deposited energy onto the TES island like a cosmic ray would.
Input: E (in eV)
Output:
No output, but the TES state is changed - The TES island should have heated up.
"""
c = self.Cx / (self.Tx**self.betaC)
h = self.betaC + 1.
T_dep = ((h* E / J_eV / c) + self.T**h)**(1./h)
self.T = T_dep
for tes in self.TESs: tes.T = self.T
def cray(self, E=60e6):
"""
Simulates a cosmic ray interaction. Runs self.Edep and then self.sim for a
predetermined time array I liked.
Input: E (in eV)
Output: time, R, I, T
"""
pre_time = numpy.ones(1000)*1e-5 + numpy.linspace(0, 2e-5, 1000)
pre_time = numpy.cumsum(pre_time)
t_arr, R_arr, I_arr, T_arr = self.sim(time=pre_time)
time = [8e-6]*50000; time = numpy.cumsum(time); time = time**2
time = numpy.append(time, time[-1] + (1. + numpy.arange(1000))*5e-5)
time = numpy.append(time, time[-1] + (1. + numpy.arange(2000))*1e-4)
c = self.Cx / (self.Tx**self.betaC)
h = self.betaC + 1.
T_dep = ((h* E / J_eV / c) + self.T**h)**(1./h)
self.T = T_dep
for tes in self.TESs: tes.T = self.T
time, R, I, T = self.sim(time=time)
#return time, R, I, T
t_arr = numpy.append(pre_time, time+pre_time[-1])
R_arr = numpy.append(R_arr, R)
I_arr = numpy.append(I_arr, I)
T_arr = numpy.append(T_arr, T)
return t_arr, R_arr, I_arr, T_arr
def loadcurve(self, Vb_max=None, Vb_min=None, Vb_step=-2e-4, step_t=.01):
"""
Simulates a loadcurve.
Input: Vb_max: max of V_bias,
Vb_min: min of V_bias,
Vb_step: V_bias step size,
step_t: the pause between steps.
Output: Vb, R, I, T, t1, t2
"""
self.lock_finder(R_frac=.9, TES_index=-1, N=1)
self.settle()
truncate = False
if Vb_max is None: Vb_max = self.Vb
if Vb_min is None: Vb_min = 0; truncate = True
Vb = numpy.arange(Vb_max, Vb_min, Vb_step)
Vb = numpy.append(Vb[0], Vb)
Vb = numpy.append(Vb, Vb[-1])
dt = 1e-5
init = 1./numpy.arange(1, 1000)
init = dt*init[::-1]
rnge = numpy.arange(init[-1]+dt, step_t, dt)
time = numpy.append(init, rnge)
def change_bias(vb):
#print "bias: %.05f V" % vb
dV = self.Vb - vb
dI = dV/self.Rb
dI = dI * self.Rsh / (self.Rsh + self.R)
self.I -= dI
self.Vb = vb
for tes in self.TESs: tes.set_state(I=self.I, T=self.T)
self.sim(time)
t = numpy.cumsum([step_t]*len(Vb)) - step_t
R = []
I = []
T = []
t1 = []
t2 = []
for i, vb in enumerate(Vb):
p = (100.*i)/len(Vb)
#if (i % 100 == 0): print "%d %%" % p
change_bias(vb)
R.append(self.R)
I.append(self.I)
T.append(self.T)
tau_p, tau_m, _, _ = self.get_taus()
t1.append(tau_p)
t2.append(tau_m)
if self.R < 1e-3 * self.TESs[0].Rn:
if truncate:
Vb = Vb[:len(R)]
break
R = numpy.array(R)
I = numpy.array(I)
T = numpy.array(T)
t1 = numpy.array(t1)
t2 = numpy.array(t2)
return Vb, R, I, T, t1, t2
def bias_steps(self, Vb_amp=0.00019073486328125, step_len=.5, N_steps=2):
"""
Simulates taking bias steps from the current bias. So bias will 'tick' between
current bias and current bias + bias step amplitude.
Input: Vb_amp: bias step amplitude.
step_len: time between 'ticks' in the bias.
N_steps: number of bias steps
Output: time, Vb, R, I, T
"""
Vb_base = self.Vb
Vb_step = Vb_base+Vb_amp
Vb = ([Vb_base, Vb_step]*N_steps)
Vb = numpy.append(Vb, Vb_base)
dt = 1e-5
time = numpy.arange(0, step_len, dt)
def change_bias(vb):
#print "bias: %.05f V" % vb
dV = self.Vb - vb
dI = dV/self.Rb
dI = dI * self.Rsh / (self.Rsh + self.R)
self.I -= dI
self.Vb = vb
for tes in self.TESs: tes.set_state(I=self.I, T=self.T)
return self.sim(time)
R = numpy.array([])
I = numpy.array([])
T = numpy.array([])
tarr = numpy.array([0])
Varr = numpy.array([])
for i, vb in enumerate(Vb):
time, r, i, t = change_bias(vb)
R = numpy.append(R, r)
I = numpy.append(I, i)
T = numpy.append(T, t)
tarr = numpy.append(tarr, time+time[1]+tarr[-1])
Varr = numpy.append(Varr, [vb]*len(r))
return tarr[:-1], Varr, R, I, T
def print_state(self):
state = self.save_state(filename=None)
for k in state.keys():
if "tes" in k: continue
print k, state[k]
for k in state.keys():
if "tes" not in k: continue
tes = state[k]
print k
for p in tes.keys():
print " ", p, tes[p]
def save_state(self, filename=None):
state = {}
for i, tes in enumerate(self.TESs):
state["tes_%02d"%i] = {}
state["tes_%02d"%i]["name"] = tes.name
state["tes_%02d"%i]["Ic"] = tes.Ic
state["tes_%02d"%i]["Tc"] = tes.Tc
state["tes_%02d"%i]["Rn"] = tes.Rn
state["tes_%02d"%i]["alpha0"] = tes.alpha0
state["tes_%02d"%i]["I"] = tes.I
state["tes_%02d"%i]["T"] = tes.T
state["Tx"] = self.Tx
state["Cx"] = self.Cx
state["Gx"] = self.Gx
state["betaC"] = self.betaC
state["betaG"] = self.betaG
state["num_rows"] = self.num_rows
state["L"] = self.L
state["Rsh"] = self.Rsh
state["Rb"] = self.Rb
state["Rl"] = self.Rl
state["Rs"] = self.Rs
state["Popt"] = self.Popt
state["center_freq"] = self.center_freq
state["bandwidth"] = self.bandwidth
state["Vb"] = self.Vb
state["Tb"] = self.Tb
state["R"] = self.R
state["I"] = self.I
state["T"] = self.T
if not filename is None:
with open(filename, 'a') as savestate:
pickle.dump(state, savestate)
return state
def load_state(self, state=None, filename=None):
if filename is None:
assert(not state is None)
else:
with open(filename, 'r') as loadstate:
state = pickle.load(loadstate)
para = {"Rs":0.0}; TESn = []
for k in state.keys():
if "tes" in k:
TESn.append(k)
continue
para[k] = state[k]
TESs = []
for tes in TESn: TESs.append(TES(**state[tes]))
para["TESs"] = TESs
return detector(**para)
def copy_TESs(self):
TESs_copy = []
for tes in self.TESs:
params = {}
params["Tc"] = float(tes.Tc)
params["Ic"] = float(tes.Ic)
params["Rn"] = float(tes.Rn)
params["I"] = float(tes.I)
params["T"] = float(tes.T)
params["name"] = tes.name
params["alpha0"] = float(tes.alpha0)
TESs_copy.append(TES(**params))
return TESs_copy
def copy_detector(self):
return detector(TESs=self.copy_TESs(), num_rows=self.num_rows,
Tx=self.Tx, Cx=self.Cx, Gx=self.Gx,
betaC = self.betaC, betaG=self.betaG,
L=self.L, Rsh=self.Rsh, Popt=self.Popt,
Rl=self.Rl, Rs=self.Rs, Rb=self.Rb,
center_freq=self.center_freq,
bandwidth=self.bandwidth,
Vb=self.Vb, Tb=self.Tb,
R=self.R, I=self.I, T=self.T)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment