LLNL-PyDV 3.6.1__tar.gz → 3.6.3__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.3
2
2
  Name: LLNL-PyDV
3
- Version: 3.6.1
3
+ Version: 3.6.3
4
4
  Summary: PyDV: Python Data Visualizer
5
5
  License: BSD
6
6
  Author: Sarah El-Jurf
@@ -258,6 +258,7 @@ class Command(cmd.Cmd, object):
258
258
  tightlayout = 0
259
259
  group = 0
260
260
  slashes = 100
261
+ do_label_done = False
261
262
 
262
263
  # Users wanted support for automatically loading some plot attributes. The
263
264
  # following commands handle the situations where there are multiple plots or
@@ -1353,7 +1354,12 @@ class Command(cmd.Cmd, object):
1353
1354
  return 0
1354
1355
  if "*." in line:
1355
1356
  for fdx in range(len(self.filelist)):
1356
- temp_line = line.replace("*", chr(ord('a') + fdx))
1357
+
1358
+ if fdx < 26:
1359
+ temp_line = line.replace("*", chr(ord('a') + fdx))
1360
+ else:
1361
+ temp_line = line.replace("*", f"@{fdx + 1}")
1362
+
1357
1363
  if len(line.split(':')) > 1: # check for list notation
1358
1364
  self.do_curve(pdvutil.getnumberargs(temp_line, self.filelist))
1359
1365
  else:
@@ -1368,8 +1374,15 @@ class Command(cmd.Cmd, object):
1368
1374
  for i in range(len(line)):
1369
1375
  curvedex = 0
1370
1376
  skip = False
1371
- if ord('A') <= ord(line[i][0].upper()) <= ord('Z'): # check for a.% b.% file index notation
1372
- filedex = ord(line[i][0].upper()) - ord('A') # file index we want
1377
+
1378
+ # check for a.% b.% @#. file index notation
1379
+ if ord('A') <= ord(line[i][0].upper()) <= ord('Z') or '@' in line[i]:
1380
+
1381
+ if ord('A') <= ord(line[i][0].upper()) <= ord('Z'):
1382
+ filedex = ord(line[i][0].upper()) - ord('A') # file index we want
1383
+ else:
1384
+ filedex = int(line[i].split(".")[0].replace("@", "")) - 1 # 0 index
1385
+
1373
1386
  prevfile = '' # set prevfile to impossible value
1374
1387
  filecounter = 0
1375
1388
  fileend = 0
@@ -1385,9 +1398,9 @@ class Command(cmd.Cmd, object):
1385
1398
  curvedex += int(line[i].split('.')[-1]) - 1
1386
1399
  if curvedex + 1 > fileend:
1387
1400
  filestart = fileend - self.filelist[filedex][1] + 1
1388
- print('error: curve index out of bounds')
1389
- print(f"\tFile {self.filelist[filedex]}: Start {filestart}, End {fileend}")
1390
- print(f"\tRequested Curve {line[i]}")
1401
+ print(f"File {filedex + 1}: {self.filelist[filedex]}: Start {filestart}, End {fileend}")
1402
+ print(f"\tRequested Curve {line[i]}: {curvedex + 1}")
1403
+ print('\tError: curve index out of bounds')
1391
1404
  skip = True
1392
1405
  elif 0 < int(line[i]) <= len(self.curvelist):
1393
1406
  curvedex = int(line[i]) - 1
@@ -1565,6 +1578,80 @@ class Command(cmd.Cmd, object):
1565
1578
  print('\n Display the mean and standard deviation for the given curves.'
1566
1579
  '\n usage: stats <curve-list>\n')
1567
1580
 
