flekspy 0.2.0__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flekspy
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Python utilities for processing FLEKS data
5
5
  Author: Yuxi Chen
6
6
  Author-email: yuxichen@umich.edu>, Hongyang Zhou <hyzhou@umich.edu
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "flekspy"
3
- version = "0.2.0"
3
+ version = "0.2.2"
4
4
  description = "Python utilities for processing FLEKS data"
5
5
  authors = ["Yuxi Chen <yuxichen@umich.edu>, Hongyang Zhou <hyzhou@umich.edu>"]
6
6
  readme = "README.md"
@@ -2,17 +2,22 @@ import glob
2
2
  import numpy as np
3
3
  import matplotlib.pyplot as plt
4
4
  import struct
5
- import math
6
- import flekspy.util.utilities as utilities
7
5
  import yt
8
- import flekspy.util.data_container as data_container
6
+
7
+ from flekspy.util import get_unit
8
+ from flekspy.util import (
9
+ DataContainer,
10
+ DataContainer1D,
11
+ DataContainer2D,
12
+ DataContainer3D,
13
+ )
9
14
 
10
15
  x_ = 0
11
16
  y_ = 1
12
17
  z_ = 2
13
18
 
14
19
 
15
- class selector:
20
+ class Selector:
16
21
  def __getitem__(self, keys) -> list:
17
22
  self.indices = list(keys)
18
23
  if len(self.indices) < 3:
@@ -20,12 +25,12 @@ class selector:
20
25
  return self.indices
21
26
 
22
27
 
23
- class dataframe:
28
+ class Dataframe:
24
29
  def __init__(self):
25
30
  self.array = None
26
31
  self.name = None
27
32
  # Selector for the spatial indices
28
- self.cut = selector()
33
+ self.cut = Selector()
29
34
  self.cut[:, :, :]
30
35
 
31
36
  def setData(self, dataIn, nameIn):
@@ -52,6 +57,7 @@ class dataframe:
52
57
  else:
53
58
  keys = list(keys) + [slice(None, None, None)] * (4 - len(keys))
54
59
  ivar = self.name.index(keys[0])
60
+
55
61
  return np.squeeze(self.array[ivar, keys[1], keys[2], keys[3]])
56
62
 
57
63
 
@@ -62,7 +68,6 @@ class IDLData(object):
62
68
  Example:
63
69
  >>> ds = IDLData("3d.out")
64
70
  >>> dc2d = ds.get_slice("y", 1)
