-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add IO functionalities to write DCIP2D mesh and models #84
Changes from 7 commits
55f14a5
78d4a6e
638222d
e9ca2f7
eb6de33
a86de9b
ac17ad4
a06d644
76e94b3
7114685
45b85bc
dd391b8
366b0c7
f7c1279
02329e1
9f8efc8
0300fe2
5be5348
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -118,7 +118,7 @@ def unpackdx(fid, nrows): | |
return tensMsh | ||
|
||
@classmethod | ||
def readUBC(TensorMesh, fileName, meshdim=None): | ||
def readUBC(TensorMesh, fileName, meshdim=None, folder=''): | ||
"""Wrapper to Read UBC GIF 2D and 3D tensor mesh and generate same dimension TensorMesh. | ||
|
||
:param string fileName: path to the UBC GIF mesh file | ||
|
@@ -127,25 +127,26 @@ def readUBC(TensorMesh, fileName, meshdim=None): | |
:return: The tensor mesh for the fileName. | ||
""" | ||
# Check the expected mesh dimensions | ||
fname = os.path.join(folder, fileName) | ||
if meshdim == None: | ||
# Read the file as line strings, remove lines with comment = ! | ||
msh = np.genfromtxt(fileName, delimiter='\n', dtype=np.str, comments='!', max_rows=1) | ||
msh = np.genfromtxt(fname, delimiter='\n', dtype=np.str, comments='!', max_rows=1) | ||
# Fist line is the size of the model | ||
sizeM = np.array(msh.ravel()[0].split(), dtype=float) | ||
# Check if the mesh is a UBC 2D mesh | ||
if sizeM.shape[0] == 1: | ||
Tnsmsh = TensorMesh._readUBC_2DMesh(fileName) | ||
Tnsmsh = TensorMesh._readUBC_2DMesh(fname) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to simplify this a bit (and reduce redundancy), why don't we just assign Thoughts? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, this is a function I wrote in a previous PR but it was a redundant check between what the user expects and what the machine read. |
||
# Check if the mesh is a UBC 3D mesh | ||
elif sizeM.shape[0] == 3: | ||
Tnsmsh = TensorMesh._readUBC_3DMesh(fileName) | ||
Tnsmsh = TensorMesh._readUBC_3DMesh(fname) | ||
else: | ||
raise Exception('File format not recognized') | ||
# expected dimension is 2 | ||
elif meshdim == 2: | ||
Tnsmsh = TensorMesh._readUBC_2DMesh(fileName) | ||
Tnsmsh = TensorMesh._readUBC_2DMesh(fname) | ||
# expected dimension is 3 | ||
elif meshdim == 3: | ||
Tnsmsh = TensorMesh._readUBC_3DMesh(fileName) | ||
Tnsmsh = TensorMesh._readUBC_3DMesh(fname) | ||
return Tnsmsh | ||
|
||
@classmethod | ||
|
@@ -300,7 +301,34 @@ def _toVTRObj(mesh, models=None): | |
vtkObj.GetCellData().SetActiveScalars(models.keys()[0]) | ||
return vtkObj | ||
|
||
def readModelUBC(mesh, fileName): | ||
def _readModelUBC_2D(mesh, fileName): | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for this @thast! |
||
Read UBC GIF 2DTensor model and generate 2D Tensor model in simpeg | ||
|
||
Input: | ||
:param string fileName: path to the UBC GIF 2D model file | ||
|
||
Output: | ||
:rtype: numpy.ndarray | ||
:return: model with TensorMesh ordered | ||
""" | ||
|
||
# Open fileand skip header... assume that we know the mesh already | ||
obsfile = np.genfromtxt( | ||
fileName, delimiter=' \n', | ||
dtype=np.str, comments='!' | ||
) | ||
|
||
dim = np.array(obsfile[0].split(), dtype=int) | ||
if not np.all([mesh.nCx, mesh.nCy] == dim): | ||
raise Exception('Dimension of the model and mesh mismatch') | ||
|
||
model = [line.split() for line in obsfile[1:]] | ||
model = utils.mkvc(np.array(model, dtype=float)[::-1].T) | ||
|
||
return model | ||
|
||
def _readModelUBC_3D(mesh, fileName): | ||
"""Read UBC 3DTensor mesh model and generate 3D Tensor mesh model | ||
|
||
:param string fileName: path to the UBC GIF mesh file to read | ||
|
@@ -310,57 +338,164 @@ def readModelUBC(mesh, fileName): | |
f = open(fileName, 'r') | ||
model = np.array(list(map(float, f.readlines()))) | ||
f.close() | ||
model = np.reshape(model, (mesh.nCz, mesh.nCx, mesh.nCy), order = 'F') | ||
model = np.reshape(model, (mesh.nCz, mesh.nCx, mesh.nCy), order='F') | ||
model = model[::-1, :, :] | ||
model = np.transpose(model, (1, 2, 0)) | ||
model = utils.mkvc(model) | ||
return model | ||
|
||
def writeModelUBC(mesh, fileName, model): | ||
def readModelUBC(mesh, fileName, folder=''): | ||
"""Read UBC 2D or 3D Tensor mesh model | ||
and generate Tensor mesh model | ||
|
||
:param string fileName: path to the UBC GIF mesh file to read | ||
:rtype: numpy.ndarray | ||
:return: model with TensorMesh ordered | ||
""" | ||
fname = os.path.join(folder, fileName) | ||
if mesh.dim == 3: | ||
model = mesh._readModelUBC_3D(fname) | ||
elif mesh.dim == 2: | ||
model = mesh._readModelUBC_2D(fname) | ||
else: | ||
raise Exception('mesh must be a Tensor Mesh 2D or 3D') | ||
return model | ||
|
||
def writeModelUBC(mesh, fileName, model, folder=''): | ||
"""Writes a model associated with a TensorMesh | ||
to a UBC-GIF format model file. | ||
|
||
:param string fileName: File to write to | ||
:param numpy.ndarray model: The model | ||
""" | ||
fname = os.path.join(folder, fileName) | ||
if mesh.dim == 3: | ||
# Reshape model to a matrix | ||
modelMat = mesh.r(model, 'CC', 'CC', 'M') | ||
# Transpose the axes | ||
modelMatT = modelMat.transpose((2, 0, 1)) | ||
# Flip z to positive down | ||
modelMatTR = utils.mkvc(modelMatT[::-1, :, :]) | ||
np.savetxt(fname, modelMatTR.ravel()) | ||
|
||
elif mesh.dim == 2: | ||
modelMat = mesh.r(model, 'CC', 'CC', 'M').T[::-1] | ||
f = open(fname, 'w') | ||
f.write('{:d} {:d}\n'.format(mesh.nCx, mesh.nCy)) | ||
f.close() | ||
f = open(fname, 'ab') | ||
np.savetxt(f, modelMat) | ||
f.close() | ||
|
||
# Reshape model to a matrix | ||
modelMat = mesh.r(model, 'CC', 'CC', 'M') | ||
# Transpose the axes | ||
modelMatT = modelMat.transpose((2, 0, 1)) | ||
# Flip z to positive down | ||
modelMatTR = utils.mkvc(modelMatT[::-1, :, :]) | ||
|
||
np.savetxt(fileName, modelMatTR.ravel()) | ||
else: | ||
raise Exception('mesh must be a Tensor Mesh 2D or 3D') | ||
|
||
def writeUBC(mesh, fileName, models=None): | ||
def _writeUBC_3DMesh(mesh, fileName, comment_lines=''): | ||
"""Writes a TensorMesh to a UBC-GIF format mesh file. | ||
|
||
:param string fileName: File to write to | ||
:param dict models: A dictionary of the models | ||
|
||
""" | ||
assert mesh.dim == 3 | ||
s = '' | ||
s = comment_lines | ||
s += '{0:d} {1:d} {2:d}\n'.format(*tuple(mesh.vnC)) | ||
# Have to it in the same operation or use mesh.x0.copy(), | ||
# otherwise the mesh.x0 is updated. | ||
origin = mesh.x0 + np.array([0, 0, mesh.hz.sum()]) | ||
origin.dtype = float | ||
|
||
s += '{0:.6f} {1:.6f} {2:.6f}\n'.format(*tuple(origin)) | ||
s += ('%.6f '*mesh.nCx+'\n')%tuple(mesh.hx) | ||
s += ('%.6f '*mesh.nCy+'\n')%tuple(mesh.hy) | ||
s += ('%.6f '*mesh.nCz+'\n')%tuple(mesh.hz[::-1]) | ||
s += ('%.6f '*mesh.nCx+'\n') % tuple(mesh.hx) | ||
s += ('%.6f '*mesh.nCy+'\n') % tuple(mesh.hy) | ||
s += ('%.6f '*mesh.nCz+'\n') % tuple(mesh.hz[::-1]) | ||
f = open(fileName, 'w') | ||
f.write(s) | ||
f.close() | ||
|
||
if models is None: return | ||
def _writeUBC_2DMesh(mesh, fileName, comment_lines=''): | ||
"""Writes a TensorMesh to a UBC-GIF format mesh file. | ||
|
||
:param string fileName: File to write to | ||
:param dict models: A dictionary of the models | ||
|
||
""" | ||
assert mesh.dim == 2 | ||
|
||
def writeF(fx, outStr=''): | ||
# Init | ||
i = 0 | ||
origin = True | ||
x0 = fx[i] | ||
f = fx[i] | ||
number_segment = 0 | ||
auxStr = '' | ||
|
||
while True: | ||
i = i + 1 | ||
if i >= fx.size: | ||
break | ||
dx = -f + fx[i] | ||
f = fx[i] | ||
n = 1 | ||
|
||
for j in range(i+1, fx.size): | ||
if -f + fx[j] == dx: | ||
n += 1 | ||
i += 1 | ||
f = fx[j] | ||
else: | ||
break | ||
|
||
number_segment += 1 | ||
if origin: | ||
auxStr += '{:.10f} {:.10f} {:d} \n'.format(x0, f, n) | ||
origin = False | ||
else: | ||
auxStr += '{:.10f} {:d} \n'.format(f, n) | ||
|
||
auxStr = '{:d}\n'.format(number_segment) + auxStr | ||
outStr += auxStr | ||
|
||
return outStr | ||
|
||
# Grab face coordinates | ||
fx = mesh.vectorNx | ||
fz = -mesh.vectorNy[::-1] | ||
|
||
# Create the string | ||
outStr = comment_lines | ||
outStr = writeF(fx, outStr=outStr) | ||
outStr += '\n' | ||
outStr = writeF(fz, outStr=outStr) | ||
|
||
# Write file | ||
f = open(fileName, 'w') | ||
f.write(outStr) | ||
f.close() | ||
|
||
def writeUBC(mesh, fileName, models=None, folder='', comment_lines=''): | ||
"""Writes a TensorMesh to a UBC-GIF format mesh file. | ||
|
||
:param str fileName: File to write to | ||
:param str folder: folder where to save model | ||
:param dict models: A dictionary of the models | ||
:param str comment_lines: comment lines preceded with '!' to add | ||
""" | ||
fname = os.path.join(folder, fileName) | ||
if mesh.dim == 3: | ||
mesh._writeUBC_3DMesh(fname, comment_lines=comment_lines) | ||
elif mesh.dim == 2: | ||
mesh._writeUBC_2DMesh(fname, comment_lines=comment_lines) | ||
else: | ||
raise Exception('mesh must be a Tensor Mesh 2D or 3D') | ||
|
||
if models is None: | ||
return | ||
assert type(models) is dict, 'models must be a dict' | ||
for key in models: | ||
assert type(key) is str, 'The dict key is a file name' | ||
mesh.writeModelUBC(key, models[key]) | ||
mesh.writeModelUBC(key, models[key], folder=folder) | ||
|
||
|
||
class TreeMeshIO(object): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we want
folder
ordirectory
?cc @rowanc1: do you know what is more common?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed directory does sound better.