1581
+ def do_deltax(self, line):
1582
+ """
1583
+ Create new curve that calculates difference between its own X points. Delta X vs # of points - 1.
1584
+ """
1585
+
1586
+ if not line:
1587
+ return 0
1588
+
1589
+ if len(line.split(':')) > 1:
1590
+ self.do_deltax(pdvutil.getletterargs(line))
1591
+ return 0
1592
+ else:
1593
+ try:
1594
+ line = line.split()
1595
+ for i in range(len(line)):
1596
+ try:
1597
+ curvidx = pdvutil.getCurveIndex(line[i], self.plotlist)
1598
+ cur = self.plotlist[curvidx]
1599
+
1600
+ c = pydvpy.makecurve(x=range(len(cur.x) - 1),
1601
+ y=cur.x[1:] - cur.x[:-1],
1602
+ name=f"{cur.name} Delta X", # we name the curve with the input 'line'
1603
+ plotname=self.getcurvename()) # get the next available data ID label
1604
+ self.addtoplot(c)
1605
+
1606
+ except pdvutil.CurveIndexError:
1607
+ pass
1608
+ except:
1609
+ if self.debug:
1610
+ traceback.print_exc(file=sys.stdout)
1611
+ finally:
1612
+ self.redraw = True
1613
+
1614
+ def help_deltax(self):
1615
+ print('\n Create new curve that calculates difference between its own X points. Delta X vs # of points - 1.'
1616
+ '\n usage: deltax <curve-list>\n')
1617
+
1618
+ def do_deltay(self, line):
1619
+ """
1620
+ Create new curve that calculates difference between its own Y points. Delta Y vs # of points - 1.
1621
+ """
1622
+
1623
+ if not line:
1624
+ return 0
1625
+
1626
+ if len(line.split(':')) > 1:
1627
+ self.do_deltay(pdvutil.getletterargs(line))
1628
+ return 0
1629
+ else:
1630
+ try:
1631
+ line = line.split()
1632
+ for i in range(len(line)):
1633
+ try:
1634
+ curvidx = pdvutil.getCurveIndex(line[i], self.plotlist)
1635
+ cur = self.plotlist[curvidx]
1636
+
1637
+ c = pydvpy.makecurve(x=range(len(cur.y) - 1),
1638
+ y=cur.y[1:] - cur.y[:-1],
1639
+ name=f"{cur.name} Delta Y", # we name the curve with the input 'line'
1640
+ plotname=self.getcurvename()) # get the next available data ID label
1641
+ self.addtoplot(c)
1642
+
1643
+ except pdvutil.CurveIndexError:
1644
+ pass
1645
+ except:
1646
+ if self.debug:
1647
+ traceback.print_exc(file=sys.stdout)
1648
+ finally:
1649
+ self.redraw = True
1650
+
1651
+ def help_deltay(self):
1652
+ print('\n Create new curve that calculates difference between its own Y points. Delta Y vs # of points - 1.'
1653
+ '\n usage: deltay <curve-list>\n')
1654
+
1568
1655
  def do_getattributes(self, line):
1569
1656
  """
1570
1657
  Return a curve's attributes
@@ -4495,11 +4582,8 @@ class Command(cmd.Cmd, object):
4495
4582
  ('densely_dashdotdotted', '(0, (3, 1, 1, 1, 1, 1))')]
4496
4583
 
4497
4584
  for i, filename in enumerate(groups):
4498
- if i < 14:
4499
- curves_ = " ".join(groups[filename])
4500
- self.do_lnstyle(curves_ + ' ' + styles[i][0].replace("'", ""))
4501
- else:
4502
- print('There are only fourteen linestyles available. Please reduce the number of files.')
4585
+ curves_ = " ".join(groups[filename])
4586
+ self.do_lnstyle(curves_ + ' ' + styles[i % len(styles)][0].replace("'", ""))
4503
4587
 
4504
4588
  # Setting Colors at the curve level
4505
4589
  curve_names = []
@@ -4520,11 +4604,8 @@ class Command(cmd.Cmd, object):
4520
4604
  colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
4521
4605
 
4522
4606
  for i, curve_name in enumerate(groups):
4523
- if i < 10:
4524
- curves_ = " ".join(groups[curve_name])
4525
- self.do_color(curves_ + ' ' + colors[i].replace("'", ""))
4526
- else:
4527
- print('There are only ten colors available. Please reduce the number of same name curves.')
4607
+ curves_ = " ".join(groups[curve_name])
4608
+ self.do_color(curves_ + ' ' + colors[i % len(colors)].replace("'", ""))
4528
4609
 
4529
4610
  for cur in self.plotlist:
4530
4611
  path = os.path.normpath(cur.filename)
@@ -4540,10 +4621,10 @@ class Command(cmd.Cmd, object):
4540
4621
  if len(curve_names) == 1 and title_update:
4541
4622
  self.do_title(f"{curve_names[0].strip()}")
4542
4623
 
4543
- if not self.group:
4624
+ if not self.group or len(files) == 1:
4544
4625
  for i, cur in enumerate(self.plotlist):
4545
4626
  self.do_label(f"{cur.plotname} {cur._original_name}")
4546
- temp_color = colors[i].replace("'", "")
4627
+ temp_color = colors[i % len(colors)].replace("'", "")
4547
4628
  self.do_color(f"{cur.plotname} {temp_color}")
4548
4629
  self.do_lnstyle(f"{cur.plotname} solid")
4549
4630
  self.slashes = 100
@@ -6679,14 +6760,16 @@ class Command(cmd.Cmd, object):
6679
6760
  """