65
- >>> dc3d = ds.get_domain()
66
71
  """
67
72
 
68
73
  def __init__(self, filename="none"):
@@ -81,7 +86,7 @@ class IDLData(object):
81
86
 
82
87
  self.filename = fileList[ifile - 1]
83
88
  self.isOuts = self.filename[-4:] == "outs"
84
- self.data = dataframe()
89
+ self.data = Dataframe()
85
90
  self.nInstance = None if self.isOuts else 1
86
91
  self.npict = 1
87
92
  self.fileformat = None
@@ -122,14 +127,12 @@ class IDLData(object):
122
127
  )
123
128
  return str
124
129
 
125
- def get_domain(self):
126
- r"""
127
- Returns a dataContainer3D object that contains all the 3D data.
128
- """
130
+ def get_domain(self) -> DataContainer:
131
+ """Return data as data container."""
129
132
  dataSets = {}
130
133
  for varname in self.data.name:
131
134
  idx = self.data.name.index(varname)
132
- unit = utilities.get_unit(varname, self.unit)
135
+ unit = get_unit(varname, self.unit)
133
136
  dataSets[varname] = yt.YTArray(
134
137
  np.squeeze(self.data.array[idx, :, :, :]), unit, registry=self.registry
135
138
  )
@@ -140,15 +143,15 @@ class IDLData(object):
140
143
  name = self.variables[idim]
141
144
  idx = self.data.name.index(name)
142
145
  labels[idim] = name.upper()
143
- unit = utilities.get_unit("X", self.unit)
146
+ unit = get_unit("X", self.unit)
144
147
  name = name.upper()
145
148
  if name in ["X", "Y", "Z"]:
146
149
  axes[idim] = yt.YTArray(
147
150
  self.data.array[idx, :, :, :], unit, registry=self.registry
148
151
  )
149
152
 
150
- if self.gencoord:
151
- dc = data_container.dataContainer2D(
153
+ if self.gencoord and self.ndim == 2:
154
+ dc = DataContainer2D(
152
155
  dataSets,
153
156
  np.squeeze(axes[0]),
154
157
  np.squeeze(axes[1]),
@@ -160,7 +163,7 @@ class IDLData(object):
160
163
  gencoord=True,
161
164
  )
162
165
  elif self.ndim == 1:
163
- dc = data_container.dataContainer1D(
166
+ dc = DataContainer1D(
164
167
  dataSets,
165
168
  np.squeeze(axes[0]),
166
169
  labels[0],
@@ -169,7 +172,7 @@ class IDLData(object):
169
172
  filename=self.filename,
170
173
  )
171
174
  elif self.ndim == 2:
172
- dc = data_container.dataContainer2D(
175
+ dc = DataContainer2D(
173
176
  dataSets,
174
177
  np.squeeze(axes[0])[:, 0],
175
178
  np.squeeze(axes[1])[0, :],
@@ -180,7 +183,7 @@ class IDLData(object):
180
183
  filename=self.filename,
181
184
  )
182
185
  else:
183
- dc = data_container.dataContainer3D(
186
+ dc = DataContainer3D(
184
187
  dataSets,
185
188
  axes[0][:, 0, 0],
186
189
  axes[1][0, :, 0],
@@ -192,6 +195,23 @@ class IDLData(object):
192
195
 
193
196
  return dc
194
197
 
198
+ def get_slice(self, norm, cut_loc) -> DataContainer2D:
199
+ """Get a 2D slice from the 3D IDL data.
200
+
201
+ Args:
202
+ norm: str
203
+ The normal direction of the slice from "x", "y" or "z"
204
+
205
+ cur_loc: float
206
+ The position of slicing.
207
+
208
+ Return: DataContainer2D
209
+ """
210
+ domain = self.get_domain()
211
+ ds = domain.get_slice(norm, cut_loc)
212
+
213
+ return ds
214
+
195
215
  def save_data(self, saveName, saveFormat="ascii"):
196
216
  # Currently only support ascii output.
197
217
  self.save_ascii_instance(saveName)
@@ -240,7 +260,7 @@ class IDLData(object):
240
260
  elif self.fileformat == "binary":
241
261
  self.read_binary()
242
262
  else:
243
- print("Unknown format = ", self.fileformat)
263
+ raise ValueError(f"Unknown format = {self.fileformat}")
244
264
 
245
265
  ndim = self.ndim
246
266
  nvar = self.nvar
@@ -295,7 +315,6 @@ class IDLData(object):
295
315
  self.npoints = abs(self.grid.prod())
296
316
 
297
317
  time = self.time
298
- npts = self.npoints
299
318
  ndim = self.grid.size
300
319
  nvar = self.nvar
301
320
  npar = self.nparam
@@ -321,9 +340,9 @@ class IDLData(object):
321
340
  time % 60.0,
322
341
  )
323
342
 
324
- nRow = ndim + nvar
325
- nCol = self.npoints
326
- self.data.array = np.zeros((nRow, nCol))
343
+ nrow = ndim + nvar
344
+ ncol = self.npoints
345
+ self.data.array = np.zeros((nrow, ncol))
327
346
 
328
347
  for i, line in enumerate(infile.readlines()):
329
348
  parts = line.split()
@@ -335,7 +354,7 @@ class IDLData(object):
335
354
  self.data.array[j][i] = float(p)
336
355
 
337
356
  nline += self.npoints
338
- shapeNew = np.append([nRow], self.grid)
357
+ shapeNew = np.append([nrow], self.grid)
339
358
  self.data.array = np.reshape(self.data.array, shapeNew, order="F")
340
359
 
341
360
  return nline
@@ -357,110 +376,123 @@ class IDLData(object):
357
376
  def read_binary_instance(self, infile):
358
377
  # On the first try, we may fail because of wrong-endianess.
359
378
  # If that is the case, swap that endian and try again.
360
- EndChar = "<" # Endian marker (default: little)
379
+ end_char = "<" # Endian marker (default: little)
361
380
  self.endian = "little"
362
- RecLenRaw = infile.read(4)
381
+ record_len_raw = infile.read(4)
363
382
 
364
- RecLen = (struct.unpack(EndChar + "l", RecLenRaw))[0]
365
- if (RecLen > 10000) or (RecLen < 0):
366
- EndChar = ">"
383
+ record_len = (struct.unpack(end_char + "l", record_len_raw))[0]
384
+ if (record_len > 10000) or (record_len < 0):
385
+ end_char = ">"
367
386
  self.endian = "big"
368
- RecLen = (struct.unpack(EndChar + "l", RecLenRaw))[0]
387
+ record_len = (struct.unpack(end_char + "l", record_len_raw))[0]
369
388
 
370
389
  headline = (
371
- struct.unpack("{0}{1}s".format(EndChar, RecLen), infile.read(RecLen))
390
+ struct.unpack(
391
+ "{0}{1}s".format(end_char, record_len), infile.read(record_len)
392
+ )
372
393
  )[0].strip()
373
394
  if str is not bytes:
374
395
  headline = headline.decode()
375
396
  self.unit = headline.split()[0]
376
397
 
377
- (OldLen, RecLen) = struct.unpack(EndChar + "2l", infile.read(8))
398
+ (old_len, record_len) = struct.unpack(end_char + "2l", infile.read(8))
378
399
  pformat = "f"
379
400
  # Parse rest of header; detect double-precision file
380
- if RecLen > 20:
401
+ if record_len > 20:
381
402
  pformat = "d"
382
403
  (self.iter, self.time, self.ndim, self.nparam, self.nvar) = struct.unpack(
383
- "{0}l{1}3l".format(EndChar, pformat), infile.read(RecLen)
404
+ "{0}l{1}3l".format(end_char, pformat), infile.read(record_len)
384
405
  )
385
406
  self.gencoord = self.ndim < 0
386
407
  self.ndim = abs(self.ndim)
387
408
  # Get gridsize
388
- (OldLen, RecLen) = struct.unpack(EndChar + "2l", infile.read(8))
409
+ (old_len, record_len) = struct.unpack(end_char + "2l", infile.read(8))
389
410
 
390
411
  self.grid = np.array(
391
412
  struct.unpack(
392
- "{0}{1}l".format(EndChar, abs(self.ndim)), infile.read(RecLen)
413
+ "{0}{1}l".format(end_char, abs(self.ndim)), infile.read(record_len)
393
414
  )
394
415
  )
395
416
  self.npoints = abs(self.grid.prod())
396
417
 
397
- time = self.time
398
418
  npts = self.npoints
399
419
  ndim = self.grid.size
400
420
  nvar = self.nvar
401
421
  npar = self.nparam
402
422
 
403
423
  # Read parameters stored in file
404
- self.para = np.zeros(npar)
405
- if npar > 0:
406
- (OldLen, RecLen) = struct.unpack(EndChar + "2l", infile.read(8))
407
- self.para[:] = struct.unpack(
408
- "{0}{1}{2}".format(EndChar, npar, pformat), infile.read(RecLen)
409
- )
410
-
411
- (OldLen, RecLen) = struct.unpack(EndChar + "2l", infile.read(8))
412
- names = (struct.unpack("{0}{1}s".format(EndChar, RecLen), infile.read(RecLen)))[
413
- 0
414
- ]
415
- if str is not bytes:
416
- names = names.decode()
417
-
418
- names.strip()
419
- names = names.split()
420
-
421
- # Save grid names (e.g. "x" or "r") and save associated params
422
- self.dims = names[0:ndim]
423
- self.variables = np.array(names)
424
+ self.read_parameters(infile, end_char, pformat, npar)
424
425
 
425
- self.strtime = "{0:04d}h{1:02d}m{2:06.3f}s".format(
426
- int(time // 3600), int(time % 3600 // 60), time % 60
427
- )
426
+ # Read variable names
427
+ self.read_variable_names(infile, end_char)
428
428
 
429
- nRow = ndim + nvar
430
- nCol = self.npoints
431
- self.data.array = np.zeros((nRow, nCol), dtype=np.float32)
429
+ nrow = ndim + nvar
430
+ n_col = self.npoints
431
+ self.data.array = np.zeros((nrow, n_col), dtype=np.float32)
432
432
 
433
433
  # Get the grid points...
434
- (OldLen, RecLen) = struct.unpack(EndChar + "2l", infile.read(8))
434
+ (old_len, record_len) = struct.unpack(end_char + "2l", infile.read(8))
435
435
  for i in range(0, ndim):
436
436
  # Read the data into a temporary grid
437
437
  tempgrid = np.array(
438
438
  struct.unpack(
439
- "{0}{1}{2}".format(EndChar, npts, pformat),
440
- infile.read(int(RecLen // ndim)),
439
+ "{0}{1}{2}".format(end_char, npts, pformat),
440
+ infile.read(int(record_len // ndim)),
441
441
  )
442
442
  )
443
443
  self.data.array[i, :] = tempgrid
444
444
 
445
445
  # Get the actual data and sort
446
446
  for i in range(ndim, nvar + ndim):
447
- (OldLen, RecLen) = struct.unpack(EndChar + "2l", infile.read(8))
447
+ (old_len, record_len) = struct.unpack(end_char + "2l", infile.read(8))
448
448
  tmp = np.array(
449
449
  struct.unpack(
450
- "{0}{1}{2}".format(EndChar, npts, pformat), infile.read(RecLen)
450
+ "{0}{1}{2}".format(end_char, npts, pformat), infile.read(record_len)
451
451
  )
452
452
  )
453
453
  self.data.array[i, :] = tmp
454
454
  # Consume the last record length
455
455
  infile.read(4)
456
456
 
457
- shapeNew = np.append([nRow], self.grid)
458
- self.data.array = np.reshape(self.data.array, shapeNew, order="F")
457
+ shape_new = np.append([nrow], self.grid)
458
+ self.data.array = np.reshape(self.data.array, shape_new, order="F")
459
+
460
+ def read_parameters(self, infile, end_char, pformat, num_params):
461
+ """Reads parameters from the binary file."""
462
+ self.para = np.zeros(num_params)
463
+ if num_params > 0:
464
+ (old_len, record_len) = struct.unpack(end_char + "2l", infile.read(8))
465
+ self.para[:] = struct.unpack(
466
+ "{0}{1}{2}".format(end_char, num_params, pformat),
467
+ infile.read(record_len),
468
+ )
469
+
470
+ def read_variable_names(self, infile, end_char):
471
+ """Reads variable names from the binary file."""
472
+ (old_len, record_len) = struct.unpack(end_char + "2l", infile.read(8))
473
+ names = (
474
+ struct.unpack(
475
+ "{0}{1}s".format(end_char, record_len), infile.read(record_len)
476
+ )
477
+ )[0]
478
+ if str is not bytes:
479
+ names = names.decode()
480
+
481
+ names.strip()
482
+ names = names.split()
483
+
484
+ # Save grid names (e.g. "x" or "r") and save associated params
485
+ self.dims = names[0 : self.ndim]
486
+ self.variables = np.array(names)
487
+
488
+ self.strtime = "{0:04d}h{1:02d}m{2:06.3f}s".format(
489
+ int(self.time // 3600), int(self.time % 3600 // 60), self.time % 60
490
+ )
459
491
 
460
492
  def plot(self, *dvname, **kwargs):
461
493
  """Plot 1D IDL outputs.
