def ip(shot, plt=False): """ Load the plasma current Parameters ---------- shot : shot number plt : Boolean (default is False). If True it plots the current time traces Returns ------- xray Data set with the current time traces Examples ------- >>> from tcv.diag import General >>> ip = General.ip(50882, plt=True) """ data = tcv.shot(shot).tdi('tcv_ip()') tcv.shot(shot).close() if plt: fig = mpl.pylab.figure(figsize=(6, 5)) ax = fig.add_subplot(111) if data.values.shape[0] > 1: ax.plot(data[data.dims[0]].values, data.values / 1e3) else: ax.plot(data[data.dims[0]].values, data.values[0, :] / 1e3) ax.set_title(r'Shot # ' + str(shot)) ax.set_xlabel(r't [s]') ax.set_ylabel(r'I$_p$ [kA]') data = data.rename({'dim_0': 'time'}) return data
def bphi(shot, plt=False): """ Load the Toroidal field Parameters ---------- shot : shot number plt : Boolean (default is False). If True it plots the current time traces Returns ------- xray Data set with the toroidal field time traces Examples ------- >>> from tcv.diag import General >>> bphi = General.bphi(50882,plt=True) """ data = tcv.shot(shot).tdi('tcv_bphi()') tcv.shot(shot).close() data.values *= -1 if plt: fig = mpl.pylab.figure(figsize=(6, 5)) ax = fig.add_subplot(111) if data.values.shape[0] > 1: ax.plot(data[data.dims[0]].values, data.values) else: ax.plot(data[data.dims[0]].values, data.values[0, :]) ax.set_title(r'Shot # ' + str(shot)) ax.set_xlabel(r't [s]') ax.set_ylabel(r'B$_{\phi}$ [T]') data = data.rename({'dim_0':'time'}) return data
def neline(shot, plt=False): """ Load the Line Integrated Density Parameters ---------- shot : shot number plt : Boolean (default is False). If True it plots the current time traces Returns ------- xray Data set with the Line Integrated Density field time traces Examples ------- >>> from tcv.diag import General >>> neLine = General.neLine(50882,plt=True) """ data = tcv.shot(shot).tdi(r'\results::fir:lin_int_dens') tcv.shot(shot).close() if plt: fig = mpl.pylab.figure(figsize=(6, 5)) ax = fig.add_subplot(111) if data.values.shape[0] > 1: ax.plot(data[data.dims[0]].values, data.values / 1e19) else: ax.plot(data[data.dims[0]].values, data.values[0, :] / 1e19) ax.set_title(r'Shot # ' + str(shot)) ax.set_xlabel(r't [s]') ax.set_ylabel(r'n$_{e}$ Line Integrated [10$^{19}$ fringes]') data = data.rename({'dim_0':'time'}) return data
def __init__(self, indict, **kwargs): NMLST.__init__(self, indict) self.rep_dict = {'$NANTECH':1,'$XECECH':[0.],'$ZECECH':[0.0],\ '$FREQECH':[0.], '$PHAIECH':[0.], '$THETECH':[0.], \ '$RFMODECH':[0.], '$EFFECH':[0.], '$NRAYECH':[0.],\ '$BSRATECH':[0.], '$BHALFECH':[0.], '$NDAMPECH':[0.]} self._TCV_ECparam() self.template_fname = '/home/vallar/matlab_TRANSP/namelist_EC_template.DAT' self.std_fname = self.path + str(self.shot) + str(self.run) + 'TR.DAT' self.out_fname = self.std_fname + '_EC' sig_ec = read_sig.DWR(indict) sig_ec._read_ecrh() self.ind_gyro = sig_ec.ind_Gyro self.jsgn, self.bsgn = sig_ec._readJB() self.jb = self.jsgn * self.bsgn self.rep_dict['$NANTECH'] = len[self.ind_gyro] self.rep_dict['$FREQECH'] = self.frequency[self.ind_gyro] self.rep_dict['$RFMODECH'] = self.omode[self.ind_gyro] self.rep_dict['$EFFECH'] = np.full(len(self.ind_gyro), 1.0, dtype=float) self.rep_dict['$NRAYECH'] = self.raysbylauncher[self.ind_gyro] self.rep_dict['$BHALFECH'] = np.full(len(self.ind_gyro), 6.0, dtype=float) self.rep_dict['$NDAMPECH'] = self.ndampech[self.ind_gyro] self.conn = tcv.shot(indict['shot']) self._read_EC_geom()
def _getNodeName(shot, remote=False): """ Class method to obtain the name of the node in the desidered shot number. Parameters: ---------- shot: int Shot Number remote: Boolean. Default False If set it connect to 'localhost:1600' supposing an ssh forwarding is taking place Return: ---------- nodeName = String array String containing the name of the signal saved into the node. """ if remote: Server = 'localhost:1600' else: Server = 'tcvdata.epfl.ch' conn = tcv.shot(shot, server=Server) _string = 'getnci(getnci(\\TOP.DIAGZ.MEASUREMENTS.UCSDFP,'\ '"MEMBER_NIDS")'\ ',"NODE_NAME")' nodeName = conn.tdi(_string) nodeName = np.core.defchararray.strip(nodeName.values) # close the connection conn.close return nodeName
def zpos(shotnum): """ Routine to check which Z position are the LoS for the current shot """ with tcv.shot(shotnum) as conn: Zant = str(conn.tdi(r'\results::ece_lfs:z_antenna').values) if Zant[: 5] == 'Error': pb5 = str(conn.tdi(r'\vsystem::tcv_publicdb_b["ILOT_NO:B5"]') .values) pb6 = str(conn.tdi(r'\vsystem::tcv_publicdb_b["ILOT_NO:B6"]') .values) if pb5[:3] == 'OFF' and pb6[:3] == 'OFF': Zant = 0.21 # already transformed in floating log.info('LoS at 21 cm') elif pb5[: 3] == 'OFF' and pb6[: 3] == 'ON ': Zant = 10 log.info('3rd LoS was used') elif pb5[: 3] == 'ON ' and pb6[: 3] == 'OFF': Zant = 0. log.info('LoS at 0 cm') elif pb5[: 3] == 'ON ' and pb6[: 3] == 'ON ': Zant = np.nan log.info('The LFS ECE radiometer was disconnected') else: Zant = np.float(Zant[: 2]) * 1e-2 log.info('LoS at %4.1f cm', Zant * 100) return Zant
def ip(shot, plt=False): """ Load the plasma current Parameters ---------- shot : shot number plt : Boolean (default is False). If True it plots the current time traces Returns ------- xray Data set with the current time traces Examples ------- >>> from tcv.diag import General >>> ip = General.ip(50882, plt=True) """ data = tcv.shot(shot).tdi('tcv_ip()') if plt: fig = mpl.pylab.figure(figsize=(6, 5)) ax = fig.add_subplot(111) if data.values.shape[0] > 1: ax.plot(data[data.dims[0]].values, data.values / 1e3) else: ax.plot(data[data.dims[0]].values, data.values[0, :] / 1e3) ax.set_title(r'Shot # ' + str(shot)) ax.set_xlabel(r't [s]') ax.set_ylabel(r'I$_p$ [kA]') return data
def zpos(shotnum): """ Routine to check which Z position are the LoS for the current shot """ with tcv.shot(shotnum) as conn: Zant = str(conn.tdi(r'\results::ece_lfs:z_antenna').values) if Zant[:5] == 'Error': pb5 = str( conn.tdi(r'\vsystem::tcv_publicdb_b["ILOT_NO:B5"]').values) pb6 = str( conn.tdi(r'\vsystem::tcv_publicdb_b["ILOT_NO:B6"]').values) if pb5[:3] == 'OFF' and pb6[:3] == 'OFF': Zant = 0.21 # already transformed in floating log.info('LoS at 21 cm') elif pb5[:3] == 'OFF' and pb6[:3] == 'ON ': Zant = 10 log.info('3rd LoS was used') elif pb5[:3] == 'ON ' and pb6[:3] == 'OFF': Zant = 0. log.info('LoS at 0 cm') elif pb5[:3] == 'ON ' and pb6[:3] == 'ON ': Zant = np.nan log.info('The LFS ECE radiometer was disconnected') else: Zant = np.float(Zant[:2]) * 1e-2 log.info('LoS at %4.1f cm', Zant * 100) return Zant
def neline(shot, plt=False): """ Load the Line Integrated Density Parameters ---------- shot : shot number plt : Boolean (default is False). If True it plots the current time traces Returns ------- xray Data set with the Line Integrated Density field time traces Examples ------- >>> from tcv.diag import General >>> neLine = General.neLine(50882,plt=True) """ data = tcv.shot(shot).tdi(r'\results::fir:lin_int_dens') if plt: fig = mpl.pylab.figure(figsize=(6, 5)) ax = fig.add_subplot(111) if data.values.shape[0] > 1: ax.plot(data[data.dims[0]].values, data.values / 1e19) else: ax.plot(data[data.dims[0]].values, data.values[0, :] / 1e19) ax.set_title(r'Shot # ' + str(shot)) ax.set_xlabel(r't [s]') ax.set_ylabel(r'n$_{e}$ Line Integrated [10$^{19}$ fringes]') return data
def channels(shot, camera, los=None): """ Provide the names of the channel chosen in the init action Parameters ---------- shot : int or MDSConnection Shot number or connection instance camera : int Number of the XTOMO camera los : int or sequence of ints Optional argument with lines of sight (LoS) of the chosen camera. If None, it loads all the 20 channels Returns ------- Array of strings with the channel names """ if los is None: los = np.arange(20) + 1 else: los = np.atleast_1d(los) with tcv.shot(shot) as conn: names = conn.tdi(r'\base::xtomo:array_{:03}:source'.format(camera)) return names[los - 1].values
def bphi(shot, plt=False): """ Load the Toroidal field Parameters ---------- shot : shot number plt : Boolean (default is False). If True it plots the current time traces Returns ------- xray Data set with the toroidal field time traces Examples ------- >>> from tcv.diag import General >>> bphi = General.bphi(50882,plt=True) """ data = tcv.shot(shot).tdi('tcv_bphi()') data.values *= -1 if plt: fig = mpl.pylab.figure(figsize=(6, 5)) ax = fig.add_subplot(111) if data.values.shape[0] > 1: ax.plot(data[data.dims[0]].values, data.values) else: ax.plot(data[data.dims[0]].values, data.values[0, :]) ax.set_title(r'Shot # ' + str(shot)) ax.set_xlabel(r't [s]') ax.set_ylabel(r'B$_{\phi}$ [T]') return data
def tedf(shot, plt=False, edge=False, q95=True): """ Load Central temperature from Double Filter technique Parameters ---------- shot : shot number plt : Boolean (default is False). If True it plots the current time traces Returns ------- xray Data set with the central temperature. Remember that there are 6 values (for different foil couples) It is generally convenient to use first one Examples ------- >>> from tcv.diag import General >>> tedf = General.tedf(50882, plt=True) """ try: data = tcv.shot(shot).tdi(r'\results::te_x_a') if plt: fig = mpl.pylab.figure(figsize=(6, 5)) ax = fig.add_subplot(111) if data.values.shape[0] > 1: ax.plot(data[data.dims[0]].values, data.values / 1e3) else: ax.plot(data[data.dims[0]].values, data.values[0, :] / 1e3) ax.set_title(r'Shot # ' + str(shot)) ax.set_xlabel(r't [s]') ax.set_ylabel(r'T_e [keV]') return data except: print 'No data stored for Xte for this shot'
def iSTimefromshot(shot, stroke=1, remote=False): """ Return the ion saturation current from shot with the proper time base 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 Return: ---------- iSat: xarray Dataarray Return the collected ion saturation current including its time and area Example: -------- >>> from tcv.diag.frp import FastRP >>> iSat = FastRP.iSTimefromshot(51080, stroke=1) >>> matplotlib.pylab.plot(iSat.time, iSat.values) """ # assume we are blind and found the name appropriately _name = FastRP._getNodeName(shot, remote=remote) _nameS = np.asarray([n[:-3] for n in _name]) # these are all the names of the ion saturation current # signal _IsName = _name[np.where(_nameS == 'IS')] if remote: Server = 'localhost:1600' else: Server = 'tcvdata.epfl.ch' conn = tcv.shot(shot, server=Server) if stroke == 1: iSat = conn.tdi(r'\FP'+_IsName[0]) print 'Retrieveing data for stroke 1' else: iSat = conn.tdi(r'\FP'+_IsName[1]) print 'Retrieveing data for stroke 2' # eventually combine the two # rename with time as dimension iSat = iSat.rename({'dim_0': 'time'}) # add in the attributes also the area iSat['area'] = conn.tdi(r'\AM4').values # detrend the costant in the first part of the # stroke iSat -= iSat.where(iSat.time < iSat.time.min() + 0.01).mean(dim='time') # close the connection # unfortunately we need the delta t is not # constant. We redefine the time basis _dTime = np.arange(iSat.size, dtype='double')*4.e-7 + \ iSat.time.min().item() iSat.time.values = _dTime conn.close return iSat
def delta(shot, plt=False, edge=False, q95=True): """ Load Triangularity (at 95% of the poloidal flux [default] or at the edge) Parameters ---------- shot : shot number plt : Boolean (default is False). If True it plots the current time traces edge : Boolean (default is False). If True it loads value at the edge Returns ------- xray Data set with the triangularity computed as default at 95% of poloidal Flux. If edge is se to True it load the edge value Examples ------- >>> from tcv.diag import General >>> delta95 = General.delta(50882, plt=True) >>> deltaEdge = General.delta(50882, plt=True, edge=True) """ if edge: q95 = False Str = r'\results::delta_edge' axlabel = r'$\delta_{edge}$' elif q95: Str = r'\results::delta_95' axlabel = r'$\delta_{95}$' data = tcv.shot(shot).tdi(Str) tcv.shot(shot).close() if plt: fig = mpl.pylab.figure(figsize=(6, 5)) ax = fig.add_subplot(111) if data.values.shape[0] > 1: ax.plot(data[data.dims[0]].values, data.values) else: ax.plot(data[data.dims[0]].values, data.values[0, :]) ax.set_title(r'Shot # ' + str(shot)) ax.set_xlabel(r't [s]') ax.set_ylabel(axlabel) data = data.rename({'dim_0':'time'}) return data
def q(shot, plt=False, edge=False): """ Load q (q95 or qedge) time trace Parameters ---------- shot : shot number plt : Boolean (default is False). If True it plots the current time traces edge: Boolean (default is False). If it is True it loads the qedge rather than the q95 Returns ------- xray Data set with the q computed as default at 95% of poloidal Flux. If edge is se to True it load the edge value Examples ------- >>> from tcv.diag import General >>> q95 = General.q(50882,plt=True) >>> qedge = General.q(50882,plt=True,edge=True) """ if edge: Str = r'\results::q_edge' axlabel = r'q$_{edge}$' else: Str = r'\results::q_95' axlabel = r'q$_{95}$' data = tcv.shot(shot).tdi(Str) tcv.shot(shot).close() if plt: fig = mpl.pylab.figure(figsize=(6, 5)) ax = fig.add_subplot(111) if data.values.shape[0] > 1: ax.plot(data[data.dims[0]].values, data.values) else: ax.plot(data[data.dims[0]].values, data.values[0, :]) ax.set_title(r'Shot # ' + str(shot)) ax.set_xlabel(r't [s]') ax.set_ylabel(axlabel) data = data.rename({'dim_0':'time'}) return data
def VfTimefromshot(shot, stroke=1, remote=False): """ Return the value of Floating potential as multi dimensional array. It is build in order to retain the name of the probe in the array in the coordinates 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 Return: ---------- vf: xarray Dataarray Return the floating potential from all the available probes. The data array has in coords the name of the signals Example: -------- >>> from tcv.diag.frp import FastRP >>> vf = FastRP.VfTimefromshot(51080, stroke=1) >>> matplotlib.pylab.plot(vf.time, vf.sel(Probe='VFT_1')) """ _name = FastRP._getNodeName(shot, remote=remote) # first of all choose only those pertaining to the chosen stroke _nameS = np.asarray([n[-1] for n in _name]) _name = _name[_nameS == str(stroke)] # now choose thich collect only vf _nameS = np.asarray([n[:2] for n in _name]) _nameVf = _name[_nameS == 'VF'] if remote: Server = 'localhost:1600' else: Server = 'tcvdata.epfl.ch' values = [] names = [] with tcv.shot(shot, server=Server) as conn: for s in _nameVf: values.append(conn.tdi(r'\fp'+s, dims='time')) names.append(s) data = xray.concat(values, dim='Probe') data['Probe'] = names # detrend initial part data -= data.where(data.time < data.time.min()+0.01).mean(dim='time') # build the timing in double precision conn.close return data
def fromshot(shot, camera, los=None): """ Return the calibrated signal of the XtomoCamera LoS chosen. Parameters ---------- shot : int or MDSConnection Shot number or connection instance camera : int Number of the XTOMO camera los : int or sequence of ints Optional argument with lines of sight (LoS) of the chosen camera. If None, it loads all the 20 channels Returns ------- Calibrated signals XTOMO signals. Examples -------- >>> import tcv >>> cam = tcv.diag.XtomoCamera.fromshot(50766, camera=1, los=[4, 5]) """ if los is None: los = np.arange(20) + 1 else: los = np.atleast_1d(los) values = [] Channels = XtomoCamera.channels(shot, camera, los=los) with tcv.shot(shot) as conn: for channel in Channels: values.append(conn.tdi(channel, dims='time')) data = xray.concat(values, dim='los') data['los'] = los # Remove the offset before the shot data -= data.where(data.time < 0).mean(dim='time') # and now we normalize conveniently # FIXME: use xray's infrastructure to compute this gain, amp = XtomoCamera.gains(shot, camera, los=los) data *= np.transpose( np.tile(gain, (data.values.shape[1], 1)) / np.tile(amp, (data.values.shape[1], 1))) data.attrs.update({'camera': camera}) return data
def tedf(shot, plt=False, edge=False, q95=True): """ Load Central temperature from Double Filter technique Parameters ---------- shot : shot number plt : Boolean (default is False). If True it plots the current time traces Returns ------- xray Data set with the central temperature. Remember that there are 6 values (for different foil couples) It is generally convenient to use first one Examples ------- >>> from tcv.diag import General >>> tedf = General.tedf(50882, plt=True) """ try: data = tcv.shot(shot).tdi(r'\results::te_x_a') tcv.shot(shot).close() if plt: fig = mpl.pylab.figure(figsize=(6, 5)) ax = fig.add_subplot(111) if data.values.shape[0] > 1: ax.plot(data[data.dims[0]].values, data.values / 1e3) else: ax.plot(data[data.dims[0]].values, data.values[0, :] / 1e3) ax.set_title(r'Shot # ' + str(shot)) ax.set_xlabel(r't [s]') ax.set_ylabel(r'T_e [keV]') data = data.rename({'dim_0':'time'}) return data except: print 'No data stored for Xte for this shot'
def fromshot(shot, camera, los=None): """ Return the calibrated signal of the XtomoCamera LoS chosen. Parameters ---------- shot : int or MDSConnection Shot number or connection instance camera : int Number of the XTOMO camera los : int or sequence of ints Optional argument with lines of sight (LoS) of the chosen camera. If None, it loads all the 20 channels Returns ------- Calibrated signals XTOMO signals. Examples -------- >>> import tcv >>> cam = tcv.diag.XtomoCamera.fromshot(50766, camera=1, los=[4, 5]) """ if los is None: los = np.arange(20) + 1 else: los = np.atleast_1d(los) values = [] with tcv.shot(shot) as conn: for channel in XtomoCamera.channels(shot, camera, los=los): values.append(conn.tdi(channel, dims='time')) data = xray.concat(values, dim='los') data['los'] = los # Remove the offset before the shot data -= data.where(data.time < 0).mean(dim='time') # and now we normalize conveniently # FIXME: use xray's infrastructure to compute this gain, amp = XtomoCamera.gains(shot, camera, los=los) data *= np.transpose(np.tile(gain, (data.values.shape[1], 1)) / np.tile(amp, (data.values.shape[1], 1))) data.attrs.update({'camera': camera}) return data
def fromshot(shotnum, los=None): """ Read the ECE LFS data from the specified shot """ with tcv.shot(shotnum) as conn: try: frequency = conn.tdi(r'\results::ece_lfs:rf_freqs') except: # FIXME: catch more specific exception frequency = Lfs.DEFAULT_FREQUENCIES type(frequency) if los: # remember that we use the los as index for channels los = np.atleast_1d(los) - 1 else: los = np.arange(frequency.size) values = [] used_los = [] with tcv.shot(shotnum) as conn: for i, channel in enumerate(Lfs.channels(conn.shot)): if i in los: values.append(conn.tdi(channel, dims='time')) used_los.append(i + 1) data = xray.concat(values, dim='los') data.coords['los'] = used_los # TODO: add frequency coordinate # Normalize to mean value mean = data.where(data.time < 0).mean(dim='time') data = (data - mean) / mean # Fill-in data attributes with tcv.shot(shotnum) as conn: data.attrs['z_antenna'] = Lfs.zpos(conn) return data
def fromshot(shotnum, los=None): """ Read the ECE LFS data from the specified shot """ with tcv.shot(shotnum) as conn: try: frequency = conn.tdi(r'\results::ece_lfs:rf_freqs') except: # FIXME: catch more specific exception frequency = Lfs.DEFAULT_FREQUENCIES type(frequency) if los: # remember that we use the los as index for channels los = np.atleast_1d(los)-1 else: los = np.arange(frequency.size) values = [] used_los = [] with tcv.shot(shotnum) as conn: for i, channel in enumerate(Lfs.channels(conn.shot)): if i in los: values.append(conn.tdi(channel, dims='time')) used_los.append(i+1) data = xray.concat(values, dim='los') data.coords['los'] = used_los # TODO: add frequency coordinate # Normalize to mean value mean = data.where(data.time < 0).mean(dim='time') data = (data - mean) / mean # Fill-in data attributes with tcv.shot(shotnum) as conn: data.attrs['z_antenna'] = Lfs.zpos(conn) return data
def _is_fast(shot, card, channel): """ We check if fast nodes are collected for shot below 34988 and eventually load fast data. """ if shot > 34988: log.info('Loading fast data after big opening') return False with tcv.shot(shot) as conn: try: conn.tdi('{}selected:channel_{:03}'.format(card, channel)) log.info('Loading high frequency for old shot') return True except: log.info('Loading low frequency for old shot') return False
def __init__(self, indict, **kwargs): NMLST.__init__(self, indict) self.rep_dict = {'$FBM_outtim': np.array([0]),'$NBPTCLS':80000,'$ZELEV_D':0.,\ '$EINJ_DBEAM':0., '$FFULL_DBEAM':0., '$FHALF_DBEAM':0., \ '$EINJ_HBEAM':0., '$FFULL_HBEAM':0., '$FHALF_HBEAM':0.} for key in kwargs: if key == 'FBM_outtim': self.rep_dict['$' + key] = np.array(kwargs[key]) else: self.rep_dict['$' + key] = kwargs[key] self.template_fname = '/home/vallar/matlab_TRANSP/namelist_NBI_template.DAT' self.std_fname = self.path + str(self.shot) + str(self.run) + 'TR.DAT' self.out_fname = self.std_fname + '_NBI' self.conn = tcv.shot(indict['shot']) self._fill_dict()
def fromshot(cls, shotnum, time): with tcv.shot(shotnum) as conn: psi = conn.tdi(r'\results::psi[*,*,$1]', time, dims=['r', 'z']) psi_axis = conn.tdi(r'\results::psi_axis[$1]', time) r0 = float(conn.tdi(r'\results::r_axis[$1]', time)) z0 = float(conn.tdi(r'\results::z_axis[$1]', time)) data = { 'r': psi.r, 'z': psi.z, 'psi': (psi / psi_axis).values, 'r0': r0, 'z0': z0, 'time': time, 'shot': psi.shot } return cls(data)
def delta(shot, plt=False, edge=False, q95=True): """ Load Triangularity (at 95% of the poloidal flux [default] or at the edge) Parameters ---------- shot : shot number plt : Boolean (default is False). If True it plots the current time traces edge : Boolean (default is False). If True it loads value at the edge Returns ------- xray Data set with the triangularity computed as default at 95% of poloidal Flux. If edge is se to True it load the edge value Examples ------- >>> from tcv.diag import General >>> delta95 = General.delta(50882, plt=True) >>> deltaEdge = General.delta(50882, plt=True, edge=True) """ if edge: q95 = False Str = r'\results::delta_edge' axlabel = r'$\delta_{edge}$' elif q95: Str = r'\results::delta_95' axlabel = r'$\delta_{95}$' data = tcv.shot(shot).tdi(Str) if plt: fig = mpl.pylab.figure(figsize=(6, 5)) ax = fig.add_subplot(111) if data.values.shape[0] > 1: ax.plot(data[data.dims[0]].values, data.values) else: ax.plot(data[data.dims[0]].values, data.values[0, :]) ax.set_title(r'Shot # ' + str(shot)) ax.set_xlabel(r't [s]') ax.set_ylabel(axlabel) return data
def q(shot, plt=False, edge=False): """ Load q (q95 or qedge) time trace Parameters ---------- shot : shot number plt : Boolean (default is False). If True it plots the current time traces edge: Boolean (default is False). If it is True it loads the qedge rather than the q95 Returns ------- xray Data set with the q computed as default at 95% of poloidal Flux. If edge is se to True it load the edge value Examples ------- >>> from tcv.diag import General >>> q95 = General.q(50882,plt=True) >>> qedge = General.q(50882,plt=True,edge=True) """ if edge: Str = r'\results::q_edge' axlabel = r'q$_{edge}$' else: Str = r'\results::q_95' axlabel = r'q$_{95}$' data = tcv.shot(shot).tdi(Str) if plt: fig = mpl.pylab.figure(figsize=(6, 5)) ax = fig.add_subplot(111) if data.values.shape[0] > 1: ax.plot(data[data.dims[0]].values, data.values) else: ax.plot(data[data.dims[0]].values, data.values[0, :]) ax.set_title(r'Shot # ' + str(shot)) ax.set_xlabel(r't [s]') ax.set_ylabel(axlabel) return data
def from_tree(cls, shotnum): """ Read the vessel's parameters from the static MDS nodes """ vessel = {} with tcv.shot(shotnum) as conn: for key, query in cls._vessel_nodes().items(): vessel[key] = conn.tdi(query).values tiles = {} tiles['R'] = np.array([ 1.1360, 1.1360, 1.1120, 1.0880, 1.0640, 1.0399, 1.0159, 0.9919, 0.9679, 0.6707, 0.6240, 0.6240, 0.6240, 0.6724, 0.9679, 1.1360, 1.1360 ]) tiles['Z'] = np.array([ 0, 0.5494, 0.5781, 0.6067, 0.6354, 0.6640, 0.6927, 0.7213, 0.7500, 0.7500, 0.7033, 0, -0.7033, -0.7500, -0.7500, -0.5494, 0.0000 ]) return cls({'vessel': vessel, 'tiles': tiles})
def from_tree(cls, shotnum): """ Read the vessel's parameters from the static MDS nodes """ vessel = {} with tcv.shot(shotnum) as conn: for key, query in cls._vessel_nodes().iteritems(): vessel[key] = conn.tdi(query).values tiles = {} tiles['R'] = np.array([ 1.1360, 1.1360, 1.1120, 1.0880, 1.0640, 1.0399, 1.0159, 0.9919, 0.9679, 0.6707, 0.6240, 0.6240, 0.6240, 0.6724, 0.9679, 1.1360, 1.1360 ]) tiles['Z'] = np.array([ 0, 0.5494, 0.5781, 0.6067, 0.6354, 0.6640, 0.6927, 0.7213, 0.7500, 0.7500, 0.7033, 0, -0.7033, -0.7500, -0.7500, -0.5494, 0.0000 ]) return cls({'vessel': vessel, 'tiles': tiles})
def _check_dtaq_trigger(shot): with tcv.shot(shot) as conn: if shot < 24087 or shot > 24725: dtNe1 = r'\atlas::dt100_northeast_001:' dtNe2 = r'\atlas::dt100_northeast_002:' else: dtNe1 = r'\atlas::dt100_southwest_001:' dtNe2 = r'\atlas::dt100_southwest_002:' mode1 = conn.tdi(dtNe1 + 'MODE').values mode2 = conn.tdi(dtNe2 + 'MODE').values mode3 = 4 mode = mode1 * mode2 * mode3 if conn.shot >= 24087 and mode != 64: log.warn('Random temporal gap (5 to 25 us) between the two or ' 'three MPX acquisition cards.') log.warn( 'Random temporal gap (0.1 to 0.2ms) between DTACQ and ' 'TCV.') raise Warning('DTACQ not in mode 4')
def _check_dtaq_trigger(shot): with tcv.shot(shot) as conn: if shot < 24087 or shot > 24725: dtNe1 = r'\atlas::dt100_northeast_001:' dtNe2 = r'\atlas::dt100_northeast_002:' else: dtNe1 = r'\atlas::dt100_southwest_001:' dtNe2 = r'\atlas::dt100_southwest_002:' mode1 = conn.tdi(dtNe1 + 'MODE').values mode2 = conn.tdi(dtNe2 + 'MODE').values mode3 = 4 mode = mode1 * mode2 * mode3 if conn.shot >= 24087 and mode != 64: log.warn( 'Random temporal gap (5 to 25 us) between the two or ' 'three MPX acquisition cards.') log.warn( 'Random temporal gap (0.1 to 0.2ms) between DTACQ and ' 'TCV.') raise Warning('DTACQ not in mode 4')
def fromshot(shot, los=None): """ Return the calibrated DMPX signals. Parameters ---------- shot : int or MDSConnection Shot number or connection instance camera : int Number of the XTOMO camera los : int or sequence of ints Optional argument with lines of sight (LoS) of the chosen camera. If None, it loads all the 20 channels Returns ------- An xray.DataArray containing the data, time basis and all the information in dictionary Examples -------- >>> from tcv.diag.dmpx import Top >>> data = Top.fromshot(50730, los=32) """ if los is None: los = np.arange(64) + 1 else: los = np.atleast_1d(los) cards, channels = Top.channels(shot, los=los) Top._check_dtaq_trigger(shot) fast = Top._is_fast(shot, cards[0], channels[0]) values = [] with tcv.shot(shot) as conn: for card, channel in zip(cards, channels): values.append( conn.tdi(Top._node(card, channel, fast), dims='time')) # now we create the xray data = xray.concat(values, dim='los') data['los'] = los # correct for bad timing if shot > 19923 and shot < 20939: data.time = (data.time + 0.04) * 0.9697 - 0.04 # correct for missing shots if shot >= 25102 and shot < 25933 and (36 in los): data.value[np.argmin(np.abs(los - 36)), :] = 0 log.warn('Channel 36 was missing for this shot') elif shot >= 27127 and shot <= 28124: # missing channels, problem with cable 2, repaired by DF in Dec # 2004 missing = np.asarray([3, 64, 62, 60, 58, 56]) for fault in missing: if fault in los: data.values[np.argmin(np.abs(los - fault)), :] = 0 log.warn('Channel %s missing for this shot', fault) if shot >= 27185 and (44 in los): # one more channel missing !... data.values[np.argmin(np.abs(los - 44)), :] = 0 log.warn('Channel 44 missing for this shot') if shot >= 28219 and shot < 31446: missing = np.asarray([19, 21]) for fault in missing: if fault in los: data.values[np.argmin(np.abs(los - fault)), :] = 0 log.warn('Channel %s missing for this shot', fault) # chose calibrate the signals # read the gain _calib, _gains = Top.gains(shot, los=los) data.values *= (_calib / _gains).reshape(los.size, 1) return data
def fromshot(shot, offset=True, filter='gottardi', Los=None): """ Return the calibrated signal of the BOLO diagnostic with the possibility to choose given LoS. So far it mimic only one of the filter used Parameters: ---------- shot: int Shot Number offset: Boolean. Default True If set it remove the offset before the shot. filter: String Type of available filter for signal processing. Available filters are\ ``bessel``\ or\ ``gottardi``\. Default is\ ``gottardi``\.x Los: Int or list Defining which chord to load. If not given collect all the 64 channels Returns: ------- Calibrated BOLO signals in the form of xarray-DataArray Attributes: ------- shot: int Shot Number units: String Unit of string xchord: float 2D LoS start and end radial position ychord: float 2D LoS start and end vertical position angle: float Cord angle xPO: float Radial position of the pinhole cameras zPO: float vertical position of the pinhole cameras Examples: ------- >>> import tcv >>> boloData = tcv.diag.Bolo.fromshot(50766, Los=[1, 4, 6]) """ conn = tcv.shot(shot) # collect the raw data raw = conn.tdi(r'\base::bolo:source', dims=('time', 'los')) # we lack the correct time bases so we load it # and substitue in the xarray data set time = conn.tdi(r'dim_of(\base::bolo:signals)').values raw.time.values = time # collect the gains gains = conn.tdi(r'\base::bolo:gains') # collect the calibration calibration = conn.tdi(r'\base::bolo:calibration') # collect the etendue etendue = conn.tdi(r'\base::bolo:geom_fact') # define the conversion factor convfact = 9.4 * 0.0015 * 0.004 # collect tau tau = conn.tdi(r'\base::bolo:tau') # collect the geometry dictionary which will be used afterward. # I will append it to the data as additional # dictionary geodict = Bolo.geo(shot, los=Los) # we define the point when the offset removing # mechanism is switched off start = conn.tdi('timing("401")').values if start < 0 and offset: raw -= raw.where(((raw.time < 0) & (raw.time > 0.7 * start))).mean(dim='time') print(' -- Offset removal -- ') else: print(' -- Offset not removed --') # now we compute the calibrated data if filter == 'gottardi': ts, sm, smd = Bolo.gottardifilt(raw) elif filter == 'savitzky': sm, smd = Bolo.savitzkyfilt(raw) elif filter == 'bessel': sm, smd = Bolo.bessel(raw) else: print('Filter not implemented, using default gottardi') filter = 'gottardi' ts, sm, smd = Bolo.gottardifilt(raw) dynVolt = sm + smd * tau.values.reshape(1, tau.shape[0]) data = dynVolt / (gains.values.reshape(1, gains.shape[0]) * calibration.values.reshape(1, calibration.shape[0]) * etendue.values.reshape(1, etendue.shape[0]) * convfact) # transform data on xarray data source and adding geo as a dictionary out = xarray.DataArray(data, dims=('time', 'los')) if filter == 'gottardi': out.coords['time'] = ts else: out.coords['time'] = time out.coords['los'] = numpy.linspace(1, 64, 64, dtype='int') # adding the attributes out.attrs['shot'] = shot out.attrs['units'] = 'W/m^2' # non in case it is called with the LOS we select the appropriate # ones. The Geodictionary is already limited for key in geodict.keys(): out.attrs[key] = geodict[key] if Los is None: return out else: print(' -- selecting chords -- ') out2 = out.sel(los=Los) return out2
def gains(shot, los=None): """ Provide the proper calibration factor for the signals so that can obtain directly the calibration used call: Calibration, Gain = Top.gains() """ conn = tcv.shot(shot) # After #26575, the real voltage is indicated in the Vista window, # before it was the reference voltage mm = 500 if shot < 26765 else 1 voltage = conn.tdi( r'\VSYSTEM::TCV_PUBLICDB_R["ILOT:DAC_V_01"]').values * mm if shot == 32035: voltage = 2000 # we first load all the calibration and then choose the correct one # according to the ordering gainC = np.zeros(64) gainR = np.zeros(64) I = np.where(shot >= np.r_[20030, 23323, 26555, 27127, 29921, 30759, 31446])[0][-1] if I == 0: log.warn('Detector gain dependence on the high voltage value not ' 'included in the signal calibration') calib = Top.calibration_data('mpx_calib_first.mat') calib_coeff_t = np.squeeze(calib['calib_coeff']) gainC[:] = 1 if I == 1: log.warn('Detector gain dependence on the high voltage value not ' 'included in the signal calibration') calib = Top.calibration_data('mpx_calib_sept02.mat') calib_coeff_t = np.squeeze(calib['calib_coeff']) gainC[:] = 1 if I == 2: log.warn('Detector gain dependence on the high voltage value not ' 'included in the signal calibration') log.warn('There were leaks in the top detector wire chamber for ' '26554<shot<27128') log.warn('Calibration is not very meaningful') calib = Top.calibration_data('mpx_calib_may04.mat') calib_coeff_t = np.np.squeeze(calib['calib_coeff']) gainC[:] = 1 if I == 3: log.warn( 'Same gain dependence on the high voltage value taken for ' 'each channel') calib = Top.calibration_data('mpx_calib_july04.mat') calib_coeff = np.squeeze(calib['calib_coeff']) R = np.squeeze(calib['R']) calib_coeff_t = calib_coeff calib = Top.calibration_data('mpx_calib_may05.mat') C = np.squeeze(calib['C']) V = np.squeeze(calib['V']) C = np.mean(C[:, :64], 1) # Use the same gain for each channel gainC[:] = np.exp(np.interp(voltage, V, np.log(C))) gainR[:] = R if I == 4: log.warn( 'Same gain dependence on the high voltage value taken for ' 'each channel') calib = Top.calibration_data('mpx_calib_may05.mat') calib_coeff = np.np.squeeze(calib['calib_coeff']) C = np.squeeze(calib['C']) V = np.squeeze(calib['V']) calib_coeff_t = calib_coeff C = np.mean(C[:, :64], 1) # Use the same gain for each channel gainC[:] = np.exp(np.interp(voltage, V, np.log(C))) # use the previous relative calibration gainR[:] = Top.calibration_data('mpx_calib_july04.mat')['R'] if I == 5: # In this case, the different behaviour of the wires is contained # in the matrix of gains. The calibration coefficients are in a # vector: one value per wire, same value for all tensions. log.info( 'Gain dependence on the high voltage value calibrated for ' 'each channel') log.warn( 'Leaks in the bottom detector, no relative calibration of ' 'the two detectors') calib = Top.calibration_data('mpx_calib_oct05.mat') calib_coeff = np.squeeze(calib['calib_coeff']) C = np.squeeze(calib['C']) V = np.squeeze(calib['V']) calib_coeff_t = calib_coeff # Interpolation to get the proper gains wrt to the high tension # value gainC[:] = [np.interp(voltage, V, np.log(C[:, jj])) for jj in range(64)] gainR[:] = np.nan if I == 6: # In this case, the different behaviour of the wires is contained # in the matrix of calibration coefficients. The gains are in a # vector: one value per tension, same value for all wires. log.info( 'Gain dependence on the high voltage value calibrated for ' 'each channel') calib = Top.calibration_data('mpx_calib_dec05_bis.mat') calib_coeff_top = np.squeeze(calib['calib_coeff_top']) C_top_av = np.squeeze(calib['C_top_av']) V_top = np.squeeze(calib['V_top']) R = np.squeeze(calib['R']) calib_coeff_t = [] for jj in range(64): # Interpolation to get the proper calibration coefficient wrt # the high tension value calib_coeff_t.append( np.interp(voltage, V_top, calib_coeff_top[:, jj])) gainC[:] = np.exp(np.interp(voltage, V_top, np.log(C_top_av))) gainR = R # now we can order accordingly to the index for shot > 26555 # the ordering of the calibration is awful II = np.zeros(64, dtype=int) if shot >= 26555: II[0:63:2] = np.r_[32:64] II[1:64:2] = np.r_[15:-1:-1, 31:15:-1] calib_coeff_t = np.asarray(calib_coeff_t)[II] gainC = gainC[II] # limit the output to the chosen diods if los is None: indexLos = np.arange(64) else: indexLos = np.atleast_1d(los) - 1 cOut = calib_coeff_t[indexLos] gOut = gainC[indexLos] return cOut, gOut
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 gains(shot, camera, los=None): """ Parameters ---------- Same as XtomoCamera.fromshot() Returns ------- The gains and the multiplication factor for the chosen camera and LoS """ if los is None: los = np.arange(20) + 1 else: los = np.atleast_1d(los) # to convert we must define an index which is not modified IndeX = los - 1 # etendue catDefault = XtomoCamera.calibration_data(shot) angFact = catDefault['angfact'][:, camera-1] gAins = np.zeros(20) aOut = np.zeros(20) # remeber that we need to collect all the values of gains # and we decide to choose the only needed afterwards with tcv.shot(shot) as conn: for diods in range(20): out = conn.tdi( '\\vsystem::tcv_publicdb_i["XTOMO_AMP:{:03}_{:03}"]' .format(camera, diods + 1)) gAins[diods] = 10**out.values aOut[diods] = angFact[diods] # now we need to reorder to take into account the ordering of the # diodes if shot <= 34800: index = np.asarray([ np.arange(1, 180, 1), 180 + [2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15, 18, 17, 20, 19]]) else: index = np.hstack([ np.arange(1, 21, 1), np.arange(40, 20, -1), np.arange(60, 40, -1), np.arange(61, 101, 1), np.arange(120, 100, -1), np.arange(140, 120, -1), np.arange(141, 161, 1), np.arange(180, 160, -1), np.arange(200, 180, -1), ]) index -= 1 # remember that matlab start from 1 mask = (camera - 1) * 20 + np.arange(0, 20, 1) ia = np.argsort(index[np.arange(index.shape[0])[np.in1d(index, mask)]]) gAins = gAins[ia] # we now need to choose only the gains for the given diods # just in case we have a single diods we reduce to a single element if np.size(los) != 20: gAins = gAins[IndeX] aOut = aOut[IndeX] return gAins, aOut
def gains(shot, los=None): """ Provide the proper calibration factor for the signals so that can obtain directly the calibration used call: Calibration, Gain = Top.gains() """ conn = tcv.shot(shot) # After #26575, the real voltage is indicated in the Vista window, # before it was the reference voltage mm = 500 if shot < 26765 else 1 voltage = conn.tdi( r'\VSYSTEM::TCV_PUBLICDB_R["ILOT:DAC_V_01"]').values * mm if shot == 32035: voltage = 2000 # we first load all the calibration and then choose the correct one # according to the ordering gainC = np.zeros(64) gainR = np.zeros(64) I = np.where(shot >= np.r_[20030, 23323, 26555, 27127, 29921, 30759, 31446])[0][-1] if I == 0: log.warn('Detector gain dependence on the high voltage value not ' 'included in the signal calibration') calib = Top.calibration_data('mpx_calib_first.mat') calib_coeff_t = np.squeeze(calib['calib_coeff']) gainC[:] = 1 if I == 1: log.warn('Detector gain dependence on the high voltage value not ' 'included in the signal calibration') calib = Top.calibration_data('mpx_calib_sept02.mat') calib_coeff_t = np.squeeze(calib['calib_coeff']) gainC[:] = 1 if I == 2: log.warn('Detector gain dependence on the high voltage value not ' 'included in the signal calibration') log.warn('There were leaks in the top detector wire chamber for ' '26554<shot<27128') log.warn('Calibration is not very meaningful') calib = Top.calibration_data('mpx_calib_may04.mat') calib_coeff_t = np.np.squeeze(calib['calib_coeff']) gainC[:] = 1 if I == 3: log.warn( 'Same gain dependence on the high voltage value taken for ' 'each channel') calib = Top.calibration_data('mpx_calib_july04.mat') calib_coeff = np.squeeze(calib['calib_coeff']) R = np.squeeze(calib['R']) calib_coeff_t = calib_coeff calib = Top.calibration_data('mpx_calib_may05.mat') C = np.squeeze(calib['C']) V = np.squeeze(calib['V']) C = np.mean(C[:, :64], 1) # Use the same gain for each channel gainC[:] = np.exp(np.interp(voltage, V, np.log(C))) gainR[:] = R if I == 4: log.warn( 'Same gain dependence on the high voltage value taken for ' 'each channel') calib = Top.calibration_data('mpx_calib_may05.mat') calib_coeff = np.np.squeeze(calib['calib_coeff']) C = np.squeeze(calib['C']) V = np.squeeze(calib['V']) calib_coeff_t = calib_coeff C = np.mean(C[:, :64], 1) # Use the same gain for each channel gainC[:] = np.exp(np.interp(voltage, V, np.log(C))) # use the previous relative calibration gainR[:] = Top.calibration_data('mpx_calib_july04.mat')['R'] if I == 5: # In this case, the different behaviour of the wires is contained # in the matrix of gains. The calibration coefficients are in a # vector: one value per wire, same value for all tensions. log.info( 'Gain dependence on the high voltage value calibrated for ' 'each channel') log.warn( 'Leaks in the bottom detector, no relative calibration of ' 'the two detectors') calib = Top.calibration_data('mpx_calib_oct05.mat') calib_coeff = np.squeeze(calib['calib_coeff']) C = np.squeeze(calib['C']) V = np.squeeze(calib['V']) calib_coeff_t = calib_coeff # Interpolation to get the proper gains wrt to the high tension # value gainC[:] = [ np.interp(voltage, V, np.log(C[:, jj])) for jj in range(64) ] gainR[:] = np.nan if I == 6: # In this case, the different behaviour of the wires is contained # in the matrix of calibration coefficients. The gains are in a # vector: one value per tension, same value for all wires. log.info( 'Gain dependence on the high voltage value calibrated for ' 'each channel') calib = Top.calibration_data('mpx_calib_dec05_bis.mat') calib_coeff_top = np.squeeze(calib['calib_coeff_top']) C_top_av = np.squeeze(calib['C_top_av']) V_top = np.squeeze(calib['V_top']) R = np.squeeze(calib['R']) calib_coeff_t = [] for jj in range(64): # Interpolation to get the proper calibration coefficient wrt # the high tension value calib_coeff_t.append( np.interp(voltage, V_top, calib_coeff_top[:, jj])) gainC[:] = np.exp(np.interp(voltage, V_top, np.log(C_top_av))) gainR = R # now we can order accordingly to the index for shot > 26555 # the ordering of the calibration is awful II = np.zeros(64, dtype=int) if shot >= 26555: II[0:63:2] = np.r_[32:64] II[1:64:2] = np.r_[15:-1:-1, 31:15:-1] calib_coeff_t = np.asarray(calib_coeff_t)[II] gainC = gainC[II] # limit the output to the chosen diods if los is None: indexLos = np.arange(64) else: indexLos = np.atleast_1d(los) - 1 cOut = calib_coeff_t[indexLos] gOut = gainC[indexLos] return cOut, gOut
def gains(shot, camera, los=None): """ Parameters ---------- Same as XtomoCamera.fromshot() Returns ------- The gains and the multiplication factor for the chosen camera and LoS """ if los is None: los = np.arange(20) + 1 else: los = np.atleast_1d(los) # to convert we must define an index which is not modified IndeX = los - 1 # etendue catDefault = XtomoCamera.calibration_data(shot) angFact = catDefault['angfact'][:, camera - 1] gAins = np.zeros(20) aOut = np.zeros(20) # remeber that we need to collect all the values of gains # and we decide to choose the only needed afterwards with tcv.shot(shot) as conn: for diods in range(20): out = conn.tdi( '\\vsystem::tcv_publicdb_i["XTOMO_AMP:{:03}_{:03}"]'. format(camera, diods + 1)) gAins[diods] = 10**out.values aOut[diods] = angFact[diods] # now we need to reorder to take into account the ordering of the # diodes if shot <= 34800: index = np.asarray([ np.arange(1, 180, 1), 180 + [ 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15, 18, 17, 20, 19 ] ]) else: index = np.hstack([ np.arange(1, 21, 1), np.arange(40, 20, -1), np.arange(60, 40, -1), np.arange(61, 101, 1), np.arange(120, 100, -1), np.arange(140, 120, -1), np.arange(141, 161, 1), np.arange(180, 160, -1), np.arange(200, 180, -1), ]) index -= 1 # remember that matlab start from 1 mask = (camera - 1) * 20 + np.arange(0, 20, 1) ia = np.argsort(index[np.arange(index.shape[0])[np.in1d(index, mask)]]) gAins = gAins[ia] # we now need to choose only the gains for the given diods # just in case we have a single diods we reduce to a single element if np.size(los) != 20: gAins = gAins[IndeX] aOut = aOut[IndeX] return gAins, aOut
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 fromshot(shot, los=None): """ Return the calibrated DMPX signals. Parameters ---------- shot : int or MDSConnection Shot number or connection instance camera : int Number of the XTOMO camera los : int or sequence of ints Optional argument with lines of sight (LoS) of the chosen camera. If None, it loads all the 20 channels Returns ------- An xray.DataArray containing the data, time basis and all the information in dictionary Examples -------- >>> from tcv.diag.dmpx import Top >>> data = Top.fromshot(50730, los=32) """ if los is None: los = np.arange(64) + 1 else: los = np.atleast_1d(los) cards, channels = Top.channels(shot, los=los) Top._check_dtaq_trigger(shot) fast = Top._is_fast(shot, cards[0], channels[0]) values = [] with tcv.shot(shot) as conn: for card, channel in zip(cards, channels): values.append(conn.tdi(Top._node(card, channel, fast), dims='time')) # now we create the xray data = xray.concat(values, dim='los') data['los'] = los # correct for bad timing if shot > 19923 and shot < 20939: data.time = (data.time + 0.04) * 0.9697 - 0.04 # correct for missing shots if shot >= 25102 and shot < 25933 and (36 in los): data.value[np.argmin(np.abs(los - 36)), :] = 0 log.warn('Channel 36 was missing for this shot') elif shot >= 27127 and shot <= 28124: # missing channels, problem with cable 2, repaired by DF in Dec # 2004 missing = np.asarray([3, 64, 62, 60, 58, 56]) for fault in missing: if fault in los: data.values[np.argmin(np.abs(los - fault)), :] = 0 log.warn('Channel %s missing for this shot', fault) if shot >= 27185 and (44 in los): # one more channel missing !... data.values[np.argmin(np.abs(los-44)), :] = 0 log.warn('Channel 44 missing for this shot') if shot >= 28219 and shot < 31446: missing = np.asarray([19, 21]) for fault in missing: if fault in los: data.values[np.argmin(np.abs(los-fault)), :] = 0 log.warn('Channel %s missing for this shot', fault) # chose calibrate the signals # read the gain _calib, _gains = Top.gains(shot, los=los) data.values *= (_calib / _gains).reshape(los.size, 1) return data
def fromshot(shot, offset=True, filter='gottardi', Los=None): """ Return the calibrated signal of the BOLO diagnostic with the possibility to choose given LoS. So far it mimic only one of the filter used Parameters: ---------- shot: int Shot Number offset: Boolean. Default True If set it remove the offset before the shot. filter: String Type of available filter for signal processing. Available filters are\ ``bessel``\ or\ ``gottardi``\. Default is\ ``gottardi``\.x Los: Int or list Defining which chord to load. If not given collect all the 64 channels Returns: ------- Calibrated BOLO signals in the form of xray-DataArray Attributes: ------- shot: int Shot Number units: String Unit of string xchord: float 2D LoS start and end radial position ychord: float 2D LoS start and end vertical position angle: float Cord angle xPO: float Radial position of the pinhole cameras zPO: float vertical position of the pinhole cameras Examples: ------- >>> import tcv >>> boloData = tcv.diag.Bolo.fromshot(50766, Los=[1, 4, 6]) """ conn = tcv.shot(shot) # collect the raw data raw = conn.tdi(r'\base::bolo:source', dims=('time', 'los')) # we lack the correct time bases so we load it # and substitue in the XRAY data set time = conn.tdi(r'dim_of(\base::bolo:signals)').values raw.time.values = time # collect the gains gains = conn.tdi(r'\base::bolo:gains') # collect the calibration calibration = conn.tdi(r'\base::bolo:calibration') # collect the etendue etendue = conn.tdi(r'\base::bolo:geom_fact') # define the conversion factor convfact = 9.4 * 0.0015 * 0.004 # collect tau tau = conn.tdi(r'\base::bolo:tau') # collect the geometry dictionary which will be used afterward. # I will append it to the data as additional # dictionary geodict = Bolo.geo(shot, los=Los) # we define the point when the offset removing # mechanism is switched off start = conn.tdi('timing("401")').values if start < 0 and offset: raw -= raw.where(((raw.time < 0) & (raw.time > 0.7 * start))).mean(dim='time') print ' -- Offset removal -- ' else: print ' -- Offset not removed --' # now we compute the calibrated data if filter == 'gottardi': ts, sm, smd = Bolo.gottardifilt(raw) elif filter == 'savitzky': sm, smd = Bolo.savitzkyfilt(raw) elif filter == 'bessel': sm, smd = Bolo.bessel(raw) else: print('Filter not implemented, using default gottardi') filter = 'gottardi' ts, sm, smd = Bolo.gottardifilt(raw) dynVolt = sm + smd * tau.values.reshape(1, tau.shape[0]) data = dynVolt / (gains.values.reshape(1, gains.shape[0]) * calibration.values.reshape(1, calibration.shape[0]) * etendue.values.reshape(1, etendue.shape[0]) * convfact) # transform data on xray data source and adding geo as a dictionary out = xray.DataArray(data, dims=('time', 'los')) if filter == 'gottardi': out.coords['time'] = ts else: out.coords['time'] = time out.coords['los'] = numpy.linspace(1, 64, 64, dtype='int') # adding the attributes out.attrs['shot'] = shot out.attrs['units'] = 'W/m^2' # non in case it is called with the LOS we select the appropriate # ones. The Geodictionary is already limited for key in geodict.keys(): out.attrs[key] = geodict[key] if Los is None: return out else: print ' -- selecting chords -- ' out2 = out.sel(los=Los) return out2