6680
6761
 
6681
6762
  try:
6682
- if len(line.split(':')) > 1:
6763
+ if len(line.split(':')) > 1 and not self.do_label_done:
6764
+ self.do_label_done = True
6683
6765
  self.do_label(pdvutil.getletterargs(line))
6684
6766
  return 0
6685
6767
  else:
6686
- line_labels = line.split('#')[1:] # First entry will be curves
6768
+ self.do_label_done = False
6769
+ line_labels = line.split('`')[1:] # First entry will be curves
6687
6770
 
6688
6771
  if line_labels: # Multiple curves and labels
6689
- curves = line.split('#')[0].split()
6772
+ curves = line.split('`')[0].split()
6690
6773
  else: # single curve and label
6691
6774
  curves = line.split()[0]
6692
6775
  line_labels = [' '.join(line.split()[1:])]
@@ -6698,16 +6781,17 @@ class Command(cmd.Cmd, object):
6698
6781
 
6699
6782
  self.plotedit = True
6700
6783
  except:
6784
+ self.do_label_done = False
6701
6785
  print('error - usage: label <curve> <new-label>\n')
6702
- print('For multiple curves, each label must start with #')
6703
- print('label a:c #mynewlabel #my other label #my thirdlabel')
6786
+ print('For multiple curves, each label must start with `')
6787
+ print('label a:c `mynewlabel `my other label `my thirdlabel')
6704
6788
  if self.debug:
6705
6789
  traceback.print_exc(file=sys.stdout)
6706
6790
 
6707
6791
  def help_label(self):
6708
6792
  print('\n Procedure: Change the key and list label for a curve\n Usage: label <curve> <new-label>\n')
6709
- print(' For multiple curves, each label must start with #')
6710
- print(' label a:c #mynewlabel #my other label #my thirdlabel')
6793
+ print(' For multiple curves, each label must start with `')
6794
+ print(' label a:c `mynewlabel `my other label `my thirdlabel')
6711
6795
 
6712
6796
  def do_labelrecordids(self, line):