462
494
 
463
- Returns:
495
+ Args:
464
496
  *dvname (str): variable names
465
497
  **kwargs: keyword argument to be passed to `plot`.
466
498
  """
@@ -468,7 +500,7 @@ class IDLData(object):
468
500
  nvar = len(dvname)
469
501
 
470
502
  f, axes = plt.subplots(nvar, 1, constrained_layout=True, sharex=True)
471
- axes = np.array(axes) # in case nRow = nCol = 1
503
+ axes = np.array(axes) # in case nrows == ncols == 1
472
504
  axes = axes.reshape(-1)
473
505
  for isub, ax in zip(range(nvar), axes):
474
506
  w = self.data[dvname[isub]]
@@ -0,0 +1,7 @@
1
+ from .utilities import download_testfile, unit_one, get_unit, get_ticks
2
+ from .data_container import (
3
+ DataContainer,
4
+ DataContainer1D,
5
+ DataContainer2D,
6
+ DataContainer3D,
7
+ )
@@ -1,12 +1,13 @@
1
+ from copy import deepcopy
2
+
1
3
  import yt
2
4
  import numpy as np
3
5
  import matplotlib.pyplot as plt
4
- import math
5
- from flekspy.util.utilities import get_unit, get_ticks
6
- from flekspy.plot.streamplot import streamplot
7
- from copy import deepcopy
8
- from scipy.interpolate import griddata
9
6
  import matplotlib.tri as tri
7
+ from scipy.interpolate import griddata
8
+
9
+ from flekspy.util.utilities import get_unit
10
+ from flekspy.plot.streamplot import streamplot
10
11
 
11
12
 
12
13
  def compare(d1, d2):
@@ -27,7 +28,7 @@ def compare(d1, d2):
27
28
  print(s.format(*l))
28
29
 
29
30
 
30
- class dataContainer(object):
31
+ class DataContainer(object):
31
32
  def __init__(
32
33
  self,
33
34
  dataSets,
@@ -42,12 +43,6 @@ class dataContainer(object):
42
43
  gencoord=False,
43
44
  filename="",
44
45
  ):
45
-
46
- # Re-generate the coordinates to make sure they are equally spaced.
47
- # x = np.linspace(x[0], x[-1], len(x))
48
- # y = np.linspace(y[0], y[-1], len(y))
49
- # z = np.linspace(z[0], z[-1], len(z))
50
-
51
46
  self.data = dataSets
52
47
  self.x = x
53
48
  self.y = y
@@ -64,22 +59,14 @@ class dataContainer(object):
64
59
  self.filename = filename
65
60
  self.gencoord = gencoord
66
61
 
67
- def __repr__(self):
68
- print("\n-----------------------------")
69
- print("Variables :", self.vars)
70
- print("\nData range :", self.range)
71
- print("\nData dimensions :", self.dimensions)
72
- print("\n")
73
-
74
- header = ("var", "min", "max", "mean")
75
- s = "{:8} " + "{:18}" * 3
76
- print(s.format(*header))
77
- for v in self.vars:
78
- d = self.data[v]
79
- s = "{:10}" + "{:+.6e}, " * 3
80
- print(s.format(v, float(d.min()), float(d.max()), float(d.mean())))
81
- print("-----------------------------")
82
- return "\n"
62
+ def __repr__(self) -> str:
63
+ str = (
64
+ f"variables : {self.vars}\n"
65
+ f"data range: {self.range}\n"
66
+ f"dimension : {self.dimensions}\n"
67
+ )
68
+
69
+ return str
83
70
 
84
71
  def add_bottom_line(self, f, verbose):
85
72
  if verbose > 0:
@@ -94,15 +81,13 @@ class dataContainer(object):
94
81
 
95
82
  def analyze_variable_string(self, var):
96
83
  r"""
