Skip to content

Commit fa05ca1

Browse files
committed
Merge branch 'main' of github.com:SCECcode/ucvm_plotting
2 parents 96f80ba + 6b556b9 commit fa05ca1

14 files changed

+629
-103
lines changed
7.88 KB
Binary file not shown.

dist/ucvm_plotting-0.0.4.tar.gz

3.05 KB
Binary file not shown.

pycvm/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
from .vs30_slice import Vs30Slice
1111
from .elevation_slice import ElevationSlice
1212
from .vs30_etree_slice import Vs30EtreeSlice
13-
from .vs30_etree_difference_slice import Vs30EtreeDifferenceSlice
13+
from .horizontal_difference_slice import HorizontalDifferenceSlice
14+
from .cross_difference_section import CrossDifferenceSection
1415
from .map_grid_horizontal_slice import MapGridHorizontalSlice
1516
from .basin_slice import BasinSlice, Z10Slice, Z25Slice
1617
from .depth_profile import DepthProfile
1718
from .elevation_profile import ElevationProfile
1819
from .difference import Difference
19-
from .cybershake import CyberShake

pycvm/common.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,7 @@ def import_binary(self, fname, num_x, num_y):
962962
if( k != -1) :
963963
rawfile = rawfile[:k] + "_data.bin"
964964
try :
965-
fh = open(rawfile, 'r')
965+
fh = open(rawfile, 'rb')
966966
except:
967967
print("ERROR: binary data does not exist.")
968968
exit(1)
@@ -973,16 +973,22 @@ def import_binary(self, fname, num_x, num_y):
973973
if len(floats) == 2 * (num_x * num_y) :
974974
fh.seek(0,0)
975975
floats = np.fromfile(fh, dtype=np.float)
976+
fh.close()
977+
978+
## maybe it is a np array
979+
if len(floats) != (num_x * num_y) :
980+
ffh = open(rawfile, 'rb')
981+
ffloats = np.load(ffh)
982+
ffh.close()
983+
floats=ffloats.reshape([num_x * num_y]);
976984

977985
print("TOTAL number of binary data read:"+str(len(floats))+"\n")
978986

979987
# sanity check,
980988
if len(floats) != (num_x * num_y) :
981-
print("import_binary(), wrong size !!!"+ str(len(floats))+ " expecting "+ str(num_x * num_y))
989+
print("import_binary(), wrong size !!!"+ str(len(floats)) + " expecting "+ str(num_x * num_y))
982990
exit(1)
983991

984-
fh.close()
985-
986992
if len(floats) == 1:
987993
return floats[0]
988994

@@ -991,7 +997,7 @@ def import_binary(self, fname, num_x, num_y):
991997
# export np float array to an exernal file
992998
#
993999
def export_np_float_array(self, floats, fname):
994-
# print("calling export_np_float_array")
1000+
# print("calling export_np_float_array -",len(floats))
9951001
rawfile = fname
9961002
if rawfile is None :
9971003
rawfile="data.bin"
@@ -1005,11 +1011,13 @@ def export_np_float_array(self, floats, fname):
10051011
exit(1)
10061012

10071013
np.save(fh, floats)
1008-
fh.close
1014+
fh.close()
1015+
1016+
10091017

10101018
# export raw floats nxy ndarray to an external file
10111019
def export_binary(self, floats, fname):
1012-
# print("calling export_binary")
1020+
print("calling export_binary -",len(floats))
10131021
rawfile = fname
10141022
if rawfile is None :
10151023
rawfile="data.bin"
@@ -1044,7 +1052,7 @@ def import_metadata(self, fname):
10441052

10451053
# export ascii meta data to an external file
10461054
def export_metadata(self,meta,fname):
1047-
# print("calling export_metadata")
1055+
print("calling export_metadata")
10481056
metafile=fname
10491057
if metafile is None:
10501058
metafile = "meta.json"
@@ -1075,7 +1083,7 @@ def import_matprops(self, fname):
10751083