6713
6797
  """
@@ -60,6 +60,7 @@
60
60
  # endorsement purposes.
61
61
 
62
62
  import numpy as np
63
+ import re
63
64
 
64
65
 
65
66
  class CurveIndexError(ValueError):
@@ -203,11 +204,16 @@ def getnumberargs(line, filelist):
203
204
  arglist += nolist + ' '
204
205
  start = line[i].split()[-1]
205
206
  end = line[i + 1].split()[0]
206
- # File notation e.g. a.1:a.10
207
+ # File notation e.g. a.1:a.10 and @#.
207
208
  filedex = None
208
209
  filestart = 0
209
210
  if (len(start.split('.')) > 1):
210
- filedex = ord(start[0].upper()) - ord('A')
211
+
212
+ if ord('A') <= ord(start[0].upper()) <= ord('Z'):
213
+ filedex = ord(start[0].upper()) - ord('A')
214
+ else:
215
+ filedex = int(start.split(".")[0].replace("@", "")) - 1 # 0 index
216
+
211
217
  start = start.split('.')[-1]
212
218
  if (filedex != 0):
213
219
  for f in range(filedex):
@@ -216,7 +222,12 @@ def getnumberargs(line, filelist):
216
222
  filestart += 1
217
223
  fileend = 0
218
224
  if (len(end.split('.')) > 1):
219
- filedex = ord(end[0].upper()) - ord('A')
225
+
226
+ if ord('A') <= ord(end[0].upper()) <= ord('Z'):
227
+ filedex = ord(end[0].upper()) - ord('A')
228
+ else:
229
+ filedex = int(end.split(".")[0].replace("@", "")) - 1 # 0 index
230
+
220
231
  end = end.split('.')[-1]
221
232
  if (filedex != 0):
222
233
  for f in range(filedex):
@@ -231,45 +242,49 @@ def getnumberargs(line, filelist):
231
242
  step = 1
232
243
  if filedex is not None:
233
244
  if int(start) > fileend and int(end) > fileend:
234
- print(f"File {filelist[filedex]}: Start {filestart}, End {fileend}")
245
+ print(f"File {filedex + 1}: {filelist[filedex]}: Start {filestart}, End {fileend}")
235
246
  print(f"\tRequested Start {start}, End {end}")
236
247
  print(f'\tStart {start} and End {end} is greater than file end {fileend}')
237
248
  print("\tThis range will not be plotted")
238
249
  ignore = True
239
250
  elif int(start) > fileend:
240
- print(f"File {filelist[filedex]}: Start {filestart}, End {fileend}")
251
+ print(f"File {filedex + 1}: {filelist[filedex]}: Start {filestart}, End {fileend}")
241
252
  print(f"\tRequested Start {start}, End {end}")
242
253
  print(f'\tStart {start} is greater than file end {fileend}')
243
254
  start = str(fileend)
244
255
  print(f'\tSetting Start to {start}')
256
+ print(f'\tNew Start {start} and New End {end}')
245
257
  elif int(end) > fileend:
246
- print(f"File {filelist[filedex]}: Start {filestart}, End {fileend}")
258
+ print(f"File {filedex + 1}: {filelist[filedex]}: Start {filestart}, End {fileend}")
247
259
  print(f"\tRequested Start {start}, End {end}")
248
260
  print(f'\tEnd {end} is greater than file end {fileend}')
249
261
  end = str(fileend)
250
262
  print(f'\tSetting End to {end}')
263
+ print(f'\tNew Start {start} and New End {end}')
251
264
  delta = int(end) - int(start)
252
265
  else:
253
266
  step = -1
254
267
  if filedex is not None:
255
268
  if int(end) > fileend and int(start) > fileend:
256
- print(f"File {filelist[filedex]}: Start {filestart}, End {fileend}")
269
+ print(f"File {filedex + 1}: {filelist[filedex]}: Start {filestart}, End {fileend}")
257
270
  print(f"\tRequested Start {end}, End {start}")
258
271
  print(f'\tStart {end} and End {start} is greater than file end {fileend}')
259
272
  print("\tThis range will not be plotted")
260
273
  ignore = True
261
274
  elif int(end) > fileend:
262
- print(f"File {filelist[filedex]}: Start {filestart}, End {fileend}")
275
+ print(f"File {filedex + 1}: {filelist[filedex]}: Start {filestart}, End {fileend}")
263
276
  print(f"\tRequested Start {end}, End {start}")
264
277
  print(f'\tStart {end} is greater than file end {fileend}')
265
278
  end = str(fileend)
266
279
  print(f'\tSetting Start to {end}')
280
+ print(f'\tNew Start {end} and New End {start}')
267
281
  elif int(start) > fileend:
268
- print(f"File {filelist[filedex]}: Start {filestart}, End {fileend}")
282
+ print(f"File {filedex + 1}: {filelist[filedex]}: Start {filestart}, End {fileend}")
269
283
  print(f"\tRequested Start {end}, End {start}")
270
284
  print(f'\tEnd {start} is greater than file end {fileend}')
271
285
  start = str(fileend)
272
286
  print(f'\tSetting End to {start}')
287
+ print(f'\tNew Start {end} and New End {start}')
273
288
  delta = int(end) - int(start)
274
289
  for j in range(int(start), int(start) + delta + step, step):
275
290
  args += str(j) + ' '
@@ -288,7 +303,16 @@ def getletterargs(line):
288
303
  Get a full list of arguments from compact list or mixed notation (ex a:d)
289
304
  """
