LLNL-PyDV 3.4.3__py3-none-any.whl

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.
pydv/pdvutil.py ADDED
@@ -0,0 +1,315 @@
1
+ # Copyright (c) 2011-2024, Lawrence Livermore National Security, LLC.
2
+ # Produced at the Lawrence Livermore National Laboratory
3
+ # Written by Mason Kwiat, Douglas S. Miller, and Kevin Griffin, Ephraim Rusu
4
+ # e-mail: rusu1@llnl.gov
5
+ # LLNL-CODE-507071
6
+ # All rights reserved.
7
+
8
+ # This file is part of PDV. For details, see <URL describing code and
9
+ # how to download source>. Please also read "Additional BSD Notice".
10
+
11
+ # Redistribution and use in source and binary forms, with or without
12
+ # modification, are permitted provided that the following conditions
13
+ # are met:
14
+
15
+ # Redistributions of source code must retain the above copyright
16
+ # notice, this list of conditions and the disclaimer below.
17
+ # Redistributions in binary form must reproduce the above copyright
18
+ # notice, this list of conditions and the disclaimer (as noted below)
19
+ # in the documentation and/or other materials provided with the
20
+ # distribution. Neither the name of the LLNS/LLNL nor the names of
21
+ # its contributors may be used to endorse or promote products derived
22
+ # from this software without specific prior written permission.
23
+
24
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27
+ # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE
28
+ # LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR
29
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
32
+ # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
35
+ # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36
+ # SUCH DAMAGE.
37
+
38
+ # Additional BSD Notice
39
+
40
+ # 1. This notice is required to be provided under our contract with
41
+ # the U.S. Department of Energy (DOE). This work was produced at
42
+ # Lawrence Livermore National Laboratory under Contract
43
+ # No. DE-AC52-07NA27344 with the DOE.
44
+
45
+ # 2. Neither the United States Government nor Lawrence Livermore
46
+ # National Security, LLC nor any of their employees, makes any
47
+ # warranty, express or implied, or assumes any liability or
48
+ # responsibility for the accuracy, completeness, or usefulness of any
49
+ # information, apparatus, product, or process disclosed, or represents
50
+ # that its use would not infringe privately-owned rights.
51
+
52
+ # 3. Also, reference herein to any specific commercial products,
53
+ # process, or services by trade name, trademark, manufacturer or
54
+ # otherwise does not necessarily constitute or imply its endorsement,
55
+ # recommendation, or favoring by the United States Government or
56
+ # Lawrence Livermore National Security, LLC. The views and opinions
57
+ # of authors expressed herein do not necessarily state or reflect
58
+ # those of the United States Government or Lawrence Livermore National
59
+ # Security, LLC, and shall not be used for advertising or product
60
+ # endorsement purposes.
61
+
62
+ import numpy as np
63
+
64
+
65
+ class CurveIndexError(ValueError):
66
+ pass
67
+
68
+
69
+ def getCurveIndex(plotname, plotlist):
70
+ """
71
+ Returns integer index to curve in plotlist from plotname
72
+ """
73
+
74
+ for j in range(len(plotlist)):
75
+ if plotname.upper() == plotlist[j].plotname:
76
+ return j
77
+ raise CurveIndexError("pdvutil.py getCurveIndex - failed to find curve index")
78
+
79
+
80
+ def parsemath(line, plotlist, commander, xdomain):
81
+ """
82
+ Parses and calculates mathematical input for curves, then updates plot
83
+ """
84
+
85
+ line = line.replace('+', ' + ')
86
+ line = line.replace('-', ' - ')
87
+ line = line.replace('*', ' * ')
88
+ line = line.replace('/', ' / ')
89
+ line = line.replace('(', ' ( ')
90
+ line = line.replace(')', ' ) ')
91
+ line = line.split()
92
+ # build the line of operations
93
+ sendline = ''
94
+ step = True
95
+ shared_x = []
96
+ for val in line:
97
+ dex = None
98
+ # Curve a-z or curve labeled @N (e.g. @27), i.e., beyond a-z?
99
+ if (len(val) == 1 and ord(val.upper()) <= ord('Z') and ord(val.upper()) >= ord('A')) or (val[0] == '@'):
100
+ dex = getCurveIndex(val, plotlist)
101
+ sendline += ' plotlist[' + str(dex) + '] '
102
+
103
+ try:
104
+ step_i = eval('plotlist[' + str(dex) + '].step')
105
+ if step_i and step:
106
+ shared_x.extend(eval('plotlist[' + str(dex) + '].x'))
107
+ except:
108
+ step_i = False
109
+
110
+ else: # no?, then just insert the operation (+,-,*,/, etc)
111
+ sendline += val
112
+
113
+ if not step_i:
114
+ step = False
115
+
116
+ sendline = sendline.lstrip()
117
+ c = eval(sendline) # evaluate it --- this works because math ops are defined for, and return, curve objects
118
+ c.name = ' '.join(line).replace('commander.', '').title() # set name
119
+ c.plotname = commander.getcurvename() # set label
120
+ c.step = False
121
+
122
+ if step:
123
+ shared_x = set(shared_x)
124
+ sendliney = ''
125
+ maths = [0] * len(line)
126
+
127
+ for i, val in enumerate(line):
128
+ dex = None
129
+ # Curve a-z or curve labeled @N (e.g. @27), i.e., beyond a-z?
130
+ if (len(val) == 1 and ord(val.upper()) <= ord('Z') and ord(val.upper()) >= ord('A')) or (val[0] == '@'):
131
+ dex = getCurveIndex(val, plotlist)
132
+ x = list(eval('plotlist[' + str(dex) + '].x'))
133
+ y = list(eval('plotlist[' + str(dex) + '].y'))
134
+
135
+ for xs in shared_x:
136
+ if xs not in x:
137
+
138
+ idxs = [i for i, v in enumerate(x) if v < xs]
139
+
140
+ if not idxs: # missing data at the beginning of the list
141
+ y.insert(0, 0.0)
142
+ y.insert(1, 0.0)
143
+ x.insert(0, xs)
144
+ x.insert(1, x[1])
145
+ elif idxs[-1] + 2 > len(x): # missing data at the end of the list
146
+ y[-1] = 0.0
147
+ y.insert(idxs[-1] + 1, 0.0)
148
+ y.insert(idxs[-1] + 2, 0.0)
149
+ x.insert(idxs[-1] + 1, xs)
150
+ x.insert(idxs[-1] + 2, xs)
151
+ else: # missing data in between
152
+ y.insert(idxs[-1] + 1, y[idxs[-1]])
153
+ y.insert(idxs[-1] + 2, y[idxs[-1]])
154
+ x.insert(idxs[-1] + 1, xs)
155
+ x.insert(idxs[-1] + 2, xs)
156
+
157
+ maths[i] = np.array(y)
158
+ sendliney += ' maths[' + str(i) + '] '
159
+
160
+ else:
161
+ sendliney += val
162
+
163
+ sendliney = sendliney.lstrip()
164
+
165
+ c.x = x
166
+ c.y = eval(sendliney)
167
+ c.step = True
168
+
169
+ if c.x is None or len(c.x) < 2:
170
+ print('error: curve overlap is not sufficient')
171
+ return 0
172
+ # put new curve into plotlist
173
+ if (c.plotname[:1] != '@' and ord(c.plotname) >= ord('A') and ord(c.plotname) <= ord('Z')):
174
+ plotlist.insert((ord(c.plotname) - ord('A')), c)
175
+ else:
176
+ plotlist.insert((int(c.plotname[1:]) - 1), c)
177
+ return c
178
+ # pultry.updateplot()
179
+
180
+
181
+ def getnumberargs(line, filelist):
182
+ """
183
+ Get a full list of arguments from compact list or mixed notation (ex 4:11)
184
+ """
185
+
186
+ line = line.split(':')
187
+ arglist = ''
188
+ if (len(line) > 1):
189
+ for i in range(len(line)):
190
+ line[i] = line[i].strip()
191
+ if (len(line[0].split()) > 1): # check for non list args
192
+ nolist = line[0].split()
193
+ nolist.pop(-1)
194
+ nolist = ' '.join(nolist)
195
+ arglist += nolist + ' '
196
+ for i in range(len(line) - 1):
197
+ if (i > 0):
198
+ if (len(line[i].split()) > 2): # check for non list args
199
+ nolist = line[i].split()
200
+ nolist.pop(-1)
201
+ nolist.pop(0)
202
+ nolist = ' '.join(nolist)
203
+ arglist += nolist + ' '
204
+ start = line[i].split()[-1]
205
+ end = line[i + 1].split()[0]
206
+ if (len(start.split('.')) > 1):
207
+ filedex = ord(start[0].upper()) - ord('A')
208
+ start = start.split('.')[-1]
209
+ if (filedex != 0):
210
+ for f in range(filedex):
211
+ start = str(int(start) + filelist[f][1])
212
+ if (len(end.split('.')) > 1):
213
+ filedex = ord(end[0].upper()) - ord('A')
214
+ end = end.split('.')[-1]
215
+ if (filedex != 0):
216
+ for f in range(filedex):
217
+ end = str(int(end) + filelist[f][1])
218
+ args = ''
219
+ delta = int(end) - int(start)
220
+ if delta >= 0:
221
+ step = 1
222
+ else:
223
+ step = -1
224
+ for j in range(int(start), int(start) + delta + step, step):
225
+ args += str(j) + ' '
226
+ arglist += args + ' '
227
+ if (len(line[-1].split()) > 1): # check for non list args
228
+ nolist = line[-1].split()
229
+ nolist.pop(0)
230
+ nolist = ' '.join(nolist)
231
+ arglist += nolist + ' '
232
+ return arglist
233
+
234
+
235
+ def getletterargs(line):
236
+ """
237
+ Get a full list of arguments from compact list or mixed notation (ex a:d)
238
+ """
239
+
240
+ line = line.split(':') # begin arduous list parsing
241
+ arglist = ''
242
+ if len(line) > 1:
243
+ for i in range(len(line)):
244
+ line[i] = line[i].strip()
245
+
246
+ # check for non list args
247
+ if len(line[0].split()) > 1:
248
+ nolist = line[0].split()
249
+ nolist.pop(-1)
250
+ nolist = ' '.join(nolist)
251
+ arglist += nolist + ' '
252
+
253
+ for i in range(len(line) - 1):
254
+ if i > 0:
255
+ # check for non list args
256
+ if len(line[i].split()) > 2:
257
+ nolist = line[i].split()
258
+ nolist.pop(-1)
259
+ nolist.pop(0)
260
+ nolist = ' '.join(nolist)
261
+ arglist += nolist + ' '
262
+
263
+ start = line[i].split()[-1].upper()
264
+
265
+ if start[0] == '@':
266
+ start = int(start[1:]) - 1
267
+ else:
268
+ start = ord(start[0]) - ord('A')
269
+
270
+ end = line[i + 1].split()[0].upper()
271
+
272
+ if end[0] == '@':
273
+ end = int(end[1:]) - 1
274
+ else:
275
+ end = ord(end[0]) - ord('A')
276
+
277
+ args = ''
278
+ for j in range((int(end) - int(start)) + 1):
279
+ if j + int(start) > 25:
280
+ args += '@' + str(j + int(start) + 1) + ' '
281
+ else:
282
+ args += chr(j + int(start) + ord('A')) + ' '
283
+ arglist += args + ''
284
+
285
+ # check for non list args
286
+ if len(line[-1].split()) > 1:
287
+ nolist = line[-1].split()
288
+ nolist.pop(0)
289
+ nolist = ' '.join(nolist)
290
+ arglist += nolist + ' ' # end arduous list parsing
291
+
292
+ return arglist
293
+
294
+
295
+ def truncate(string, size, justify='left'):
296
+ """
297
+ Truncate a string to given length
298
+ """
299
+
300
+ if len(string) > size:
301
+ if justify == 'left':
302
+ string = string[:size]
303
+ elif justify == 'right':
304
+ extra = len(string) - size + 3
305
+ string = '...' + string[extra:]
306
+
307
+ return string
308
+
309
+
310
+ def get_actual_index(origref, val):
311
+ for i in range(len(origref)):
312
+ if origref[i] == val:
313
+ return i
314
+
315
+ return -1