97
- This method analyzes the plot string and return the plot variable and plot range.
84
+ Parses the input string and return the plot variable and plot range.
98
85
 
99
- Parameters
100
- ----------------------
101
- var: String
102
- Example: var = "{bb}<(-10)>(-9.8)"
86
+ Args:
87
+ var: str
88
+ Example: var = "{bb}<(-10)>(-9.8)"
103
89
 
104
- Return: a tuple contains the variable name, variable min and max.
105
- Example: return "{bb}", -10, -9.8
90
+ Return: a tuple of the variable name, variable min and max.
106
91
  """
107
92
  vMin = None
108
93
  vMax = None
@@ -126,15 +111,13 @@ class dataContainer(object):
126
111
 
127
112
  return varName, vMin, vMax
128
113
 
129
- def evaluate_expression(self, expression, unit="planet"):
114
+ def evaluate_expression(self, expression: str, unit: str = "planet"):
130
115
  r"""
131
- This method calculates the variable expression and return the result, which is
132
- a YTArray.
116
+ Evaluates the variable expression and return the result of an YTArray.
133
117
 
134
- Parameters
135
- -------------------
136
- expression: String
137
- Example: expression = "np.log({rhos0}+{rhos1})"
118
+ Args:
119
+ expression: str
120
+ Example: expression = "np.log({rhos0}+{rhos1})"
138
121
  """
139
122
 
140
123
  if expression.find("{") < 0:
@@ -152,16 +135,14 @@ class dataContainer(object):
152
135
 
153
136
  def add_variable(self, name, val):
154
137
  r"""
155
- This method adds a variable to the dataset for visualization purpose
156
-
157
- Parameters
158
- ------------------
159
- name: String
160
- The name of the variable to be added into self.data
138
+ Adds a variable to the dataset.
161
139
 
162
- val: array-like structure
163
- Values of the variable stored in an array
140
+ Args:
141
+ name: str
142
+ The name of the variable to be added into self.data
164
143
 
144
+ val: array-like structure
145
+ Values of the variable stored in an array
165
146
  """
166
147
 
167
148
  if type(val) != yt.units.yt_array.YTArray:
@@ -173,14 +154,13 @@ class dataContainer(object):
173
154
 
174
155
  def get_variable(self, var, unit="planet"):
175
156
  r"""
176
- This method calculate the value of the variable.
157
+ Return raw variables or calculate derived variables.
177
158
 
178
- Parameters
179
- ------------------
180
- var: String
181
- Example: var = "pbeta"
159
+ Args:
160
+ var: str
161
+ variable name
182
162
 
183
- Return: A YTArray
163
+ Return: YTArray
184
164
  """
185
165
 
186
166
  if var in self.data.keys():
@@ -227,7 +207,7 @@ class dataContainer(object):
227
207
  return ytarr if str(ytarr.units) == "dimensionless" else ytarr.in_units(varUnit)
228
208
 
229
209
 
230
- class dataContainer3D(dataContainer):
210
+ class DataContainer3D(DataContainer):
231
211
  r"""
232
212
  A class handles 3D box data sets.
233
213
  """
@@ -236,30 +216,27 @@ class dataContainer3D(dataContainer):
236
216
  self, dataSets, x, y, z, xlabel="X", ylabel="Y", zlabel="Z", *args, **kwargs
237
217
  ):
238
218
  r"""
239
- Parameters
240
- ---------------------
241
- dataSets: dictonary
242
- The key is the variable name, and the dictionary value is usually a YTArray.
219
+ Args:
220
+ dataSets: dictonary
221
+ The key is the variable name, and the dictionary value is usually a YTArray.
243
222
 
244
- x/y/z: A 1D YTArray
223
+ x/y/z: A 1D YTArray
245
224
  """
246
- super(dataContainer3D, self).__init__(
225
+ super(DataContainer3D, self).__init__(
247
226
  dataSets, x, y, z, xlabel, ylabel, zlabel, *args, **kwargs
248
227
  )
249
228
 
250
- def get_slice(self, norm, cut_loc):
251
- r"""
252
- Get a 2D slice from the 3D box data.
229
+ def get_slice(self, norm, cut_loc) -> "DataContainer2D":
230
+ """Get a 2D slice from the 3D box data.
253
231
 
254
- Parameters
255
- ------------------
256
- norm: String
257
- The normal direction of the slice. Potential value: 'x', 'y' or 'z'
232
+ Args:
233
+ norm: str
234
+ The normal direction of the slice from "x", "y" or "z"
258
235
 
259
- cur_loc: Float
260
- The position of slicing.
236
+ cur_loc: float
237
+ The position of slicing.
261
238
 
262
- Return: A dataContainer2D object
239
+ Return: DataContainer2D
263
240
  """