10761084
# export material properties in JSON form to an external file
10771085
def export_matprops(self,blob,fname):
1078-
# print("calling export_matprops")
1086+
print("calling export_matprops")
10791087
matpropsfile=fname
10801088
if matpropsfile is None :
10811089
matpropsfile="matprops.json"
@@ -1145,7 +1153,7 @@ def makebounds(self,minval=0.0,maxval=5.0,nstep=0,meanval=None, substep=5,all=Tr
11451153
l=0
11461154
nsubstep=substep
11471155
nnstep=float(step)/nsubstep
1148-
if(meanval != None) :
1156+
if(meanval != None and step!= 0) :
11491157
l =(meanval-minval) //step
11501158

11511159
for i in range(0,nstep) :

pycvm/vs30_etree_difference_slice.py renamed to pycvm/cross_difference_section.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
##
2-
# @file vs30_etree_difference_slice.py
3-
# @brief Take 2 slices of vs30 values, plot a difference horizontal slice
2+
# @file cross_difference_section.py
3+
# @brief Take 2 slices of cross sections, plot a difference plot
44
# @author Mei-Hui Su - SCEC
55
# @version
66
#
77
# Imports
8-
from horizontal_slice import HorizontalSlice
8+
from cross_section import CrossSection
99
from common import Point, MaterialProperties, UCVM, UCVM_CVMS, \
1010
math, pycvm_cmapDiscretize, cm, mcolors, basemap, np, plt
1111

1212
##
13-
# @class Vs30EtreeSlice
14-
# @brief Gets a horizontal slice of Vs30 data.
13+
# @class CrossDifferencSection
14+
# @brief Gets 2 cross section and make a difference plot
1515
#
16-
# Retrieves 2 horizontal slices of Vs30 values and make a difference plot
17-
class Vs30EtreeDifferenceSlice(HorizontalSlice):
16+
# Retrieves 2 cross sections and make a difference plot
17+
class CrossDifferenceSection(CrossSection):
1818

1919
##
2020
# Initializes the super class and copies the parameters over.
@@ -26,8 +26,8 @@ class Vs30EtreeDifferenceSlice(HorizontalSlice):
2626
#
2727
def __init__(self, upperleftpoint, bottomrightpoint, meta={}):
2828

29-
# Initializes the base class which is a horizontal slice.
30-
HorizontalSlice.__init__(self, upperleftpoint, bottomrightpoint, meta)
29+
# Initializes the base class which is a cross section.
30+
CrossSection.__init__(self, upperleftpoint, bottomrightpoint, meta)
3131

3232
if 'datafile1' in self.meta :
3333
self.datafile1 = self.meta['datafile1']
@@ -41,7 +41,7 @@ def __init__(self, upperleftpoint, bottomrightpoint, meta={}):
4141

4242

4343
##
44-
# Retrieves the values for this Vs30 slice and stores them in the class.
44+
# Retrieves the values for this cross section and stores them in the class.
4545
def getplotvals(self, property="vs") :
4646

4747
# How many y and x values will we need?
@@ -61,7 +61,7 @@ def getplotvals(self, property="vs") :
6161
else :
6262
self.num_y = int(math.ceil(self.plot_height / self.spacing)) + 1
6363

64-
## The 2D array of retrieved Vs30 values.
64+
## The 2D array of retrieved values.
6565
self.materialproperties = [[MaterialProperties(-1, -1, -1) for x in range(self.num_x)] for x in range(self.num_y)]
6666

6767
u = UCVM(install_dir=self.installdir, config_file=self.configfile)
@@ -102,7 +102,7 @@ def getplotvals(self, property="vs") :
102102

103103
i = 0
104104
j = 0
105-
105+
106106
for idx in range(len(dataA)) :
107107
self.materialproperties[i][j].vs = dataA[idx]-dataB[idx]
108108
j = j + 1
@@ -111,8 +111,8 @@ def getplotvals(self, property="vs") :
111111
i = i + 1
112112

113113
##
114-
# Plots the Vs30 data as a horizontal slice. This code is very similar to the
115-
# HorizontalSlice routine.
114+
# Plots the Difference data as a cross section. This code is very similar to the
115+
# CrossSection routine.
116116
#
117117
# @param filename The location to which the plot should be saved. Optional.
118118
# @param title The title of the plot to use. Optional.
@@ -131,10 +131,10 @@ def plot(self) :
131131
cvmdesc = self.cvm
132132

133133
if 'title' not in self.meta:
134-
title = "%sVs30 Etree Difference Plot For %s" % (location_text, cvmdesc)
134+
title = "%sCross Section Difference Plot For %s" % (location_text, cvmdesc)
135135
self.meta['title'] = title
136136

137137
self.meta['mproperty']="vs"
138-
self.meta['difference']="vs30"
138+
self.meta['difference']="vs"
139139

140-
HorizontalSlice.plot(self)
140+
CrossSection.plot(self)

pycvm/cross_section.py

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
# @brief Plots a cross section between two @link common.Point Points @endlink.
3030
#
3131
# Generates a cross section that can either be saved as a file or displayed
32-
# to the user.
32+
# to the user or differenced with another plot.
3333
class CrossSection:
3434

3535
##
@@ -86,8 +86,15 @@ def __init__(self, startingpoint, endingpoint, meta={}):
8686
self.floors = None
8787
if 'vsfloor' in self.meta and 'vpfloor' in self.meta and 'densityfloor' in self.meta :
8888
self.floors=self.meta['vsfloor']+","+self.meta['vpfloor']+","+self.meta['densityfloor']
89-
90-
89+
90+
if 'scalemin' in self.meta and 'scalemax' in self.meta :
91+
## user supplied a fixed scale bounds
92+
self.scalemin=float(self.meta['scalemin'])
93+
self.scalemax=float(self.meta['scalemax'])
94+
else:
95+
self.scalemin=None
96+
self.scalemax=None
97+
9198
## The CVM to use (must be installed with UCVM).
9299
if 'cvm' in self.meta :
93100
self.cvm = self.meta['cvm']
@@ -147,7 +154,6 @@ def getplotvals(self, mproperty='vs'):
147154
# print("total lat.."+ str(len(depth_list)))
148155

149156
u = UCVM(install_dir=self.installdir, config_file=self.configfile, z_range=self.z_range, floors=self.floors)
150-
151157
### MEI -- TODO, need to have separate routine that generates cross section datafile
152158
if (self.datafile != None) :
153159
## Private number of x points.
@@ -157,10 +163,14 @@ def getplotvals(self, mproperty='vs'):
157163
print("\nUsing -->"+self.datafile)
158164
## print("expecting x "+str(self.num_x)+" y "+str(self.num_y))
159165

160-
if self.datafile.rfind(".raw") != -1:
166+
167+
if self.datafile.rfind(".binary") != -1 :
161168
data = u.import_binary(self.datafile, self.num_x, self.num_y)
162-
else: ## ends in .bin
163-
data = u.import_np_float_array(self.datafile, self.num_x, self.num_y)
169+
else :
170+
if self.datafile.rfind(".raw") != -1 :
171+
data = u.import_raw_data(self.datafile, self.num_x, self.num_y)
172+
else: ## with .bin file
173+
data = u.import_np_float_array(self.datafile, self.num_x, self.num_y)
164174

165175
## this set of data is only for --datatype: either 'vs', 'vp', 'rho', or 'poisson'
166176
## The 2D array of retrieved material properties.
@@ -178,6 +188,8 @@ def getplotvals(self, mproperty='vs'):
178188
self.materialproperties[y][x].setProperty('Poisson',tmp)
179189
if(mproperty == 'vs'):
180190
self.materialproperties[y][x].setProperty('Vs',tmp)
191+
192+
print("\nUsing --> "+self.datafile)
181193
else:
182194
data = u.query(point_list, self.cvm)
183195

@@ -323,33 +335,43 @@ def plot(self) :
323335
self.min_val=np.nanmin(newdatapoints)
324336
self.mean_val=np.mean(newdatapoints)
325337

326-
BOUNDS = u.makebounds()
327-
TICKS = u.maketicks()
338+
# Set colormap and range
339+
colormap = basemap.cm.GMT_seis
340+
341+
if self.scalemin != None and self.scalemax != None:
342+
BOUNDS= u.makebounds(float(self.scalemin), float(self.scalemax), 5)
343+
TICKS = u.maketicks(float(self.scalemin), float(self.scalemax), 5)
344+
umax=round(self.scalemax)
345+
umin=round(self.scalemin)
346+
umean=round((umax+umin)/2)
347+
else:
348+
## default BOUNDS are from 0 to 5
349+
BOUNDS = u.makebounds()
350+
TICKS = u.maketicks()
351+
umax=round(self.max_val)
352+
umin=round(self.min_val)
353+
umean=round(self.mean_val)
328354

329355
if mproperty == "vp":
330356
BOUNDS = [bound * 1.7 for bound in BOUNDS]
331357
TICKS = [tick * 1.7 for tick in TICKS]
332358

333-
# Set default colormap and range
334-
colormap = basemap.cm.GMT_seis
335-
norm = mcolors.BoundaryNorm(BOUNDS, colormap.N)
336-
337-
umax=round(self.max_val)
338-
if( umax < 5 ) :
339-
umax=5
340-
umin=round(self.min_val)
341-
359+
## s, s_r 0,5 / scalemin,scalemax
360+
## sd umin,umax
361+
## b 0,5 / scalemin,scalemax
362+
## d, d_r 0,5 / scalemin,scalemax
363+
## dd umin,umax
342364
if color_scale == "s":
343365
colormap = basemap.cm.GMT_seis
344-
norm = mcolors.Normalize(vmin=0,vmax=umax)
366+
norm = mcolors.Normalize(vmin=BOUNDS[0],vmax=BOUNDS[len(BOUNDS) - 1])
345367
elif color_scale == "s_r":
346368
colormap = basemap.cm.GMT_seis_r
347-
norm = mcolors.Normalize(vmin=0,vmax=umax)
369+
norm = mcolors.Normalize(vmin=BOUNDS[0],vmax=BOUNDS[len(BOUNDS) - 1])
348370
elif color_scale == "sd":
349-
BOUNDS= u.makebounds(self.min_val, self.max_val, 5, self.mean_val, substep=5)
350371
colormap = basemap.cm.GMT_seis
351-
TICKS = u.maketicks(self.min_val, self.max_val, 5)
352-
norm = mcolors.Normalize(vmin=self.min_val,vmax=self.max_val)
372+
BOUNDS= u.makebounds(umin, umax, 5, umean, substep=5)
373+
TICKS = u.maketicks(umin, umax, 5)
374+
norm = mcolors.Normalize(vmin=BOUNDS[0],vmax=BOUNDS[len(BOUNDS) - 1])
353375
elif color_scale == "b":
354376
C = []
355377
for bound in BOUNDS :
@@ -366,13 +388,17 @@ def plot(self) :
366388
colormap = pycvm_cmapDiscretize(basemap.cm.GMT_seis_r, len(BOUNDS) - 1)
367389
norm = mcolors.BoundaryNorm(BOUNDS, colormap.N)
368390
elif color_scale == 'dd':
369-
BOUNDS= u.makebounds(self.min_val, self.max_val, 5, self.mean_val, substep=5)
370-
TICKS = u.maketicks(self.min_val, self.max_val, 5)
391+
BOUNDS= u.makebounds(umin, umax, 5, umean, substep=5)
392+
TICKS = u.maketicks(umin, umax, 5)
371393
colormap = pycvm_cmapDiscretize(basemap.cm.GMT_seis, len(BOUNDS) - 1)
372394
norm = mcolors.BoundaryNorm(BOUNDS, colormap.N)
373395
else:
374396
print("ERROR: unknown option for colorscale.")
375-
397+
398+
if 'difference' in self.meta :
399+
bwr = cm.get_cmap('bwr')
400+
colormap = pycvm_cmapDiscretize(bwr, len(BOUNDS) - 1)
401+
376402

377403
## MEI, TODO this is a temporary way to generate an output of a cross_section input file
378404
if( self.datafile == None ):
@@ -412,7 +438,10 @@ def plot(self) :
412438
if(mproperty.title() == "Density") :
413439
cbar.set_label(mproperty.title() + " (g/cm^3)")
414440
else:
415-
cbar.set_label(mproperty.title() + " (km/s)")
441+
if 'difference' in self.meta :
442+
cbar.set_label(mproperty.title() + " (km)")
443+
else:
444+
cbar.set_label(mproperty.title() + " (km/s)")
416445
else:
417446
cbar.set_label("Poisson(Vs,Vp)")
418447

0 commit comments

Comments
 (0)