def crosssignal(container, sig1name='ch01', sig2name='ch02', tmin=0.5, tmax=0.55, nperseg=None, degrees=True, fmin=None, fmax=None): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) return sig1 = getattr(container, sig1name) sig2 = getattr(container, sig2name) cs = CrossSignal(sig1, sig2, tmin=tmin, tmax=tmax, nperseg=nperseg, offsetminimum=True, normalizetodc=True, degrees=degrees, fmin=fmin, fmax=fmax) return cs
def loadConfig(container=None): """ """ if not isContainer(container): raise FdpError("loadConfig() is a BES container method, not signal method") config_file = os.path.join(os.path.dirname(__file__), 'configuration.xml') tree = ET.parse(config_file) root = tree.getroot() shot = container.shot configname = None for shotrange in root: if shotrange.tag=='shotrange': start = int(shotrange.attrib['start']) stop = int(shotrange.attrib['stop']) if shot>=start and shot<=stop: configname = shotrange.attrib['config'] break if configname is None: warn("Invalid shot for configuration", FdpWarning) return for config in root: if config.tag=='config' and config.attrib['name']==configname: for channel in config: signal = getattr(container, channel.attrib['name']) signal.row = int(channel.attrib['row']) signal.column = int(channel.attrib['column']) print('BES configuration loaded') return warn("BES configuration name not found", FdpWarning) return
def plotcoherence(container, *args, **kwargs): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) return fmin = kwargs.get('fmin', 0) fmax = kwargs.get('fmax', 200) cs = crosssignal(container, *args, **kwargs) mask = np.logical_and(fmin <= cs.freqs, cs.freqs <= fmax) coherence = cs.coherence[mask] stdev = cs.coherence_error[mask] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(cs.freqs[mask], coherence) ax.plot((fmin, fmax), (cs.minsig_coherence, cs.minsig_coherence), 'k-') ax.fill_between(cs.freqs[mask], coherence - stdev, coherence + stdev, alpha=0.5, linewidth=0) ax.set_ylim([0, 1]) ax.set_xlabel('Frequency (kHz)') ax.set_title('{} -- {} -- {}/{} -- Coherence'.format( container.shot, container._name.upper(), cs.signal1name.upper(), cs.signal2name.upper())) return cs
def loadConfig(container=None): """ """ if not isContainer(container): raise FdpError( "loadConfig() is a BES container method, not signal method") config_file = os.path.join(os.path.dirname(__file__), 'configuration.xml') tree = ET.parse(config_file) root = tree.getroot() shot = container.shot configname = None for shotrange in root: if shotrange.tag == 'shotrange': start = int(shotrange.attrib['start']) stop = int(shotrange.attrib['stop']) if shot >= start and shot <= stop: configname = shotrange.attrib['config'] break if configname is None: warn("Invalid shot for configuration", FdpWarning) return for config in root: if config.tag == 'config' and config.attrib['name'] == configname: for channel in config: signal = getattr(container, channel.attrib['name']) signal.row = int(channel.attrib['row']) signal.column = int(channel.attrib['column']) print('BES configuration loaded') return warn("BES configuration name not found", FdpWarning) return
def fft(obj, *args, **kwargs): """ Calculate FFT(s) for signal or container. Return Fft instance from classes/fft.py """ # default to offsetminimum=True for BES ffts offsetminimum = kwargs.pop('offsetminimum', True) normalizetodc = kwargs.pop('normalizetodc', True) if isSignal(obj): return Fft(obj, offsetminimum=offsetminimum, normalizetodc=normalizetodc, *args, **kwargs) elif isContainer(obj): signalnames = UT.get_signals_in_container(obj) ffts = [] for sname in signalnames: signal = getattr(obj, sname) ffts.append( Fft(signal, offsetminimum=offsetminimum, normalizetodc=normalizetodc, *args, **kwargs)) return ffts
def coh(container, signal1, signal2): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) return print('end coh()') result = 1 freq=0 return result, freq
def preprocess(self): if isContainer(self) and self._name == 'magnetics': if self.shot < 200000: self.highn._mdstree = 'ops_pc' for signame in self.highn.listSignals(): signal = getattr(self.highn, signame) signal._mdstree = 'ops_pc' signal.time._mdstree = 'ops_pc'
def listContainers(obj): attrnames = dir(obj) containers = [] for attrname in attrnames: attr = getattr(obj, attrname) if isContainer(attr): containers.append(attrname) return containers
def bisignal(container, sig1name='ch01', sig2name='ch02', tmin=0.5, tmax=0.55, nperseg=2048): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) return sig1 = getattr(container, sig1name) sig2 = getattr(container, sig2name) bs = CrossSignal(sig1, sig2, tmin=tmin, tmax=tmax, nperseg=nperseg, offsetminimum=True, normalizetodc=True) return bs
def listAttributes(obj): attrnames = dir(obj) attributes = [] for attrname in attrnames: attr = getattr(obj, attrname) if not isContainer(attr) and \ not isSignal(attr) and \ not hasattr(attr, '__func__'): attributes.append(attrname) return attributes
def plotcrossphase(container, *args, **kwargs): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) return spectrum = kwargs.pop('spectrum', False) fmin = kwargs.get('fmin', 0) fmax = kwargs.get('fmax', 200) degrees = kwargs.get('degrees', True) if degrees: units = 'degrees' else: units = 'radians' cs = crosssignal(container, *args, **kwargs) mask = np.logical_and(fmin <= cs.freqs, cs.freqs <= fmax) if spectrum: crossphase = cs.crossphase[mask, :] fig = plt.figure() ax = fig.add_subplot(111) pcm = ax.pcolormesh(cs.times, cs.freqs[mask], crossphase, cmap=plt.cm.RdBu) pcm.set_clim([-50, 300]) cb = plt.colorbar(pcm, ax=ax) cb.set_label(r'Angle (' + units + ')') ax.set_ylim([fmin, fmax]) ax.set_xlabel('Time (s)') ax.set_ylabel('Frequency (kHz)') ax.set_title('{} -- {} -- {}/{} -- Crossphase'.format( container.shot, container._name.upper(), cs.signal1name.upper(), cs.signal2name.upper())) else: crossphase = cs.crossphase_binavg[mask] stdev = cs.crossphase_error[mask] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(cs.freqs[mask], crossphase) ax.fill_between(cs.freqs[mask], crossphase - stdev, crossphase + stdev, alpha=0.5, linewidth=0) ax.set_xlabel('Frequency (kHz)') ax.set_ylabel('Angle (' + units + ')') ax.set_title('{} -- {} -- {}/{} -- Crossphase'.format( container.shot, container._name.upper(), cs.signal1name.upper(), cs.signal2name.upper())) return cs
def plotcoherence(container, *args, **kwargs): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) return bs = bisignal(container, *args, **kwargs) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(bs.freqs, bs.cohere) ax.set_xlim(0, 200) ax.set_xlabel('Frequency (kHz)') ax.set_ylabel('Coherence') ax.set_title('{} -- {} -- {}/{} -- Coherence'.format( container.shot, container._name.upper(), bs.signal1name.upper(), bs.signal2name.upper()))
def get_signals_in_container(container): """Return list of attribute names corresponding to valid signals""" if not isContainer(container): raise FdpError("Expecting a container object") attrnames = dir(container) valid_signals = [] for attrname in attrnames: attr = getattr(container, attrname) if isSignal(attr): try: attr[:] valid_signals.append(attr) except: print('{} is empty, ignoring'.format(attrname)) return valid_signals
def fft(obj, *args, **kwargs): """ Calculate FFT(s) for signal or container. Return Fft instance from classes/fft.py """ if isSignal(obj): return Fft(obj, *args, **kwargs) elif isContainer(obj): signalnames = UT.get_signals_in_container(obj) ffts = [] for sname in signalnames: signal = getattr(obj, sname) ffts.append(Fft(signal, *args, **kwargs)) return ffts
def testSignalAxes(self, container=None): """ Recursively parse tree Assert all signals contain 'axes' attribute Assert all signals contain 'time' attribute Assert all 'axes' elements are axis objects Assert all axis attributes are in 'axes' """ if not container: container = self.shot if not isinstance(container, fdp.classes.shot.Shot): if isinstance(container._parent, fdp.classes.shot.Shot): print('Parsing {}'.format(container._name)) else: print('Parsing {}.{}'.format(container._parent._name, container._name)) for attrname in dir(container): attr = getattr(container, attrname) if isContainer(attr): self.testSignalAxes(attr) elif isSignal(attr): self.assertTrue( hasattr(attr, 'axes'), "Signal {} does not have 'axes' attr".format(attr._name)) self.assertTrue( hasattr(attr, 'time'), "Signal {} does not have 'time' attr".format(attr._name)) self.assertTrue( isAxis(getattr(attr, 'time')), "'time' attr is not axis object for signal {}".format( attr._name)) for axisname in attr.axes: self.assertTrue( hasattr(attr, axisname), "'axes' element {} not an attribute for signal {}". format(axisname, attr._name)) axis = getattr(attr, axisname) self.assertTrue( isAxis(axis), "'axes' element {} is not axis object for signal {}". format(axisname, attr._name)) for sigattrname in dir(attr): sigattr = getattr(attr, sigattrname) if isAxis(sigattr): self.assertIn( sigattrname, attr.axes, "{} is axis but not in 'axes' attr for signal {}". format(sigattrname, attr._name))
def plotcrosspower(container, *args, **kwargs): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) return spectrum = kwargs.pop('spectrum', False) fmin = kwargs.get('fmin', 0) fmax = kwargs.get('fmax', 200) cs = crosssignal(container, *args, **kwargs) mask = np.logical_and(fmin <= cs.freqs, cs.freqs <= fmax) if spectrum: logcrosspower = 10 * np.log10(cs.crosspower[mask, :]) fig = plt.figure() ax = fig.add_subplot(111) pcm = ax.pcolormesh(cs.times, cs.freqs[mask], logcrosspower, cmap=plt.cm.YlGnBu) pcm.set_clim([logcrosspower.max() - 100, logcrosspower.max() - 20]) cb = plt.colorbar(pcm, ax=ax) cb.set_label(r'$10\,\log_{10}(Crosspower)$ $(V^2/Hz)$') ax.set_xlabel('Time (s)') ax.set_ylabel('Frequency (kHz)') ax.set_title('{} -- {} -- {}/{} -- Crosspower'.format( container.shot, container._name.upper(), cs.signal1name.upper(), cs.signal2name.upper())) else: logcrosspower = 10 * np.log10(cs.crosspower_binavg[mask]) # logstdevupper = 10*np.log10(cs.crosspower_binavg[mask] # + np.sqrt(cs.crosspower_var[mask])) # logstdevlower = 10*np.log10(cs.crosspower_binavg[mask] # - np.sqrt(cs.crosspower_var[mask])) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(cs.freqs[mask], logcrosspower) # ax.fill_between(cs.freqs[mask], logstdevlower, logstdevupper, # alpha=0.5, linewidth=0) ax.set_xlabel('Frequency (kHz)') ax.set_ylabel(r'$10\,\log_{10}(Crosspower)$ $(V^2/Hz)$') ax.set_title('{} -- {} -- {}/{} -- Crosspower'.format( container.shot, container._name.upper(), cs.signal1name.upper(), cs.signal2name.upper())) return cs
def plotcorrelation(container, *args, **kwargs): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) return envelope = kwargs.pop('envelope', False) cs = crosssignal(container, *args, **kwargs) fig = plt.figure() ax = fig.add_subplot(111) if envelope: ax.plot(cs.time_delays * 1000000., cs.correlation_coef_envelope) ax.plot((0, 0), (0, 1), 'k-') else: ax.plot(cs.time_delays * 1000000., cs.correlation_coef) ax.plot((0, 0), (-1, 1), 'k-') ax.set_xlabel('Time delay (us)') ax.set_title('{} -- {} -- {}/{} -- Time-lag cross-correlation'.format( container.shot, container._name.upper(), cs.signal1name.upper(), cs.signal2name.upper())) return cs
def __init__(self, container, tmin=0.0, tmax=5.0, savemovie=False, hightimeres=False, saveeps = False): if not isContainer(container): raise FdpError("Use at container level, not signal level") self.container = container if tmax>10: # if tmax large, assume ms input and convert to s tmin = tmin/1e3 tmax = tmax/1e3 self.tmin = tmin self.tmax = tmax self.hightimeres = hightimeres self.saveeps = saveeps self.savemovie = savemovie self.signals = None self.data = None self.time = None self.istart = None self.istop = None self.writer = None self.filter = None self.fdata = None self.ftime = None self.cdata = None self.getSignals() self.loadConfig() self.setTimeIndices() self.loadData() self.applyNormalization() self.filterData() #self.gridData() self.makeAnimation() if self.savemovie: self.saveAnimationVideo()
def testSignalAxes(self, container=None): """ Recursively parse tree Assert all signals contain 'axes' attribute Assert all signals contain 'time' attribute Assert all 'axes' elements are axis objects Assert all axis attributes are in 'axes' """ if not container: container = self.shot if not isinstance(container, fdp.classes.shot.Shot): if isinstance(container._parent, fdp.classes.shot.Shot): print('Parsing {}'.format(container._name)) else: print('Parsing {}.{}'.format(container._parent._name, container._name)) for attrname in dir(container): attr = getattr(container, attrname) if isContainer(attr): self.testSignalAxes(attr) elif isSignal(attr): self.assertTrue(hasattr(attr, 'axes'), "Signal {} does not have 'axes' attr".format(attr._name)) self.assertTrue(hasattr(attr, 'time'), "Signal {} does not have 'time' attr".format(attr._name)) self.assertTrue(isAxis(getattr(attr, 'time')), "'time' attr is not axis object for signal {}".format(attr._name)) for axisname in attr.axes: self.assertTrue(hasattr(attr, axisname), "'axes' element {} not an attribute for signal {}".format( axisname, attr._name)) axis = getattr(attr, axisname) self.assertTrue(isAxis(axis), "'axes' element {} is not axis object for signal {}".format( axisname, attr._name)) for sigattrname in dir(attr): sigattr = getattr(attr, sigattrname) if isAxis(sigattr): self.assertIn(sigattrname, attr.axes, "{} is axis but not in 'axes' attr for signal {}".format( sigattrname, attr._name))
def fft(obj, *args, **kwargs): """ Calculate FFT(s) for signal or container. Return Fft instance from classes/fft.py """ # default to offsetminimum=True for BES ffts offsetminimum = kwargs.pop('offsetminimum', True) normalizetodc = kwargs.pop('normalizetodc', True) if isSignal(obj): return Fft(obj, offsetminimum=offsetminimum, normalizetodc=normalizetodc, *args, **kwargs) elif isContainer(obj): signalnames = UT.get_signals_in_container(obj) ffts = [] for sname in signalnames: signal = getattr(obj, sname) ffts.append(Fft(signal, offsetminimum=offsetminimum, normalizetodc=normalizetodc, *args, **kwargs)) return ffts
def gui(obj): if isSignal(obj): return BaseGui(obj) if isContainer(obj): return BesGui(obj)
def info(obj, *args, **kwargs): if isSignal(obj): infoSignal(obj, *args, **kwargs) elif isContainer(obj) or isShot(obj): infoContainer(obj, *args, **kwargs) return