290
305
 
291
- line = line.split(':') # begin arduous list parsing
306
+ if "`" in line: # list of multiple label names from do_label()
307
+ label_line = line.split("`", 1)
308
+ temp_line = label_line[0].split(':')
309
+ temp_line[-1] = temp_line[-1] + "`" + label_line[1]
310
+ line = temp_line
311
+ elif len(re.split(r"(\b[a-zA-Z]:[a-zA-Z]\b)|(\b[a-zA-Z]:@\d+\b)|(\b@\d+:@\d+\b)", line)) == 1: # single label w/ :
312
+ return line
313
+ else:
314
+ line = line.split(':') # begin arduous list parsing
315
+
292
316
  arglist = ''
293
317
  if len(line) > 1:
294
318
  for i in range(len(line)):
@@ -646,22 +646,10 @@ def read(fname, gnu=False, xcol=0, verbose=False, pattern=None, matches=None):
646
646
  with open(fname, 'r') as f:
647
647
  for line in f:
648
648
  labels = False
649
- split_line = re.split(r'[ \t]+', str.strip(line))
650
-
651
- # No space between curvename and hashtag #mycurve
652
- try: # Exponential numbers and single text will cause issues
653
- if re.search('[a-zA-Z]', split_line[0]):
654
- split_line_2 = re.split(r'#', str.strip(line))
655
- split_line = [None] * 2
656
- split_line[0] = '#'
657
- split_line[1] = split_line_2[1]
658
- except:
659
- split_line = re.split(r'[ \t]+', str.strip(line))
660
649
 
661
650
  # Check for labels
662
- split_line_3 = re.split(r'#', str.strip(line))
663
- for split in split_line_3:
664
-
651
+ split_line_label = re.split(r'#', str.strip(line))
652
+ for split in split_line_label:
665
653
  if re.search('[a-zA-Z]', split):
666
654
  if 'xlabel' in split:
667
655
  xlabel = split.replace('xlabel', '').strip()
@@ -674,11 +662,18 @@ def read(fname, gnu=False, xcol=0, verbose=False, pattern=None, matches=None):
674
662
  if labels:
675
663
  split_line = [None] * 2
676
664
  split_line[0] = '#'
677
- split_line[1] = split_line_3[1].strip()
665
+ split_line[1] = line.split("# xlabel")[0].split("# ylabel")[0].split("#xlabel")[0].split("#ylabel")[0][1:].strip() # noqae501
678
666
  xlabels[split_line[1]] = xlabel
679
667
  ylabels[split_line[1]] = ylabel
680
668
  xlabel = ''
681
669
  ylabel = ''
670
+ else: # might be numerical or text
671
+ if "#" in line: # text
672
+ split_line = [None] * 2
673
+ split_line[0] = '#'
674
+ split_line[1] = line[1:].strip()
675
+ else: # numerical
676
+ split_line = re.split(r'[ \t]+', str.strip(line))
682
677
 
683
678
  if not split_line or not split_line[0]:
684
679
  continue
@@ -4714,14 +4709,14 @@ def overlap_interp(cr1, cr2, npts_interp=0):
4714
4709
  return cr1_interp, cr2_interp
4715
4710
 
4716
4711
 
4717
- def AvgDiff(cr1, cr2, npts=100, tol=1e-6):
4712
+ def AvgDiff(cr1, cr2, npts=0, tol=1e80):
4718
4713
  """
4719
4714
  Calculate the difference between the overlapping interpolated curves.
4720
4715
 
4721
4716
  >>> curves = pydvpy.read('testData.txt')
4722
4717
 
4723
4718
  >>> cr1_interp, cr2_interp, differences, avgDiff, maxDiff, failed_curve, failed = pydvpy.AvgDiff(curves[0],
4724
- curves[1], npts=100, tol=1e-6)
4719
+ curves[1], npts=0, tol=1e80)
4725
4720
 
4726
4721
  :param cr1: The first curve
4727
4722
  :type cr1: Curve
@@ -4763,14 +4758,14 @@ def AvgDiff(cr1, cr2, npts=100, tol=1e-6):
4763
4758
  return cr1_interp, cr2_interp, differences, avgDiff, maxDiff, failed_curve, failed
4764
4759
 
4765
4760
 
4766
- def AbsDiff(cr1, cr2, npts=100, tol=1e-6):
4761
+ def AbsDiff(cr1, cr2, npts=0, tol=1e80):
4767
4762
  """
