8
8
import shutil
9
9
import os
10
10
11
- """
12
- read_mdsplus_channel(shot_numbers=31779, trees='KSTAR',
13
- point_names='EP53:FOO', server='203.230.126.231:8005',
14
- resample=None, verbose=False)
15
11
16
- Mostly copied from connection_test.py by D. Eldon
17
- """
18
- def read_mds (shot_numbers = 31779 , trees = 'KSTAR' ,
19
- point_names = 'EP53:FOO' , server = '203.230.126.231:8005' ,
12
+ def read_mds (shot_numbers = None , trees = None , point_names = None , server = None ,
20
13
resample = None , rescale = None , out_filename = None , reread_data = False ,
21
- config = None ,
22
- verbose = False ,):
14
+ config = None , verbose = False ,):
15
+ """
16
+ read_mds(shot_numbers=None, trees=None, point_names=None, server=None,
17
+ resample=None, rescale=None, out_filename=None, reread_data=False,
18
+ config=None, verbose=False,)
19
+
20
+ Read data from MDSPlus server for porivded shot numbers, trees, and pointnames.
21
+
22
+ Input keyword arguments:
23
+ shot_numbers: <int> or <list(int)>. Default is None.
24
+ trees: <str> or list(str) or dict(tress -> list of pointnames). Default is None. If
25
+ list, then the lenght of this list should match length of list provided to
26
+ pointnames arguments for one-to-one mapping.
27
+ point_names: <str> or list(str). Default is None. If list, then the lenght of this
28
+ list should match length of list provided to trees arguments for one-to-one
29
+ mapping.
30
+ server: <str>. MDSPlus server in the format of username@ip_address:port . Note that
31
+ it is assumed that your ssh configuration is setup to directly access this
32
+ server in case any tunneling is required.
33
+ resample: <lenght 3 iterable like list, tuple of floats> or
34
+ <dict(start: start_time, stop: stop_time, increment: time_step)>. If
35
+ provided as iterable, it should be in order start, stop, increment. It is
36
+ recommended to use dictionary input to ensure correct mapping. All times
37
+ should be float values and would be used in querying from time axis of
38
+ data.
39
+ rescale: <int, float> or <list(int or float)> or <dict(tree -> int or float)>
40
+ Used for rescaling time axis of data before resampling query (if any).
41
+ If <int, float>, same rescaling factor is applied across all trees.
42
+ If <list>, length of this list must be same as length of trees list for
43
+ one to one mapping of rescaling factor to a particular tree.
44
+ If <dict>, each tree would get it's own rescaling factor. If a tree is not
45
+ present in this dictionary, rescaling factor will default to 1.
46
+ Resamlplong factor gets multiplied with stored MDSPlus time axis data, thus
47
+ for example, if time axis data for a tree is in ms, supply rescaling factor
48
+ of 1e-3 to convert the downloaded data in seconds and resample in units of
49
+ seconds.
50
+ out_filename: <str> If provided, downloaded data will be stored in this filename in
51
+ HDF5 format. Thus `.h5` extension should be provided.
52
+ reread_data: <bool> If True, even if a pointname data is already present in
53
+ in `out_filename`, it will be downloaded again and overwritten. Can be
54
+ used if resample or rescale is changed from previous download.
55
+ config: <str> or <dict>. If <str>, the configuration file in YAML format would be
56
+ read to create the configuration dictionary. Use <dict> if using in
57
+ interactive mode.
58
+ Configuration dictionary can have any of the above arguments present in it.
59
+ Arguments provided by configuration dictionary take presidence over argument
60
+ directly provided to the function.
61
+ verbose: <bool> If true, status messages will be printed while downloading data.
62
+ """
23
63
if config is not None :
24
- with open (config , 'r' ) as f :
25
- config = yaml .safe_load (f )
64
+ if isinstance (config , str ):
65
+ with open (config , 'r' ) as f :
66
+ config = yaml .safe_load (f )
26
67
if 'shot_numbers' in config :
27
68
shot_numbers = config ['shot_numbers' ]
28
69
if 'trees' in config :
@@ -150,13 +191,20 @@ def read_mds(shot_numbers=31779, trees='KSTAR',
150
191
151
192
152
193
def add_slash (s ):
194
+ """
195
+ Make the name uppercase and add \\ suffix if not present already or if the name
196
+ does not start with PTDATA.
197
+ """
153
198
if s .startswith ("\\ " ) or s .startswith ("PTDATA" ):
154
199
return s .upper ()
155
200
ss = "\\ " + s .upper ()
156
201
return r'' + ss .encode ('unicode_escape' ).decode ('utf-8' )[1 :]
157
202
158
203
159
204
def add_resample (pn , resample , rescale_fac ):
205
+ """
206
+ Add resampling function wrapped in TDI call based on resample and rescale factor.
207
+ """
160
208
if resample is None :
161
209
return pn
162
210
if isinstance (resample , dict ):
@@ -166,20 +214,35 @@ def add_resample(pn, resample, rescale_fac):
166
214
return f"resample({ pn } , { resample [0 ]} , { resample [1 ]} , { resample [2 ]} )"
167
215
168
216
def get_time_array (resample ):
217
+ """
218
+ For a resample request, locally generate the time axis.
219
+ """
169
220
if isinstance (resample , dict ):
170
221
resample = [resample ['start' ], resample ['stop' ], resample ['increment' ]]
171
222
return np .arange (resample [0 ], resample [1 ] + resample [2 ]* 0.1 , resample [2 ])
172
223
173
224
174
225
def dim_of (pn , ii ):
226
+ """
227
+ Add dim_of() wrapper for extracting dimensional information like time axis.
228
+ """
175
229
return f"dim_of({ pn } , { ii } )"
176
230
177
231
178
232
def units_of (pn ):
233
+ """
234
+ Add units_of wrapper for extracting units of the data.
235
+ """
179
236
return f"units_of({ pn } )"
180
237
181
238
182
239
def check_exists (h5 , shot_number , tree , point_name ):
240
+ """
241
+ check_exists(h5, shot_number, tree, point_name)
242
+
243
+ Check if data for a point_name, tree, shot_number combination exists in the h5 file
244
+ object.
245
+ """
183
246
sn = str (shot_number )
184
247
if sn in h5 :
185
248
if tree in h5 [sn ]:
@@ -189,6 +252,12 @@ def check_exists(h5, shot_number, tree, point_name):
189
252
return True
190
253
191
254
def append_h5 (h5 , shot_number , tree , point_name , data_dict ):
255
+ """
256
+ append_h5(h5, shot_number, tree, point_name, data_dict)
257
+
258
+ Append downloaded data for a point_name, tree, shot_number combination to the h5
259
+ file object. If data already exists, it will be overwritten.
260
+ """
192
261
sntpn_dict = data_dict [shot_number ][tree ][point_name ]
193
262
sn = str (shot_number )
194
263
pn = point_name
@@ -207,12 +276,17 @@ def append_h5(h5, shot_number, tree, point_name, data_dict):
207
276
208
277
209
278
def get_args ():
210
- parser = argparse .ArgumentParser (description = 'Read MDSplus channel' )
211
- parser .add_argument ('-n' , '--shot_numbers' , type = int , nargs = '+' , help = 'Shot number(s)' )
279
+ parser = argparse .ArgumentParser (description = 'Read data from MDSPlus server for '
280
+ 'porivded shot numbers, trees, and '
281
+ 'pointnames.' )
282
+ parser .add_argument ('-n' , '--shot_numbers' , type = int , nargs = '+' ,
283
+ help = 'Shot number(s)' )
212
284
parser .add_argument ('-t' , '--trees' , nargs = '+' , help = 'Tree name(s)' )
213
- parser .add_argument ('-p' , '--point_names' , nargs = '+' , help = 'Point name(s)' )
214
- parser .add_argument ('-s' , '--server' , default = '203.230.126.231:8005' ,
215
- help = 'Server address. Default is 203.230.126.231:8005' )
285
+ parser .add_argument ('-p' , '--point_names' , nargs = '+' ,
286
+ help = 'Point name(s). Must match number of trees provided '
287
+ 'unless a single tree is given.' )
288
+ parser .add_argument ('-s' , '--server' , default = None ,
289
+ help = 'Server address. Default is None' )
216
290
parser .add_argument ('-r' , '--resample' , nargs = '+' , type = float , default = None ,
217
291
help = 'Resample signal(s) by providing a list of start, stop, '
218
292
'and increment values. For negative value, enclose them '
@@ -244,6 +318,9 @@ def get_args():
244
318
return args
245
319
246
320
def read_mds_cli ():
321
+ """
322
+ Command line version of read_mds which gets converted into a script in package.
323
+ """
247
324
args = get_args ()
248
325
if args .configTemplate :
249
326
root_dir = os .path .dirname (os .path .abspath (__file__ ))
0 commit comments