def __init__(self, acq, shot, config_name=None, **kwargs): self.shot = shot self.acq = acq if config_name != None: self.__dict__.update(get_config_as_dict('Diagnostic', config_name)) if pyfusion.VERBOSE>3: print(get_config_as_dict('Diagnostic', config_name)) self.__dict__.update(kwargs) self.config_name=config_name
def __init__(self, acq, shot, config_name=None, **kwargs): self.shot = shot self.acq = acq if config_name != None: self.__dict__.update(get_config_as_dict('Diagnostic', config_name)) if pyfusion.VERBOSE > 3: print(get_config_as_dict('Diagnostic', config_name)) self.__dict__.update(kwargs) self.config_name = config_name
def get_coords_for_channel(channel_name=None, **kwargs): config_dict = kwargs.copy() if channel_name: config_dict.update(get_config_as_dict('Diagnostic', channel_name)) coord_name = 'dummy' coord_values = (0.0,0.0,0.0) transforms = [] for k in config_dict.keys(): if k.startswith('coords_'): coord_name = k[7:] coord_values = tuple(map(float,config_dict[k].split(','))) coords_instance = Coords(coord_name, coord_values) if 'coord_transform' in config_dict: transform_list = pyfusion.config.pf_options('CoordTransform', config_dict['coord_transform']) for transform_name in transform_list: # this seems to return all the globals too transform_class_str = pyfusion.config.pf_get('CoordTransform', config_dict['coord_transform'], transform_name) # so tyr to exclude the globals if pyfusion.config.has_option('global',transform_name): continue transform_class = import_from_str(transform_class_str) #if not hasattr(transform_class, 'output_coord'): # raise Exception('??') coords_instance.load_transform(transform_class) debug_(pyfusion.DEBUG,1, key=['coord', 'device_name']) return coords_instance
def get_coords_for_channel(channel_name=None, **kwargs): config_dict = kwargs.copy() if channel_name: config_dict.update(get_config_as_dict("Diagnostic", channel_name)) coord_name = "dummy" coord_values = (0.0, 0.0, 0.0) transforms = [] for k in config_dict.keys(): if k.startswith("coords_"): coord_name = k[7:] coord_values = tuple(map(float, config_dict[k].split(","))) coords_instance = Coords(coord_name, coord_values) if "coord_transform" in config_dict: transform_list = pyfusion.config.pf_options("CoordTransform", config_dict["coord_transform"]) for transform_name in transform_list: # this seems to return all the globals too transform_class_str = pyfusion.config.pf_get( "CoordTransform", config_dict["coord_transform"], transform_name ) # so tyr to exclude the globals if pyfusion.config.has_option("global", transform_name): continue transform_class = import_from_str(transform_class_str) # if not hasattr(transform_class, 'output_coord'): # raise Exception('??') coords_instance.load_transform(transform_class) debug_(pyfusion.DEBUG, 1, key=["coord", "device_name"]) return coords_instance
def testAcqAttrsConfigKwargs(self): """Check that config, kwarg attributes are correctly attached to object. If config is supplied, load config before kwargs. """ config_dict = get_config_as_dict('Acquisition', 'test_baseacq') test_acq = BaseAcquisition('test_baseacq', dummy_var_1 = 5) self.assertEqual(test_acq.dummy_var_1, 5)
def testAcqAttrsConfigKwargs(self): """Check that config, kwarg attributes are correctly attached to object. If config is supplied, load config before kwargs. """ config_dict = get_config_as_dict('Acquisition', 'test_baseacq') test_acq = BaseAcquisition('test_baseacq', dummy_var_1=5) self.assertEqual(test_acq.dummy_var_1, 5)
def testAcqAttrsConfig(self): """Check that config, kwarg attributes are correctly attached to object. If config is supplied, load config before kwargs. """ config_dict = get_config_as_dict('Acquisition', 'test_baseacq') test_acq = BaseAcquisition('test_baseacq') for config_arg in config_dict.keys(): self.assertTrue(hasattr(test_acq, config_arg))
def testEqualityConfigOrArgs(self): """Check that config and kwarg instantiated Acquisition classes are same.""" acq_from_config = BaseAcquisition('test_baseacq') # create a BaseAcquisition instance with keyword args config_dict = get_config_as_dict('Acquisition', 'test_baseacq') acq_from_kwargs = BaseAcquisition(**config_dict) # Acquistion instantiated only from keywords won't have # config_name set but should otherwise be equal self.assertTrue( equal_except_for(acq_from_config, acq_from_kwargs, 'config_name'))
def testEqualityConfigOrArgs(self): """Check that config and kwarg instantiated Acquisition classes are same.""" acq_from_config = BaseAcquisition('test_baseacq') # create a BaseAcquisition instance with keyword args config_dict = get_config_as_dict('Acquisition', 'test_baseacq') acq_from_kwargs = BaseAcquisition(**config_dict) # Acquistion instantiated only from keywords won't have # config_name set but should otherwise be equal self.assertTrue(equal_except_for(acq_from_config, acq_from_kwargs, 'config_name'))
def __init__(self, acq, shot, config_name=None, **kwargs): self.shot = shot self.acq = acq self.no_cache = False # this allows getData to request that cached data is NOT used - eg for saving local #bdb?? add device name here, so can prepend to Diagnostic # e.g. LHD_Diagnostic - avoids ambiguity debug_(pyfusion.DEBUG,5,key='device_name') if config_name is not None: self.__dict__.update(get_config_as_dict('Diagnostic', config_name)) # look for the first valid date range for this diag - # see config/'Valid Dates' in the reference docs self.config_name=config_name for Mod in ['M1','M2','M3','M4']: if self.find_valid_for_date(): break else: self.__dict__.update(get_config_as_dict('Diagnostic', config_name.replace('W7X','W7X'+Mod))) else: raise LookupError(config_name) if pyfusion.VERBOSE>3: print(get_config_as_dict('Diagnostic', config_name)) self.__dict__.update(kwargs)
def __init__(self, config_name, **kwargs): if pyfusion.config.pf_has_section('Device', config_name): self.__dict__.update(get_config_as_dict('Device', config_name)) self.__dict__.update(kwargs) self.name = config_name #### attach acquisition if hasattr(self, 'acq_name'): acq_class_str = pyfusion.config.pf_get('Acquisition', self.acq_name, 'acq_class') self.acquisition = import_from_str(acq_class_str)(self.acq_name) # shortcut self.acq = self.acquisition else: pyfusion.logging.warning( "No acquisition class specified for device")
def get_coords_for_channel(channel_name=None, **kwargs): config_dict = kwargs.copy() if channel_name: config_dict.update(get_config_as_dict('Diagnostic', channel_name)) coord_name = 'dummy' coord_values = (0.0,0.0,0.0) transforms = [] for k in config_dict.keys(): if k.startswith('coords_'): coord_name = k[7:] coord_values = tuple(map(float,config_dict[k].split(','))) coords_instance = Coords(coord_name, coord_values) if config_dict.has_key('coord_transform'): transform_list = pyfusion.config.pf_options('CoordTransform', config_dict['coord_transform']) for transform_name in transform_list: transform_class_str = pyfusion.config.pf_get('CoordTransform', config_dict['coord_transform'], transform_name) transform_class = import_from_str(transform_class_str) coords_instance.load_transform(transform_class) return coords_instance
def write_DA(self, filename): from pyfusion.data.DA_datamining import DA, Masked_DA dd = {} res = np.array(self.fitdata, dtype=np.float32) nt = len(res) nc = len(res[0]) for key in ['date', 'progId', 'shot']: dd[key] = np.zeros(nt, dtype=np.int64) dd['date'][:] = self.shot[0] dd['progId'][:] = self.shot[1] dd['shot'][:] = self.shot[1] + 1000*self.shot[0] for key in ['nits','maxits']: dd[key] = np.zeros([nt,nc], dtype=np.uint16) # make all the f32 arrays - note - ne is just I0 for now - fixed below lookup = [(0, 't_mid'), (1, 'Te'), (2, 'Vf'), (3, 'I0'), (4, 'resid'), (5, 'nits'), (6, 'maxits'), (7, 'Ie_Ii'), (3, 'ne18')] if self.fitter.fit_params.get('esterr',False): lookup.extend([(8, 'eTe'), (9, 'eVf'), (10, 'eI0') ]) for (ind, key) in lookup: if key not in dd: dd[key] = np.zeros([nt, nc], dtype=np.float32) dd[key][:] = res[:, :, ind] # fudge t_mid is not a vector...should fix properly dd['t_mid'] = dd['t_mid'][:, 0] dd['info'] = dict(params=self.actual_params, coords=[self.coords[ic] for ic in self.select], #area=[self.area[ic] for ic in self.select], # needs to be in npz file etc first shotdata=dict(shot=[self.shot], utc_ns=[self.imeas.utc[0]]), channels=[chn.replace(self.dev.name+'_', '') .replace('_I', '') for chn in [self.i_chans[ic] for ic in self.select]], orig_name = os.path.split(filename)[-1], username = os.getlogin()) da = DA(dd) da.masked = Masked_DA(['Te', 'I0', 'Vf', 'ne18', 'Ie_Ii'], baseDA=da) # da.da['mask']=(da['resid']/abs(da['I0']) < .7) & (da['nits']<100) # da.da['mask'] = ((da['resid']/abs(da['I0']) < .7) & (da['nits'] < da['maxits']) # from version 0.7.0 onwards, resid is already normed to I0 lpf = self.fitter.actual_fparams['lpf'] # Note: these multilines ('down to here') can be applied to a DA by # pasting to reset mask AFTER uncommenting the following # line # lpf = da['info']['params']['actual_fit_params']['lpf'] rthr = 0.7 # LP20160309_29_L53__amoebaNone1.2N_2k.npz is < .12 others # None 0310_9 up to 0.7-0.8 if lpf is not None: rthr = rthr * np.sqrt(lpf/100.0) da.da['mask'] = ((da['resid'] < rthr) & (da['nits'] < da['maxits']) & (np.abs(da['Vf']) < 200) & (np.abs(da['Te']) < 200) & (da['I0']>0.0004)) # additional restriction applied if the error estimate is available if 'eTe' in da.da: # want error not too big and smaller than temp da.da['mask'] &= ((np.abs(da['eTe']) < 100) & (np.abs(da['eTe']) < np.abs(da['Te']))) # down to here qe = 1.602e-19 mp = 1.67e-27 fact = 1/(0.6*qe)*np.sqrt(self.amu*mp/(qe))/1e18 # units of 1e18 # check if each channel has an area for (c, chn) in enumerate([self.i_chans[ic] for ic in self.select]): cd = get_config_as_dict('Diagnostic', chn) A = cd.get('area', None) if A is None: A = 1.0e-6 pyfusion.logging.warn('Defaulting area for {chn} to {A}'.format(chn=chn, A=A)) A = float(A) da.da['ne18'][:, c] = fact/A * da['I0'][:, c]/np.sqrt(da['Te'][:, c]) da.save(filename)
def __init__(self, config_name=None, **kwargs): if config_name != None: self.__dict__.update(get_config_as_dict('Acquisition', config_name)) self.__dict__.update(kwargs)
def __init__(self, acq, shot, config_name=None, **kwargs): self.shot = shot self.acq = acq if config_name != None: self.__dict__.update(get_config_as_dict('Diagnostic', config_name)) self.__dict__.update(kwargs)
import pyfusion as pf pf.config.get('global','database') # 'sqlite:///sqlite.txt' pf.read_config('shaun_feb_2010.cfg') from pyfusion.conf.utils import get_config_as_dict get_config_as_dict('Device','H1') get_config_as_dict('Diagnostic','H1PoloidalAll') import pyfusion as pf h1=pf.getDevice("H1") data=h1.acq.getdata(70071,'H1ToroidalAxial') data.meta.keys() data.plot_signals() # overlay fs on spectrum run examples/plot_specgram.py dev_name='LHD' shot_number=27233 hold=0 time_range=[.35,.5] NFFT=256 noverlap=220 run examples/plot_text_pyfusion.py filename='PF2_120229_MP_27233_27233_1_256.dat' hold=1 min_e=0.8 freq_scale=1e3 colorbar();xlim(0.35,.5);ylim(0,150000) # mode identification overlaid on spectrum - used in LHD report Feb 2012 run examples/plot_specgram.py dev_name='LHD' shot_number=27233 hold=0 time_range=[.35,1.5] NFFT=256 noverlap=220 clim(-210,-40) run examples/mode_identify_example_2012.py hold=1 fsfile='PF2_120229_MP_27233_27233_1_256.dat' xlim(0.35,.5);ylim(0,150000) xlabel('Time (s)'); ylabel('Frequency (kHz)') # chirp following example run examples/plot_text_pyfusion.py filename='PF2_120229_MP_27233_27233_1_256.dat' hold=1 min_e=0.8 freq_scale=1e3 plot=1 time_range=[0.35,.4]
def process_swept_Langmuir(self, t_range=None, t_comp=[0, 0.1], fit_params = dict(maxits=200, alg='leastsq',esterr=1), initial_TeVfI0=dict(Te=50, Vf=15, I0=None), dtseg=4e-3, overlap=1, rest_swp='auto', clipfact=5, clip_iprobe = None, leakage=None, threshold=0.01, threshchan=12, filename=None, amu=1, plot=None, return_data=False, suffix=''): """ ==> results[time,probe,quantity] plot = 1 : V-I and data if there are not too many. plot >= 2 : V-I curves plot >= 3 : ditto + time plot plot >= 4 : ditto + all I-V iterations can send parameters through the init or process - either way they all are recorded in actual_params clip_iprobe = [-0.015, .02] # used to check if a resistive term is affecting Te Start by processing in the ideal order: - logical, but processes more data than necessary fix up the voltage sweep compensate I detect plasma reduce time segment and process Faster order - reduces time range earlier: (maybe implement later) detect plasma time range with quick and dirty method restrict time range, but keep pre-shot data accessible for evaluation of success of removal """ self.figs = [] # reset the count of figures used to stop too many plots self.actual_params = locals().copy() # try to catch mispelling, variables in the wrong place for k in fit_params: if k not in 'Lnorm,cov,esterr,alg,xtol,ftol,lpf,maxits,track_ratio'.split(','): raise ValueError('Unknown fit_params key ' + k) self.actual_params.pop('self') self.actual_params.update(dict(i_diag=self.i_diag, v_diag=self.v_diag)) # and do it for actuals too for k in self.actual_params: if k not in 'amu,clipfact,clip_iprobe,dtseg,filename,initial_TeVfI0,leakage,overlap,plot,rest_swp,suffix,t_comp,t_range,threshold,threshchan,fit_params,v_diag,i_diag,return_data'.split(','): raise ValueError('Unknown actual_params key ' + k) self.actual_params.update(dict(i_diag_utc=self.imeasfull.utc, pyfusion_version=pyfusion.VERSION)) self.amu = amu if not isinstance(self.imeasfull.channels, (list, tuple, np.ndarray)): self.imeasfull.channels = [self.imeasfull.channels] self.i_chans = [ch.config_name for ch in self.imeasfull.channels] for ch in self.i_chans: # only take the current channels, not U if ch[-1] != 'I': raise ValueError("Warning - removal of V chans doesn't work!!!") # hopefully we can ignore _U channels eventually, but not yet self.i_chans.remove(ch) self.coords = [ch.coords.w7_x_koord for ch in self.imeasfull.channels] # if you want just one voltage channel, at the moment, you still # need it to be a multi-channel diag. (to simplify this code). self.v_chans = [ch.config_name for ch in self.vmeasfull.channels] # want to say self.vmeas[ch].signal where ch is the imeas channel name self.vlookup = {} for (c, vch) in enumerate(self.v_chans): self.vlookup[vch] = c self.vassoc = [] # list of sweepVs associated with each i channel # one per i channel - these refer to their # respective self.v_chans # for OP1.1, only a few V chans were recorded and # in practice only two channels are necessary. default_sweep = 'NO SWEEP' default_sweep = 'W7X_L57_LP01_U' for ch in self.i_chans: cd = get_config_as_dict('Diagnostic', ch) # TODO(bdb): use of default_sweep should generate a warning self.vassoc.append(cd.get('sweepv', default_sweep)) # first do the things that are better done on the whole data set. # prepare_sweeps will populate self.vcorrfull # self.check_crosstalk(verbose=0) # this could be slow self.prepare_sweeps(rest_swp=rest_swp) self.get_iprobe(leakage=leakage, t_comp=t_comp) tb = self.iprobefull.timebase # the 3000 below tries to avoid glitches from Hilbert at both ends #w_plasma = np.where((np.abs(self.iprobefull.signal[threshchan]) > threshold) & (tb > tb[3000]) &(tb < tb[-3000]))[0] # only look at electron current - bigger (shot 0309.52 LP53 has a positive spike at 2s) w_plasma = np.where((-self.iprobefull.signal[threshchan] > threshold) & (tb > tb[3000]) &(tb < tb[-3000]))[0] if t_range is None: t_range = [tb[w_plasma[0]], tb[w_plasma[-1]]] self.t_range = t_range if t_range is not None: self.imeas = self.imeasfull.reduce_time(t_range) self.iprobe = self.iprobefull.reduce_time(t_range) self.vcorr = self.vcorrfull.reduce_time(t_range) else: self.imeas = self.imeasfull self.iprobe = self.iprobefull self.vcorr = self.vcorrfull # We need to segment iprobe, also i_meas to check clipping, and vsweep self.segs = zip(self.imeas.segment(dtseg, overlap), self.iprobe.segment(dtseg, overlap), self.vcorr.segment(dtseg, overlap)) if self.debug>0: print(' {n} segments'.format(n=len(self.segs))) self.fitdata = [] debug_(self.debug, 3, key='process_loop') for mseg, iseg, vseg in self.segs: # print('len vseg', len(vseg.signal[0])) if len(vseg.signal[0]) < dtseg//5: # skip short segments continue print(np.round(np.mean(mseg.timebase),4), end='s: ') # midpoint if clip_iprobe is not None: print('fudge hard clipping') # have to clip the raw signal, because that is where the decision is made # but we have to do it AFTER isage is extracted, becuause the leakage # will make the clipping uneven (a sinusoidal top) - so clip isge too iseg.signal = np.clip(iseg.signal, *clip_iprobe) mseg.signal = iseg.signal.copy() self.fitdata.append(self.fit_swept_Langmuir_seg_multi(mseg, iseg, vseg, clipfact=clipfact, initial_TeVfI0=initial_TeVfI0, fit_params=fit_params, plot=plot)) # note: fitter.actual_fparams only records the most recent! self.actual_params.pop('fit_params') # only want the ACTUAL ones. self.actual_params['actual_fit_params'] = self.fitter.actual_fparams if filename is not None: if '*' in filename: fmt = 'LP{s0}_{s1}_' if 'L5' in self.i_diag: fmt += 'L5' + self.i_diag.split('L5')[1][0] filename = filename.replace('*',fmt+'_') if filename.endswith('_'): # remove ending _ filename = filename[0:-1] if '{' in filename: filename = filename.format(s0=self.shot[0], s1=self.shot[1], i_diag=self.i_diag) print('writing {fn}'.format(fn=filename)) # Lukas had trouble with this in python 3 self.write_DA(filename) if return_data: return(self.fitdata)
def __init__(self, config_name=None, **kwargs): if config_name is not None: self.__dict__.update(get_config_as_dict('Acquisition', config_name)) self.__dict__.update(kwargs)