4768
4763
  Calculate the absolute difference between the overlapping interpolated curves.
4769
4764
 
4770
4765
  >>> curves = pydvpy.read('testData.txt')
4771
4766
 
4772
4767
  >>> cr1_interp, cr2_interp, differences, avgDiff, maxDiff, failed_curve, failed = pydvpy.AbsDiff(curves[0],
4773
- curves[1], npts=100, tol=1e-6)
4768
+ curves[1], npts=0, tol=1e80)
4774
4769
 
4775
4770
  :param cr1: The first curve
4776
4771
  :type cr1: Curve
@@ -4813,14 +4808,14 @@ def AbsDiff(cr1, cr2, npts=100, tol=1e-6):
4813
4808
  return cr1_interp, cr2_interp, differences, avgDiff, maxDiff, failed_curve, failed
4814
4809
 
4815
4810
 
4816
- def RelDiff(cr1, cr2, npts=100, tol=1e-6):
4811
+ def RelDiff(cr1, cr2, npts=0, tol=1e80):
4817
4812
  """
4818
4813
  Calculate the relative difference between the overlapping interpolated curves.
4819
4814
 
4820
4815
  >>> curves = pydvpy.read('testData.txt')
4821
4816
 
4822
4817
  >>> cr1_interp, cr2_interp, differences, avgDiff, maxDiff, failed_curve, failed = pydvpy.RelDiff(curves[0],
4823
- curves[1], npts=100, tol=1e-6)
4818
+ curves[1], npts=0, tol=1e80)
4824
4819
 
4825
4820
  :param cr1: The first curve
4826
4821
  :type cr1: Curve
@@ -4882,9 +4877,9 @@ def RelDiff(cr1, cr2, npts=100, tol=1e-6):
4882
4877
  return cr1_interp, cr2_interp, differences, avgDiff, maxDiff, failed_curve, failed
4883
4878
 
4884
4879
 
4885
- def AbsAndRelDiff(cr1, cr2, npts=100, tol=1e-6):
4880
+ def AbsAndRelDiff(cr1, cr2, npts=0, abs_tol=1e80, rel_tol=1e80):
4886
4881
  """
4887
- Calculate the relative and absolute difference between the overlapping interpolated curves.
4882
+ Calculate the absolute and relative difference between the overlapping interpolated curves.
4888
4883
  Returns the updated AND statement for `failed` along with curves from AbsDiff and RelDiff
4889
4884
 
4890
4885
  >>> curves = pydvpy.read('testData.txt')
@@ -4892,7 +4887,7 @@ def AbsAndRelDiff(cr1, cr2, npts=100, tol=1e-6):
4892
4887
  >>> (cr1_interp, cr2_interp,
4893
4888
  differences_Abs, avgDiff_Abs, maxDiff_Abs, failed_curve_Abs, failed_Abs
4894
4889
  differences_Rel, avgDiff_Rel, maxDiff_Rel, failed_curve_Rel, failed_Rel
4895
- failed_AND) = pydvpy.AbsAndRelDiff(curves[0], curves[1], npts=100, tol=1e-6)
4890
+ failed_AND) = pydvpy.AbsAndRelDiff(curves[0], curves[1], npts=0, abs_tol=1e80, rel_tol=1e80)
4896
4891
 
4897
4892
  :param cr1: The first curve
4898
4893
  :type cr1: Curve
@@ -4900,8 +4895,10 @@ def AbsAndRelDiff(cr1, cr2, npts=100, tol=1e-6):
4900
4895
  :type cr2: Curve
4901
4896
  :param npts: The number of points in the interpolation
4902
4897
  :type npts: int
