LLNL-PyDV 3.6.3__tar.gz → 3.7.0__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.3
3
+ Version: 3.7.0
4
4
  Summary: PyDV: Python Data Visualizer
5
5
  License: BSD
6
6
  Author: Sarah El-Jurf
@@ -76,6 +76,8 @@ class Curve(object):
76
76
  title='',
77
77
  record_id='',
78
78
  step=False,
79
+ step_original_x=np.empty(0),
80
+ step_original_y=np.empty(0),
79
81
  xticks_labels=None,
80
82
  plotname='',
81
83
  color='',
@@ -108,6 +110,8 @@ class Curve(object):
108
110
  self.title = title
109
111
  self.record_id = record_id
110
112
  self.step = step
113
+ self.step_original_x = step_original_x,
114
+ self.step_original_y = step_original_y,
111
115
  self.xticks_labels = xticks_labels
112
116
  self.plotname = plotname
113
117
  self.color = color
@@ -254,6 +258,8 @@ class Curve(object):
254
258
  title=self.title,
255
259
  record_id=self.record_id,
256
260
  step=self.step,
261
+ step_original_x=self.step_original_x,
262
+ step_original_y=self.step_original_y,
257
263
  xticks_labels=self.xticks_labels,
258
264
  plotname=self.plotname,
259
265
  color=self.color,
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+ pth=$(realpath $0)
3
+ pth=$(dirname $pth)
4
+ pth="$pth/pdv_launcher.py $*"
5
+
6
+ if [[ $pth == *"pdv-sa"* ]]; then
7
+
8
+ /usr/tce/bin/python3 $pth
9
+
10
+ else
11
+
12
+ FILE="/usr/apps/weave/weave-prod-cpu/bin/activate"
13
+
14
+ if [ -e "$FILE" ]; then
15
+
16
+ source $FILE
17
+
18
+ fi
19
+
20
+ python3 $pth
21
+
22
+ fi
@@ -5896,7 +5896,7 @@ class Command(cmd.Cmd, object):
5896
5896
 
5897
5897
  def do_linemarker(self, line):
5898
5898
  """
5899
- Set the marker symbol for the curves
5899
+ Set the marker symbol and marker size for the curves
5900
5900
  """
5901
5901
 
5902
5902
  if not line:
@@ -6771,7 +6771,7 @@ class Command(cmd.Cmd, object):
6771
6771
  if line_labels: # Multiple curves and labels
6772
6772
  curves = line.split('`')[0].split()
6773
6773
  else: # single curve and label
6774
- curves = line.split()[0]
6774
+ curves = [line.split()[0]]
6775
6775
  line_labels = [' '.join(line.split()[1:])]
6776
6776
 
6777
6777
  for i in range(len(curves)):
@@ -7728,10 +7728,7 @@ class Command(cmd.Cmd, object):
7728
7728
  xmin = 1e-2
7729
7729
  for cur in orderlist:
7730
7730
  if not cur.hidden:
7731
- xdat = numpy.array(cur.x)
7732
- for i in range(len(xdat)):
7733
- if xdat[i] < 1e-300:
7734
- xdat[i] = 1e301
7731
+ xdat = numpy.where(cur.x < 1e-300, 1e301, cur.x)
7735
7732
  localmin = min(xdat)
7736
7733
  if localmin and localmin < xmin:
7737
7734
  xmin = localmin
@@ -8595,13 +8592,9 @@ class Command(cmd.Cmd, object):
8595
8592
  xdat = numpy.array(cur.x)
8596
8593
  ydat = numpy.array(cur.y)
8597
8594
  if yls:
8598
- for i in range(len(ydat)):
8599
- if (ydat[i] < 0):
8600
- ydat[i] = 1e-301 # custom ydata clipping
8595
+ ydat = numpy.where(ydat < 0, 1e-301, ydat) # custom ydata clipping
8601
8596
  if xls:
8602
- for i in range(len(xdat)):
8603
- if xdat[i] < 0:
8604
- xdat[i] = 1e-301 # custom ydata clipping
8597
+ xdat = numpy.where(xdat < 0, 1e-301, xdat) # custom ydata clipping
8605
8598
 
8606
8599
  if cur.ebar is not None:
8607
8600
  plt.errorbar(xdat,
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env /usr/apps/weave/weave-prod-cpu/bin/python3
2
-
3
1
  import sys
4
2
  import os
5
3
 
@@ -14,4 +12,3 @@ try:
14
12
  except ImportError:
15
13
  import pydv.pdv
16
14
  pydv.pdv.Command().main()
17
-
@@ -308,7 +308,7 @@ def getletterargs(line):
308
308
  temp_line = label_line[0].split(':')
309
309
  temp_line[-1] = temp_line[-1] + "`" + label_line[1]
310
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/ :
311
+ elif len(re.split(r"(^[a-zA-Z]:[a-zA-Z]$)|(^[a-zA-Z]:@\d+$)|(^@\d+:@\d+$)", line)) == 1: # single label w/ :
312
312
  return line
313
313
  else:
314
314
  line = line.split(':') # begin arduous list parsing
@@ -70,12 +70,12 @@ A python interface for PyDV functionality.
70
70
  """
71
71
 
72
72
  import json
73
- import os
74
73
  import traceback
75
74
  import sys
76
75
  import re
77
76
  import copy
78
- import random as sysrand
77
+ from multiprocessing import Pool, cpu_count
78
+ import subprocess
79
79
 
80
80
  from distutils.version import LooseVersion
81
81
 
@@ -124,6 +124,8 @@ def makecurve(x=np.empty(0),
124
124
  title='',
125
125
  record_id='',
126
126
  step=False,
127
+ step_original_x=np.empty(0),
128
+ step_original_y=np.empty(0),
127
129
  xticks_labels=None,
128
130
  plotname='',
129
131
  color='',
@@ -172,6 +174,10 @@ def makecurve(x=np.empty(0),
172
174
  :type record_id: str
173
175
  :param step: whether this is a step curve.
174
176
  :type step: bool
177
+ :param step_original_x: list of original x values for step function
178
+ :type step_original_x: list
179
+ :param step_original_y: list of original y values for step function
180
+ :type step_original_y: list
175
181
  :param xticks_labels: Dictionary of x tick labels if x data are strings.
176
182
  :type xticks_labels: dict
177
183
  :param plotname: The plot name of the curve.
@@ -233,6 +239,8 @@ def makecurve(x=np.empty(0),
233
239
  title=title,
234
240
  record_id=record_id,
235
241
  step=step,
242
+ step_original_x=step_original_x,
243
+ step_original_y=step_original_y,
236
244
  xticks_labels=xticks_labels,
237
245
  plotname=plotname,
238
246
  color=color,
@@ -394,13 +402,9 @@ def create_plot(curvelist,
394
402
  ydat = np.array(cur.y)
395
403
 
396
404
  if (yls):
397
- for i in range(len(ydat)):
398
- if (ydat[i] < 0):
399
- ydat[i] = 1e-301 # custom ydata clipping
405
+ ydat = np.where(ydat < 0, 1e-301, ydat) # custom ydata clipping
400
406
  if (xls):
401
- for i in range(len(xdat)):
402
- if (xdat[i] < 0):
403
- xdat[i] = 1e-301 # custom xdata clipping
407
+ xdat = np.where(xdat < 0, 1e-301, xdat) # custom ydata clipping
404
408
 
405
409
  if cur.ebar is not None:
406
410
  c = plt.errorbar(xdat, ydat, yerr=[cur.ebar[0], cur.ebar[1]],
@@ -483,15 +487,15 @@ def save(fname, curvelist, verbose=False, save_labels=False):
483
487
  curves.append(curvelist)
484
488
 
485
489
  try:
486
- f = open(fname, 'w')
487
- for cur in curves:
488
- if save_labels:
489
- print('# ' + cur.name + ' # xlabel ' + cur.xlabel + ' # ylabel ' + cur.ylabel + '\n')
490
- f.write('# ' + cur.name + ' # xlabel ' + cur.xlabel + ' # ylabel ' + cur.ylabel + '\n')
491
- else:
492
- f.write('# ' + cur.name + '\n')
493
- for dex in range(len(cur.x)):
494
- f.write(' ' + str(cur.x[dex]) + ' ' + str(cur.y[dex]) + '\n')
490
+ with open(fname, "w") as f:
491
+ for cur in curves:
492
+ if save_labels:
493
+ print('# ' + cur.name + ' # xlabel ' + cur.xlabel + ' # ylabel ' + cur.ylabel + '\n')
494
+ f.write('# ' + cur.name + ' # xlabel ' + cur.xlabel + ' # ylabel ' + cur.ylabel + '\n')
495
+ else:
496
+ f.write('# ' + cur.name + '\n')
497
+ for dex in range(len(cur.x)):
498
+ f.write(' ' + str(cur.x[dex]) + ' ' + str(cur.y[dex]) + '\n')
495
499
  except:
496
500
  print('Error: Can not write to: ' + fname)
497
501
  if verbose:
@@ -575,203 +579,35 @@ def read(fname, gnu=False, xcol=0, verbose=False, pattern=None, matches=None):
575
579
  return readcsv(fname=fname, xcol=xcol, verbose=verbose)
576
580
  elif str(fname).endswith(".json"):
577
581
  return readsina(fname=fname, verbose=verbose)
578
-
579
- def bundle_curve(_curve, build_x, build_y):
580
-
581
- _curve.xticks_labels = {}
582
-
583
- # Numerical data
582
+ elif gnu or str(fname).endswith(".gnu"):
583
+ return __loadcolumns(fname, xcol)
584
+ elif pdbLoaded:
584
585
  try:
585
- float(build_x[0])
586
-
587
- # X tick label data
586
+ fpdb = pdb.open(fname, 'r')
587
+ return __loadpdb(fname, fpdb)
588
588
  except:
589
+ pass
589
590
 
590
- xticks = list(set(build_x))
591
- xticks.sort()
592
- xticks_dict = {}
593
-
594
- for i, xtick in enumerate(xticks):
595
- xticks_dict[xtick] = i
596
-
597
- build_x = [xticks_dict[xtick] for xtick in build_x]
598
-
599
- _curve.xticks_labels = xticks_dict
600
-
601
- # Step Data
602
- if len(build_x) != len(build_y):
603
- build_y.append(build_y[-1])
604
-
605
- _curve.x = np.array(build_x, dtype=float).repeat(2)[1:]
606
- _curve.y = np.array(build_y, dtype=float).repeat(2)[:-1]
607
- _curve.step = True
608
- _curve.step_original_x = np.array(build_x, dtype=float)
609
- _curve.step_original_y = np.array(build_y[:-1], dtype=float)
610
- # Numerical Data
611
- else:
612
- _curve.x = np.array(build_x, dtype=float)
613
- _curve.y = np.array(build_y, dtype=float)
614
- _curve.step = False
615
-
616
- return _curve
617
-
618
- curve_list = list()
619
591
  regex = None
620
592
 
621
593
  if pattern:
622
594
  regex = re.compile(r"%s" % pattern)
623
- fname = os.path.expanduser(fname)
624
- _, ext = os.path.splitext(fname)
595
+
625
596
  try:
626
- if gnu or ext == '.gnu':
627
- return __loadcolumns(fname, xcol)
628
597
 
629
- if pdbLoaded:
630
- try:
631
- fpdb = pdb.open(fname, 'r')
632
- return __loadpdb(fname, fpdb)
633
- except:
634
- pass
635
-
636
- match_count = 0
637
- build_list_x = list()
638
- build_list_y = list()
639
- current = None
640
- new_curve = True
641
- potential_curve_name = ""
642
- xlabels = {}
643
- ylabels = {}
644
- xlabel = ''
645
- ylabel = ''
646
- with open(fname, 'r') as f:
647
- for line in f:
648
- labels = False
649
-
650
- # Check for labels
651
- split_line_label = re.split(r'#', str.strip(line))
652
- for split in split_line_label:
653
- if re.search('[a-zA-Z]', split):
654
- if 'xlabel' in split:
655
- xlabel = split.replace('xlabel', '').strip()
656
- labels = True
657
- if 'ylabel' in split:
658
- ylabel = split.replace('ylabel', '').strip()
659
- labels = True
660
-
661
- # Contains x and/or y labels
662
- if labels:
663
- split_line = [None] * 2
664
- split_line[0] = '#'
665
- split_line[1] = line.split("# xlabel")[0].split("# ylabel")[0].split("#xlabel")[0].split("#ylabel")[0][1:].strip() # noqae501
666
- xlabels[split_line[1]] = xlabel
667
- ylabels[split_line[1]] = ylabel
668
- xlabel = ''
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))
677
-
678
- if not split_line or not split_line[0]:
679
- continue
680
- elif split_line[0] in {'##', 'end', 'End', 'END'}:
681
- continue
682
- elif split_line[0] == '#':
683
- # We may have just finished buiding a curve, so we need to
684
- # add it to the list of curves.
685
- # If this is the first curve, then current will be None, so
686
- # we won't add anything.
687
- # If there is a sequence of lines that start with # before
688
- # getting to the actual data, then the new_curve flag will
689
- # keep us from adding all those comments as curves.
690
- if current and not new_curve:
691
- # Need this since it will add last match below and outside loop
692
- if matches and match_count >= matches:
693
- break
694
-
695
- curve_list.append(bundle_curve(current, build_list_x, build_list_y))
696
- build_list_x = list()
697
- build_list_y = list()
698
-
699
- # Begin setup of new curve
700
- new_curve = True
701
- potential_curve_name = ' '.join(split_line[1:])
702
- else:
703
- if new_curve:
704
- curve_name = potential_curve_name
705
- new_curve = False
706
- if regex:
707
- if regex.search(curve_name):
708
- match_count += 1
709
- current = makecurve(name=curve_name,
710
- filename=fname,
711
- xlabel=xlabels.get(curve_name, ''),
712
- ylabel=ylabels.get(curve_name, ''))
713
- # Step Data
714
- if len(split_line) == 1:
715
- build_list_x.append(split_line[0])
716
- # Numerical Data
717
- elif len(split_line) == 2:
718
- build_list_x.append(split_line[0])
719
- build_list_y.append(split_line[-1])
720
- # Label Data and Paired Data
721
- else:
722
- try: # Paired Data
723
- float(split_line[0])
724
- build_list_x += split_line[::2]
725
- build_list_y += split_line[1::2]
726
- except: # Label Data
727
- build_list_x.append(" ".join(split_line[:-1]))
728
- build_list_y.append(split_line[-1])
729
- else:
730
- current = None
731
- else:
732
- current = makecurve(name=curve_name,
733
- filename=fname,
734
- xlabel=xlabels.get(curve_name, ''),
735
- ylabel=ylabels.get(curve_name, ''))
736
-
737
- # Step Data
738
- if len(split_line) == 1:
739
- build_list_x.append(split_line[0])
740
- # Numerical Data
741
- elif len(split_line) == 2:
742
- build_list_x.append(split_line[0])
743
- build_list_y.append(split_line[-1])
744
- # Label Data and Paired Data
745
- else:
746
- try: # Paired Data
747
- float(split_line[0])
748
- build_list_x += split_line[::2]
749
- build_list_y += split_line[1::2]
750
- except: # Label Data
751
- build_list_x.append(" ".join(split_line[:-1]))
752
- build_list_y.append(split_line[-1])
753
-
754
- elif current and not new_curve: # add data to current curve
755
-
756
- # Step Data
757
- if len(split_line) == 1:
758
- build_list_x.append(split_line[0])
759
- # Numerical Data
760
- elif len(split_line) == 2:
761
- build_list_x.append(split_line[0])
762
- build_list_y.append(split_line[-1])
763
- # Label Data and Paired Data
764
- else:
765
- try: # Paired Data
766
- float(split_line[0])
767
- build_list_x += split_line[::2]
768
- build_list_y += split_line[1::2]
769
- except: # Label Data
770
- build_list_x.append(" ".join(split_line[:-1]))
771
- build_list_y.append(split_line[-1])
772
-
773
- if current and build_list_x and build_list_y:
774
- curve_list.append(bundle_curve(current, build_list_x, build_list_y))
598
+ # first get the lines that contain the candidate ULTRA curves
599
+ try: # using grep and wc. Much faster
600
+ locs = _get_linelocs_from_text_ultra_grep(fname)
601
+ except: # opening file directly
602
+ locs = _get_linelocs_from_text_ultra(fname)
603
+
604
+ # Parallel curve read using Pool()
605
+ with Pool(processes=cpu_count()) as pool:
606
+
607
+ # Create input tuples for each # line from locs above. Use -1 because last loc idx is end of file
608
+ input_tuples = list(map(lambda idx: (fname, locs, idx, regex), range(len(locs) - 1)))
609
+
610
+ curve_list = list(filter(None, pool.map(_get_curve_from_text_ultra_perproc, input_tuples)))
775
611
 
776
612
  except IOError:
777
613
  print('could not load file: {}'.format(fname))
@@ -2371,14 +2207,14 @@ def sqrtx(curvelist):
2371
2207
  curvelist.x = np.sqrt(curvelist.x)
2372
2208
 
2373
2209
 
2374
- def xmax(curvelist, limit):
2210
+ def xmax(curvelist, max):
2375
2211
  """
2376
2212
  Filter out points in the curve or list of curves whose x values are greater than limit.
2377
2213
 
2378
2214
  :param curvelist: The curve or list of curves
2379
2215
  :type curvelist: curve or list
2380
- :param limit: The maximum value
2381
- :type limit: float
2216
+ :param max: The maximum value
2217
+ :type max: float
2382
2218
  """
2383
2219
 
2384
2220
  curves = list()
@@ -2389,16 +2225,8 @@ def xmax(curvelist, limit):
2389
2225
  curves.append(curvelist)
2390
2226
 
2391
2227
  for c in curves:
2392
- nx = []
2393
- ny = []
2394
-
2395
- for i in range(len(c.x)):
2396
- if c.x[i] <= float(limit):
2397
- nx.append(c.x[i])
2398
- ny.append(c.y[i])
2399
-
2400
- c.x = np.array(nx)
2401
- c.y = np.array(ny)
2228
+ c.x = c.x[np.where(c.x <= float(max))]
2229
+ c.y = c.y[np.where(c.x <= float(max))]
2402
2230
 
2403
2231
 
2404
2232
  def xmin(curvelist, min):
@@ -2419,16 +2247,8 @@ def xmin(curvelist, min):
2419
2247
  curves.append(curvelist)
2420
2248
 
2421
2249
  for c in curves:
2422
- nx = []
2423
- ny = []
2424
-
2425
- for i in range(len(c.x)):
2426
- if c.x[i] >= float(min):
2427
- nx.append(c.x[i])
2428
- ny.append(c.y[i])
2429
-
2430
- c.x = np.array(nx)
2431
- c.y = np.array(ny)
2250
+ c.x = c.x[np.where(c.x >= float(min))]
2251
+ c.y = c.y[np.where(c.x >= float(min))]
2432
2252
 
2433
2253
 
2434
2254
  def xminmax(curvelist, min, max):
@@ -2451,16 +2271,8 @@ def xminmax(curvelist, min, max):
2451
2271
  curves.append(curvelist)
2452
2272
 
2453
2273
  for c in curves:
2454
- nx = []
2455
- ny = []
2456
-
2457
- for i in range(len(c.x)):
2458
- if float(min) <= c.x[i] <= float(max):
2459
- nx.append(c.x[i])
2460
- ny.append(c.y[i])
2461
-
2462
- c.x = np.array(nx)
2463
- c.y = np.array(ny)
2274
+ c.x = c.x[np.where(np.logical_and(c.x >= float(min), c.x <= float(max)))]
2275
+ c.y = c.y[np.where(np.logical_and(c.x >= float(min), c.x <= float(max)))]
2464
2276
 
2465
2277
 
2466
2278
  def ymax(curvelist, max):
@@ -2481,16 +2293,8 @@ def ymax(curvelist, max):
2481
2293
  curves.append(curvelist)
2482
2294
 
2483
2295
  for c in curves:
2484
- nx = []
2485
- ny = []
2486
-
2487
- for i in range(len(c.y)):
2488
- if c.y[i] <= float(max):
2489
- nx.append(c.x[i])
2490
- ny.append(c.y[i])
2491
-
2492
- c.x = np.array(nx)
2493
- c.y = np.array(ny)
2296
+ c.x = c.x[np.where(c.y <= float(max))]
2297
+ c.y = c.y[np.where(c.y <= float(max))]
2494
2298
 
2495
2299
 
2496
2300
  def ymin(curvelist, min):
@@ -2511,16 +2315,8 @@ def ymin(curvelist, min):
2511
2315
  curves.append(curvelist)
2512
2316
 
2513
2317
  for c in curves:
2514
- nx = []
2515
- ny = []
2516
-
2517
- for i in range(len(c.y)):
2518
- if c.y[i] >= float(min):
2519
- nx.append(c.x[i])
2520
- ny.append(c.y[i])
2521
-
2522
- c.x = np.array(nx)
2523
- c.y = np.array(ny)
2318
+ c.x = c.x[np.where(c.y >= float(min))]
2319
+ c.y = c.y[np.where(c.y >= float(min))]
2524
2320
 
2525
2321
 
2526
2322
  def yminmax(curvelist, min, max):
@@ -2543,16 +2339,8 @@ def yminmax(curvelist, min, max):
2543
2339
  curves.append(curvelist)
2544
2340
 
2545
2341
  for c in curves:
2546
- nx = []
2547
- ny = []
2548
-
2549
- for i in range(len(c.y)):
2550
- if float(min) <= c.y[i] <= float(max):
2551
- nx.append(c.x[i])
2552
- ny.append(c.y[i])
2553
-
2554
- c.x = np.array(nx)
2555
- c.y = np.array(ny)
2342
+ c.x = c.x[np.where(np.logical_and(c.y >= float(min), c.y <= float(max)))]
2343
+ c.y = c.y[np.where(np.logical_and(c.y >= float(min), c.y <= float(max)))]
2556
2344
 
2557
2345
 
2558
2346
  def yn(curvelist, n):
@@ -2961,32 +2749,24 @@ def getymax(c, xmin=None, xmax=None):
2961
2749
  list -- a list of tuples where each tuple contains the x-value and
2962
2750
  the max y-value.
2963
2751
  """
2964
- try:
2965
- if xmin is not None:
2966
- r = __get_sub_range(c.x, xmin, xmax)
2967
- ymax = max(c.y[r[0]:r[1] + 1])
2968
- else:
2969
- ymax = max(c.y)
2970
- r = [0, len(c.x) - 1]
2971
- except:
2972
- pass
2752
+ xl = c.x[0] if xmin is None else xmin
2753
+ xr = c.x[-1] if xmax is None else xmax
2754
+ domain = list(c.x[np.where(np.logical_and(c.x >= xl, c.x <= xr))])
2755
+ domain.extend([xl, xr])
2756
+ domain = list(set(domain))
2757
+ domain.sort()
2758
+ y_interp = np.interp(domain, c.x, c.y,
2759
+ left=c.math_interp_left,
2760
+ right=c.math_interp_right,
2761
+ period=c.math_interp_period)
2973
2762
 
2974
- if r[0] >= r[1]:
2975
- # User range is in between actual curve points
2976
- # c.x val1 val2 c.x
2977
- xl = c.x[0] if xmin is None else xmin
2978
- xr = c.x[-1] if xmax is None else xmax
2979
- range_x = np.linspace(xl, xr, num=1000)
2980
- y_interp = np.interp(range_x, c.x, c.y)
2981
- ymax = max(y_interp)
2763
+ indices = np.where(y_interp == np.max(y_interp))[0]
2982
2764
 
2983
- # User range has only one curve point in between
2984
- # val1 c.x val2
2985
- if r[0] == r[1] and c.y[r[0]] > ymax: # Local max
2986
- ymax = c.y[r[0]]
2987
- xy_pairs_at_max = getx(c, ymax, xmin, xmax)
2765
+ xypairs = list()
2766
+ for index in indices:
2767
+ xypairs.append((domain[index], y_interp[index]))
2988
2768
 
2989
- return __toCurveString(c), xy_pairs_at_max
2769
+ return __toCurveString(c), xypairs
2990
2770
 
2991
2771
 
2992
2772
  def getymin(c, xmin=None, xmax=None):
@@ -3003,33 +2783,24 @@ def getymin(c, xmin=None, xmax=None):
3003
2783
  list -- a list of tuples where each tuple contains the x-value and
3004
2784
  the min y-value.
3005
2785
  """
3006
- try:
3007
- if xmin is not None:
3008
- r = __get_sub_range(c.x, xmin, xmax)
3009
- ymin = min(c.y[r[0]:r[1] + 1])
3010
- else:
3011
- ymin = min(c.y)
3012
- r = [0, len(c.x) - 1]
3013
- except:
3014
- pass
2786
+ xl = c.x[0] if xmin is None else xmin
2787
+ xr = c.x[-1] if xmax is None else xmax
2788
+ domain = list(c.x[np.where(np.logical_and(c.x >= xl, c.x <= xr))])
2789
+ domain.extend([xl, xr])
2790
+ domain = list(set(domain))
2791
+ domain.sort()
2792
+ y_interp = np.interp(domain, c.x, c.y,
2793
+ left=c.math_interp_left,
2794
+ right=c.math_interp_right,
2795
+ period=c.math_interp_period)
3015
2796
 
3016
- if r[0] >= r[1]:
3017
- # User range is in between actual curve points
3018
- # c.x val1 val2 c.x
3019
- xl = c.x[0] if xmin is None else xmin
3020
- xr = c.x[-1] if xmax is None else xmax
3021
- range_x = np.linspace(xl, xr, num=1000)
3022
- y_interp = np.interp(range_x, c.x, c.y)
3023
- ymin = min(y_interp)
2797
+ indices = np.where(y_interp == np.min(y_interp))[0]
3024
2798
 
3025
- # User range has only one curve point in between
3026
- # val1 c.x val2
3027
- if r[0] == r[1] and c.y[r[0]] < ymin: # Local min
3028
- ymin = c.y[r[0]]
3029
-
3030
- xy_pairs_at_min = getx(c, ymin, xmin, xmax)
2799
+ xypairs = list()
2800
+ for index in indices:
2801
+ xypairs.append((domain[index], y_interp[index]))
3031
2802
 
3032
- return __toCurveString(c), xy_pairs_at_min
2803
+ return __toCurveString(c), xypairs
3033
2804
 
3034
2805
 
3035
2806
  def cumsum(c1):
@@ -3630,13 +3401,8 @@ def errorbar(scur, cury1, cury2, curx1=None, curx2=None, mod=1):
3630
3401
  :type mod: int
3631
3402
  """
3632
3403
  ebar = [np.zeros(len(scur.x)), np.zeros(len(scur.x)), np.zeros(len(scur.x)), np.zeros(len(scur.x))]
3633
- lowy = list()
3634
- for i in range(len(scur.x)):
3635
- y = np.interp(scur.x[i], cury1.x, cury1.y)
3636
- if scur.y[i] - y <= 0:
3637
- lowy.append(y)
3638
- else:
3639
- lowy.append(scur.y[i])
3404
+ y = np.interp(scur.x, cury1.x, cury1.y)
3405
+ lowy = np.where(scur.y - y <= 0, y, scur.y)
3640
3406
 
3641
3407
  ebar[0] = np.array(lowy)
3642
3408
  ebar[1] = np.interp(scur.x, cury2.x, cury2.y)
@@ -3942,7 +3708,7 @@ def getx(c, value, xmin=None, xmax=None):
3942
3708
  else:
3943
3709
 
3944
3710
  # User range is in between actual curve points
3945
- # c.x val1 val2 c.x
3711
+ # c.x xmin xmax c.x
3946
3712
  xl = c.x[0] if xmin is None else xmin
3947
3713
  xr = c.x[-1] if xmax is None else xmax
3948
3714
  range_x = np.linspace(xl, xr, num=1000)
@@ -3952,7 +3718,7 @@ def getx(c, value, xmin=None, xmax=None):
3952
3718
  xypairs.append((x, y))
3953
3719
 
3954
3720
  # User range has only one curve point in between
3955
- # val1 c.x val2
3721
+ # xmin c.x xmax
3956
3722
  if r[0] == r[1]:
3957
3723
  if c.y[r[0]] == float(value): # value exists in curve
3958
3724
  xypairs.append((c.x[r[0]], float(value)))
@@ -3978,27 +3744,10 @@ def gety(c, value):
3978
3744
  """
3979
3745
  xypairs = list()
3980
3746
 
3981
- # if float(value) < np.amin(c.x) or float(value) > np.amax(c.x):
3982
- # raise ValueError, 'x-value out of range'
3983
-
3984
- for i in range(len(c.x)):
3985
- if float(value) < np.amin(c.x):
3986
- xypairs.append((float(value), 0)) # c.y[0]))
3987
- elif float(value) > np.amax(c.x):
3988
- xypairs.append((float(value), 0)) # c.y[-1]))
3989
- elif c.x[i] == float(value):
3990
- xypairs.append((float(value), c.y[i]))
3991
- else:
3992
- xmax = c.x[i]
3993
- if i + 1 < len(c.x):
3994
- xmax = c.x[i + 1]
3995
-
3996
- if c.x[i] < float(value) < xmax:
3997
- y = np.interp(float(value), [c.x[i], xmax], [c.y[i], c.y[i + 1]])
3998
- xypairs.append((float(value), y))
3999
- elif xmax < float(value) < c.x[i]:
4000
- y = np.interp(float(value), [xmax, c.x[i]], [c.y[i + 1], c.y[i]])
4001
- xypairs.append((float(value), y))
3747
+ xypairs.append((float(value), np.interp(float(value), c.x, c.y,
3748
+ left=c.math_interp_left,
3749
+ right=c.math_interp_right,
3750
+ period=c.math_interp_period)))
4002
3751
 
4003
3752
  return xypairs
4004
3753
 
@@ -4185,15 +3934,9 @@ def sort(curve):
4185
3934
  :type curve: Curve
4186
3935
  """
4187
3936
  index_array = np.argsort(curve.x)
4188
- x = list()
4189
- y = list()
4190
-
4191
- for index in index_array:
4192
- x.append(curve.x[index])
4193
- y.append(curve.y[index])
4194
3937
 
4195
- curve.x = np.array(x)
4196
- curve.y = np.array(y)
3938
+ curve.x = curve.x[index_array]
3939
+ curve.y = curve.y[index_array]
4197
3940
 
4198
3941
 
4199
3942
  def rev(curve):
@@ -4225,8 +3968,7 @@ def random(curve):
4225
3968
  :param curve: The curve to sort
4226
3969
  :type curve: Curve
4227
3970
  """
4228
- for i in range(len(curve.y)):
4229
- curve.y[i] = sysrand.uniform(-1, 1)
3971
+ curve.y = np.random.uniform(-1, 1, len(curve.y))
4230
3972
 
4231
3973
 
4232
3974
  def xindex(curvelist):
@@ -4313,21 +4055,16 @@ def max_curve(curvelist):
4313
4055
 
4314
4056
  # Calculate max
4315
4057
  x = np.array(ux)
4316
- y = np.zeros(len(x))
4317
4058
 
4318
- for i in range(len(x)):
4319
- y[i] = float(-sys.maxsize - 1)
4320
- for j in range(len(curvelist)):
4321
- try:
4322
- vals = gety(curvelist[j], x[i])
4323
- for val in vals:
4324
- if y[i] < val[1]:
4325
- y[i] = val[1]
4326
- except:
4327
- pass
4059
+ all_data = []
4060
+ for cur in curvelist:
4061
+ all_data.append(np.interp(x, cur.x, cur.y,
4062
+ left=cur.math_interp_left,
4063
+ right=cur.math_interp_right,
4064
+ period=cur.math_interp_period))
4328
4065
 
4329
4066
  nc = makecurve(x=x,
4330
- y=y,
4067
+ y=np.max(all_data, axis=0),
4331
4068
  name='Max(' + name_suffix + ')')
4332
4069
 
4333
4070
  return nc
@@ -4359,21 +4096,16 @@ def min_curve(curvelist):
4359
4096
 
4360
4097
  # Calculate min
4361
4098
  x = np.array(ux)
4362
- y = np.zeros(len(x))
4363
4099
 
4364
- for i in range(len(x)):
4365
- y[i] = float(sys.maxsize)
4366
- for j in range(len(curvelist)):
4367
- try:
4368
- vals = gety(curvelist[j], x[i])
4369
- for val in vals:
4370
- if y[i] > val[1]:
4371
- y[i] = val[1]
4372
- except:
4373
- pass
4100
+ all_data = []
4101
+ for cur in curvelist:
4102
+ all_data.append(np.interp(x, cur.x, cur.y,
4103
+ left=cur.math_interp_left,
4104
+ right=cur.math_interp_right,
4105
+ period=cur.math_interp_period))
4374
4106
 
4375
4107
  nc = makecurve(x=x,
4376
- y=y,
4108
+ y=np.min(all_data, axis=0),
4377
4109
  name='Min(' + name_suffix + ')')
4378
4110
 
4379
4111
  return nc
@@ -4404,23 +4136,16 @@ def average_curve(curvelist):
4404
4136
 
4405
4137
  # Calculate average
4406
4138
  x = np.array(ux)
4407
- y = np.zeros(len(x))
4408
4139
 
4409
- for i in range(len(x)):
4410
- cnt = 0
4411
- for j in range(len(curvelist)):
4412
- try:
4413
- vals = gety(curvelist[j], x[i])
4414
- for val in vals:
4415
- y[i] += val[1]
4416
- cnt += 1
4417
- except:
4418
- pass
4419
-
4420
- y[i] /= cnt
4140
+ all_data = []
4141
+ for cur in curvelist:
4142
+ all_data.append(np.interp(x, cur.x, cur.y,
4143
+ left=cur.math_interp_left,
4144
+ right=cur.math_interp_right,
4145
+ period=cur.math_interp_period))
4421
4146
 
4422
4147
  nc = makecurve(x=x,
4423
- y=y,
4148
+ y=np.mean(all_data, axis=0),
4424
4149
  name='Average(' + name_suffix + ')')
4425
4150
 
4426
4151
  return nc
@@ -4471,10 +4196,7 @@ def __ifft(cr, ci):
4471
4196
  :type c: Curve
4472
4197
  :return: tuple - two curves, one with the real part and the other with the imaginary part for their y-values.
4473
4198
  """
4474
- carray = np.zeros(len(cr.y), dtype=complex)
4475
-
4476
- for i in range(len(cr.y)):
4477
- carray[i] = complex(cr.y[i], ci.y[i])
4199
+ carray = cr.y + 1j * ci.y
4478
4200
 
4479
4201
  numpy1_10 = LooseVersion(np.__version__) >= LooseVersion("1.10.0")
4480
4202
 
@@ -4659,6 +4381,172 @@ def __loadpdb(fname, fpdb):
4659
4381
  return curvelist
4660
4382
 
4661
4383
 
4384
+ def _get_linelocs_from_text_ultra_grep(fname):
4385
+
4386
+ # first find all the character offsets of the # lines in the ULTRA file
4387
+ stdout_val = subprocess.check_output(['/usr/bin/grep',
4388
+ '--byte-offset',
4389
+ '--only-matching',
4390
+ '--text',
4391
+ '^#',
4392
+ fname],
4393
+ stderr=subprocess.STDOUT).decode('utf8')
4394
+ locs = [int(line.strip().split(':')[0]) for line in stdout_val.split('\n')[:-1]] # last is just empty newline
4395
+
4396
+ # now get the last character offset in the ULTRA file
4397
+ stdout_val = subprocess.check_output(['/usr/bin/wc',
4398
+ '-c',
4399
+ fname],
4400
+ stderr=subprocess.PIPE).decode('utf8')
4401
+ locs.append(int(stdout_val.split()[0])) # append end of file byte location
4402
+
4403
+ return locs
4404
+
4405
+
4406
+ def _get_linelocs_from_text_ultra(fname):
4407
+ # These are byte locations not actual line locations, each standard ASCII character is one byte.
4408
+
4409
+ with open(fname, 'r') as openfile:
4410
+
4411
+ loc = 0 # byte tracker for whole file
4412
+ locs = [] # location list of titles or comments
4413
+
4414
+ for line in openfile:
4415
+
4416
+ if line.strip()[:1] == '#': # title or comment
4417
+ locs.append(loc) # append title or comment byte location to location list
4418
+
4419
+ loc += len(line) # add number of bytes in line to byte tracker
4420
+
4421
+ locs.append(loc) # append end of file byte location to location list
4422
+
4423
+ return locs
4424
+
4425
+
4426
+ def _get_curve_from_text_ultra_perproc(input_tuple):
4427
+ fname, locs, idx, regex = input_tuple
4428
+
4429
+ # Defaults
4430
+ xlabel = ''
4431
+ ylabel = ''
4432
+ step = False
4433
+ step_original_x = np.empty(0)
4434
+ step_original_y = np.empty(0)
4435
+ xticks_labels = {}
4436
+
4437
+ try:
4438
+ with open(fname, 'r') as openfile:
4439
+
4440
+ # Finds byte location
4441
+ openfile.seek(locs[idx])
4442
+
4443
+ # ONLY reads content of single curve based on byte location
4444
+ content = openfile.read(locs[idx + 1] - locs[idx])
4445
+
4446
+ # Creates a list of lines that splits on newline and creates x y pairs
4447
+ lcont = list(filter(lambda line: len(line) > 0, map(lambda line: line.strip(), content.split('\n'))))
4448
+
4449
+ if len(lcont) < 2: # at least one data point
4450
+ return None
4451
+
4452
+ ##############
4453
+ # Curve name #
4454
+ ##############
4455
+ name = lcont[0].split("# xlabel")[0].split("# ylabel")[0].split("#xlabel")[0].split("#ylabel")[0][1:].strip() # noqae501
4456
+ if regex:
4457
+ if regex.search(name):
4458
+ print(f'Found match: {name}')
4459
+ else:
4460
+ return None
4461
+
4462
+ #################
4463
+ # x and y label #
4464
+ #################
4465
+ split_line_label = re.split(r'#', str.strip(lcont[0]))
4466
+ for split in split_line_label:
4467
+ if re.search('[a-zA-Z]', split):
4468
+ if 'xlabel' in split:
4469
+ xlabel = split.replace('xlabel', '').strip()
4470
+ if 'ylabel' in split:
4471
+ ylabel = split.replace('ylabel', '').strip()
4472
+
4473
+ ########
4474
+ # DATA #
4475
+ ########
4476
+
4477
+ # xticklabel or horizontal data
4478
+ if len(lcont[1].split()) > 2:
4479
+
4480
+ # horizontal data see tests/diff_formats.txt format 3a and format 3b
4481
+ try:
4482
+
4483
+ float(lcont[1].rsplit(None, 1)[0].split()[0])
4484
+
4485
+ # Split the horizontal data into x y pairs
4486
+ pairs = []
4487
+ for line in lcont[1:]:
4488
+ numbers = [x for x in line.split() if x]
4489
+ line_pairs = ['{} {}'.format(numbers[i], numbers[i + 1]) for i in range(0, len(numbers), 2)]
4490
+ pairs.extend(line_pairs)
4491
+
4492
+ lcont = [lcont[0]]
4493
+ lcont.extend(pairs)
4494
+
4495
+ # X tick label data see tests/diff_formats.txt My curve6
4496
+ except ValueError:
4497
+ pass
4498
+
4499
+ # Splits newline x y pairs into individual x y
4500
+ if lcont[-1] != 'end':
4501
+ v = [item for s in lcont[1:] for item in s.rsplit(None, 1)]
4502
+ else:
4503
+ v = [item for s in lcont[1:-1] for item in s.rsplit(None, 1)]
4504
+
4505
+ xvals = v[::2]
4506
+ yvals = v[1::2]
4507
+
4508
+ # Numerical data
4509
+ try:
4510
+ float(xvals[0])
4511
+
4512
+ # X tick label data
4513
+ except:
4514
+
4515
+ xticks = list(set(xvals))
4516
+ xticks.sort()
4517
+ xticks_dict = {}
4518
+
4519
+ for i, xtick in enumerate(xticks):
4520
+ xticks_dict[xtick] = i
4521
+
4522
+ xvals = [xticks_dict[xtick] for xtick in xvals]
4523
+
4524
+ xticks_labels = xticks_dict
4525
+
4526
+ # Step Data
4527
+ if len(xvals) != len(yvals):
4528
+ step_original_x = np.array(xvals, dtype=float)
4529
+ step_original_y = np.array(yvals, dtype=float)
4530
+
4531
+ yvals.append(yvals[-1])
4532
+ xvals = np.array(xvals, dtype=float).repeat(2)[1:]
4533
+ yvals = np.array(yvals, dtype=float).repeat(2)[:-1]
4534
+ step = True
4535
+
4536
+ # Numerical Data
4537
+ else:
4538
+ xvals = np.array(xvals, dtype=float)
4539
+ yvals = np.array(yvals, dtype=float)
4540
+
4541
+ return makecurve(x=xvals, y=yvals, name=name, filename=fname,
4542
+ xlabel=xlabel, ylabel=ylabel,
4543
+ step=step, step_original_x=step_original_x, step_original_y=step_original_y,
4544
+ xticks_labels=xticks_labels)
4545
+ except Exception as e:
4546
+ print(str(e))
4547
+ return None
4548
+
4549
+
4662
4550
  ########################################################
4663
4551
  ################# Curve Comparisons #################### # noqa e266
4664
4552
  ########################################################
@@ -0,0 +1 @@
1
+ 07.07.2025
@@ -0,0 +1 @@
1
+ 3.7.0
@@ -1,7 +1,7 @@
1
1
  [tool]
2
2
  [tool.poetry]
3
3
  name = "LLNL-PyDV"
4
- version = "3.6.3"
4
+ version = "3.7.0"
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.3"
68
+ current_version = "3.7.0"
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
- 04.14.2025
@@ -1 +0,0 @@
1
- 3.6.3
File without changes
File without changes
File without changes
File without changes
File without changes