Beispiel #1
0
    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()
Beispiel #2
0
    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
Beispiel #3
0
    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')
Beispiel #4
0
    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$']}
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
    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
Beispiel #9
0
    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
Beispiel #10
0
    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
Beispiel #11
0
    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