diff --git a/iexcode/instruments/Lakeshore_335.py b/iexcode/instruments/Lakeshore_335.py index 3c2784d571404a2ce8f1cb692b6ca77291bac749..b2e511c34fe46652350a41ab6790d09703cc7862 100644 --- a/iexcode/instruments/Lakeshore_335.py +++ b/iexcode/instruments/Lakeshore_335.py @@ -10,17 +10,182 @@ from epics import caget, caput from iexcode.instruments.IEX_BL_config import * from iexcode.instruments.utilities import read_dict -def Lakeshore_reset(pv,d): +class Lakeshore_335: """ - resets the lake short to the default paramters defind in the dictionary d + Lakeshore 355 data class """ - for key in d.keys(): - caput(pv+key,d[key]) + def __init__(self,ioc,**kwargs): + """ + ioc = "29idARPES:" + **kwargs + Q = "TC1:" + defaults => dictionary of default parameter used by reset + + """ + kwargs.setdefault('Q','TC1:') + + self.pv = ioc+"LS335:"+kwargs['Q'] + self.reset(**kwargs) + self.get() + pass + + def reset(self,**kwargs): + """ + resets the lake short to the default paramters defind in the dictionary defaults + **kwargs + defaults = {"read.SCAN":".5 second","OUT1:Cntrl":"A","OUT2:Cntrl":"B","OUT1:Mode":"Closed Loop"} + + """ + kwargs.setdefault("defaults",{"read.SCAN":".5 second","OUT1:Cntrl":"A", + "OUT2:Cntrl":"B","OUT1:Mode":"Closed Loop","P1":1,"I1":5,"D1":1,"RampR1":5,"OnRamp1":"ON"}) + + d=kwargs['defaults'] + for key in d.keys(): + caput(self.pv+key,d[key]) + + def heater_range_list(self): + return ["off","low","medium","high"] + + def pv_dictionary(self): + d={ + "INA":None, + "INB":None, + "IN1":None, + "IN2":None, + "IN1:Name_RBV":"", + "IN2:Name_RBV":"", + "OUT1:SP":None, + "OUT1:SP_RBV":None, + "HTR1":None, + "HTR1:Range":"", + "HTR1:Range_RBV":"", + "OUT1:Cntrl_RBV":"", + "P1":None, + "P1_RBV":None, + "I1":None, + "I1_RBV":None, + "D1":None, + "D1_RBV":None, + "RampR1":None, + "RampR1_RBV":None, + "OnRamp1":"", + "OnRamp1_RBV":"", + } + def get(self): + """gets the current valuse + """ + d = self.pv_dictionary() + + caput(self.pv+"read.PROC",1) + sleep(1) + caput(self.pv+"read.PROC",0) + + for key in d.keys(): + if d[key] != None: + caget(self.pv+key,as_string=True) + else: + caget(self.pv+key) + return d + + def set(self,TA_sp,bandwidth=5,seconds=5*60,heater_range=None,out_num=1): + """ + TA_SP = temperature set point + bandwidth = the temperature range acceptable + seconds = time to wait for stablized + heater_range = "off","low","medium","high" + = None then uses current setting + out_num = control loop number (1 or 2) + """ + d = self.pv_dictionary + + + + TA = caget(self.pv+"INA") + while True: + #sepoint with +/- current temperature + if TA - bandwidth <= TA_sp > TA + bandwidth: + #regulate off sample + self.regulate_TA(TA_sp,heater_range,out_num) + if self.TA_stable(TA_sp,bandwidth,seconds) == True: + break + else: + self.regulate_TB(TA_sp,heater_range,out_num) + + caget() + + def TA_stable(self,T_sp,bandwidth=5,seconds=5*60,out_num=1): + """ + returns True or False is the temperature is with in the bandwidth over a given + time interval in seconds + T_sp = temperature set point + bandwidth = +/- Temperature to be stablized + seconds = time to wait to stablize + out_num = control loop number (1 or 2) + """ + read_interval = 0.5 + name_rbv = caget(self.pv+"IN"+str(out_num)+":Name_RBV", as_string=True) + + for t in range(0,seconds/read_interval): #sampling every 0.5 seconds + T = caget(self.pv+"IN"+str(out_num)) + if T - bandwidth <= T_sp > T + bandwidth: + return False + else: + sleep(read_interval) + return True + + + + def regulate_TA(self,T_sp,heater_range=None,out_num=1): + """ + """ + self.Cntrl(1,'A') + self.Cntrl(2,'B') + sleep(0.5) + self.set_point(1,T_sp,heater_range) + self.set_point(2,0,heater_range='off') + + def regulate_TB(self,T_sp,heater_range=None,out_num=1): + self.Cntrl(1,'B') + self.Cntrl(2,'A') + sleep(0.5) + self.set_point(1,T_sp,heater_range) + self.set_point(2,0,heater_range='off') + + def Cntrl(self,out_num,sensor): + """ + out_num = control loop number (1 or 2) + sensor = 'A' or 'B' + """ + caput(self.pv+"OUT"+str(out_num)+":Cntrl",sensor) + sleep(.5) + + def set_point(self,out_num,T_sp,heater_range=None): + caput(self.pv+"OUT"+str(out_num)+":SP") + self.set_heater_range(out_num,heater_range) + + def set_heater_range(self,out_num,heater_range): + """ + sets the heater range + out_num = control loop number (1 or 2) + """ + if heater_range == None: + heater_range = caget(self.pv+"OUT"+str(out_num)+"HTR1:Range_RBV",as_string=True) + else: + heater_range = heater_range.upper() + if heater_range not in self.heater_range_list(): + message = "heater_range = "+heater_range+" not a valid choice" + message += "\nchoose one of "+str(self.heater_range_list) + print_warning_message(message) + return + else: + caput(self.pv+"OUT"+str(out_num)+"HTR1:Range",heater_range) + sleep(.5) + return caget(self.pv+"OUT"+str(out_num)+"HTR1:Range_RBV",as_string=True) ############################################################################################################# ############################## Lakeshore 335 Diode Curves ############################## -############################################################################################################## +############################################################################################################# #---Settings as of 12/04/2018--- #DiodeCurve_Write(22,"SI435") #DiodeCurve_SetInput("A",22,400) @@ -145,7 +310,7 @@ def DiodeCurve_SetInput(Channel,Curve,Tmax): caput(PV,cmd,wait=True,timeout=1800) ############################################################################################################## -############################## PID Settings ############################## +############################## PID Settings for open cycle ############################## ############################################################################################################## @@ -159,184 +324,7 @@ def DiodeCurve_SetInput(Channel,Curve,Tmax): #Lakeshore 355 I = time in seconds for one oscilation / 1000; D=50-100 for starters -def PID_dict(which,T): #Dictionary of PID setting to try for the ARPES chamber - """Dictionary for common PID setting for the ARPES system. - Since the PID is dependent on the cooling power, this will change with the cryogen and the flow rate: - - Flow = "LHe,LN" => LHe = needle valve = "on" and flow = 70 - """ - PID={} -# PID[which,T]=[P,I,D,Range] Range=HIGH,MEDIUM,LOW,OFF - PID['RT', 378.0]=[200.0,0.0,0.0,'MEDIUM'] - PID['RT', 375.0]=[200.0,0.0,0.0,'MEDIUM'] - PID['RT', 338.0]=[100.0,0.0,0.0,'MEDIUM'] - PID['RT', 298.0]=[20.0,0.0,0.0,'LOW'] - PID['GHe', 378.0]=[210.0,0.0,0.0,'MEDIUM'] - PID['GHe', 375.0]=[210.0,0.0,0.0,'MEDIUM'] - PID['GHe', 338.0]=[130.0,0.0,0.0,'MEDIUM'] - PID['GHe', 298.0]=[60.0,0.0,0.0,'MEDIUM'] - PID['GHe', 250.0]=[10.0,0.0,0.0,'LOW'] - PID['LHe',298.0]=[20.0,5.0,1.0,'HIGH'] # +/- 1.1 deg, over 10 min, heater power 53% - PID['LHe',200.0]=[10.0,5.0,1.0,'HIGH'] # +/- 1.1 deg, over 10 min, heater power 53% - PID['LHe',150.0]=[200.0,0.1,0,'HIGH'] # Stablized at 153, heater power 43% - PID['LHe',180.0]=[200.0,0.1,0,'HIGH'] - PID['LHe',230.0]=[200.0,0.1,0,'HIGH'] - PID['LHe',300.0]=[200.0,0.1,0,'HIGH'] - PID['LHe',40.0]=[200.0,0.1,0,'HIGH'] # - PID['LN2',230]=[10.0,0.6,100,'HIGH'] #stable 237.83, needle valve=ON; flow 6 half turns from max) - PID['LN2',180]=[50.0,4,100,'MEDIUM'] - return PID[which,T] - -def PID_set(which,T,heater='ON'): - """ - Uses preset PID settings as defined in PID_dict() - To cool down: heater='OFF' - - """ - P,I,D,Range=PID_dict(which,T) - caput("29idARPES:LS335:TC1:P1",P) - caput("29idARPES:LS335:TC1:I1",I) - caput("29idARPES:LS335:TC1:D1",D) - if heater == 'ON': - caput("29idARPES:LS335:TC1:HTR1:Range",Range) - elif heater == 'OFF': - caput("29idARPES:LS335:TC1:HTR1:Range",'OFF') - print('\nP = ',PID_dict(which,T)[0]) - print('I = ',PID_dict(which,T)[1]) - print('D = ',PID_dict(which,T)[2]) - print('Range = ',PID_dict(which,T)[3]) - - -def SetT_Sample(which,T,precision=5,minutes=15,offset=6): - """ - Sets PID settings for a given set point as defined in PID_dict(). - Available set points: - which = 'RT' : T = 298, 338, 375 - which = 'LHe': T = 150, 200 - which = 'GHe': T = 250, 298, 338, 370 - which = 'LN2': T = 230, 180 - precision is temperature in K - """ - current_T=caget("29idARPES:LS335:TC1:IN1") - print('\nSet T to '+ str(T)+' K @ '+ dateandtime()) - if T>current_T: - PID_set(which,T,'ON') - Range=PID_dict(which,T)[3] - SetT_Up(T,offset,Range,precision,minutes) - else: - PID_set(which,T,'OFF') - Range=PID_dict(which,T)[3] - SetT_Down(T,offset,Range,precision,minutes) - caput("29idARPES:LS335:TC1:OUT1:SP",T) - - -def SetT_Up(T,offset,Range,precision=5,minutes=15): - if Range=='LOW': Range=1 - if Range=='MEDIUM': Range=2 - if Range=='HIGH': Range=3 - t=15 - u=0 - caput('29idARPES:LS335:TC1:OUT1:SP',T) # set the set point to T - while True: # while TA < T - TA=caget('29idARPES:LS335:TC1:IN1') # get current temperature at the sample - TB=caget('29idARPES:LS335:TC1:IN2') # get current temperature (B=cold finger) - if TA<T-precision: # if it hasn't reach SP - caput("29idARPES:LS335:TC1:HTR1:Range",min(Range,3)) # increase heater range to Range +1 - while True: # while TB < T+offset: - TB=caget('29idARPES:LS335:TC1:IN2') # get current temperature at the cold finger - if (t%120)==0: - print('\nTA = ',TA,' TB = ',TB, ' @ ',dateandtime()) - if TB<(T+offset) and t<=minutes*60: #if it hasn't reach the SP+offser - sleep(15) - t+=15 - #print t, TA, TB - elif TB<(T+offset) and t>minutes*60: - heater_power=caget('29idARPES:LS335:TC1:HTR1') - heater_range=caget('29idARPES:LS335:TC1:HTR1:Range') - if heater_power > 90: - caput("29idARPES:LS335:TC1:HTR1:Range",min(heater_range+1,3)) - print('Change Range to',caget('29idARPES:LS335:TC1:HTR1:Range'),' @ ',dateandtime()) - elif heater_range==3 or heater_power<=90: - P=caget("29idARPES:LS335:TC1:P1") - caput("29idARPES:LS335:TC1:P1",P*1.5) - print('Change P to',caget("29idARPES:LS335:TC1:P1"),' @ ',dateandtime()) - t=0 - - else: #else - break # break - caput("29idARPES:LS335:TC1:HTR1:Range",'OFF') # turn off the heater - elif TA>T-precision: # if it has reach the set point - break # break - print('TA = ',TA,' TB = ',TB, ' @ ',dateandtime()) # print temperatures - caput("29idARPES:LS335:TC1:HTR1:Range",Range) # set the heater range to preset value - - - - - - -def SetT_Down(T,offset,Range,precision=5,minutes=15): - t=0 - caput('29idARPES:LS335:TC1:OUT1:SP',T) # set the set point to T - while True: # while TA < T - TA=caget('29idARPES:LS335:TC1:IN1') - TB=caget('29idARPES:LS335:TC1:IN2') - if (t%120)==0: - print('\nTA = ',TA,' TB = ',TB, ' @ ',dateandtime()) - if TA>T+precision: - sleep(15) - t+=15 - elif t>minutes*60: - P=caget("29idARPES:LS335:TC1:P1") - caput("29idARPES:LS335:TC1:P1",P/1.5) - t=0 - else: - break - caput("29idARPES:LS335:TC1:HTR1:Range",Range) - print('TA = ',TA,' TB = ',TB, ' @ ',dateandtime()) - -def Get_PID(which='LHe'): - T=caget("29idARPES:LS335:TC1:IN1") - SP=caget("29idARPES:LS335:TC1:OUT1:SP") - P=caget("29idARPES:LS335:TC1:P1") - I=caget("29idARPES:LS335:TC1:I1") - D=caget("29idARPES:LS335:TC1:D1") - Range=caget("29idARPES:LS335:TC1:HTR1:Range",as_string=True) -# print SP,P,I,D,Range - print("Current T:", T,'K') - print("PID[\'"+which+"\',"+str(SP)+"]=["+str(P)+","+str(I)+","+str(D)+",\'"+Range+"\']") - - - -############################################################################################################## -############################## SI9700 Kludge ############################## - -############################################################################################################## -def ResetPID(): - caput('29idd:tc1:SetPID_1.INPA','') - caput('29idd:tc1:SetPID_1.INPB','') - caput('29idd:tc1:SetPID_1.INPC','') - -def GetCurrentPID(): - T=caget('29idd:tc1:getVal_A.VAL') - P=caget('29idd:tc1:SetPID_1.A') - I=caget('29idd:tc1:SetPID_1.B') - D=caget('29idd:tc1:SetPID_1.C') - return T,P,I,D - -def SetTempSetting(T,P,I,D): - #Change the sample temperature T with the specified PID values - caput('29idd:tc1:getVal_A.VAL',T) - caput('29idd:tc1:SetPID_1.A',P) - caput('29idd:tc1:SetPID_1.B',I) - caput('29idd:tc1:SetPID_1.C',D) - -# GetCurrentPID => (60.0121, 8.0, 50.0, 12.0) ## Temperature overshoots no more than 5.5 degrees -#it takes about 3 min to stablize at any temp -#cooling is about 10 degrees/min - - -#functions use from ScanFunctions_IEX import BL_ioc def PVLakeshores(which): """ which = RSXS / ARPES /Hydra / DetPool @@ -351,98 +339,5 @@ def PVLakeshores(which): } return d[which] -def dateandtime(): - return strftime("%a %d %b %Y %H:%M:%S",localtime()) -def tempr(which=None): - """ - reads the temperature in the current branch unless otherwise specificed - """ - if which == None: - which=BL_ioc() - PVs=PVLakeshores(which) - sample=PVs[0]+PVs[1] - print(which+" Sample Temperature: {} K".format(caget(sample))) - -def temps(tempset,which=None): - """ - Set sthe sample temperature set point and waits for it to stablelize for the current branch - unless specified by which = Kappa / ARPES /Hydra set by PVLakeshores - """ - if which == None: - which=BL_ioc() - - P, Sample, ColdFinger, SetPoint = PVLakeshores(which) - - print("Initial Sample Temperature:",caget(P+Sample)," K",dateandtime()) - caput(P+SetPoint,1.0*tempset) - stop_var=0 - b=0 - sleep(0) - while b == 0: - delta=abs(caget(P+Sample)-1.0*tempset) - if abs(delta) < 1: - c=0 - while c < 10: - sleep(1) - delta=delta+(caget(P+Sample)-1.0*tempset) - c=c+1 - if abs(delta/10) < 1: - print("Stable Sample Temperature:",caget(P+Sample)," K",dateandtime()) - b=1 - else: - temp1=caget(P+Sample) - sleep(10) - temp2=caget(P+Sample) - if abs(temp1-temp2) < 0.1: - sleep(30) - temp2=caget(P+Sample) - if abs(temp1-temp2) < .5: - print("UNABLE TO STABLIZE TEMPERATURE! Stopped at T=:",caget(P+Sample)," K",dateandtime()) - b=1 - -def ARPES_warming(Tmax,PowerMax=50,Tdiff=10): - """ - Ramps the temperature up for ARPES using open loop and manual power at PowerMax with - the heater on High until Tmax - Tdif is reached and then switches to - closed loop with the heater on Medium - - PowerMax=50,Tdiff=10 - PowerMax=55,Tdiff=25 - """ - P="29idARPES:LS335:TC1:" - #Needs modified in controller changed - Tsample=P+"IN1" - Tcontrol=P+"IN2" - Tsetpoint=P+"OUT1:SP" - HeaterRange=P+"HTR1:Range" - ControlMode=P+"OUT1:Mode" - ManualPower=P+"OUT1:MOUT" - - caput(Tsetpoint,Tmax) - caput(ManualPower,PowerMax) - caput(ControlMode,"Open Loop") - caput(HeaterRange,'HIGH') - - print("T", caget(Tsample)) - print("Started warming:", dateandtime()) - - while True: - TA=caget(Tsample) - TB=caget(Tsample) - if TB >= Tmax: - print ("Control is to high",TB) - break - if TA < Tmax - Tdiff: - sleep(60) - else: - break - print("T", caget(Tsample)) - print("Switch to closed loop", dateandtime()) - - caput(HeaterRange,'MEDIUM');sleep(1) - caput(ControlMode,"Closed Loop");sleep(1) - caput(HeaterRange,'OFF');sleep(1) - caput(HeaterRange,'MEDIUM');sleep(1) - temps(Tmax,which='ARPES')