264
241
 
265
242
  axDir = {"X": 0, "Y": 1, "Z": 2}
@@ -286,7 +263,7 @@ class dataContainer3D(dataContainer):
286
263
  axLabes = {0: ("Y", "Z"), 1: ("X", "Z"), 2: ("X", "Y")}
287
264
  ax = {0: (1, 2), 1: (0, 2), 2: (0, 1)}
288
265
 
289
- return dataContainer2D(
266
+ return DataContainer2D(
290
267
  dataSets,
291
268
  axes[ax[idir][0]],
292
269
  axes[ax[idir][1]],
@@ -297,7 +274,7 @@ class dataContainer3D(dataContainer):
297
274
  )
298
275
 
299
276
 
300
- class dataContainer2D(dataContainer):
277
+ class DataContainer2D(DataContainer):
301
278
  r"""
302
279
  A class handles 2D Cartesian data.
303
280
  """
@@ -312,29 +289,27 @@ class dataContainer2D(dataContainer):
312
289
  cut_norm=None,
313
290
  cut_loc=None,
314
291
  *args,
315
- **kwargs
292
+ **kwargs,
316
293
  ):
317
294
  r"""
318
- Parameters
319
- ---------------------
320
- dataSets: dictonary
321
- The key is the variable name, and the dictionary value is usually a YTArray.
295
+ Args:
296
+ dataSets: dictonary
297
+ The keys are variable names, and the values are YTArrays.
322
298
 
323
- x/y: A 1D YTArray
299
+ x/y: 1D YTArray
324
300
 
325
- xlabel/ylabel: String
301
+ xlabel/ylabel: str
326
302
 
327
- cut_norm: String
328
- 'x', 'y' or 'z'
303
+ cut_norm: str
304
+ "x", "y" or "z"
329
305
 
330
- cut_loc: Float
331
- cut_norm and cut_loc are used to record the position of slice if this 2D
332
- data set is obtained from a 3D box.
306
+ cut_loc: float
307
+ cut_norm and cut_loc are used to record the position of slice if this 2D data set is obtained from a 3D box.
333
308
  """
334
309
 
335
310
  zlabel = None
336
311
  z = (0, 0)
337
- super(dataContainer2D, self).__init__(
312
+ super(DataContainer2D, self).__init__(
338
313
  dataSets, x, y, z, xlabel, ylabel, zlabel, *args, **kwargs
339
314
  )
340
315
 
@@ -347,7 +322,7 @@ class dataContainer2D(dataContainer):
347
322
  dif.data[var] -= other.data[var]
348
323
  return dif
349
324
 
350
- def contour(
325
+ def plot(
351
326
  self,
352
327
  vars,
353
328
  xlim=None,
@@ -357,60 +332,45 @@ class dataContainer2D(dataContainer):
357
332
  cmap="turbo",
358
333
  figsize=(10, 6),
359
334
  pcolor=False,
360
- log=False,
335
+ logscale=False,
361
336
  addgrid=False,
362
337
  bottomline=10,
363
- plot=None,
364
- cbticks=None,
365
338
  showcolorbar=True,
366
- createcanvas=False,
367
339
  *args,
368
- **kwargs
340
+ **kwargs,
369
341
  ):
370
342
  r"""
371
- Contour plots.
372
-
373
- Parameters
374
- ----------------------
375
- vars: String
376
- Ploting variables and ploting range.
377
- Example: vars = "Bx<(50)>(-50) By (np.log(2*{rhos0}))>(-5)"
378
-
379
- xlim/ylim: A list/tuple contains the x- y-axis range
343
+ 2D plots.
380
344
 
381
- unit: String
382
- 'planet' or 'si'
345
+ Args:
346
+ vars: str
347
+ Ploting variables and ploting range.
348
+ Example: vars = "Bx<(50)>(-50) By (np.log(2*{rhos0}))>(-5)"
383
349
 
384
- nlevels: Integer
385
- Number of the countour plot color levels
350
+ xlim/ylim: A list/tuple contains the x- y-axis range
386
351
 
387
- cmap: String
388
- Color map type
352
+ unit: str
353
+ "planet" or "si"
389
354
 
390
- figsize: A tuple
355
+ nlevels: int
356
+ Number of the contour levels
391
357
 
392
- log: Bool
393
- Using log plot or not.
358
+ cmap: str
359
+ Color map type
394
360
 
395
- plot: list or tuple of [f, axes]
396
- Used to fine tune the individual subplot
361
+ figsize: tuple
397
362
 
398
- createcanvas: boolean
399
- If set to True, skip the contour making process to get an empty
400
- canvas which can be used to generate subplots in different styles.
401
- Set this flag to get the value for 'plot' parameter.
363
+ logscale: Bool
364
+ True to scale the variable in log.
402
365
 
403
- Examples
404
- ----------------
405
- >>> f,axes = dc.contour("Bx<(50)>(-50) By (np.log(2*{rhos0}))>(-5)",xlim=[-40,-5])
366
+ Examples:
367
+ >>> f, axes = dc.contour("Bx<(50)>(-50) By (np.log(2*{rhos0}))>(-5)", xlim=[-40,-5])
406
368
  """
407
369
 
408
370
  if type(vars) == str:
409
371
  vars = vars.split()
410
372
 
411
373
  nvar = len(vars)
412
- nRow = int(round(np.sqrt(nvar)))
413
- nCol = math.ceil(nvar / nRow)
414
374
 
415
375
  varNames = []
416
376
  varMin = []
@@ -421,17 +381,11 @@ class dataContainer2D(dataContainer):
421
381
  varMin.append(vmin)
422
382
  varMax.append(vmax)
423
383
 
424
- if plot:
425
- f, axes = plot
426
- else:
427
- f, axes = plt.subplots(nRow, nCol, figsize=figsize)
428
- axes = np.array(axes) # in case nRow = nCol = 1
429
-
384
+ f, axes = plt.subplots(nvar, 1, figsize=figsize, layout="constrained")
385
+ axes = np.array(axes) # in case nrows == ncols == 1
430
386
  axes = axes.reshape(-1)
431
387
 
432
388
  for isub, ax in zip(range(nvar), axes):
433
- if createcanvas: # no need to make any contour, just keep
434
- break # the canvas clean
435
389
  ytVar = self.evaluate_expression(varNames[isub], unit)
436
390
  v = ytVar
437
391
  varUnit = "dimensionless"
@@ -442,8 +396,7 @@ class dataContainer2D(dataContainer):
442
396
  vmin = v.min() if varMin[isub] == None else varMin[isub]
443
397
  vmax = v.max() if varMax[isub] == None else varMax[isub]
444
398
 
445
- logplot = log and vmin > 0
446
- if logplot:
399
+ if logscale:
447
400
  v = np.log10(v)
448
401
 
449
402
  levels = np.linspace(vmin, vmax, nlevels)
@@ -461,7 +414,7 @@ class dataContainer2D(dataContainer):
461
414
  cmap=cmap,
462
415
  extend="both",
463
416
  *args,
464
- **kwargs
417
+ **kwargs,
465
418
  )
466
419
  else:
467
420
  if pcolor or abs(vmin - vmax) < 1e-20 * abs(vmax):
@@ -477,7 +430,7 @@ class dataContainer2D(dataContainer):
477
430
  cmap=cmap,
478
431
  extend="both",
479
432
  *args,
480
- **kwargs
433
+ **kwargs,
481
434
  )
