#!/usr/bin/python2
# -*- coding: utf-8 -*-
""" CREATED: 7/2012
AUTHOR: MICHAL ODSTRČIL
"""
from numpy import *
from pygolem_lite.config import *
from pygolem_lite.modules import *
from pygolem_lite.utilities import *
from pygolem_lite import *
from matplotlib.pyplot import *
from scipy.optimize import leastsq
import time, datetime, re
from scipy.sparse import spdiags, eye
from scipy.sparse.linalg import spsolve, splu
from scipy.signal import medfilt, fftconvolve, convolve
from scipy.stats.mstats import mquantiles
print "------------basicdiagn --------"
CdFieldTrigger = loadconst("Tcd_aktual") * 1e-6 + TororoidalMagneticFieldTrigger # [s]
BdFieldTrigger = loadconst('Tbd_aktual') * 1e-6 + TororoidalMagneticFieldTrigger # [s]
StFieldTrigger = loadconst('Tst_aktual') * 1e-6 + TororoidalMagneticFieldTrigger # [s]
saveconst('Tb', TororoidalMagneticFieldTrigger) # save in SI units
saveconst('Tbd', BdFieldTrigger) # save in SI units
saveconst('Tcd', CdFieldTrigger) # save in SI units
saveconst('Tst', StFieldTrigger) # save in SI units
BVoltage = loadconst('Ub_limit') # [V]
CdVoltage = loadconst('Ucd_limit') # [V]
BdVoltage = loadconst('Ubd_limit') # [V]
StVoltage = loadconst('Ust_limit') # [V]
if BdVoltage < 10:
BdFieldTrigger = nan
if CdVoltage == 0:
CdFieldTrigger = nan
if StFieldTrigger < 10:
StFieldTrigger = nan
print "CdFieldTrigger", CdFieldTrigger, "BdFieldTrigger", BdFieldTrigger, "StFieldTrigger", StFieldTrigger
print "BVoltage", BVoltage, "CdVoltage", CdVoltage, 'BdVoltage', BdVoltage, "StVoltage", StVoltage
try:
# get time vector
S = Shot()
tvec, tmp = S['any', 'btor']
shot = S.shot_num
### data damaged by triggers !!!! do not change !!!
ind_wrong = zeros(len(tvec), dtype = bool)
###ind_wrong |= abs( CdFieldTrigger - tvec) < 1e-4 # [s]
ind_wrong |= abs(TororoidalMagneticFieldTrigger - tvec + 0.5e-4 ) < 5e-4 # [s]
ind_wrong |= abs(BdFieldTrigger - tvec + 0.5e-4) < 0.5e-4 # [s]
ind_wrong |= abs(StFieldTrigger - tvec + 0.5e-4) < 0.5e-4 # [s]
dt = mean(diff(tvec)) # time step
except Exception, e:
print "Basicdiagn failure: ", e
params = []
for i in str(S['wwwcomment']).split("="):
try:
if re.match( "\d+.*", i):
i = re.sub( "(\ *[\d\,\.]+).*", r"\1", i)
i = re.sub(",", ".", i)
params.append( float(i) )
print "parametr", float(i) , "loaded"
except Exception, e:
print "Error in loading data from comment", str(e)
for i in range(len(params)):
saveconst('param_'+str(i+1), params[i]) # save in SI units
print "===================params", params
def save_config():
names = [
'ToroidalMagneticFieldCoilInductance',
'TororoidalMagneticFieldCapacitor',
'BreakDownElectricFieldCapacitor',
'CurrentDriveElectricFieldCapacitor',
'StabilizationCapacitor',
'Zeff'
]
for i in names:
exec('saveconst("'+i+'", '+i+')')
def getDate():
s = cat( "date")
#nicely formated date
shot_date = datetime.date( 2000 + int(s[4:6]), int(s[2:4]), int(s[:2]) )
s = cat( "starttime")
shot_time = datetime.time( int(s[0:2]), int(s[2:4]), int(s[4:6]) )
save('shot_date', shot_date)
save('shot_time', shot_time)
def reverse_if_changed(signal, orientation_file, normal_orientation):
orientation = cat(orientation_file)
reverse = (orientation != normal_orientation)
signal = -signal if reverse else signal
return reverse, signal
def getBtoroidal():
tvec, dBt = S['any', 'btor'] # mag field derivative
#mBt = mean(dBt)
min_time = max(nanmin([TororoidalMagneticFieldTrigger, BdFieldTrigger, CdFieldTrigger, StFieldTrigger])-1e-4 , 2e-3)
mBt = mean(dBt[tvec < min_time] )
sBt = std(dBt[tvec < min_time] )
dBt -= mBt # remove bias
Bt = cumsum(dBt) * dt * Bt_calibration # integrate
ReversedB, Bt = reverse_if_changed(Bt, '../../../Bt_orientation', 'ACW')
saveconst("ReversedB", ReversedB)
BtMax = amax(Bt) # max
BtMean = mean(Bt) # mean
saveconst('BtMax', BtMax, fmt="%.3f" )
#saveconst('BtMean', BtMean)
save_adv('Btoroidal', tvec, Bt)
save_adv('dBdt_toroidal', tvec, dBt)
saveconst('noise_level', sBt)
return Bt, dBt, BtMax, BtMean
def getUloop():
tvec, Uloop = S['any', 'uloop']
#m_Uloop = mean(Uloop)
Uloop *= UloopCalibration
ind_zero = (tvec < TororoidalMagneticFieldTrigger + 1e-4)
Uloop[ind_zero] = 0 # remove noise from tyristors
ReversedCD, Uloop = reverse_if_changed(Uloop, '../../../CD_orientation', 'CW')
saveconst("ReversedCD", ReversedCD)
#ind_wrong = abs(TororoidalMagneticFieldTrigger-tvec) < 1e-4 # [s]
#Uloop[ind_wrong] = median(Uloop[ind_wrong] ) #remove noise from toroidal field trigger
#Uloop[ind_wrong] = 0 # medfilt(Uloop, 51)[ind_wrong] # remove signal damaged by tyristors
#plot(Uloop)
#show()
#ind_bias = [(tvec > TororoidalMagneticFieldTrigger) & ( tvec < nanmin([CdFieldTrigger, StFieldTrigger])) | (abs(tvec - TororoidalMagneticFieldTrigger) < 1e-4 ) ]
#Uloop_bias = median(Uloop[ind_bias])
#Uloop -= Uloop_bias
#plot(tvec, Uloop)
#plot(tvec[ind_bias], Uloop[ind_bias])
#show()
#Uloop = medfilt(Uloop, 5) # odstranit ?? nicim ten osklivy sum v datech !!!
Uloop[ind_zero] = 0 # remove noise from tyristors
UloopMax = mquantiles(Uloop,0.99)[0]
#UloopMean = sum(cumsum(abs(Uloop))) / len(Uloop) ** 2 # used for detection of
UloopMean = mean(abs(Uloop))
#exit()
saveconst('UloopMax', UloopMax, fmt="%.3f" )
save_adv('Uloop', tvec, Uloop)
return Uloop, UloopMax, UloopMean, ReversedCD
def getIrogowski(ReversedCD):
tvec, dIrog = S['any', 'irog']
#dIrog[abs(tvec - TororoidalMagneticFieldTrigger) < 1e-4 ] = 0 # cut off triggers
if ReversedCD:
dIrog *= -1
Ibias = mean(dIrog[tvec < max(nanmin([TororoidalMagneticFieldTrigger, BdFieldTrigger, CdFieldTrigger, StFieldTrigger])-1e-4 , 2e-3)] )
dIrog[ind_wrong & (tvec < nanmin([CdFieldTrigger, 40e-3])) ]=0
dIrog -= Ibias
Irog = cumsum(dIrog) * dt
Irog *= RogowskiCalibration
#Irog[tvec < nanmin([CdFieldTrigger, BdFieldTrigger])] = 0 # remove noise
#plot(tvec, dIrog/amax(dIrog))
#plot(tvec, convolve(medfilt(dIrog, 51),ones(200)/200, mode='same')/amax(dIrog))
#plot(tvec, convolve(Irog,ones(200)/200 , mode='same'))
#show()
try:
# try to detect cd trigger from data
ker = ones(200)/200
I_start = tvec[where( (fftconvolve(dIrog, ker, mode='same')> 0.05) | (fftconvolve(Irog,ker, mode='same') > 5) )[0][0]]
except:
I_start = nan # no I start
print "I_start", I_start
Irog[tvec < I_start - 1e-4] = 0
dIdt_rogMax = mquantiles(abs(diff(Irog)),0.98)[0] # maximum
IrogMax = mquantiles(abs(Irog),0.98)[0]
saveconst('dIdt_rogMax', dIdt_rogMax, fmt="%.3f" )
saveconst('IrogowskiMax', IrogMax, fmt="%.3f" )
save_adv('Irogowski', tvec, Irog)
save_adv('dIdt_rogowski', tvec, dIrog)
#plot(medfilt(dIrog,51))
#plot(convolve(dIrog,ones(200)/200, mode='full'))
#show()
#exit()
return Irog, dIdt_rogMax, IrogMax, I_start
def getIplasma(Uloop,Irog,I_start, PlasmaStart = None, PlasmaEnd = None ):
#plot(Uloop)
#plot(Irog)
#show()
#exit()
#print Uloop
t0 = time.time()
x0 = array([ 1.2 , ChamberResistance])
time_lag = 1.5e-3 # [ms] expected time before breakdown
if PlasmaStart is not None:
ind = (tvec > I_start) & (tvec < min(PlasmaStart - 1e-4, I_start + time_lag) )
else:
ind = (tvec > I_start) & (tvec < I_start + time_lag)
def fit(param, result = False):
Ich = zeros(len(tvec))
search_range = ( range(ind[0], ind[-1]) if not result else range(1, len(tvec)) )
#search_range = range(1, len(tvec))
for i in search_range: # implicite differencial equation I_n = ( U_n + C1/dt *I_(n-1) ) / (C2 + C1/dt)
Ich[i]=(Uloop[i]+param[0]*Ich[i-1])/(param[1]+param[0]);
if result:
return Ich
return (Irog - Ich)[ind]
conv = 0
x = nan
#time_lag = 1.5e-3 # [ms] expected time before breakdown
#while time_lag > 0.5e-3:
#if PlasmaStart is not None:
#ind = (tvec > I_start) & (tvec < min(PlasmaStart - 1e-4, I_start + time_lag) )
#else:
#ind = (tvec > I_start) & (tvec < I_start + time_lag)
#if all(~ind) and ~isnan(CdFieldTrigger): # no intersect
#ind = (tvec > CdFieldTrigger) & (tvec < CdFieldTrigger + time_lag)
#if all(~ind) and ~isnan(BdFieldTrigger): # no intersect
#ind = (tvec > BdFieldTrigger) & (tvec < BdFieldTrigger + time_lag)
#if all(~ind):
#print "!! Something wrong with triggers !!!", CdFieldTrigger, BdFieldTrigger
#ind = tvec < time_lag
#ind = where(ind)[0][::max(1, sum(ind)/100)] # take maximaly 100 points
#print "fitting from t=", tvec[ind[0]], " to t=", tvec[ind[-1]]
##print CdFieldTrigger + 0.1e-3, BdFieldTrigger + 0.1e-3, BdFieldTrigger + time_lag
##plot(tvec, Irog)
##plot(tvec[ind], Irog[ind])
###plot(Uloop)
##show()
##exit()
##all(ind == False)
#def fit(param, result = False):
#Ich = zeros(len(tvec))
#search_range = ( range(ind[0], ind[-1]) if not result else range(1, len(tvec)) )
##search_range = range(1, len(tvec))
#for i in search_range: # implicite differencial equation I_n = ( U_n + C1/dt *I_(n-1) ) / (C2 + C1/dt)
#Ich[i]=(Uloop[i]+param[0]*Ich[i-1])/(param[1]+param[0]);
#if result:
#return Ich
#return (Irog - Ich)[ind]
#x0 = array([ChamberInduktance/dt , ChamberResistance])
#x0 = array([ 1.2 , ChamberResistance])
#try:
##xxx
#x, conv = leastsq(fit, x0 , xtol=1e-3)
#print "fitting done", x, x0
#except:
#print "Fitting failed"
#conv = 0; x = [nan, nan]
#if conv == 0 or (abs(x[0]-x0[0])/x0[0] + abs(x[1]-x0[1])/x0[1] > 5 ): # failed convergence
#print "far from expected value"
#time_lag *= 0.8 # try shorter time
#else:
#time_lag = 0
#if conv == 0 or (abs(x[0]-x0[0])/x0[0] + abs(x[1]-x0[1])/x0[1] > 8 ): # failed convergence
#print "failed convergence in chamber properties solver", x0, x
#x = x0 # if everything fails ...
x = x0
Ich = fit(x, result = True)
#print Ich
saveconst('ChamberInduktance', x[0]*dt)
saveconst('ChamberResistance', x[1])
#print 'Time of fitting %g' % (time.time() - t0)
Ipl = Irog - Ich
#print Irog
#print Ipl
#plot(tvec,Uloop/amax(Uloop))
#plot(tvec,Irog/amax(Irog))
#show()
#plot(Irog)
#plot(Ich)
#plot(Ipl)
#show()
##exit()
# make a deconvolution of the Ip signal, because due to copper shielding and slow response of the rogowski coil, the signal is convoluted with exponential function,
t_exp = 0.7e-4 #roughly estimated influence of the chamber, crosschecked with signal from mirnov coils
win = 60
regularization = 1e-2
Ipl,retrofit = deconvolveExp(Ipl,t_exp,dt,win,regularization)
if PlasmaStart is not None: # second round ..
Ipl1 = median(Ipl[abs(tvec-PlasmaEnd - 1e-3) < 1e-4])
Ipl0 = median(Ipl[abs(tvec-PlasmaStart+5e-4) < 1e-4])
a = (Ipl1 - Ipl0) / (PlasmaEnd - PlasmaStart) # slope of drift
b = Ipl0 - a*PlasmaStart
#Ipl[tvec > PlasmaStart] -= a*tvec[tvec > PlasmaStart] + b
Ipl -= a*tvec + b
print " correction of drift after plasma "
ind = tvec > PlasmaEnd
dIpl = r_[0,diff(Ipl)]
print median(dIpl[ind])
dIpl -= median(dIpl[ind])
Ipl[ind]= cumsum(dIpl[ind])
Ipl[tvec < max(nanmin([TororoidalMagneticFieldTrigger, BdFieldTrigger, CdFieldTrigger, StFieldTrigger])-1e-4 , 2e-3)] = 0
plasma_current_decay = amax(diff(fftconvolve(-Ipl, ones(100)/100, mode='same'))) / dt
save_adv('Iplasma', tvec, Ipl)
save_adv('Ich', tvec, Ich)
saveconst('plasma_current_decay', plasma_current_decay)
return Ipl, Ich
def getPhotod(PlasmaStart,PlasmaEnd, channel, name):
tvec, Photod = S['any', channel]
bias = median(Photod[tvec < nanmin([CdFieldTrigger, BdFieldTrigger, StFieldTrigger]) -1e-4 ]) # remove noise from tyristors
Photod -= bias # constant light in room ...
Photod = medfilt(Photod, 3) # remove fast outliers
## remove light from room (50Hz)
PlasmaEnd += 1e-3
Photod *= sign(mean(Photod[ (tvec>PlasmaStart) & (tvec<PlasmaEnd) ])) # invert signal
try:
ind = (tvec<PlasmaStart)|(tvec>PlasmaEnd)
power_suply = ones((len(tvec), 3))
power_suply[:,1] = cos(2*pi*tvec*100)
power_suply[:,2] = sin(2*pi*tvec*100)
proj = linalg.lstsq(power_suply[ind,:],Photod[ind])[0]
corr = dot(proj.T,power_suply.T ).T
Photod -=corr
except Exception, e :
print "getPhotod: power sockets subtraction failed " , str(e)
if shot > 10527 and shot < 12897 or shot> 13105 : # only fot the new photocells
t = time.time()
if name == "Photod":
Photod,_ = deconvolveExp( Photod,1e-4,dt,300,3)
elif name == "PhotodHalpha":
Photod,_ = deconvolveExp( Photod,0.6e-3,dt,600,3)
Photod *= 1.4
print " dekonvoluce =================", time.time() - t
save_adv(name, tvec, Photod)
getMeanPhotod(Photod, PlasmaStart, PlasmaEnd, name)
return Photod
def PlasmaDetect(Iplasma, dIdt_rogMax, Uloop):
N_steps = len(Iplasma)
Iplasma = Iplasma.copy()
Iplasma[tvec < TororoidalMagneticFieldTrigger + 1e-4] = 0 # no plasma before mag. field
downsample = max(len(Iplasma)/1000, 1)
d = medfilt(Iplasma[::downsample], int((3e-4/dt/downsample)/2)*2+1)
d = medfilt( diff(d)/dt/downsample, int((3e-4/dt/downsample)/2)*2+1)
d = convolve( d, ones(20)/20, mode="same" ) # smooth the signal
################
min_dI = 5e4 # sensitivity of plasma detection
####################
d_start = d.copy() # prevent false plasma start detect
d_start[d_start < 0] = 0
try:
# prevent to be plasma false alarm started by triggers !!!
PlasmaStart = tvec[::downsample][where( (d_start > max(0.2*amax(d) , min_dI) ) & ~ ind_wrong[downsample::downsample] )[0][0]]
PlasmaEnd = tvec[::downsample][where( d < min(0.2*amin(d), -min_dI) )[0][-1] ]
PlasmaStart += 0.25e-3 # a fix that is removing efect of detection function "d" smoothing
PlasmaEnd -= 0.25e-3
except:
PlasmaStart = nan
PlasmaEnd = nan
Plasma = int(~ isnan(PlasmaStart) and ~ isnan(PlasmaEnd)) and (PlasmaStart < PlasmaEnd)
if not Plasma:
PlasmaStart = nan
PlasmaEnd = nan
#if Plasma and mean(Uloop[argmin(abs(tvec - PlasmaStart)):argmin(abs(tvec - PlasmaEnd))]) < 0: # negative uloop in plasma
#Plasma = False; PlasmaStart = nan; PlasmaEnd = nan
PlasmaTimeLength = PlasmaEnd - PlasmaStart
saveconst("PlasmaStartAdvanced", PlasmaStart - 0.1e-3 , fmt="%.5f" )
saveconst("PlasmaStart", PlasmaStart, fmt="%.5f" )
saveconst("PlasmaEnd", PlasmaEnd, fmt="%.5f" )
saveconst("PlasmaEndDelayed", PlasmaEnd * 1.1, fmt="%.5f" )
saveconst("Plasma", Plasma )
saveconst("PlasmaTimeLength", PlasmaTimeLength, fmt="%.5f" )
save_adv("PlasmaDetect", tvec[::downsample], d/amax(abs(d))*dIdt_rogMax )
return Plasma, PlasmaStart, PlasmaEnd, PlasmaTimeLength
def getMeanBt(Btor,PlasmaStart, PlasmaEnd ):
MeanBt = mean(Btor[(tvec > PlasmaStart) & (tvec < PlasmaEnd)])
saveconst('BtMean', MeanBt, fmt="%.3f" )
saveconst('ReversedBt', int(MeanBt > 0))
return MeanBt
def getMeanPhotod(Photod, PlasmaStart, PlasmaEnd, name):
MeanPhotod = median(Photod[(tvec > PlasmaStart) & (tvec < PlasmaEnd)])
saveconst(name + "Mean", MeanPhotod)
return MeanPhotod
def getTotalCharge(Ipla, PlasmaStart,PlasmaEnd ):
TotalCharge = (Ipla + abs(Ipla)) / 2 * dt
TotalCharge = cumsum(TotalCharge[(tvec > PlasmaStart) & (tvec < PlasmaEnd)])
TotalCharge = mean(TotalCharge)
saveconst('TotalCharge', TotalCharge, fmt="%.3f" )
return TotalCharge
def getMeanCurrent(Ipla, PlasmaStart,PlasmaEnd ):
MeanIpla = median(Ipla[(tvec > PlasmaStart) & (tvec < PlasmaEnd)])
saveconst("IplaMean", MeanIpla, fmt="%.1f" )
return MeanIpla
def getMeanUloop(Uloop, PlasmaStart,PlasmaEnd ):
MeanUloop = median(Uloop[(tvec > PlasmaStart) & (tvec < PlasmaEnd)])
saveconst("UloopMean", MeanUloop, fmt="%.2f" )
return MeanUloop
def getOhmicHeatingPower(MeanUloop,MeanPlasmaCurrent):
OhmicHeatingPower = abs(MeanUloop*MeanPlasmaCurrent)
saveconst("OhmicHeatingPowerMean", OhmicHeatingPower, fmt="%.2f" )
return OhmicHeatingPower
def getQedge(MeanBt,MeanPlasmaCurrent):
Qedge = 2*pi*MeanPlasmaRadius**2 / (Mu0 * MajorRadius ) *abs(MeanBt/MeanPlasmaCurrent)
saveconst("QedgeMean", Qedge, fmt="%.1f" )
return Qedge
def getMeanElectronTemperature(MeanUloop, MeanPlasmaCurrent):
#ElectronTemperature = (MajorRadius/MeanPlasmaRadius**2 * 8 * Zeff / 1.54e3)**(2./3) * (abs( MeanPlasmaCurrent / MeanUloop )) ** (2./3) #Ref: PhD Brotankova eq. 3.21 p. 26
ElectronTemperature = (MajorRadius/MeanPlasmaRadius**2 * 8 * Zeff*(1-sqrt(Aspect))**2 / 1.54e3)**(2./3) *abs(MeanPlasmaCurrent/(MeanUloop+1e-3))**(2./3)
saveconst("ElectronTemperatureMean", ElectronTemperature, fmt="%.1f" )
return ElectronTemperature
def getElectronTemperature(Uloop, Iplasma, PlasmaStart, PlasmaEnd):
#corrected for impurities and neoclasical effects.
ind = (tvec > PlasmaStart) & (tvec < PlasmaEnd)
ElectronTempTime = (MajorRadius/MeanPlasmaRadius**2 * 8 * Zeff*(1-sqrt(Aspect))**2 / 1.54e3)**(2./3) *abs(Iplasma/(abs(Uloop)+1e-3))**(2./3)
ElectronTempTime[~ind | (ElectronTempTime > 100 ) ] = nan
ker = sum(ind)/1000
medElectronTemp = medfilt(ElectronTempTime, 2*(ker)+1)
ind = ~isnan(medElectronTemp)
medElectronTemp[ind] = fftconvolve(medElectronTemp[ind], ones(ker)/ker, mode="same")
maxT = mquantiles(medElectronTemp[(tvec > PlasmaStart) & (tvec < PlasmaEnd)],0.99)[0]
save_adv("ElectronTemp", tvec, medElectronTemp)
#save_adv("ElectronMed", tvec, medElectronTemp)
saveconst("ElectronTempMax", maxT, fmt="%.1f" )
return ElectronTempTime, medElectronTemp, maxT
def getBreakDownVoltage(Uloop, Btor, Ipla, PlasmaStart, PlasmaEnd):
dt = (PlasmaStart + PlasmaEnd)/50
ind = (tvec > PlasmaStart-dt) & (tvec < PlasmaStart + dt)
#print PlasmaStart, PlasmaEnd
#plot(Uloop)
#show()
#try:
#t0 = time.time()
#plot(medfilt(Uloop[ind], 21), '.-')
#savefig('breakdown.png')
#clf()
#print "time breakdown " , t0 - time.time()
# kompromis mezi rychlostí a stabilitou
break_ind = where(ind)[0][argmax(medfilt(Uloop[ind], 21))]
#break_ind = argmin( abs(tvec - PlasmaStart ) )
Umax = Uloop[break_ind]
Btime = tvec[break_ind]
Bbreak = Btor[break_ind]
Bipla = Btor[break_ind]
saveconst("BreakDownVoltage", Umax, fmt="%.1f" )
saveconst("BreakDownTime", Btime)
saveconst("BreakDownBt", Bbreak)
saveconst("BreakDownIp", Bipla)
return Umax, Btime, Bbreak, Bipla
def getStateEqElectronDensity(Aktual_PfeifferMerkaVakua):
StateEqElectronDensity = (Aktual_PfeifferMerkaVakua/1000)/(kB * RoomTemperature)
saveconst("StateEqElectronDensity", StateEqElectronDensity)
return StateEqElectronDensity
def getElectronConfinementTimeFirstApprox(MeanUloop,MeanPlasmaCurrent, StateEqElectronDensity, ElectronTemperature ):
ElectronConfinementTimeFirstApprox = 3./8* PlasmaVolume * (ElectronTemperature* eV * StateEqElectronDensity) / abs( MeanPlasmaCurrent * MeanUloop) #Ref: PhD Brotankova
saveconst("ElectronConfinementTimeFirstApprox", ElectronConfinementTimeFirstApprox)
return ElectronConfinementTimeFirstApprox
def getChamberResistance(Plasma):
if Plasma:
Ibd = loadconst("BreakDownIp")
Ubd = loadconst("BreakDownVoltage")
else:
Ubd = loadconst("UloopMax")
Ibd = loadconst("IrogowskiMax")
ChamberResistance = abs( Ubd / Ibd )
saveconst("ChamberResistance_old", ChamberResistance)
return ChamberResistance
def Failures(Plasma, UloopMax, dIdt_rogMax, MeanUloop, BtMax, MeanBt, PlasmaStart, PlasmaEnd ):
PlasmaStatus = ""
if abs(UloopMax) < 1:
PlasmaStatus += "Failure (UloopMax < 1V);"
if abs(MeanUloop) < 3 and Plasma:
PlasmaStatus += "Too low Uloop (MeanUloop < 3V);"
if abs(dIdt_rogMax) < 0.01 :
PlasmaStatus += "Failure (dIdt_rogMax < 0.01V);"
if abs(MeanUloop) < 0.3 :
PlasmaStatus += "Failure (MeanUloop) < 0.3V);"
if abs(BtMax) < 0.01 :
PlasmaStatus += "Failure (BtMax) < 0.01T);"
if abs(MeanBt) < 0.01 :
PlasmaStatus += "Failure (MeanBt) < 0.01T);"
if PlasmaStatus == "":
PlasmaStatus = "OK"
print "PlasmaStatus: ", PlasmaStatus
saveconst("PlasmaStatus", PlasmaStatus)
if PlasmaStatus != "OK":
saveconst("PlasmaStartAdvanced", nan , fmt="%.5f" )
saveconst("PlasmaStart", nan, fmt="%.5f" )
saveconst("PlasmaEnd", nan, fmt="%.5f" )
saveconst("PlasmaEndDelayed", nan , fmt="%.5f" )
saveconst("PlasmaTimeLength", nan , fmt="%.5f" )
saveconst("Plasma", 0 )
return PlasmaStatus
def getGreenwaldDensity(Ipla):
N_gw = (1e-6*Ipla)/(pi*MeanPlasmaRadius**2)*1e20 #[m^-3]
save_adv("GreenwaldDensity", tvec, N_gw)
return N_gw
def getOhmicHeatingPowerTime(Ipla, Ich, Uloop):
Power = Ipla * Uloop
PowerCh = Ich * Uloop
save_adv("OhmicHeatingPower", tvec, Power)
save_adv("OhmicHeatingChamber", tvec, PowerCh)
return Power, PowerCh
def getQedgeTime(Btor,Ipla, PlasmaStart,PlasmaEnd ):
QedgeTime = 2*pi*MeanPlasmaRadius**2 / (Mu0 * MajorRadius ) *abs(Btor/(Ipla+1e-3))
QedgeTime[(tvec < PlasmaStart) | (tvec > PlasmaEnd)] = nan
QedgeTime[QedgeTime > 2* nanmedian(QedgeTime)] = nan
save_adv("Qedge",tvec, QedgeTime)
return QedgeTime
def getMagneticFlux(Uloop):
Flux = cumsum(Uloop+abs(Uloop))/2*dt
save_adv("TotalMagneticFlux", tvec, Flux)
return Flux
def getTransformatorSaturation(Uloop, Plasma, PlasmaEnd):
if Plasma == 1:
S = cumsum(Uloop[tvec < PlasmaEnd]) * dt / MaxTransformatorSaturation
else:
S = cumsum(Uloop) * dt / MaxTransformatorSaturation
S = amax(S) # maximal saturation
saveconst('TransformatorSaturation', S)
return S
def EnergyBalance(Ipla, Irog, Uloop, PlasmaStart,PlasmaEnd):
l_i = log(1.65+0.89*nu)
L_i = l_i*Mu0*MajorRadius/(4*pi)
L_e = MajorRadius*Mu0*(log(8*MajorRadius/MeanPlasmaRadius)-2) # wikipedia
L = L_i + L_e
W_e = L_e*Irog**2/2
W_i = L_i*Ipla**2/2
W_mag = W_i+W_e
win = 1000
lam= 1e0
P_mag, retrofit, chi2 = DiffFilter(W_i+W_e, dt,win, lam)
P_mag = squeeze(P_mag)
P_total = Uloop*Irog
P_input = Uloop*Ipla
L_correction = 5 #effective inductance is very different from calculated value, due to coupling with curent drive RLC circuit
sigma_plasma = abs(Ipla/(abs(Uloop)+0.1))
sigma_chamber = 1/9.2e-3 #FIXME conductivity of chamber
P_mag = -P_mag*L_correction
P_plasma = -P_input-P_mag*sigma_plasma/(sigma_plasma+sigma_chamber)
P_chamber = -(P_total-P_input)-P_mag*sigma_chamber/(sigma_plasma+sigma_chamber)
save_adv("PowerTotal", tvec, P_total)
save_adv("PowerMagnetic", tvec, P_mag)
save_adv("PowerPlasma", tvec, P_plasma)
save_adv("PowerChamber", tvec, P_chamber)
saveconst('MeanPowerPlasma', - mean( P_plasma[( tvec > PlasmaStart ) & ( tvec < PlasmaEnd)] ))
return P_total, P_mag, P_plasma, P_chamber
def BreakdownProba():
from pygolem_lite.breakdown import predict
if S['shotno'] > 15170 and S['working_gas'] == "H":
pressure = S['pressure'] / 2.4
else:
pressure = S['pressure']
bd_proba = predict(Ub=S['ub'], Ucd=S['ucd'], pressure=S['pressure'], Tcd=S['tcd'], gas_filling=S['gas_filling'], preionization=S['preionization'] > 0 )
if S['shotno'] > 15170 and S['working_gas'] != "H":
bd_proba = nan
saveconst('breakdown_probability', bd_proba)
def getBreakDownRate(Ipla, Ich, PlasmaStart, PlasmaEnd, trange = 0.4e-3):
ind = (tvec > PlasmaStart - trange/2) & (tvec < PlasmaStart + trange/2) # 200us time window
#ind = where(ind)[::max(1, sum(ind)/100)]
#print ind
down = max(1, sum(ind)/50)
#print "================ down ", down
tvec_tmp = (tvec - PlasmaStart)[ind][::down]
ipla_tmp = smooth(Ipla[ind], down/2.)[::down]
def fit(param, result = False):
ipla_exp = param[0]*exp( 1e3 * tvec_tmp / abs(param[1]) ) + param[2]
if not result:
return (ipla_tmp - ipla_exp)
else:
return ipla_exp
x0 = array([ 50 , 1, 0]) # initial guess
convergence = True
res = leastsq(fit, x0 , xtol=1e-5, full_output=1)
(param, pcov, infodict, errmsg, ier) = res
if ier not in [1,2,3,4]:
print "fitting failed"
convergence = False
print "fitting breakdown done", param, x0
s_sq = sum(fit(param)**2)/(len(ipla_tmp)-len(x0))
pcov = pcov * s_sq
#print pcov
rate = abs(param[1])*1e-3
err = sqrt(pcov[1,1])*1e-3
ind_ext = (tvec > PlasmaStart - 0.4e-3) & (tvec < PlasmaStart + 0.6e-3)
plot(tvec[ind_ext]-PlasmaStart, Ipla[ind_ext])
plot(tvec_tmp, ipla_tmp)
plot(tvec_tmp, fit(param, True))
#plot(tvec_tmp, fit(x0, True), ':')
title('Exp. Rate const= %g+-%g, window=%g' % (rate, err, trange) )
ylabel('I [A]')
xlabel('Time from breakdown [s]')
savefig('rate.png')
savetxt('data', hstack([tvec_tmp[:,None], ipla_tmp[:,None]]), fmt="%g")
if not convergence or rate > 0.01:
print "convergence failed", convergence, rate
rate = nan; err = nan
saveconst('breakdown_rate', rate)
saveconst('breakdown_rate_err', err )
return rate, err