diff --git a/tools/Paraview macros/etvk_lines.py b/tools/Paraview macros/etvk_lines.py deleted file mode 100644 index 5b07c44d..00000000 --- a/tools/Paraview macros/etvk_lines.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright (C) 2015-2022: The University of Edinburgh -# Authors: Craig Warren, Antonis Giannopoulos, and John Hartley -# -# This file is part of gprMax. -# -# gprMax is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# gprMax is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with gprMax. If not, see . - -import mmap -import os -from xml.etree import ElementTree as ET -import json - - - -def load_materials(ml): - # create a threshold filter for each material type - for i, m in enumerate(ml): - threshold = Threshold(Input=model) - threshold.ThresholdRange = [i, i] - print(threshold.Scalars) - threshold.Scalars = ['CELLS', 'Material'] - RenameSource(m, threshold) - - # Show data in view, except for free_space - if i != 1: - thresholddisplay = Show(threshold, renderview) - thresholddisplay.ColorArrayName = ['CELLS', 'Material'] - threshold.UpdatePipeline() - -from paraview.simple import * - -# Get whatever source is loaded (should be model) -model = GetActiveSource() - -# Get active view -renderview = GetActiveView() - -# Show Data Axes Grid -renderview.AxesGrid.Visibility = 1 - -# Hide display of root data -Hide(model) - -# one file only for now - -fp = model.FileName[0] - -# materials string -ms = None - -# load json embedded in comment of line 3 -with open(fp, 'rb') as f: - f.readline() - f.readline() - # comments - c = f.readline().decode() - -# strip comment tags -c = c[5:-5] -# model information -c = json.loads(c) - -# discretisation -dl = c['dx_dy_dz'] -# n voxels -nl = c['nx_ny_nz'] - -# load material filters -try: - ml = c['Materials'] - load_materials(ml) -except KeyError: - print('No Materials to load') - -RenderAllViews() - -# Reset view to fit data -renderview.ResetCamera() - -# Show color bar/color legend -# thresholdDisplay.SetScalarBarVisibility(renderview, False) diff --git a/tools/Paraview macros/etvk_voxels.py b/tools/Paraview macros/etvk_voxels.py deleted file mode 100644 index a4a0f719..00000000 --- a/tools/Paraview macros/etvk_voxels.py +++ /dev/null @@ -1,205 +0,0 @@ -# Copyright (C) 2015-2022: The University of Edinburgh -# Authors: Craig Warren, Antonis Giannopoulos, and John Hartley -# -# This file is part of gprMax. -# -# gprMax is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# gprMax is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with gprMax. If not, see . - -import mmap -import os -from xml.etree import ElementTree as ET -import json - -def display_pmls_new(pmlthick, dx_dy_dz, nx_ny_nz): - """Display PMLs as box sources using PML thickness values. - Only suitable for gprMax > v.4 - - Args: - pmlthick (tuple): PML thickness values for each slab (cells) - dx_dy_dz (tuple): Spatial resolution (m) - nx_ny_dz (tuple): Domain size (cells) - """ - - pml_names = ['x0', 'y0', 'z0', 'xmax', 'ymax', 'zmax'] - pmls = dict.fromkeys(pml_names, None) - - if pmlthick[0] != 0: - x0 = Box(Center=[pmlthick[0] * dx_dy_dz[0] / 2, - nx_ny_nz[1] * dx_dy_dz[1] / 2, - nx_ny_nz[2] * dx_dy_dz[2] / 2], - XLength=pmlthick[0] * dx_dy_dz[0], - YLength=nx_ny_nz[1] * dx_dy_dz[1], - ZLength=nx_ny_nz[2] * dx_dy_dz[2]) - pmls['x0'] = x0 - - if pmlthick[3] != 0: - xmax = Box(Center=[dx_dy_dz[0] * (nx_ny_nz[0] - pmlthick[3] / 2), - nx_ny_nz[1] * dx_dy_dz[1] / 2, - nx_ny_nz[2] * dx_dy_dz[2] / 2], - XLength=pmlthick[3] * dx_dy_dz[0], - YLength=nx_ny_nz[1] * dx_dy_dz[1], - ZLength=nx_ny_nz[2] * dx_dy_dz[2]) - pmls['xmax'] = xmax - - if pmlthick[1] != 0: - y0 = Box(Center=[nx_ny_nz[0] * dx_dy_dz[0] / 2, - pmlthick[1] * dx_dy_dz[1] / 2, - nx_ny_nz[2] * dx_dy_dz[2] / 2], - XLength=nx_ny_nz[0] * dx_dy_dz[0], - YLength=pmlthick[1] * dx_dy_dz[1], - ZLength=nx_ny_nz[2] * dx_dy_dz[2]) - pmls['y0'] = y0 - - if pmlthick[4] != 0: - ymax = Box(Center=[nx_ny_nz[0] * dx_dy_dz[0] / 2, - dx_dy_dz[1] * (nx_ny_nz[1] - pmlthick[4] / 2), - nx_ny_nz[2] * dx_dy_dz[2] / 2], - XLength=nx_ny_nz[0] * dx_dy_dz[0], - YLength=pmlthick[4] * dx_dy_dz[1], - ZLength=nx_ny_nz[2] * dx_dy_dz[2]) - pmls['ymax'] = ymax - - if pmlthick[2] != 0: - z0 = Box(Center=[nx_ny_nz[0] * dx_dy_dz[0] / 2, - nx_ny_nz[1] * dx_dy_dz[1] / 2, - pmlthick[2] * dx_dy_dz[2] / 2], - XLength=nx_ny_nz[0] * dx_dy_dz[0], - YLength=nx_ny_nz[1] * dx_dy_dz[1], - ZLength=pmlthick[2] * dx_dy_dz[2]) - pmls['z0'] = z0 - - if pmlthick[5] != 0: - zmax = Box(Center=[nx_ny_nz[0] * dx_dy_dz[0] / 2, - nx_ny_nz[1] * dx_dy_dz[1] / 2, - dx_dy_dz[2] * (nx_ny_nz[2] - pmlthick[5] / 2)], - XLength=nx_ny_nz[0] * dx_dy_dz[0], - YLength=nx_ny_nz[1] * dx_dy_dz[1], - ZLength=pmlthick[5] * dx_dy_dz[2]) - pmls['zmax'] = zmax - - # Name PML sources and set opacity - tmp = [] - for pml in pmls: - if pmls[pml]: - RenameSource('PML - ' + pml, pmls[pml]) - Hide(pmls[pml], renderview) - tmp.append(pmls[pml]) - - # Create a group of PMLs to switch on/off easily - if tmp: - pml_gp = AppendDatasets(Input=tmp) - RenameSource('PML - All', pml_gp) - pml_view = Show(pml_gp) - pml_view.Opacity = 0.5 - -def load_src_rx(srcs, dl): - # Display sources and receivers as Paraview box sources - for item in srcs: - p = item['position'] - n = item['name'] - src_rx = Box(Center=[p[0] + dl[0]/2, - p[1] + dl[1]/2, - p[2] + dl[2]/2], - XLength=dl[0], YLength=dl[1], ZLength=dl[2]) - RenameSource(n, src_rx) - Show(src_rx) - - -def load_materials(ml): - # create a threshold filter for each material type - for i, m in enumerate(ml): - threshold = Threshold(Input=model) - threshold.ThresholdRange = [i, i] - threshold.Scalars = ['CELLS', 'Material'] - RenameSource(m, threshold) - - # Show data in view, except for free_space - if i != 1: - thresholddisplay = Show(threshold, renderview) - thresholddisplay.ColorArrayName = ['CELLS', 'Material'] - threshold.UpdatePipeline() - -from paraview.simple import * - -# Get whatever source is loaded (should be model) -model = GetActiveSource() - -# Get active view -renderview = GetActiveView() - -# Show Data Axes Grid -renderview.AxesGrid.Visibility = 1 - -# Hide display of root data -Hide(model) - -# one file only for now - -fp = model.FileName[0] - -# materials string -ms = None - -# load json embedded in comment of line 3 -with open(fp, 'rb') as f: - f.readline() - f.readline() - # comments - c = f.readline().decode() - -# strip comment tags -c = c[5:-5] -# model information -c = json.loads(c) - -# discretisation -dl = c['dx_dy_dz'] -# n voxels -nl = c['nx_ny_nz'] - -# load material filters -try: - ml = c['Materials'] - load_materials(ml) -except KeyError: - print('No Materials to load') - -# load sources -try: - srcs = c['Sources'] - load_src_rx(srcs, dl) -except KeyError: - print('No sources to load') - -# load rxs -try: - rxs = c['Receivers'] - load_src_rx(rxs, dl) -except KeyError: - print('No receivers to load') - -# load pmls -try: - pt = c['PMLthickness'] - display_pmls_new(pt, dl, nl) -except KeyError: - print('No PMLs to load') - -RenderAllViews() - -# Reset view to fit data -renderview.ResetCamera() - -# Show color bar/color legend -# thresholdDisplay.SetScalarBarVisibility(renderview, False) diff --git a/tools/Paraview macros/gprMax.py b/tools/Paraview macros/gprMax.py index ff6dcc9e..f7f8cdea 100644 --- a/tools/Paraview macros/gprMax.py +++ b/tools/Paraview macros/gprMax.py @@ -16,16 +16,67 @@ # You should have received a copy of the GNU General Public License # along with gprMax. If not, see . +import json import mmap import os from xml.etree import ElementTree as ET from paraview.simple import * +# Read Paraview version number to set threshold filter method +pvv = GetParaViewVersion() +if pvv.major == 5 and pvv.minor > 9: + new_thres = True +else: + new_thres = False -def display_pmls_new(pmlthick, dx_dy_dz, nx_ny_nz): +def threshold_filt(input, lt, ut, scalars): + """Create threshold filter according to Paraview version. + + Args: + input (array): input data to threshold filter + lt, ut (int): lower and upper bounds of thresholding operation + scalars (list/str): name of scalar array to perform thresholding + + Returns: + threshold (object): threshold filter + """ + + threshold = Threshold(Input=input) + threshold.Scalars = scalars + + if new_thres: + threshold.LowerThreshold = lt + threshold.UpperThreshold = ut + else: + threshold.ThresholdRange = [lt, ut] + + return threshold + + +def display_src_rx(srcs_rxs, dl): + """Display sources and receivers as Paraview box sources. + Only suitable for gprMax >= v4 + + Args: + srcs_rxs (list): source/receiver names and positions + dl (tuple): spatial discretisation + """ + + for item in srcs_rxs: + pos = item['position'] + name = item['name'] + src_rx = Box(Center=[pos[0] + dl[0]/2, + pos[1] + dl[1]/2, + pos[2] + dl[2]/2], + XLength=dl[0], YLength=dl[1], ZLength=dl[2]) + RenameSource(name, src_rx) + Show(src_rx) + + +def display_pmls(pmlthick, dx_dy_dz, nx_ny_nz): """Display PMLs as box sources using PML thickness values. - Only suitable for gprMax > v.4 + Only suitable for gprMax >= v4 Args: pmlthick (tuple): PML thickness values for each slab (cells) @@ -118,11 +169,17 @@ renderview.AxesGrid.Visibility = 1 # Hide display of root data Hide(model) -# VTI or VTP file + +##################################### +# Get filename or list of filenames # +##################################### + +# Single .vti or .vtu file if len(model.FileName) == 1: files = model.FileName dirname = os.path.dirname(files[0]) -# PVD file + +# Multiple .vti or .vtu files referenced in a .pvd file else: files = [] dirname = os.path.dirname(model.FileName) @@ -130,152 +187,155 @@ else: root = tree.getroot() for elem in root: for subelem in elem.findall('DataSet'): - tmp = os.path.join(dirname, subelem.get('file').encode('utf-8')) + tmp = os.path.join(dirname, subelem.get('file')) files.append(tmp) +# Dictionaries to hold data - mainly for material_ID_max: - material_ID_max = int(model.CellData.GetArray('Material').GetRange()[1]) - - # Read gprMax XML section + ####################### + # Read data from file # + ####################### + # Determine gprMax version + # Read XML data mm = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) - xml_pos = mm.find('v.4 + + # Look for tag which indicates version <4 try: - root.attrib['Version'] - v4 = True - dx_dy_dz = tuple(float(s) for s in root.get( - 'dx_dy_dz').strip('()').split(',')) - nx_ny_nz = tuple(float(s) for s in root.get( - 'nx_ny_nz').strip('()').split(',')) - if any(x == 1 for x in nx_ny_nz): - renderview.CameraParallelProjection = 1 - try: - root.attrib['PMLthickness'] - pmlthick = tuple(int(s) for s in root.get( - 'PMLthickness').strip('[]').split(',')) - except: - pass - - # Old behaviour - gprMax material_ID_max: + material_ID_max = int(elem.text) # Read sources for elem in root.findall('Sources'): - srcs_old[elem.get('name')] = int(elem.text) + srcs[elem.get('name')] = int(elem.text) # Read receivers for elem in root.findall('Receivers'): - rxs_old[elem.get('name')] = int(elem.text) + rxs[elem.get('name')] = int(elem.text) # Read PMLs for elem in root.findall('PML'): - pmls_old[elem.get('name')] = int(elem.text) + pmls[elem.get('name')] = int(elem.text) -# Create a Threshold (filter) for each material + except: + v4 = True + # Comments () embedded in line 3 of file + f.readline() + f.readline() + c = f.readline().decode() + # Strip comment tags + c = c[5:-5] + # Model information + c = json.loads(c) + print('\ngprMax version: ' + c['gprMax_version']) + print(file) + + ################ + # Display data # + ################ + + if v4: + # Discretisation + dl = c['dx_dy_dz'] + # Number of voxels + nl = c['nx_ny_nz'] + + # Store materials + try: + mats = c['Materials'] + for i, material in enumerate(mats): + materials[material] = i + if i > material_ID_max: + material_ID_max = i + except KeyError: + print('No materials to load') + + # Display any sources + try: + srcs = c['Sources'] + display_src_rx(srcs, dl) + except KeyError: + print('No sources to load') + + # Display any receivers + try: + rxs = c['Receivers'] + display_src_rx(rxs, dl) + except KeyError: + print('No receivers to load') + + # Display any PMLs + try: + pt = c['PMLthickness'] + display_pmls(pt, dl, nl) + except KeyError: + print('No PMLs to load') + + else: + # Display any sources and PMLs + srcs_pmls = dict(srcs) + srcs_pmls.update(pmls) + if srcs_pmls: + for k, v in srcs_pmls.items(): + threshold = threshold_filt(model, v, v, 'Sources_PML') + RenameSource(k, threshold) + + # Show data in view + thresholddisplay = Show(threshold, renderview) + thresholddisplay.ColorArrayName = 'Sources_PML' + if v == 1: + thresholddisplay.Opacity = 0.5 + threshold.UpdatePipeline() + + # Display any receivers + if rxs: + for k, v in rxs.items(): + threshold = threshold_filt(model, v, v, 'Receivers') + RenameSource(k, threshold) + + # Show data in view + thresholddisplay = Show(threshold, renderview) + thresholddisplay.ColorArrayName = 'Receivers' + threshold.UpdatePipeline() + +# Display materials material_range = range(0, material_ID_max + 1) for k, v in sorted(materials.items(), key=lambda x: x[1]): if v in material_range: - threshold = Threshold(Input=model) - threshold.Scalars = 'Material' - threshold.ThresholdRange = [v, v] + threshold = threshold_filt(model, v, v, ['CELLS', 'Material']) RenameSource(k, threshold) # Show data in view, except for free_space if v != 1: thresholddisplay = Show(threshold, renderview) - thresholddisplay.ColorArrayName = 'Material' + thresholddisplay.ColorArrayName = ['CELLS', 'Material'] + threshold.UpdatePipeline() -# New behaviour -if v4: - # Display sources and receivers as Paraview box sources - for k, v in srcs.items() + rxs.items(): - src_rx = Box(Center=[v[0] + dx_dy_dz[0]/2, - v[1] + dx_dy_dz[1]/2, - v[2] + dx_dy_dz[2]/2], - XLength=dx_dy_dz[0], YLength=dx_dy_dz[1], ZLength=dx_dy_dz[2]) - RenameSource(k, src_rx) - Show(src_rx) - - # Display PMLs as Paraview box sources - try: - pmlthick - display_pmls_new(pmlthick, dx_dy_dz, nx_ny_nz) - except: - pass - -# Old behaviour -else: - # Create threshold for sources/pml(name and numeric value) - srcs_pmls_old = dict(srcs_old.items() + pmls_old.items()) - if srcs_pmls_old: - for k, v in srcs_pmls_old.items(): - threshold = Threshold(Input=model) - threshold.Scalars = 'Sources_PML' - threshold.ThresholdRange = [v, v] - RenameSource(k, threshold) - - # Show data in view - thresholddisplay = Show(threshold, renderview) - thresholddisplay.ColorArrayName = 'Sources_PML' - - if v == 1: - thresholddisplay.Opacity = 0.5 - - if rxs_old: - # Create threshold for receivers (name and numeric value) - for k, v in rxs_old.items(): - threshold = Threshold(Input=model) - threshold.Scalars = 'Receivers' - threshold.ThresholdRange = [v, v] - RenameSource(k, threshold) - - # Show data in view - thresholddisplay = Show(threshold, renderview) - thresholddisplay.ColorArrayName = 'Receivers' RenderAllViews()