482
435
  if addgrid:
483
436
  if self.gencoord:
@@ -490,13 +443,8 @@ class dataContainer2D(dataContainer):
490
443
 
491
444
  ax.plot(gx, gy, "x")
492
445
 
493
- if cbticks:
494
- ticks = cbticks
495
- else:
496
- ticks = get_ticks(vmin, vmax)
497
-
498
446
  if showcolorbar:
499
- cb = f.colorbar(cs, ax=ax, ticks=ticks)
447
+ cb = f.colorbar(cs, ax=ax, pad=0.01)
500
448
  cb.formatter.set_powerlimits((0, 0))
501
449
 
502
450
  ax.set_xlim(xlim)
@@ -505,36 +453,29 @@ class dataContainer2D(dataContainer):
505
453
  ax.set_ylabel(self.ylabel)
506
454
  title = varNames[isub]
507
455
  if varUnit != "dimensionless":
508
- title = title + " [" + varUnit + "]"
509
- if logplot:
456
+ title += " [" + varUnit + "]"
457
+ if logscale:
510
458
  title = "$log_{10}$(" + title + ")"
511
459
  ax.set_title(title)
512
460
 
513
- # Delete axes for empty subplots
514
- for ax in axes[nvar : nRow * nCol]:
515
- f.delaxes(ax)
516
-
517
- plt.tight_layout()
518
461
  if self.cut_norm != None and self.cut_loc != None:
519
462
  print("Plots at " + self.cut_norm + " = ", self.cut_loc)
520
463
 
521
464
  self.add_bottom_line(f, bottomline)
522
- return f, axes.reshape(nRow, nCol)
465
+
466
+ return f, axes
523
467
 
524
468
  def add_contour(self, ax, var, unit="planet", rmask=None, *args, **kwargs):
525
- r"""
526
- Adding contour lines to an axis.
469
+ r"""Adding contour lines to an axis.
527
470
 
528
- Parameters
529
- --------------------
530
- ax: matplotlib axis
531
- The aixs to plot contour lines.
471
+ Args:
472
+ ax: matplotlib axis
473
+ The axis to plot contour lines.
532
474
 
533
- var: String
475
+ var: string
534
476
 
535
- Examples
536
- ----------------------
537
- >>> f,axes = dc.contour("Bx<(50)>(-50) By (np.log(2*{rhos0}))>(-5)",xlim=[-40,-5])
477
+ Examples:
478
+ >>> f, axes = dc.plot("Bx<(50)>(-50) By (np.log(2*{rhos0}))>(-5)", xlim=[-40,-5])
538
479
  >>> dc.add_contour(axes[0,0], "rhos1>1")
539
480
  """
540
481
 
@@ -574,24 +515,23 @@ class dataContainer2D(dataContainer):
574
515
  ymax=None,
575
516
  rmask=None,
576
517
  *args,
577
- **kwargs
518
+ **kwargs,
578
519
  ):
579
520
  r"""
580
521
  Adding streamlines to an axis.
581
522
 
582
- Parameters
583
- --------------------
584
- ax: matplotlib axis
585
- The aixs to add streamlines
523
+ Args:
524
+ ax: matplotlib axis
525
+ The axis to add streamlines
586
526
 
587
- var1/var2: String
527
+ var1/var2: str
528
+ Streamline variable names
588
529
 
589
- density: Int
590
- It controls the number of streamlines.
530
+ density: int
531
+ It controls the number of streamlines.
591
532
 
592
- Examples
593
- ----------------------
594
- >>> f,axes = dc.contour("Bx<(50)>(-50) By (np.log(2*{rhos0}))>(-5)",xlim=[-40,-5])
533
+ Examples:
534
+ >>> f, axes = dc.plot("Bx<(50)>(-50) By (np.log(2*{rhos0}))>(-5)", xlim=[-40,-5])
595
535
  >>> dc.add_stream(axes[1,0], "Bx", "Bz", density=2)
