diff --git a/gprMax/cmds_geometry/add_grass.py b/gprMax/cmds_geometry/add_grass.py index 741d0e4d..850be20c 100644 --- a/gprMax/cmds_geometry/add_grass.py +++ b/gprMax/cmds_geometry/add_grass.py @@ -21,7 +21,6 @@ import logging import gprMax.config as config import numpy as np -from ..exceptions import CmdInputError from ..fractals import FractalSurface, Grass from ..materials import DispersiveMaterial from ..utilities import round_value @@ -61,7 +60,8 @@ class AddGrass(UserObjectGeometry): limits = self.kwargs['limits'] n_blades = self.kwargs['n_blades'] except KeyError: - raise CmdInputError(self.__str__() + ' requires at least eleven parameters') + logger.exception(self.__str__() + ' requires at least eleven parameters') + raise try: seed = self.kwargs['seed'] @@ -70,68 +70,84 @@ class AddGrass(UserObjectGeometry): # Get the correct fractal volume volumes = [volume for volume in grid.fractalvolumes if volume.ID == fractal_box_id] - if volumes: + try: volume = volumes[0] - else: - raise CmdInputError(self.__str__() + f' cannot find FractalBox {fractal_box_id}') + except NameError: + logger.exception(self.__str__() + f' cannot find FractalBox {fractal_box_id}') + raise p1, p2 = uip.check_box_points(p1, p2, self.__str__()) xs, ys, zs = p1 xf, yf, zf = p2 if frac_dim < 0: - raise CmdInputError(self.__str__() + ' requires a positive value for the fractal dimension') + logger.exception(self.__str__() + ' requires a positive value for the fractal dimension') + raise ValueError if limits[0] < 0 or limits[1] < 0: - raise CmdInputError(self.__str__() + ' requires a positive value for the minimum and maximum heights for grass blades') + logger.exception(self.__str__() + ' requires a positive value for the minimum and maximum heights for grass blades') + raise ValueError # Check for valid orientations if xs == xf: if ys == yf or zs == zf: - raise CmdInputError(self.__str__() + ' dimensions are not specified correctly') + logger.exception(self.__str__() + ' dimensions are not specified correctly') + raise ValueError if xs != volume.xs and xs != volume.xf: - raise CmdInputError(self.__str__() + ' must specify external surfaces on a fractal box') + logger.exception(self.__str__() + ' must specify external surfaces on a fractal box') + raise ValueError fractalrange = (round_value(limits[0] / grid.dx), round_value(limits[1] / grid.dx)) # xminus surface if xs == volume.xs: - raise CmdInputError(self.__str__() + ' grass can only be specified on surfaces in the positive axis direction') + logger.exception(self.__str__() + ' grass can only be specified on surfaces in the positive axis direction') + raise ValueError # xplus surface elif xf == volume.xf: if fractalrange[1] > grid.nx: - raise CmdInputError(self.__str__() + ' cannot apply grass to fractal box as it would exceed the domain size in the x direction') + logger.exception(self.__str__() + ' cannot apply grass to fractal box as it would exceed the domain size in the x direction') + raise ValueError requestedsurface = 'xplus' elif ys == yf: if xs == xf or zs == zf: - raise CmdInputError(self.__str__() + ' dimensions are not specified correctly') + logger.exception(self.__str__() + ' dimensions are not specified correctly') + raise ValueError if ys != volume.ys and ys != volume.yf: - raise CmdInputError(self.__str__() + ' must specify external surfaces on a fractal box') + logger.exception(self.__str__() + ' must specify external surfaces on a fractal box') + raise ValueError fractalrange = (round_value(limits[0] / grid.dy), round_value(limits[1] / grid.dy)) # yminus surface if ys == volume.ys: - raise CmdInputError(self.__str__() + ' grass can only be specified on surfaces in the positive axis direction') + logger.exception(self.__str__() + ' grass can only be specified on surfaces in the positive axis direction') + raise ValueError # yplus surface elif yf == volume.yf: if fractalrange[1] > grid.ny: - raise CmdInputError(self.__str__() + ' cannot apply grass to fractal box as it would exceed the domain size in the y direction') + logger.exception(self.__str__() + ' cannot apply grass to fractal box as it would exceed the domain size in the y direction') + raise ValueError requestedsurface = 'yplus' elif zs == zf: if xs == xf or ys == yf: - raise CmdInputError(self.__str__() + ' dimensions are not specified correctly') + logger.exception(self.__str__() + ' dimensions are not specified correctly') + raise ValueError if zs != volume.zs and zs != volume.zf: - raise CmdInputError(self.__str__() + ' must specify external surfaces on a fractal box') + logger.exception(self.__str__() + ' must specify external surfaces on a fractal box') + raise ValueError fractalrange = (round_value(limits[0] / grid.dz), round_value(limits[1] / grid.dz)) # zminus surface if zs == volume.zs: - raise CmdInputError(self.__str__() + ' grass can only be specified on surfaces in the positive axis direction') + logger.exception(self.__str__() + ' grass can only be specified on surfaces in the positive axis direction') + raise ValueError # zplus surface elif zf == volume.zf: if fractalrange[1] > grid.nz: - raise CmdInputError(self.__str__() + ' cannot apply grass to fractal box as it would exceed the domain size in the z direction') + logger.exception(self.__str__() + ' cannot apply grass to fractal box as it would exceed the domain size in the z direction') + raise ValueError requestedsurface = 'zplus' else: - raise CmdInputError(self.__str__() + ' dimensions are not specified correctly') + logger.exception(self.__str__() + ' dimensions are not specified correctly') + raise ValueError surface = FractalSurface(xs, xf, ys, yf, zs, zf, frac_dim) surface.ID = 'grass' @@ -143,7 +159,8 @@ class AddGrass(UserObjectGeometry): surface.operatingonID = volume.ID surface.generate_fractal_surface(grid) if n_blades > surface.fractalsurface.shape[0] * surface.fractalsurface.shape[1]: - raise CmdInputError(self.__str__() + ' the specified surface is not large enough for the number of grass blades/roots specified') + logger.exception(self.__str__() + ' the specified surface is not large enough for the number of grass blades/roots specified') + raise ValueError # Scale the distribution so that the summation is equal to one, i.e. a probability distribution surface.fractalsurface = surface.fractalsurface / np.sum(surface.fractalsurface) @@ -188,7 +205,8 @@ class AddGrass(UserObjectGeometry): grass = next((x for x in grid.materials if x.ID == 'grass')) testgrass = next((x for x in grass.tau if x < grid.dt), None) if testgrass: - raise CmdInputError(self.__str__() + ' requires the time step for the model to be less than the relaxation time required to model grass.') + logger.exception(self.__str__() + ' requires the time step for the model to be less than the relaxation time required to model grass.') + raise ValueError volume.fractalsurfaces.append(surface) diff --git a/gprMax/cmds_geometry/add_surface_roughness.py b/gprMax/cmds_geometry/add_surface_roughness.py index 6b20c22c..1120b9ce 100644 --- a/gprMax/cmds_geometry/add_surface_roughness.py +++ b/gprMax/cmds_geometry/add_surface_roughness.py @@ -21,7 +21,6 @@ import logging import gprMax.config as config import numpy as np -from ..exceptions import CmdInputError from ..fractals import FractalSurface from ..utilities import round_value from .cmds_geometry import UserObjectGeometry @@ -62,7 +61,8 @@ class AddSurfaceRoughness(UserObjectGeometry): limits = np.array(self.kwargs['limits']) fractal_box_id = self.kwargs['fractal_box_id'] except KeyError: - raise CmdInputError(self.__str__() + ' incorrect parameters') + logger.exception(self.__str__() + ' incorrect parameters') + raise try: seed = self.kwargs['seed'] @@ -74,73 +74,90 @@ class AddSurfaceRoughness(UserObjectGeometry): if volumes: volume = volumes[0] else: - raise CmdInputError(self.__str__() + ' cannot find FractalBox {fractal_box_id}') + logger.exception(self.__str__() + f' cannot find FractalBox {fractal_box_id}') + raise ValueError p1, p2 = uip.check_box_points(p1, p2, self.__str__()) xs, ys, zs = p1 xf, yf, zf = p2 if frac_dim < 0: - raise CmdInputError(self.__str__() + ' requires a positive value for the fractal dimension') + logger.exception(self.__str__() + ' requires a positive value for the fractal dimension') + raise ValueError if weighting[0] < 0: - raise CmdInputError(self.__str__() + ' requires a positive value for the fractal weighting in the first direction of the surface') + logger.exception(self.__str__() + ' requires a positive value for the fractal weighting in the first direction of the surface') + raise ValueError if weighting[1] < 0: - raise CmdInputError(self.__str__() + ' requires a positive value for the fractal weighting in the second direction of the surface') + logger.exception(self.__str__() + ' requires a positive value for the fractal weighting in the second direction of the surface') + raise ValueError # Check for valid orientations if xs == xf: if ys == yf or zs == zf: - raise CmdInputError(self.__str__() + ' dimensions are not specified correctly') + logger.exception(self.__str__() + ' dimensions are not specified correctly') + raise ValueError if xs != volume.xs and xs != volume.xf: - raise CmdInputError(self.__str__() + ' can only be used on the external surfaces of a fractal box') + logger.exception(self.__str__() + ' can only be used on the external surfaces of a fractal box') + raise ValueError fractalrange = (round_value(limits[0] / grid.dx), round_value(limits[1] / grid.dx)) # xminus surface if xs == volume.xs: if fractalrange[0] < 0 or fractalrange[1] > volume.xf: - raise CmdInputError(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the upper coordinates of the fractal box or the domain in the x direction') + logger.exception(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the upper coordinates of the fractal box or the domain in the x direction') + raise ValueError requestedsurface = 'xminus' # xplus surface elif xf == volume.xf: if fractalrange[0] < volume.xs or fractalrange[1] > grid.nx: - raise CmdInputError(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the lower coordinates of the fractal box or the domain in the x direction') + logger.exception(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the lower coordinates of the fractal box or the domain in the x direction') + raise ValueError requestedsurface = 'xplus' elif ys == yf: if xs == xf or zs == zf: - raise CmdInputError(self.__str__() + ' dimensions are not specified correctly') + logger.exception(self.__str__() + ' dimensions are not specified correctly') + raise ValueError if ys != volume.ys and ys != volume.yf: - raise CmdInputError(self.__str__() + ' can only be used on the external surfaces of a fractal box') + logger.exception(self.__str__() + ' can only be used on the external surfaces of a fractal box') + raise ValueError fractalrange = (round_value(limits[0] / grid.dy), round_value(limits[1] / grid.dy)) # yminus surface if ys == volume.ys: if fractalrange[0] < 0 or fractalrange[1] > volume.yf: - raise CmdInputError(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the upper coordinates of the fractal box or the domain in the y direction') + logger.exception(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the upper coordinates of the fractal box or the domain in the y direction') + raise ValueError requestedsurface = 'yminus' # yplus surface elif yf == volume.yf: if fractalrange[0] < volume.ys or fractalrange[1] > grid.ny: - raise CmdInputError(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the lower coordinates of the fractal box or the domain in the y direction') + logger.exception(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the lower coordinates of the fractal box or the domain in the y direction') + raise ValueError requestedsurface = 'yplus' elif zs == zf: if xs == xf or ys == yf: - raise CmdInputError(self.__str__() + ' dimensions are not specified correctly') + logger.exception(self.__str__() + ' dimensions are not specified correctly') + raise ValueError if zs != volume.zs and zs != volume.zf: - raise CmdInputError(self.__str__() + ' can only be used on the external surfaces of a fractal box') + logger.exception(self.__str__() + ' can only be used on the external surfaces of a fractal box') + raise ValueError fractalrange = (round_value(limits[0] / grid.dz), round_value(limits[1] / grid.dz)) # zminus surface if zs == volume.zs: if fractalrange[0] < 0 or fractalrange[1] > volume.zf: - raise CmdInputError(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the upper coordinates of the fractal box or the domain in the x direction') + logger.exception(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the upper coordinates of the fractal box or the domain in the x direction') + raise ValueError requestedsurface = 'zminus' # zplus surface elif zf == volume.zf: if fractalrange[0] < volume.zs or fractalrange[1] > grid.nz: - raise CmdInputError(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the lower coordinates of the fractal box or the domain in the z direction') + logger.exception(self.__str__() + ' cannot apply fractal surface to fractal box as it would exceed either the lower coordinates of the fractal box or the domain in the z direction') + raise ValueError requestedsurface = 'zplus' else: - raise CmdInputError(self.__str__() + ' dimensions are not specified correctly') + logger.exception(self.__str__() + ' dimensions are not specified correctly') + raise ValueError surface = FractalSurface(xs, xf, ys, yf, zs, zf, frac_dim) surface.surfaceID = requestedsurface @@ -152,7 +169,8 @@ class AddSurfaceRoughness(UserObjectGeometry): # List of existing surfaces IDs existingsurfaceIDs = [x.surfaceID for x in volume.fractalsurfaces] if surface.surfaceID in existingsurfaceIDs: - raise CmdInputError(self.__str__() + f' has already been used on the {surface.surfaceID} surface') + logger.exception(self.__str__() + f' has already been used on the {surface.surfaceID} surface') + raise ValueError surface.generate_fractal_surface(grid) volume.fractalsurfaces.append(surface) diff --git a/gprMax/cmds_geometry/add_surface_water.py b/gprMax/cmds_geometry/add_surface_water.py index 024135d2..e9285155 100644 --- a/gprMax/cmds_geometry/add_surface_water.py +++ b/gprMax/cmds_geometry/add_surface_water.py @@ -20,7 +20,6 @@ import logging import gprMax.config as config -from ..exceptions import CmdInputError from ..materials import DispersiveMaterial from ..utilities import round_value from .cmds_geometry import UserObjectGeometry @@ -53,28 +52,33 @@ class AddSurfaceWater(UserObjectGeometry): fractal_box_id = self.kwargs['fractal_box_id'] depth = self.kwargs['depth'] except KeyError: - raise CmdInputError(self.__str__() + ' requires exactly eight parameters') + logger.exception(self.__str__() + ' requires exactly eight parameters') + raise # Get the correct fractal volume volumes = [volume for volume in grid.fractalvolumes if volume.ID == fractal_box_id] if volumes: volume = volumes[0] else: - raise CmdInputError(self.__str__() + f' cannot find FractalBox {fractal_box_id}') + logger.exception(self.__str__() + f' cannot find FractalBox {fractal_box_id}') + raise ValueError p1, p2 = uip.check_box_points(p1, p2, self.__str__()) xs, ys, zs = p1 xf, yf, zf = p2 if depth <= 0: - raise CmdInputError(self.__str__() + ' requires a positive value for the depth of water') + logger.exception(self.__str__() + ' requires a positive value for the depth of water') + raise ValueError # Check for valid orientations if xs == xf: if ys == yf or zs == zf: - raise CmdInputError(self.__str__() + ' dimensions are not specified correctly') + logger.exception(self.__str__() + ' dimensions are not specified correctly') + raise ValueError if xs != volume.xs and xs != volume.xf: - raise CmdInputError(self.__str__() + ' can only be used on the external surfaces of a fractal box') + logger.exception(self.__str__() + ' can only be used on the external surfaces of a fractal box') + raise ValueError # xminus surface if xs == volume.xs: requestedsurface = 'xminus' @@ -86,9 +90,11 @@ class AddSurfaceWater(UserObjectGeometry): elif ys == yf: if xs == xf or zs == zf: - raise CmdInputError(self.__str__() + ' dimensions are not specified correctly') + logger.exception(self.__str__() + ' dimensions are not specified correctly') + raise ValueError if ys != volume.ys and ys != volume.yf: - raise CmdInputError(self.__str__() + ' can only be used on the external surfaces of a fractal box') + logger.exception(self.__str__() + ' can only be used on the external surfaces of a fractal box') + raise ValueError # yminus surface if ys == volume.ys: requestedsurface = 'yminus' @@ -100,9 +106,11 @@ class AddSurfaceWater(UserObjectGeometry): elif zs == zf: if xs == xf or ys == yf: - raise CmdInputError(self.__str__() + ' dimensions are not specified correctly') + logger.exception(self.__str__() + ' dimensions are not specified correctly') + raise ValueError if zs != volume.zs and zs != volume.zf: - raise CmdInputError(self.__str__() + ' can only be used on the external surfaces of a fractal box') + logger.exception(self.__str__() + ' can only be used on the external surfaces of a fractal box') + raise ValueError # zminus surface if zs == volume.zs: requestedsurface = 'zminus' @@ -113,17 +121,20 @@ class AddSurfaceWater(UserObjectGeometry): filldepth = filldepthcells * grid.dz else: - raise CmdInputError(self.__str__() + ' dimensions are not specified correctly') + logger.exception(self.__str__() + ' dimensions are not specified correctly') + raise ValueError surface = next((x for x in volume.fractalsurfaces if x.surfaceID == requestedsurface), None) if not surface: - raise CmdInputError(self.__str__() + ' specified surface {} does not have a rough surface applied'.format(requestedsurface)) + logger.exception(self.__str__() + f' specified surface {requestedsurface} does not have a rough surface applied') + raise ValueError surface.filldepth = filldepthcells # Check that requested fill depth falls within range of surface roughness if surface.filldepth < surface.fractalrange[0] or surface.filldepth > surface.fractalrange[1]: - raise CmdInputError(self.__str__() + ' requires a value for the depth of water that lies with the range of the requested surface roughness') + logger.exception(self.__str__() + ' requires a value for the depth of water that lies with the range of the requested surface roughness') + raise ValueError # Check to see if water has been already defined as a material if not any(x.ID == 'water' for x in grid.materials): @@ -141,6 +152,7 @@ class AddSurfaceWater(UserObjectGeometry): water = next((x for x in grid.materials if x.ID == 'water')) testwater = next((x for x in water.tau if x < grid.dt), None) if testwater: - raise CmdInputError(self.__str__() + ' requires the time step for the model to be less than the relaxation time required to model water.') + logger.exception(self.__str__() + ' requires the time step for the model to be less than the relaxation time required to model water.') + raise ValueError logger.info(f'Water on surface from {xs * grid.dx:g}m, {ys * grid.dy:g}m, {zs * grid.dz:g}m, to {xf * grid.dx:g}m, {yf * grid.dy:g}m, {zf * grid.dz:g}m with depth {filldepth:g}m, added to {surface.operatingonID}.') diff --git a/gprMax/cmds_geometry/box.py b/gprMax/cmds_geometry/box.py index 51b5cf28..ded070ba 100644 --- a/gprMax/cmds_geometry/box.py +++ b/gprMax/cmds_geometry/box.py @@ -22,7 +22,6 @@ import gprMax.config as config import numpy as np from ..cython.geometry_primitives import build_box -from ..exceptions import CmdInputError from ..materials import Material from .cmds_geometry import UserObjectGeometry @@ -52,9 +51,10 @@ class Box(UserObjectGeometry): try: p1 = self.kwargs['p1'] p2 = self.kwargs['p2'] - except KeyError: - raise CmdInputError(self.__str__() + ' Please specify two points.') + logger.exception(self.__str__() + ' Please specify two points.') + raise + # check materials have been specified # isotropic case try: @@ -64,7 +64,8 @@ class Box(UserObjectGeometry): try: materialsrequested = self.kwargs['material_ids'] except KeyError: - raise CmdInputError(self.__str__() + ' No materials have been specified') + logger.exception(self.__str__() + ' No materials have been specified') + raise # check averaging try: @@ -83,7 +84,8 @@ class Box(UserObjectGeometry): if len(materials) != len(materialsrequested): notfound = [x for x in materialsrequested if x not in materials] - raise CmdInputError(self.__str__() + ' material(s) {} do not exist'.format(notfound)) + logger.exception(self.__str__() + f' material(s) {notfound} do not exist') + raise ValueError # Isotropic case if len(materials) == 1: diff --git a/gprMax/cmds_geometry/cmds_geometry.py b/gprMax/cmds_geometry/cmds_geometry.py index 5912d465..87f048e3 100644 --- a/gprMax/cmds_geometry/cmds_geometry.py +++ b/gprMax/cmds_geometry/cmds_geometry.py @@ -32,17 +32,17 @@ class UserObjectGeometry: def __str__(self): """Readable string of parameters given to object.""" s = '' - for k, v in self.kwargs.items(): + for _, v in self.kwargs.items(): if isinstance(v, tuple) or isinstance(v, list): v = ' '.join([str(el) for el in v]) s += str(v) + ' ' return f'{self.hash}: {s[:-1]}' - def params_str(self): - """Readable user string as per hash commands.""" - return self.hash + ': ' + str(self.kwargs) - def create(self, grid, uip): """Create the object and add it to the grid.""" - logger.debug('This method is incomplete') + pass + + def rotate(self): + """Rotate geometry object.""" + logger.debug('Must complete rotate method.') diff --git a/gprMax/cmds_geometry/cylinder.py b/gprMax/cmds_geometry/cylinder.py index 0ead2438..dcc09205 100644 --- a/gprMax/cmds_geometry/cylinder.py +++ b/gprMax/cmds_geometry/cylinder.py @@ -22,7 +22,6 @@ import gprMax.config as config import numpy as np from ..cython.geometry_primitives import build_cylinder -from ..exceptions import CmdInputError from ..materials import Material from .cmds_geometry import UserObjectGeometry @@ -55,16 +54,16 @@ class Cylinder(UserObjectGeometry): p1 = self.kwargs['p1'] p2 = self.kwargs['p2'] r = self.kwargs['r'] - except KeyError: - raise CmdInputError(self.__str__() + ' Please specify 2 points and a radius') + logger.exception(self.__str__() + ' please specify 2 points and a radius') + raise # check averaging try: # go with user specified averaging averagecylinder = self.kwargs['averaging'] except KeyError: - # if they havent specfied - go with the grid default + # if they havent specified - go with the grid default averagecylinder = grid.averagevolumeobjects # check materials have been specified @@ -76,20 +75,23 @@ class Cylinder(UserObjectGeometry): try: materialsrequested = self.kwargs['material_ids'] except KeyError: - raise CmdInputError(self.__str__() + ' No materials have been specified') + logger.exception(self.__str__() + ' no materials have been specified') + raise x1, y1, z1 = uip.round_to_grid(p1) x2, y2, z2 = uip.round_to_grid(p2) if r <= 0: - raise CmdInputError(self.__str__() + ' the radius {:g} should be a positive value.'.format(r)) + logger.exception(self.__str__() + f' the radius {r:g} should be a positive value.') + raise ValueError # Look up requested materials in existing list of material instances materials = [y for x in materialsrequested for y in grid.materials if y.ID == x] if len(materials) != len(materialsrequested): notfound = [x for x in materialsrequested if x not in materials] - raise CmdInputError(self.__str__() + ' material(s) {} do not exist'.format(notfound)) + logger.exception(self.__str__() + f' material(s) {notfound} do not exist') + raise ValueError # Isotropic case if len(materials) == 1: diff --git a/gprMax/cmds_geometry/cylindrical_sector.py b/gprMax/cmds_geometry/cylindrical_sector.py index 4ffa965e..2be7ce65 100644 --- a/gprMax/cmds_geometry/cylindrical_sector.py +++ b/gprMax/cmds_geometry/cylindrical_sector.py @@ -22,7 +22,6 @@ import gprMax.config as config import numpy as np from ..cython.geometry_primitives import build_cylindrical_sector -from ..exceptions import CmdInputError from ..materials import Material from .cmds_geometry import UserObjectGeometry @@ -73,7 +72,8 @@ class CylindricalSector(UserObjectGeometry): r = self.kwargs['r'] thickness = extent2 - extent1 except KeyError: - raise CmdInputError(self.__str__()) + logger.exception(self.__str__()) + raise # check averaging try: @@ -92,26 +92,31 @@ class CylindricalSector(UserObjectGeometry): try: materialsrequested = self.kwargs['material_ids'] except KeyError: - raise CmdInputError(self.__str__() + ' No materials have been specified') + logger.exception(self.__str__() + ' No materials have been specified') + raise sectorstartangle = 2 * np.pi * (start / 360) sectorangle = 2 * np.pi * (end / 360) if normal != 'x' and normal != 'y' and normal != 'z': - raise CmdInputError(self.__str__() + ' the normal direction must be either x, y or z.') + logger.exception(self.__str__() + ' the normal direction must be either x, y or z.') + raise ValueError if r <= 0: - raise CmdInputError(self.__str__() + ' the radius {:g} should be a positive value.'.format(r)) + logger.exception(self.__str__() + f' the radius {r:g} should be a positive value.') if sectorstartangle < 0 or sectorangle <= 0: - raise CmdInputError(self.__str__() + ' the starting angle and sector angle should be a positive values.') + logger.exception(self.__str__() + ' the starting angle and sector angle should be a positive values.') + raise ValueError if sectorstartangle >= 2 * np.pi or sectorangle >= 2 * np.pi: - raise CmdInputError(self.__str__() + ' the starting angle and sector angle must be less than 360 degrees.') + logger.exception(self.__str__() + ' the starting angle and sector angle must be less than 360 degrees.') + raise ValueError # Look up requested materials in existing list of material instances materials = [y for x in materialsrequested for y in grid.materials if y.ID == x] if len(materials) != len(materialsrequested): notfound = [x for x in materialsrequested if x not in materials] - raise CmdInputError(self.__str__() + ' material(s) {} do not exist'.format(notfound)) + logger.exception(self.__str__() + f' material(s) {notfound} do not exist') + raise ValueError if thickness > 0: # Isotropic case diff --git a/gprMax/cmds_geometry/edge.py b/gprMax/cmds_geometry/edge.py index 9359ef7b..e700658c 100644 --- a/gprMax/cmds_geometry/edge.py +++ b/gprMax/cmds_geometry/edge.py @@ -22,7 +22,6 @@ import gprMax.config as config from ..cython.geometry_primitives import (build_edge_x, build_edge_y, build_edge_z) -from ..exceptions import CmdInputError from .cmds_geometry import UserObjectGeometry logger = logging.getLogger(__name__) @@ -50,7 +49,8 @@ class Edge(UserObjectGeometry): p2 = self.kwargs['p2'] material_id = self.kwargs['material_id'] except KeyError: - raise CmdInputError(self.__str__() + ' requires exactly 3 parameters') + logger.exception(self.__str__() + ' requires exactly 3 parameters') + raise p1, p2 = uip.check_box_points(p1, p2, self.__str__()) xs, ys, zs = p1 @@ -59,13 +59,15 @@ class Edge(UserObjectGeometry): material = next((x for x in grid.materials if x.ID == material_id), None) if not material: - raise CmdInputError('Material with ID {} does not exist'.format(material_id)) + logger.exception(f'Material with ID {material_id} does not exist') + raise ValueError # Check for valid orientations # x-orientated wire if xs != xf: if ys != yf or zs != zf: - raise CmdInputError(self.__str__() + ' the edge is not specified correctly') + logger.exception(self.__str__() + ' the edge is not specified correctly') + raise ValueError else: for i in range(xs, xf): build_edge_x(i, ys, zs, material.numID, grid.rigidE, grid.rigidH, grid.ID) @@ -73,7 +75,8 @@ class Edge(UserObjectGeometry): # y-orientated wire elif ys != yf: if xs != xf or zs != zf: - raise CmdInputError(self.__str__() + ' the edge is not specified correctly') + logger.exception(self.__str__() + ' the edge is not specified correctly') + raise ValueError else: for j in range(ys, yf): build_edge_y(xs, j, zs, material.numID, grid.rigidE, grid.rigidH, grid.ID) @@ -81,7 +84,8 @@ class Edge(UserObjectGeometry): # z-orientated wire elif zs != zf: if xs != xf or ys != yf: - raise CmdInputError(self.__str__() + ' the edge is not specified correctly') + logger.exception(self.__str__() + ' the edge is not specified correctly') + raise ValueError else: for k in range(zs, zf): build_edge_z(xs, ys, k, material.numID, grid.rigidE, grid.rigidH, grid.ID) diff --git a/gprMax/cmds_geometry/fractal_box.py b/gprMax/cmds_geometry/fractal_box.py index 1c742abe..2667e392 100644 --- a/gprMax/cmds_geometry/fractal_box.py +++ b/gprMax/cmds_geometry/fractal_box.py @@ -21,7 +21,6 @@ import logging import gprMax.config as config import numpy as np -from ..exceptions import CmdInputError from ..fractals import FractalVolume from .cmds_geometry import UserObjectGeometry @@ -65,7 +64,8 @@ class FractalBox(UserObjectGeometry): mixing_model_id = self.kwargs['mixing_model_id'] ID = self.kwargs['id'] except KeyError: - raise CmdInputError(self.__str__() + ' Incorrect parameters') + logger.exception(self.__str__() + ' Incorrect parameters') + raise try: seed = self.kwargs['seed'] @@ -88,15 +88,19 @@ class FractalBox(UserObjectGeometry): xf, yf, zf = p2 if frac_dim < 0: - raise CmdInputError(self.__str__() + ' requires a positive value for the fractal dimension') + logger.exception(self.__str__() + ' requires a positive value for the fractal dimension') + raise ValueError if weighting[0] < 0: - raise CmdInputError(self.__str__() + ' requires a positive value for the fractal weighting in the x direction') + logger.exception(self.__str__() + ' requires a positive value for the fractal weighting in the x direction') + raise ValueError if weighting[1] < 0: - raise CmdInputError(self.__str__() + ' requires a positive value for the fractal weighting in the y direction') + logger.exception(self.__str__() + ' requires a positive value for the fractal weighting in the y direction') + raise ValueError if weighting[2] < 0: - raise CmdInputError(self.__str__() + ' requires a positive value for the fractal weighting in the z direction') + logger.exception(self.__str__() + ' requires a positive value for the fractal weighting in the z direction') if n_materials < 0: - raise CmdInputError(self.__str__() + ' requires a positive value for the number of bins') + logger.exception(self.__str__() + ' requires a positive value for the number of bins') + raise ValueError # Find materials to use to build fractal volume, either from mixing models or normal materials mixingmodel = next((x for x in grid.mixingmodels if x.ID == mixing_model_id), None) @@ -105,11 +109,13 @@ class FractalBox(UserObjectGeometry): if mixingmodel: if nbins == 1: - raise CmdInputError(self.__str__() + ' must be used with more than one material from the mixing model.') + logger.exception(self.__str__() + ' must be used with more than one material from the mixing model.') + raise ValueError # Create materials from mixing model as number of bins now known from fractal_box command mixingmodel.calculate_debye_properties(nbins, grid) elif not material: - raise CmdInputError(self.__str__() + ' mixing model or material with ID {} does not exist'.format(mixing_model_id)) + logger.exception(self.__str__() + f' mixing model or material with ID {mixing_model_id} does not exist') + raise ValueError volume = FractalVolume(xs, xf, ys, yf, zs, zf, frac_dim) volume.ID = ID diff --git a/gprMax/cmds_geometry/fractal_box_builder.py b/gprMax/cmds_geometry/fractal_box_builder.py index 3f6ff9f7..7f03bfc4 100644 --- a/gprMax/cmds_geometry/fractal_box_builder.py +++ b/gprMax/cmds_geometry/fractal_box_builder.py @@ -16,14 +16,17 @@ # You should have received a copy of the GNU General Public License # along with gprMax. If not, see . +import logging + import gprMax.config as config import numpy as np from ..cython.geometry_primitives import (build_voxels_from_array, build_voxels_from_array_mask) -from ..exceptions import CmdInputError from .cmds_geometry import UserObjectGeometry +logger = logging.getLogger(__name__) + class FractalBoxBuilder(UserObjectGeometry): """Internal class for fractal box modifications. This class should be used @@ -300,7 +303,8 @@ class FractalBoxBuilder(UserObjectGeometry): else: if volume.nbins == 1: - raise CmdInputError(self.__str__() + ' is being used with a single material and no modifications, therefore please use a #box command instead.') + logger.exception(self.__str__() + ' is being used with a single material and no modifications, therefore please use a #box command instead.') + raise ValueError else: volume.generate_fractal_volume(grid) volume.fractalvolume += volume.mixingmodel.startmaterialnum diff --git a/gprMax/cmds_geometry/geometry_objects_read.py b/gprMax/cmds_geometry/geometry_objects_read.py index ed8145e8..9d334227 100644 --- a/gprMax/cmds_geometry/geometry_objects_read.py +++ b/gprMax/cmds_geometry/geometry_objects_read.py @@ -23,7 +23,6 @@ import gprMax.config as config import h5py from ..cython.geometry_primitives import build_voxels_from_array -from ..exceptions import CmdInputError from ..hash_cmds_file import get_user_objects from ..utilities import round_value from .cmds_geometry import UserObjectGeometry @@ -43,8 +42,9 @@ class GeometryObjectsRead(UserObjectGeometry): p1 = self.kwargs['p1'] geofile = self.kwargs['geofile'] matfile = self.kwargs['matfile'] - except: - raise CmdInputError(self.__str__() + 'requires exactly five parameters') + except KeyError: + logger.exception(self.__str__() + 'requires exactly five parameters') + raise # discretise the point using uip object. This has different behaviour # depending on the type of uip object. So we can use it for @@ -94,7 +94,8 @@ class GeometryObjectsRead(UserObjectGeometry): f = h5py.File(geofile, 'r') dx_dy_dz = f.attrs['dx_dy_dz'] if round_value(dx_dy_dz[0] / G.dx) != 1 or round_value(dx_dy_dz[1] / G.dy) != 1 or round_value(dx_dy_dz[2] / G.dz) != 1: - raise CmdInputError(self.__str__() + ' requires the spatial resolution of the geometry objects file to match the spatial resolution of the model') + logger.exception(self.__str__() + ' requires the spatial resolution of the geometry objects file to match the spatial resolution of the model') + raise ValueError data = f['/data'][:] diff --git a/gprMax/cmds_geometry/plate.py b/gprMax/cmds_geometry/plate.py index f12ed285..af5d4fa2 100644 --- a/gprMax/cmds_geometry/plate.py +++ b/gprMax/cmds_geometry/plate.py @@ -22,7 +22,6 @@ import gprMax.config as config from ..cython.geometry_primitives import (build_face_xy, build_face_xz, build_face_yz) -from ..exceptions import CmdInputError from .cmds_geometry import UserObjectGeometry logger = logging.getLogger(__name__) @@ -50,7 +49,8 @@ class Plate(UserObjectGeometry): p1 = self.kwargs['p1'] p2 = self.kwargs['p2'] except KeyError: - raise CmdInputError(self.__str__() + ' 2 points must be specified') + logger.exception(self.__str__() + ' 2 points must be specified') + raise # isotropic try: @@ -60,7 +60,8 @@ class Plate(UserObjectGeometry): try: materialsrequested = self.kwargs['material_ids'] except KeyError: - raise CmdInputError(self.__str__() + ' No materials have been specified') + logger.exception(self.__str__() + ' No materials have been specified') + raise p1, p2 = uip.check_box_points(p1, p2, self.__str__()) xs, ys, zs = p1 @@ -69,25 +70,30 @@ class Plate(UserObjectGeometry): # Check for valid orientations if xs == xf: if ys == yf or zs == zf: - raise CmdInputError(self.__str__() + ' the plate is not specified correctly') + logger.exception(self.__str__() + ' the plate is not specified correctly') + raise ValueError elif ys == yf: if xs == xf or zs == zf: - raise CmdInputError(self.__str__() + ' the plate is not specified correctly') + logger.exception(self.__str__() + ' the plate is not specified correctly') + raise ValueError elif zs == zf: if xs == xf or ys == yf: - raise CmdInputError(self.__str__() + ' the plate is not specified correctly') + logger.exception(self.__str__() + ' the plate is not specified correctly') + raise ValueError else: - raise CmdInputError(self.__str__() + ' the plate is not specified correctly') + logger.exception(self.__str__() + ' the plate is not specified correctly') + raise ValueError # Look up requested materials in existing list of material instances materials = [y for x in materialsrequested for y in grid.materials if y.ID == x] if len(materials) != len(materialsrequested): notfound = [x for x in materialsrequested if x not in materials] - raise CmdInputError(self.__str__() + ' material(s) {} do not exist'.format(notfound)) + logger.exception(self.__str__() + f' material(s) {notfound} do not exist') + raise ValueError # yz-plane plate if xs == xf: diff --git a/gprMax/cmds_geometry/sphere.py b/gprMax/cmds_geometry/sphere.py index ab359fa5..6514e584 100644 --- a/gprMax/cmds_geometry/sphere.py +++ b/gprMax/cmds_geometry/sphere.py @@ -22,7 +22,6 @@ import gprMax.config as config import numpy as np from ..cython.geometry_primitives import build_sphere -from ..exceptions import CmdInputError from ..materials import Material from .cmds_geometry import UserObjectGeometry @@ -53,7 +52,8 @@ class Sphere(UserObjectGeometry): p1 = self.kwargs['p1'] r = self.kwargs['r'] except KeyError: - raise CmdInputError(self.__str__() + ' Please specify a point and a radius.') + logger.exception(self.__str__() + ' please specify a point and a radius.') + raise # check averaging try: @@ -72,7 +72,8 @@ class Sphere(UserObjectGeometry): try: materialsrequested = self.kwargs['material_ids'] except KeyError: - raise CmdInputError(self.__str__() + ' No materials have been specified') + logger.exception(self.__str__() + ' no materials have been specified') + raise # Centre of sphere xc, yc, zc = uip.round_to_grid(p1) @@ -82,7 +83,8 @@ class Sphere(UserObjectGeometry): if len(materials) != len(materialsrequested): notfound = [x for x in materialsrequested if x not in materials] - raise CmdInputError(self.__str__() + ' material(s) {} do not exist'.format(notfound)) + logger.exception(self.__str__() + f' material(s) {notfound} do not exist') + raise ValueError # Isotropic case if len(materials) == 1: diff --git a/gprMax/cmds_geometry/triangle.py b/gprMax/cmds_geometry/triangle.py index 68046594..226b1703 100644 --- a/gprMax/cmds_geometry/triangle.py +++ b/gprMax/cmds_geometry/triangle.py @@ -22,7 +22,6 @@ import gprMax.config as config import numpy as np from ..cython.geometry_primitives import build_triangle -from ..exceptions import CmdInputError from ..materials import Material from .cmds_geometry import UserObjectGeometry @@ -59,7 +58,8 @@ class Triangle(UserObjectGeometry): up3 = self.kwargs['p3'] thickness = self.kwargs['thickness'] except KeyError: - raise CmdInputError(self.params_str() + ' Specify 3 points and a thickness') + logger.exception(self.__str__() + ' specify 3 points and a thickness') + raise # check averaging try: @@ -78,7 +78,8 @@ class Triangle(UserObjectGeometry): try: materialsrequested = self.kwargs['material_ids'] except KeyError: - raise CmdInputError(self.__str__() + ' No materials have been specified') + logger.exception(self.__str__() + ' no materials have been specified') + raise # Check whether points are valid against grid uip.check_tri_points(up1, up2, up3, object) @@ -88,7 +89,8 @@ class Triangle(UserObjectGeometry): x3, y3, z3 = uip.round_to_grid(up3) if thickness < 0: - raise CmdInputError(self.__str__() + ' requires a positive value for thickness') + logger.exception(self.__str__() + ' requires a positive value for thickness') + raise ValueError # Check for valid orientations # yz-plane triangle @@ -101,14 +103,16 @@ class Triangle(UserObjectGeometry): elif z1 == z2 and z2 == z3: normal = 'z' else: - raise CmdInputError(self.__str__() + ' the triangle is not specified correctly') + logger.exception(self.__str__() + ' the triangle is not specified correctly') + raise ValueError # Look up requested materials in existing list of material instances materials = [y for x in materialsrequested for y in grid.materials if y.ID == x] if len(materials) != len(materialsrequested): notfound = [x for x in materialsrequested if x not in materials] - raise CmdInputError(self.__str__() + ' material(s) {} do not exist'.format(notfound)) + logger.exception(self.__str__() + f' material(s) {notfound} do not exist') + raise ValueError if thickness > 0: # Isotropic case