4903
- :param tol: The tolerance for failure
4904
- :type tol: float
4898
+ :param abs_tol: The tolerance for absolute difference failure
4899
+ :type abs_tol: float
4900
+ :param rel_tol: The tolerance for relative difference failure
4901
+ :type rel_tol: float
4905
4902
  :returns:
4906
4903
  - cr1_interp (:py:class:`Curve`) - The first overlapping interpolated curve
4907
4904
  - cr2_interp (:py:class:`Curve`) - The second overlapping interpolated curve
@@ -4921,12 +4918,12 @@ def AbsAndRelDiff(cr1, cr2, npts=100, tol=1e-6):
4921
4918
  (cr1_interp, cr2_interp,
4922
4919
  differences_Abs, avgDiff_Abs,
4923
4920
  maxDiff_Abs, failed_curve_Abs,
4924
- failed_Abs) = AbsDiff(cr1, cr2, npts, tol)
4921
+ failed_Abs) = AbsDiff(cr1, cr2, npts, abs_tol)
4925
4922
 
4926
4923
  (cr1_interp, cr2_interp,
4927
4924
  differences_Rel, avgDiff_Rel,
4928
4925
  maxDiff_Rel, failed_curve_Rel,
4929
- failed_Rel) = RelDiff(cr1, cr2, npts, tol)
4926
+ failed_Rel) = RelDiff(cr1, cr2, npts, rel_tol)
4930
4927
 
4931
4928
  if failed_Abs and failed_Rel:
4932
4929
  failed_AND = True
@@ -4939,9 +4936,9 @@ def AbsAndRelDiff(cr1, cr2, npts=100, tol=1e-6):
4939
4936
  failed_AND)
4940
4937
 
4941
4938
 
4942
- def AbsOrRelDiff(cr1, cr2, npts=100, tol=1e-6):
4939
+ def AbsOrRelDiff(cr1, cr2, npts=0, abs_tol=1e80, rel_tol=1e80):
4943
4940
  """
4944
- Calculate the relative and absolute difference between the overlapping interpolated curves.
4941
+ Calculate the absolute and relative difference between the overlapping interpolated curves.
4945
4942
  Returns the updated OR statement for `failed` along with curves from AbsDiff and RelDiff
4946
4943
 
4947
4944
  >>> curves = pydvpy.read('testData.txt')
@@ -4949,7 +4946,7 @@ def AbsOrRelDiff(cr1, cr2, npts=100, tol=1e-6):
4949
4946
  >>> (cr1_interp, cr2_interp,
4950
4947
  differences_Abs, avgDiff_Abs, maxDiff_Abs, failed_curve_Abs, failed_Abs
4951
4948
  differences_Rel, avgDiff_Rel, maxDiff_Rel, failed_curve_Rel, failed_Rel
4952
- failed_OR) = pydvpy.AbsOrRelDiff(curves[0], curves[1], npts=100, tol=1e-6)
4949
+ failed_OR) = pydvpy.AbsOrRelDiff(curves[0], curves[1], npts=0, abs_tol=1e80, rel_tol=1e80)
4953
4950
 
4954
4951
  :param cr1: The first curve
4955
4952
  :type cr1: Curve
@@ -4957,8 +4954,10 @@ def AbsOrRelDiff(cr1, cr2, npts=100, tol=1e-6):
4957
4954
  :type cr2: Curve
4958
4955
  :param npts: The number of points in the interpolation
4959
4956
  :type npts: int
4960
- :param tol: The tolerance for failure
4961
- :type tol: float
4957
+ :param abs_tol: The tolerance for absolute difference failure
4958
+ :type abs_tol: float
4959
+ :param rel_tol: The tolerance for relative difference failure
4960
+ :type rel_tol: float
4962
4961
  :returns:
4963
4962
  - cr1_interp (:py:class:`Curve`) - The first overlapping interpolated curve
4964
4963
  - cr2_interp (:py:class:`Curve`) - The second overlapping interpolated curve
@@ -4978,12 +4977,12 @@ def AbsOrRelDiff(cr1, cr2, npts=100, tol=1e-6):
4978
4977
  (cr1_interp, cr2_interp,
4979
4978
  differences_Abs, avgDiff_Abs,
4980
4979
  maxDiff_Abs, failed_curve_Abs,
4981
- failed_Abs) = AbsDiff(cr1, cr2, npts, tol)
4980
+ failed_Abs) = AbsDiff(cr1, cr2, npts, abs_tol)
4982
4981
 
4983
4982
  (cr1_interp, cr2_interp,
4984
4983
  differences_Rel, avgDiff_Rel,
4985
4984
  maxDiff_Rel, failed_curve_Rel,
4986
- failed_Rel) = RelDiff(cr1, cr2, npts, tol)
4985
+ failed_Rel) = RelDiff(cr1, cr2, npts, rel_tol)
4987
4986
 
4988
4987
  if failed_Abs or failed_Rel:
4989
4988
  failed_OR = True
@@ -5386,7 +5385,7 @@ def MedianFilter(c, npts):
5386
5385
  name=f"{c.name} MedianFilter npts={npts}")
5387
5386
 
5388
5387
 
5389
- def TimeShift(cbase, cset, tol=1e-6, pairID=0, version=0):
5388
+ def TimeShift(cbase, cset, tol=1e80, pairID=0, version=0):
5390
5389
  """
