Skip to content

Commit bb58957

Browse files
author
Julian Kates-Harbeck
committed
adding support for signals which use other signals as mappings, such as ppf/hrts/te (profile) and ppf/hrts/rho (rho coordinate)
1 parent e76e939 commit bb58957

File tree

3 files changed

+48
-23
lines changed

3 files changed

+48
-23
lines changed

data/signals.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -137,33 +137,33 @@ def fetch_nstx_data(signal_path,shot_num,c):
137137

138138
profile_num_channels = 64
139139
#ZIPFIT comes from actual measurements
140-
etemp_profile = ProfileSignal("Electron temperature profile",["ZIPFIT01/PROFILES.ETEMPFIT"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerance=0.02)
141-
edens_profile = ProfileSignal("Electron density profile",["ZIPFIT01/PROFILES.EDENSFIT"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerance=0.02)
142-
itemp_profile = ProfileSignal("Ion temperature profile",["ZIPFIT01/PROFILES.ITEMPFIT"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerance=0.02)
143-
zdens_profile = ProfileSignal("Impurity density profile",["ZIPFIT01/PROFILES.ZDENSFIT"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerance=0.02)
144-
trot_profile = ProfileSignal("Rotation profile",["ZIPFIT01/PROFILES.TROTFIT"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerance=0.02)
145-
pthm_profile = ProfileSignal("Thermal pressure profile",["ZIPFIT01/PROFILES.PTHMFIT"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerance=0.02)# thermal pressure doesn't include fast ions
146-
neut_profile = ProfileSignal("Neutrals profile",["ZIPFIT01/PROFILES.NEUTFIT"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerance=0.02)
140+
etemp_profile = ProfileSignal("Electron temperature profile",["ppf/hrts/te","ZIPFIT01/PROFILES.ETEMPFIT"],[jet,d3d],mapping_paths=["ppf/hrts/rho",None],causal_shifts=[25,10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerances=[0.05,0.02])
141+
edens_profile = ProfileSignal("Electron density profile",["ppf/hrts/ne","ZIPFIT01/PROFILES.EDENSFIT"],[jet,d3d],mapping_paths=["ppf/hrts/rho",None],causal_shifts=[25,10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerances=[0.05,0.02])
142+
itemp_profile = ProfileSignal("Ion temperature profile",["ZIPFIT01/PROFILES.ITEMPFIT"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerances=[0.02])
143+
zdens_profile = ProfileSignal("Impurity density profile",["ZIPFIT01/PROFILES.ZDENSFIT"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerances=[0.02])
144+
trot_profile = ProfileSignal("Rotation profile",["ZIPFIT01/PROFILES.TROTFIT"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerances=[0.02])
145+
pthm_profile = ProfileSignal("Thermal pressure profile",["ZIPFIT01/PROFILES.PTHMFIT"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerances=[0.02])# thermal pressure doesn't include fast ions
146+
neut_profile = ProfileSignal("Neutrals profile",["ZIPFIT01/PROFILES.NEUTFIT"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerances=[0.02])
147147

148-
q_profile = ProfileSignal("Q profile",["ZIPFIT01/PROFILES.BOOTSTRAP.QRHO"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerance=0.02)#compare to just q95
149-
bootstrap_current_profile = ProfileSignal("Rotation profile",["ZIPFIT01/PROFILES.BOOTSTRAP.JBS_SAUTER"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerance=0.02)
148+
q_profile = ProfileSignal("Q profile",["ZIPFIT01/PROFILES.BOOTSTRAP.QRHO"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerances=[0.02])#compare to just q95
149+
bootstrap_current_profile = ProfileSignal("Rotation profile",["ZIPFIT01/PROFILES.BOOTSTRAP.JBS_SAUTER"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerances=[0.02])
150150

151-
#equilibrium_image = 2DSignal("2D Magnetic Equilibrium",["EFIT01/RESULTS.GEQDSK.PSIRZ"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerance=0.02)
151+
#equilibrium_image = 2DSignal("2D Magnetic Equilibrium",["EFIT01/RESULTS.GEQDSK.PSIRZ"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerances=[0.02])
152152

153153
#EFIT is the inverse problem from external magnetic measurements
154-
#pressure_profile = ProfileSignal("Pressure profile",["EFIT01/RESULTS.GEQDSK.PRES"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerance=0.02)# pressure might be unphysical since it is not constrained by measurements, only the EFIT which does not know about density and temperature
155-
q_psi_profile = ProfileSignal("Q(psi) profile",["EFIT01/RESULTS.GEQDSK.QPSI"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerance=0.02)
154+
#pressure_profile = ProfileSignal("Pressure profile",["EFIT01/RESULTS.GEQDSK.PRES"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerances=[0.02])# pressure might be unphysical since it is not constrained by measurements, only the EFIT which does not know about density and temperature
155+
q_psi_profile = ProfileSignal("Q(psi) profile",["EFIT01/RESULTS.GEQDSK.QPSI"],[d3d],causal_shifts=[10],mapping_range=(0,1),num_channels=profile_num_channels,data_avail_tolerances=[0.02])
156156

157157

158158
# epress_profile_spatial = ProfileSignal("Electron pressure profile",["ppf/hrts/pe/"],[jet],causal_shifts=[25],mapping_range=(2,4),num_channels=profile_num_channels)
159-
etemp_profile_spatial = ProfileSignal("Electron temperature profile",["ppf/hrts/te"],[jet],causal_shifts=[25],mapping_range=(2,4),num_channels=profile_num_channels,data_avail_tolerance=0.05)
160-
edens_profile_spatial = ProfileSignal("Electron density profile",["ppf/hrts/ne"],[jet],causal_shifts=[25],mapping_range=(2,4),num_channels=profile_num_channels,data_avail_tolerance=0.05)
161-
rho_profile_spatial = ProfileSignal("Rho at spatial positions",["ppf/hrts/rho"],[jet],causal_shifts=[25],mapping_range=(2,4),num_channels=profile_num_channels,data_avail_tolerance=0.05)
159+
etemp_profile_spatial = ProfileSignal("Electron temperature profile",["ppf/hrts/te"],[jet],causal_shifts=[25],mapping_range=(2,4),num_channels=profile_num_channels,data_avail_tolerances=[0.05])
160+
edens_profile_spatial = ProfileSignal("Electron density profile",["ppf/hrts/ne"],[jet],causal_shifts=[25],mapping_range=(2,4),num_channels=profile_num_channels,data_avail_tolerances=[0.05])
161+
rho_profile_spatial = ProfileSignal("Rho at spatial positions",["ppf/hrts/rho"],[jet],causal_shifts=[25],mapping_range=(2,4),num_channels=profile_num_channels,data_avail_tolerances=[0.05])
162162

163-
etemp = Signal("electron temperature",["ppf/hrtx/te0"],[jet],causal_shifts=[25],data_avail_tolerance=0.05)
163+
etemp = Signal("electron temperature",["ppf/hrtx/te0"],[jet],causal_shifts=[25],data_avail_tolerances=[0.05])
164164
# epress = Signal("electron pressure",["ppf/hrtx/pe0/"],[jet],causal_shifts=[25])
165165

166-
q95 = Signal("q95 safety factor",['ppf/efit/q95',"EFIT01/RESULTS.AEQDSK.Q95"],[jet,d3d],causal_shifts=[15,10],normalize=False,data_avail_tolerance=0.03)
166+
q95 = Signal("q95 safety factor",['ppf/efit/q95',"EFIT01/RESULTS.AEQDSK.Q95"],[jet,d3d],causal_shifts=[15,10],normalize=False,data_avail_tolerances=[0.03,0.02])
167167

168168
ip = Signal("plasma current",["jpf/da/c2-ipla","d3d/ipspr15V"],[jet,d3d],is_ip=True) #"d3d/ipsip" was used before, ipspr15V seems to be available for a superset of shots.
169169
iptarget = Signal("plasma current target",["d3d/ipsiptargt"],[d3d])

plasma/primitives/data.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
# self.signals.append(Signal(signal_descriptions[i],signal_paths[i]))
1616

1717
class Signal(object):
18-
def __init__(self,description,paths,machines,tex_label=None,causal_shifts=None,is_ip=False,normalize=True,data_avail_tolerance=0,is_strictly_positive=False):
18+
def __init__(self,description,paths,machines,tex_label=None,
19+
causal_shifts=None,is_ip=False,normalize=True,
20+
data_avail_tolerances=None,is_strictly_positive=False,
21+
mapping_paths=None):
1922
assert(len(paths) == len(machines))
2023
self.description = description
2124
self.paths = paths
@@ -26,8 +29,11 @@ def __init__(self,description,paths,machines,tex_label=None,causal_shifts=None,i
2629
self.is_ip = is_ip
2730
self.num_channels = 1
2831
self.normalize = normalize
29-
self.data_avail_tolerance = data_avail_tolerance
32+
if data_avail_tolerances == None:
33+
data_avail_tolerances = [0 for m in machines]
34+
self.data_avail_tolerances = data_avail_tolerances
3035
self.is_strictly_positive=is_strictly_positive
36+
self.mapping_paths = mapping_paths
3137

3238
def is_strictly_positive_fn(self):
3339
return self.is_strictly_positive
@@ -112,10 +118,21 @@ def get_path(self,machine):
112118
idx = self.get_idx(machine)
113119
return self.paths[idx]
114120

121+
def get_mapping_path(self,machine):
122+
if self.mapping_paths is None:
123+
return None
124+
else:
125+
idx = self.get_idx(machine)
126+
return self.mapping_paths[idx]
127+
115128
def get_causal_shift(self,machine):
116129
idx = self.get_idx(machine)
117130
return self.causal_shifts[idx]
118131

132+
def get_data_avail_tolerance(self,machine):
133+
idx = self.get_idx(machine)
134+
return self.data_avail_tolerances[idx]
135+
119136
def get_idx(self,machine):
120137
assert(machine in self.machines)
121138
idx = self.machines.index(machine)
@@ -143,8 +160,8 @@ def __repr__(self):
143160
return self.description
144161

145162
class ProfileSignal(Signal):
146-
def __init__(self,description,paths,machines,tex_label=None,causal_shifts=None,mapping_range=(0,1),num_channels=32,data_avail_tolerance=0,is_strictly_positive=False):
147-
super(ProfileSignal, self).__init__(description,paths,machines,tex_label,causal_shifts,is_ip=False,data_avail_tolerance=data_avail_tolerance,is_strictly_positive=is_strictly_positive)
163+
def __init__(self,description,paths,machines,tex_label=None,causal_shifts=None,mapping_range=(0,1),num_channels=32,data_avail_tolerances=None,is_strictly_positive=False,mapping_paths=None):
164+
super(ProfileSignal, self).__init__(description,paths,machines,tex_label,causal_shifts,is_ip=False,data_avail_tolerance=data_avail_tolerance,is_strictly_positive=is_strictly_positive,mapping_paths=mapping_paths)
148165
self.mapping_range = mapping_range
149166
self.num_channels = num_channels
150167

@@ -195,10 +212,18 @@ def get_connection(self):
195212

196213
def fetch_data(self,signal,shot_num,c):
197214
path = signal.get_path(self)
215+
mapping_path = signal.get_mapping_path(self)
198216
success = False
199217
mapping = None
200218
try:
201219
time,data,mapping,success = self.fetch_data_fn(path,shot_num,c)
220+
if mapping_path is not None:
221+
time_map,data_map,mapping_map,success_map = self.fetch_data_fn(mapping_path,shot_num,c)
222+
assert(time == time_map), "time for signal {} and mapping {} don't align: \n{}\n\n{}\n".format(path,mapping_path,time,time_map)
223+
success = (success and success_map)
224+
if not success:
225+
print("No success for signal {} and mapping {}".format(path,mapping_path))
226+
mapping = data_map
202227
except Exception as e:
203228
time,data = create_missing_value_filler()
204229
print(e)

plasma/primitives/shots.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,11 @@ def get_signals_and_times_from_file(self,conf):
401401
signal_arrays.append(sig)
402402
time_arrays.append(t)
403403
if self.is_disruptive and self.t_disrupt > np.max(t):
404-
if self.t_disrupt > np.max(t) + signal.data_avail_tolerance:
404+
if self.t_disrupt > np.max(t) + signal.get_data_avail_tolerance(self.machine):
405405
print('Shot {}: disruption event is not contained in valid time region of signal {} by {}s, omitting.'.format(self.number,signal,self.t_disrupt - np.max(t)))
406406
valid = False
407407
else:
408-
t_max = np.max(t) + signal.data_avail_tolerance
408+
t_max = np.max(t) + signal.get_data_avail_tolerance(self.machine)
409409
else:
410410
t_max = min(t_max,np.max(t))
411411

0 commit comments

Comments
 (0)