596
536
  """
597
537
 
@@ -618,7 +558,7 @@ class dataContainer2D(dataContainer):
618
558
  xy = np.zeros((len(self.x), 2))
619
559
  xy[:, 0] = self.x.value
620
560
  xy[:, 1] = self.y.value
621
- # The first and last row/column may be None. Remove them
561
+ # Remove the first and last row/column since they may be None
622
562
  vect1 = griddata(xy, v1, (gridx, gridy), method="linear")[1:-1, 1:-1]
623
563
  vect2 = griddata(xy, v2, (gridx, gridy), method="linear")[1:-1, 1:-1]
624
564
  xx = gridx[1:-1, 0]
@@ -638,26 +578,23 @@ class dataContainer2D(dataContainer):
638
578
  vect1[i, j] = np.nan
639
579
  vect2[i, j] = np.nan
640
580
 
641
- streamplot(
642
- ax, xx, yy, vect1.T, vect2.T, density=density, *args, **kwargs
643
- )
581
+ streamplot(ax, xx, yy, vect1.T, vect2.T, density=density, *args, **kwargs)
644
582
 
645
583
 
646
- class dataContainer1D(dataContainer):
584
+ class DataContainer1D(DataContainer):
647
585
  r"""
648
586
  A class handles 1D Cartesian data.
649
587
  """
650
588
 
651
589
  def __init__(self, dataSets, x, xlabel, *args, **kwargs):
652
590
  r"""
653
- Parameters
654
- ---------------------
655
- dataSets: dictonary
656
- The key is the variable name, and the dictionary value is usually a YTArray.
591
+ Args:
592
+ dataSets: dictonary
593
+ The key is the variable name, and the dictionary value is usually a YTArray.
657
594
 
658
- x: A 1D YTArray
595
+ x: 1D YTArray
659
596
 
660
- xlabel: String
597
+ xlabel: str
661
598
  """
662
599
 
663
600
  ylabel = None
@@ -666,7 +603,7 @@ class dataContainer1D(dataContainer):
666
603
  zlabel = None
667
604
  z = (0, 0)
668
605
 
669
- super(dataContainer1D, self).__init__(
606
+ super(DataContainer1D, self).__init__(
670
607
  dataSets, x, y, z, xlabel, ylabel, zlabel, *args, **kwargs
671
608
  )
672
609
 
@@ -675,25 +612,21 @@ class dataContainer1D(dataContainer):
675
612
  vars,
676
613
  xlim=None,
677
614
  ylim=None,
678
- unit="planet",
615
+ unit: str = "planet",
679
616
  figsize=(12, 8),
680
- log=False,
681
617
  bottomline=10,
682
618
  *args,
683
- **kwargs
619
+ **kwargs,
684
620
  ):
685
621
  """
686
- Examples
687
- ----------------
688
- >>> f,axes=dc.plot("absdivb bx",xlim=[-5,5],color='k',linestyle='solid',marker='x')
622
+ Examples:
623
+ >>> f, axes = dc.plot("absdivb bx", xlim=[-5,5])
689
624
  """
690
625
 
691
626
  if type(vars) == str:
692
627
  vars = vars.split()
693
628
 
694
629
  nvar = len(vars)
695
- nRow = int(round(np.sqrt(nvar)))
696
- nCol = math.ceil(nvar / nRow)
697
630
 
698
631
  varNames = []
699
632
  varMin = []
@@ -704,18 +637,13 @@ class dataContainer1D(dataContainer):
704
637
  varMin.append(vmin)
705
638
  varMax.append(vmax)
706
639
 
707
- f, axes = plt.subplots(nRow, nCol, figsize=figsize)
708
- axes = np.array(axes) # in case nRow = nCol = 1
709
-
640
+ f, axes = plt.subplots(nvar, 1, figsize=figsize)
641
+ axes = np.array(axes) # in case nrows == ncols == 1
710
642
  axes = axes.reshape(-1)
711
643
 
712
644
  for isub, ax in zip(range(nvar), axes):
713
645
  ytVar = self.evaluate_expression(varNames[isub], unit)
714
646
  v = ytVar
715
- varUnit = "dimensionless"
716
- if type(ytVar) == yt.units.yt_array.YTArray:
717
- v = ytVar.value
718
- varUnit = str(ytVar.units)
719
647
 
720
648
  vmin = v.min() if varMin[isub] == None else varMin[isub]
721
649
  vmax = v.max() if varMax[isub] == None else varMax[isub]
@@ -728,4 +656,5 @@ class dataContainer1D(dataContainer):
728
656
  ax.legend()
729
657
 
730
658
  self.add_bottom_line(f, bottomline)
659
+
731
660
  return f, axes
@@ -1,8 +1,8 @@
1
- import yt
2
1
  import os
3
2
  import glob
4
3
  import numpy as np
5
4
 
5
+ import yt
6
6
  from yt.funcs import setdefaultattr
7
7
  from yt.frontends.boxlib.api import BoxlibHierarchy, BoxlibDataset
8
8
  from yt.fields.field_info_container import FieldInfoContainer
@@ -11,8 +11,8 @@ from yt.data_objects.selection_objects.data_selection_objects import (
11
11
  )
12
12
  from yt.visualization.profile_plotter import PhasePlot
13
13
 
14
- import flekspy.util.data_container as data_container
15
- from flekspy.util.utilities import get_unit
14
+ from flekspy.util import DataContainer2D, DataContainer3D
15
+ from flekspy.util import get_unit
16
16
 
17
17
 
18
18
  class FLEKSFieldInfo(FieldInfoContainer):
@@ -119,16 +119,13 @@ class FLEKSData(BoxlibDataset):
119
119
  r"""
120
120
  Read and plot the AMReX format output from FLEKS.
121
121
 
122
- Parameters
123
- ----------
124
- output_dir : String
125
- The path to the data.
126
-
127
- Examples
128
- --------
122
+ Args:
123
+ output_dir : String
124
+ The path to the data.
129
125
 
130
- >>> import flekspy
131
- >>> ds = flekspy.FLEKSData("3d_particle*n00004750_amrex")
126
+ Examples:
127
+ >>> import flekspy
128
+ >>> ds = flekspy.FLEKSData("3d_particle*n00004750_amrex")
132
129
  """
133
130
 
134
131
  _index_class = FLEKSHierarchy
@@ -206,15 +203,13 @@ class FLEKSData(BoxlibDataset):
206
203
  def pvar(self, var):
207
204
  return (self.particle_types[0], var)
208
205
 
209
- def get_slice(self, norm, cut_loc):
206
+ def get_slice(self, norm, cut_loc) -> DataContainer2D:
210
207
  r"""
211
- This method returns a dataContainer2D object that contains a slice along
212
- the normal direction.
208
+ Returns a DataContainer2D object that contains a slice along the normal direction.
213
209
 
214
- Parameters
215
- ---------------------
216
- norm (str): slice normal direction in "x", "y" or "z"
217
- cut_loc (float): cut location along the normal direction
210
+ Args:
211
+ norm (str): slice normal direction in "x", "y" or "z"
212
+ cut_loc (float): cut location along the normal direction
218
213
  """
219
214
 
220
215
  axDir = {"X": 0, "Y": 1, "Z": 2}
@@ -238,7 +233,8 @@ class FLEKSData(BoxlibDataset):
238
233
 
239
234
  dataSets = {}
240
235
  for var in self.field_list:
241
- dataSets[var[1]] = np.squeeze(abArr[var])
236
+ if abArr[var].size != 0: # remove empty sliced particle output
237
+ dataSets[var[1]] = np.squeeze(abArr[var])
242
238
 
243
239
  axLabes = {0: ("Y", "Z"), 1: ("X", "Z"), 2: ("X", "Y")}
244
240
 
@@ -253,7 +249,7 @@ class FLEKSData(BoxlibDataset):
253
249
  )
254
250
  )
255
251
 
256
- return data_container.dataContainer2D(
252
+ return DataContainer2D(
257
253
  dataSets,
258
254
  axes[0],
259
255
  axes[1],
@@ -263,9 +259,9 @@ class FLEKSData(BoxlibDataset):
263
259
  cut_loc,
264
260
  )
265
261
 
266
- def get_domain(self):
262
+ def get_domain(self) -> DataContainer3D:
267
263
  r"""
268
- Reading in all the simulation data into a 3D box. It returns a dataContainer3D object.
264
+ Read all the simulation data into a 3D box.
269
265
  """
270
266
  domain = self.covering_grid(
271
267
  level=0, left_edge=self.domain_left_edge, dims=self.domain_dimensions
@@ -285,25 +281,23 @@ class FLEKSData(BoxlibDataset):
285
281
  )
286
282
  )
287
283
 
288
- return data_container.dataContainer3D(dataSets, axes[0], axes[1], axes[2])
284
+ return DataContainer3D(dataSets, axes[0], axes[1], axes[2])
289
285
 
290
286
  def plot_slice(self, norm, cut_loc, vars, unit_type="planet", *args, **kwargs):
291
287
  r"""Plot 2D slice
292
288
 
293
- Parameters
294
- ----------
295
- norm : string, one of 'x', 'y' or 'z'. Norm direction of the slice.
296
-
297
- cut_loc : float. The location of the slice.
298
-
299
- vars : a list or string of plotting variables.
300
- Example: "Bx rhos0" or ["Bx", "rhos0"]
289
+ Args:
290
+ norm: str
291
+ Normal direction of the slice in "x", "y" or "z".
292
+ cut_loc: float
293
+ The location of the slice.
301
294
 
302
- unit_type : The unit system of the plots. "planet" or "si".
295
+ vars: a list or string of plotting variables.
296
+ Example: "Bx rhos0" or ["Bx", "rhos0"]
303
297
 
304
- Examples
305
- --------
298
+ unit_type: The unit system of the plots. "planet" or "si".
306
299
 
300
+ Examples:
307
301
  >>> vars = ["rhos0", "uzs0", "Bz", "pxxs1", "Ex"]
308
302
  >>> splt = ds.plot_slice("y", 0.0, vars)
309
303
  >>> splt.display()
@@ -427,26 +421,23 @@ class FLEKSData(BoxlibDataset):
427
421
  ):
428
422
  r"""Plot the particle position of particles inside a box.
429
423
 
430
- Parameters
431
- ----------
432
- x_field & y_field: string
433
- The x- y- axes, from "p_x", "p_y", "p_z".
424
+ Args:
425
+ x_field & y_field: str
426
+ The x- y- axes, from "p_x", "p_y", "p_z".
434
427
 
435
- z_field: string
436
- It is usually the particle weight: "p_w".
428
+ z_field: str
429
+ color variable, usually the particle weight "p_w".
437
430
 
438
- region : YTSelectionContainer
439
- Spatial region to be selected, such as all_data, box, region, or sphere.
431
+ region: YTSelectionContainer
432
+ Spatial region to be selected, such as all_data, box, region, or sphere.
440
433
 
441
- unit_type : string
442
- The unit system of the plots. "planet" or "si".
434
+ unit_type: str
435
+ The unit system of the plots. "planet" or "si".
443
436
 
444
437
  See more at https://yt-project.org/doc/reference/api/yt.visualization.particle_plots.html#yt.visualization.particle_plots.ParticlePlot
445
438
 
446
- Examples
447
- --------
448
- >>> pp = ds.plot_particles([8, -1, -1], [10, 0, 0], "p_x",
449
- "p_y", "p_w", unit_type="planet")
439
+ Examples:
440
+ >>> pp = ds.plot_particles([8, -1, -1], [10, 0, 0], "p_x", "p_y", "p_w", unit_type="planet")
450
441
  >>> pp.show()
451
442
  """
452
443
  if region is None:
@@ -1 +0,0 @@
1
- from .utilities import download_testfile, unit_one, get_unit, get_ticks
File without changes
File without changes
File without changes
File without changes