5391
5390
  This filter will take a curve and return a time shifted curve.
5392
5391
  It uses the slope of the baseline curve to find the time offset
@@ -5399,7 +5398,7 @@ def TimeShift(cbase, cset, tol=1e-6, pairID=0, version=0):
5399
5398
 
5400
5399
  >>> curves = pydvpy.read('testData.txt')
5401
5400
 
5402
- >>> new_curve = pydvpy.TimeShift(curves[0], curves[1], tol=1e-6, pairID=0, version=0)
5401
+ >>> new_curve = pydvpy.TimeShift(curves[0], curves[1], tol=1e80, pairID=0, version=0)
5403
5402
 
5404
5403
  :param cbase: The base Curve
5405
5404
  :type cbase: Curve
@@ -5468,3 +5467,32 @@ def TimeShift(cbase, cset, tol=1e-6, pairID=0, version=0):
5468
5467
  return makecurve(x=xshifted,
5469
5468
  y=yset,
5470
5469
  name=f"{cset.name} pairID={pairID} version={version}")
5470
+
5471
+
5472
+ def getfl(curvelist):
5473
+ """
5474
+ Returns the first and last data point from the yData array
5475
+
5476
+ >>> curves = pydvpy.read('testData.txt')
5477
+
5478
+ >>> first_last = pydvpy.getfl(curves) OR
5479
+
5480
+ >>> first_last = pydvpy.getfl(curves[0])
5481
+
5482
+ :param curvelist: The Curve or list of Curves
5483
+ :type curvelist: Curve or list
5484
+ :return: list -- A list of y values at the first and last index
5485
+ """
5486
+ first_last = list()
5487
+
5488
+ curves = list()
5489
+
5490
+ if isinstance(curvelist, list):
5491
+ curves.extend(curvelist)
5492
+ else:
5493
+ curves.append(curvelist)
5494
+
5495
+ for cur in curves:
5496
+ first_last.append([cur.y[0], cur.y[-1]])
5497
+
5498
+ return first_last
@@ -0,0 +1 @@
1
+ 04.14.2025
@@ -0,0 +1 @@
1
+ 3.6.3
@@ -1,7 +1,7 @@
1
1
  [tool]
2
2
  [tool.poetry]
3
3
  name = "LLNL-PyDV"
4
- version = "3.6.1"
4
+ version = "3.6.3"
5
5
  description = "PyDV: Python Data Visualizer"
6
6
  license = "BSD"
7
7
  classifiers = [
@@ -65,7 +65,7 @@ build-backend = "poetry.core.masonry.api"
65
65
  line-length = 79
66
66
 
67
67
  [tool.bumpver]
68
- current_version = "3.6.1"
68
+ current_version = "3.6.3"
69
69
  version_pattern = "MAJOR.MINOR.PATCH"
70
70
  commit_message = "bump version {old_version} -> {new_version}"
71
71
  commit = true
@@ -1 +0,0 @@
1
- 02.19.2025
@@ -1 +0,0 @@
1
- 3.6.1
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes