def __init__(self, shot, Gas='D2', amend=False): """ Parameters ---------- shot : int shot number Gas : string type of gas used to establish mass and Z. Possibilities are 'D2' [default],'H','He' amend : boolean. Default is False. If True it does not create all the tree but only amend the computation of the positions and and of the RCP according to what saved in the general Tree """ self.shot = shot self.gas = 'D2' if Gas == 'D2': self.Z = 1 self.mu = 2 elif Gas == 'H': self.Z = 1 self.mu = 1 elif Gas == 'He': self.Z = 4 self.mu = 4 else: print('Gas not found, assuming Deuterium') self.gas = 'D2' self.Z = 1 self.mu = 2 self.TcvTree = mds.Tree('tcv_shot', self.shot) # load the equilibrium which will be used # to compute rho from rmid for the Lparallel self.Eq = eqtools.TCVLIUQETree(self.shot) self.amend = amend if not self.amend: # load the data for langmuir self._Target = langmuir.LP(self.shot, Type='floor') # load the data for the connection length self._loadConnection() # compute the Lambda self._computeLambda() # load the profiles from reciprocating self._loadUpstream() # load and compute the rho poloidal # and the R-Rsep as a function of time # at high temporal resolution self._computeRho() self._computeRRsep()
def __init__(self, shot, gas='D2', Lp='Div'): """ Parameters ---------- shot : Shot number gas : String indicating the gas. 'D2','H','He' Lp : String indicating if the parallel connection length should be considered from target to midplane 'Mid' or from target to X-point 'Div' """ self.shot = shot self.Lp = Lp # globally define the gas self.gas = gas if gas == 'D2': self.Z = 1 self.mu = 2 elif gas == 'H': self.Z = 1 self.mu = 1 elif gas == 'He': self.Z = 4 self.mu = 4 else: print('Gas not found, assuming Deuterium') self.gas = 'D2' self.Z = 1 self.mu = 2 # equilibrium quantities self._eq = eqtools.TCVLIUQETree(self.shot) # this is the iP in the time bases of LIUQE self._tLiuqe = self._eq.getTimeBase() self.BtSign = np.sign(self._eq.getBtVac().mean()) # now define the tree where the probe data are saved self._filament = mds.Tree('tcv_topic21', shot) # this is for different quantities self._tree = mds.Tree('tcv_shot', shot) # this can be done one single time and then accordingly # to analysis region we choose the appropriate timing try: self.Target = langmuir.LP(self.shot) except: print('Langmuir probe data not found') self.Target = None
def __init__(self, shot): self.shot = shot # the equilibrium self.eq = eqtools.TCVLIUQETree(self.shot) # now open the three and read the important results self.tree = mds.Tree('tcv_shot', self.shot) R = [ 0.624, 0.624, 0.666, 0.672, 0.965, 0.971, 1.136, 1.136, 0.971, 0.965, 0.672, 0.666, 0.624, 0.624, 0.624 ] Z = [ 0.697, 0.704, 0.75, 0.75, 0.75, 0.747, 0.55, -0.55, -0.747, -0.75, -0.75, -0.75, -0.704, -0.697, 0.697 ] try: # remember that we have all at LIUQE times pRadN = self.tree.getNode(r'\results::bolo:emissivity') self.time = pRadN.getDimensionAt(2).data() self.R = pRadN.getDimensionAt(0).data() self.Z = pRadN.getDimensionAt(1).data() self.pRad = pRadN.data() # now add the part on the equilibrium self.rxP = self.tree.getNode(r'\results::r_xpts').data() self.zxP = self.tree.getNode(r'\results::z_xpts').data() self.actX = self.tree.getNode( r'\results::indx_act_xp').data().astype('int') - 1 self.rmAx = self.tree.getNode(r'\results::r_axis').data() self.zmAx = self.tree.getNode(r'\results::z_axis').data() self.rLcfs = self.tree.getNode(r'\results::r_contour').data() self.zLcfs = self.tree.getNode(r'\results::z_contour').data() self.rLim = numpy.asarray(R) self.zLim = numpy.asarray(Z) self.tree.quit() # determine the grid of psiNormalize self.psiN = self.eq.rz2psinorm(self.R, self.Z, self.time, make_grid=True, each_t=True) except: print('Prad node not filled')
def __init__(self, shot, Type='floor'): """ Python class to read and compute appropriate profiles of LPs. It compute appropriately also divertor collisionality using the already stored parallel connection length (or computing if not found). It use the parallel connection length up to the position of the X-point according to the definition of Myra :param shot: Shot number :param Type: Type of probes used. Possible values are 'floor','HFSwall','LFSwall' """ self.shot = shot self.type = Type # open the appropriate Tree and get the available probes and # locations self._Tree = mds.Tree('tcv_shot', self.shot) # these are the probes number used in the present shot self.Probes = self._Tree.getNode(r'\results::langmuir:probes').data() # load the position of the langmuir probes self.pos = io.loadmat(r'/home/vianello/NoTivoli/work/tcv15.2.2.3/' + 'data/lp_codes/LPposit.mat')['lppos'] # we now have properly defined all the quantities needed self._defineProbe(type=self.type) # appropriate remapping upstream self.RemapUpstream() # load the equilibrium self.Eqm = eqtools.TCVLIUQETree(self.shot) # try to open the filament Tree otherwise we will # need to compute using Field Line Tracing try: self._filament = mds.Tree('tcv_topic21', self.shot) self._tagF = True except: self._tagF = False print('Filament Tree not found')
# routine to get values from a shot and plot them import MDSplus as mds import numpy as np import matplotlib.pyplot as plt from matplotlib import ticker import scipy.interpolate as interp import eqtools #shot=input('Shot number? ') shot=58823 t=mds.Tree('tcv_shot', shot) expdata={} expprof={} col=['k', 'r','b'] eq=eqtools.TCVLIUQETree(shot) ################ #THOMSON DATA ################ #ne ne_s = t.getNode(r'\tcv_shot::top.results.thomson.profiles.auto:ne') rho_thomson_s = t.getNode(r'\tcv_shot::top.results.thomson.profiles.auto:rho') #normalized poloidal flux rho_thomson = rho_thomson_s.data()**0.5 ne = ne_s.data() ne_t = ne_s.getDimensionAt(0).data() ne0 = ne[0,:] ne5 = ne[20,:] expdata[0] = {'nq':2, 'x':[ne_t, ne_t], \ 'y':[ne0*1e-20, ne5*1e-20], 'ylab':r'n$_e$ $10^{20}\,(m^{-3})$',\ 'lab':[r'$\rho_{POL}=0$', r'$\rho_{POL}=0.5$']}
def iSstatfromshot(shot, stroke=1, npoint=20, trange=None, remote=False): """ It compute the profile as a function of rho or radius of the statisical properties of ion saturation current, namely the auto-correlation the rms the flatness and the skewness by slicing the signal in the given number of point Parameters: ---------- shot: int Shot Number stroke: int. Default 1 Choose between the 1st or 2nd stroke remote: Boolean. Default False If set it connect to 'localhost:1600' supposing an ssh forwarding is taking place npoint: Number of point for the radial resolution Return: ---------- xarray DataArray with dimension rho and values the auto-correlation time. As attribute it saves also rms : rms of the signal skew: skewness flat: flatness Example: -------- >>> from tcv.diag.frp import FastRP >>> stat = FastRP.iSstatfromshot(51080, stroke=1) >>> matplotlib.pylab.plot(stat.rho, stat.values) """ # the the position in R R = FastRP._getpostime(shot, stroke=stroke, remote=remote) # the the iSat iS = FastRP.iSTimefromshot(shot, stroke=stroke, remote=remote) # if trange is None: trange = [R.time.min().item(), R.time.max().item()] # limit to the same timing iS = iS[((iS.time >= trange[0]) & (iS.time <= trange[1]))].values T = R[((R.time >= trange[0]) & (R.time <= trange[1]))].time.values R = R[((R.time >= trange[0]) & (R.time <= trange[1]))].values dt = (T.max()-T.min())/(T.size-1) # now we slice appropriately iSS = np.array_split(iS, npoint) tau = np.zeros(npoint) rms = np.asarray([k.std() for k in iSS]) Fl = np.asarray([stats.kurtosis(k, fisher=False) for k in iSS]) Sk = np.asarray([stats.skew(k) for k in iSS]) for i in range(np.size(iSS)): dummy = iSS[i] c = np.correlate(dummy, dummy, mode='full') # normalize c /= c.max() lag = np.arange(c.size)-c.size/2 # check if c.min > c/2 then is NaN if (c.min() >= 1./np.exp(1)): tau[i] = np.float('nan') else: tau[i] = 2*np.abs(lag[np.argmin(np.abs(c-1/np.exp(1)))])*dt # determine the position rO = np.asarray([np.nanmean(k) for k in np.array_split(R, npoint)]) tO = np.asarray([np.nanmean(k) for k in np.array_split(T, npoint)]) # convert in rho eq = eqtools.TCVLIUQETree(shot) rho = np.zeros(npoint) for r, t, i in zip(rO, tO, range(npoint)): rho[i] = eq.rz2psinorm(r, 0, t, sqrt=True) data = xray.DataArray(tau, coords=[('rho', rho)]) data.attrs['rms'] = rms data.attrs['Flat'] = Fl data.attrs['Skew'] = Sk return data
def _getpostime(shot, stroke=1, r=None, remote=False): """ Given the shot and the stroke it load the appropriate position of the probe. It save it as a xray data structure with coords ('time', 'r') Parameters: ---------- shot: int Shot Number stroke: int. Default 1 Choose between the 1st or 2nd stroke remote: Boolean. Default False If set it connect to 'localhost:1600' supposing an ssh forwarding is taking place r: Float This can be a floating or an ndarray or a list containing the relative radial distance with respect to the front tip. It is given in [m] with positive values meaning the tip is behind the front one Return: ---------- rProbe:xarray DataArray rProbe if given, the relative distance from the top tip. Remeber that it limits the time to the maximum position to the maximum available point in the psi grid Example: -------- >>> from tcv.diag.frp import FastRP >>> rProbe = FastRP._getpostime(51080, stroke=1, r=[0.001, 0.002]) >>> matplotlib.pylab.plot(vf.time, rho.values) """ # determine first of all the equilibrium eq = eqtools.TCVLIUQETree(shot) rMax = eq.getRGrid().max() if remote: Server = 'localhost:1600' else: Server = 'tcvdata.epfl.ch' # open the connection conn = tcv.shot(shot, server=Server) # now determine the radial location if stroke == 1: cPos = conn.tdi(r'\fpcalpos_1') else: cPos = conn.tdi(r'\fpcalpos_2') # limit our self to the region where equilibrium # is computed # to avoid the problem of None values if we are # considering also retracted position we distingish if r is None: add = 0 else: add = np.atleast_1d(r).max() # we need to find the minimum maximum time where # the probe is within the range of psiRZ trange = [cPos[(cPos/1e2 + add) < rMax].dim_0.values.min(), cPos[(cPos/1e2 + add) < rMax].dim_0.values.max()] rN = cPos[((cPos.dim_0 > trange[0]) & (cPos.dim_0 < trange[1]))].values/1e2 tN = cPos[((cPos.dim_0 > trange[0]) & (cPos.dim_0 < trange[1]))].dim_0.values # ok now distinguish between the different cases # if r is not None: rOut = np.vstack((rN, rN+r)) data = xray.DataArray(rOut, coords=[np.append(0, r), tN], dims=['r', 'time']) else: data = xray.DataArray(rN, coords=[('time', tN)]) conn.close return data
def Rrsepfromshot(shot, stroke=1, r=None, remote=False): """ It compute the R-Rsep array as a function of time for a given stroke. It save it as a xray data structure with coords ('time', 'r') Parameters: ---------- shot: int Shot Number stroke: int. Default 1 Choose between the 1st or 2nd stroke remote: Boolean. Default False If set it connect to 'localhost:1600' supposing an ssh forwarding is taking place r: Float This can be a floating or an ndarray or a list containing the relative radial distance with respect to the front tip (useful to determine the rho corresponding to back probes). It is given in [m] with positive values meaning the tip is behind the front one Return: ---------- Rrsep:xarray DataArray R-Rsep upstream remapped with dimension time Example: -------- >>> from tcv.diag.frp import FastRP >>> Rrsep = FastRP.Rrsepfromshot(51080, stroke=1, r=[0.001, 0.002]) """ # determine first of all the equilibrium eq = eqtools.TCVLIUQETree(shot) rN = FastRP._getpostime(shot, stroke=stroke, remote=remote, r=r) if r is not None: r = np.atleast_1d(r) rho = np.zeros((r.size+1, rN.shape[1])) for R, t, i in zip(rN.values[0, :], rN.time.values, range(rN.time.size)): rho[:, i] = eq.rz2rmid(np.append(R, R+r), np.repeat(0, r.size+1), t) - eq.getRmidOutSpline()(t) data = xray.DataArray(rho, coords=[np.append(0, r), rN.time.values], dims=['r', 'time']) else: rho = np.zeros(rN.size) for R, t, i in zip(rN.values, rN.time.values, range(rN.time.size)): try: rho[i] = eq.rz2rmid(R, 0, t) - \ eq.getRmidOutSpline()(t) except: rho[i] = np.nan data = xray.DataArray(rho, coords=[('time', rN.time.values)]) return data
def rhofromshot(shot, stroke=1, r=None, remote=False): """ It compute the rho poloidal for the given stroke. It save it as a xray data structure with coords ('time', 'r') Parameters: ---------- shot: int Shot Number stroke: int. Default 1 Choose between the 1st or 2nd stroke remote: Boolean. Default False If set it connect to 'localhost:1600' supposing an ssh forwarding is taking place r: Float This can be a floating or an ndarray or a list containing the relative radial distance with respect to the front tip (useful to determine the rho corresponding to back probes). It is given in [m] with positive values meaning the tip is behind the front one Return: ---------- rho:xarray DataArray Rho, (sqrt(normalized flux)) with dimension time and second dimension, if given, the relative distance from the top tip Example: -------- >>> from tcv.diag.frp import FastRP >>> rho = FastRP.rhofromshot(51080, stroke=1, r=[0.001, 0.002]) >>> matplotlib.pylab.plot(vf.time, rho.values) """ # determine first of all the equilibrium eq = eqtools.TCVLIUQETree(shot) rN = FastRP._getpostime(shot, stroke=stroke, remote=remote, r=r) if r is not None: r = np.atleast_1d(r) rho = np.zeros((r.size+1, rN.shape[1])) for R, t, i in zip(rN.values[0, :], rN.time.values, range(rN.time.size)): try: rho[:, i] = eq.rz2psinorm(np.append(R, R+r), np.repeat(0, r.size+1), t, sqrt=True) except: rho[:, i] = np.nan data = xray.DataArray(rho, coords=[np.append(0, r), rN.time.values], dims=['r', 'time']) else: rho = np.zeros(rN.size) for R, t, i in zip(rN.values, rN.time.values, range(rN.time.size)): try: rho[i] = eq.rz2psinorm(R, 0, t, sqrt=True) except: rho[i] = np.nan data = xray.DataArray(rho, coords=[('time', rN.time.values)]) return data
def VfRhofromshot(shot, stroke=1, npoint=20, trange=None, remote=False, alltime=False): """ Return the floating potential profile as a function of normalized poloidal flux for all the available probe array considering their position within the probe array. Parameters: ---------- shot: int Shot Number stroke: int. Default 1 Choose between the 1st or 2nd stroke npoint: int. Default 20 Number of point in space trange: 2D array or list eventually we can use a limited number of point (for example just entering the plasma). Default it uses all the stroke remote: Boolean. Default False If set it connect to 'localhost:1600' supposing an ssh forwarding is taking place alltime: Boolean. Default False if set to true it compute the rho for each point in time and then average. Otherwise rho is computed at reduced timing (downsampled to npoint in time) Return: ------- Dictionaro of xRay DataArray with coordinates the rho and as attributes the error, the absolute radial position and the R-Rsep position, upstream remapped Example: -------- >>> d = VfRhofromshot(51080, stroke=1, npoint=20) >>> matplotlib.pylab.plot(d['VFB_1'].rho, d['VFB_1'].values, 'o') """ # first of all collect the floating potential vf = FastRP.VfTimefromshot(shot, stroke=stroke, remote=remote) # read the probe name and create a dictionary with # probe associated to the radial position rDict = {} for p in vf.Probe.values: if p[2] == 'R': rDict[p] = 0.003 else: rDict[p] = 0. if alltime: rho = FastRP.rhofromshot(shot, stroke=stroke, remote=remote, r=0.003) # now for each of the probe we perform the # evaluation of the profile if trange is None: trange = [rho.time.min(), rho.time.max()] # now limit all the signals to the appropriate timing vf = vf[:, ((vf.time >= trange[0]) & (vf.time <= trange[1]))] rho = rho[:, ((rho.time >= trange[0]) & (rho.time <= trange[1]))] # now we can use the groupby and apply method # of xray dout = {} for n in vf.Probe.values: print 'Computing profile for ' + n y = vf.sel(Probe=n).values x = rho.sel(r=rDict[n]).values out = FastRP._getprofileR(x, y, npoint=npoint) dout[n] = out else: eq = eqtools.TCVLIUQETree(shot) R = FastRP._getpostime(shot, stroke=stroke, remote=remote, r=0.003) # now for each of the probe we perform the # evaluation of the profile if trange is None: trange = [R.time.min(), R.time.max()] # now limit all the signals to the appropriate timing vf = vf[:, ((vf.time >= trange[0]) & (vf.time <= trange[1]))] R = R[:, ((R.time >= trange[0]) & (R.time <= trange[1]))] dout = {} for n in vf.Probe.values: print 'Computing profile for ' + n y = vf.sel(Probe=n).values x = R.sel(r=rDict[n]).values t = R.time.values out = FastRP._getprofileT(x, y, t, npoint=npoint) rho = np.zeros(npoint) for x, t, i in zip(out.R.values, out.time, range(npoint)): rho[i] = eq.rz2psinorm(x, 0, t, sqrt=True) _id = np.argsort(rho) out2 = xray.DataArray(out.values[_id], coords=[('rho', rho[_id])]) out2.attrs['err'] = out.err[_id] out2.attrs['R'] = out.R.values[_id] dout[n] = out2 return dout
def iSRhofromshot(shot, stroke=1, npoint=20, trange=None, remote=False, alltime=False): """ Return the ion saturation current profile as a function of normalized poloidal flux save in an xray DataStructure Parameters: ---------- shot: int Shot Number stroke: int. Default 1 Choose between the 1st or 2nd stroke npoint: int. Default 20 Number of point in space trange: 2D array or list eventually we can use a limited number of point (for example just entering the plasma). Default it uses all the stroke remote: Boolean. Default False If set it connect to 'localhost:1600' supposing an ssh forwarding is taking place alltime: Boolean. Default False if set to true it compute the rho for each point in time and then average. Otherwise rho is computed at reduced timing (downsampled to npoint in time) Return: ------- xRay DataArray with coordinates the rho and as attributes the error, the absolute radial position and the R-Rsep position, upstream remapped. As attributes we also save the UnivariateSpline object for the profile along the 3 saved x (rho, R, R-Rsep Upstream Remapped) Example: -------- >>> data = iSRhofromshot(51080, stroke=1, npoint=20) >>> matplotlib.pylab.plot(data.rho, data.values, 'o') >>> matplotlib.pylab.errorbar(data.rho, data.values, yerr=data.err, fmt='none') """ # get the appropriate iSat iSat = FastRP.iSTimefromshot(shot, stroke=stroke, remote=remote) if alltime: # get the appropriate rho rho = FastRP.rhofromshot(shot, stroke=stroke, remote=remote) # get the appropriate R-Rsep rresp = FastRP.Rrsepfromshot(shot, stroke=stroke, remote=remote) # now we need to limit to the tMin and tMax # this is true both in case it is given or # in the case we have rho if trange is None: trange = [rho.time.min(), rho.time.max()] iN = iSat.where(((iSat.time >= rho.time.min()) & (iSat.time <= rho.time.max()))).values iN = iN[~np.isnan(iN)] rN = rho.values else: print 'limiting in time' trange = np.atleast_1d(trange) rN = rho.where(((rho.time >= trange[0]) & (rho.time <= trange[1]))).values rN = rN[~np.isnan(rN)] iN = iSat.where(((iSat.time >= trange[0]) & (iSat.time <= trange[1]))).values iN = iN[~np.isnan(iN)] # now sort along rN and average corrispondingly iN = iN[np.argsort(rN)] rN = rN[np.argsort(rN)] iSliced = np.array_split(iN, npoint) rSliced = np.array_split(rN, npoint) iOut = np.asarray([np.nanmean(k) for k in iSliced]) iErr = np.asarray([np.nanstd(k) for k in iSliced]) rOut = np.asarray([np.nanmean(k) for k in rSliced]) data = xray.DataArray(iOut, coords=[('rho', rOut)]) data.attrs['err'] = iErr data.attrs['units'] = 'A' # save into the data also the object for spline interpolation data.attrs['spline'] = UnivariateSpline(rOut, iOut, w=1./iErr, ext=0) else: print 'downsampling in time' R = FastRP._getpostime(shot, stroke=stroke, remote=remote) if trange is None: trange = [R.time.min(), R.time.max()] iN = iSat.where(((iSat.time >= R.time.min()) & (iSat.time <= R.time.max()))).values iN = iN[~np.isnan(iN)] rN = R.values tN = R.time.values else: print 'limiting in time' trange = np.atleast_1d(trange) tN = R.time[((R.time >= trange[0]) & (R.time <= trange[1]))].values rN = R.where(((R.time >= trange[0]) & (R.time <= trange[1]))).values rN = rN[~np.isnan(rN)] iN = iSat.where(((iSat.time >= trange[0]) & (iSat.time <= trange[1]))).values iN = iN[~np.isnan(iN)] # slice also the timing out = FastRP._getprofileT(rN, iN, tN, npoint=npoint) # now convert into appropriate equilibrium rho = np.zeros(npoint) rrsep = np.zeros(npoint) eq = eqtools.TCVLIUQETree(shot) for x, t, i in zip(out.R.values, out.time, range(npoint)): rho[i] = eq.rz2psinorm(x, 0, t, sqrt=True) rrsep[i] = eq.rz2rmid(x, 0, t) - eq.getRmidOutSpline()(t) _id = np.argsort(rho) data = xray.DataArray(out.values[_id], coords=[('rho', rho[_id])]) data.attrs['err'] = out.err[_id] data.attrs['R'] = out.R.values[_id] data.attrs['Rrsep'] = rrsep[_id] data.attrs['Rsp'] = UnivariateSpline(data.attrs['R'], data.values, w=1./data.err, ext=0) data.attrs['Rhosp'] = UnivariateSpline(data.rho.values, data.values, w=1./data.err, ext=0) data.attrs['RrsepSp'] = UnivariateSpline(data.attrs['Rrsep'], data.values, w=1./data.err, ext=0) return data
libDir+'Codes/python/general/cyFieldlineTracer/') sys.path.append( libDir+'/Codes/python/general/pyEquilibrium/') from cyfieldlineTracer import get_fieldline_tracer import equilibrium # build an array of position and corresponding # r-rsep at 1s Rarray = np.linspace(1.1, 1.14, num=15) if platform.system() == 'Darwin': rmid = np.asarray([0.00330571, 0.00614673, 0.00899073, 0.01183706, 0.01468492, 0.01753404, 0.02038422, 0.02323521, 0.0260868 , 0.02893873, 0.03179075, 0.03464259, 0.037494 , 0.0403447 , 0.0431944]) else: Eq = eqtools.TCVLIUQETree(57418) rmid = Eq.rz2rmid(Rarray, np.repeat(0, Rarray.size), 1)-Eq.getRmidOutSpline()(1) Tracer = get_fieldline_tracer( 'RK4', machine='TCV', shot=57418, time=1, remote=True, interp='quintic', rev_bt=True) # now build a list of field lines as a # To trace a field line, call the trace method my_fieldlines = [Tracer.trace(r,0.0,mxstep=1000000,ds=1e-2,tor_lim=20.0*np.pi) for r in Rarray] # Here the first two arguments are the R and Z starting points # mxstep is the maximum number of steps to take # ds is the distance between each step along the field line import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D