# Path: gprMax/constants.py

# 
# Path: gprMax/constants.py

# 
# Path: gprMax/utilities.py
# def round_value(value, decimalplaces=0):
#     """Rounding function.
# 
#     Args:
#         value (float): Number to round.
#         decimalplaces (int): Number of decimal places of float to represent rounded value.
# 
#     Returns:
#         rounded (int/float): Rounded value.
#     """
# 
#     # Rounds to nearest integer (half values are rounded downwards)
#     if decimalplaces == 0:
#         rounded = int(d.Decimal(value).quantize(d.Decimal('1'), rounding=d.ROUND_HALF_DOWN))
# 
#     # Rounds down to nearest float represented by number of decimal places
#     else:
#         precision = '1.{places}'.format(places='0' * decimalplaces)
#         rounded = float(d.Decimal(value).quantize(d.Decimal(precision), rounding=d.ROUND_FLOOR))
# 
#     return rounded


import numpy as np
from scipy import fftpack
from gprMax.constants import floattype
from gprMax.constants import complextype
from gprMax.fractals_generate_ext import generate_fractal2D
from gprMax.fractals_generate_ext import generate_fractal3D
from gprMax.utilities import round_value

        # 3D FFT
        A = fftpack.fftn(A)
        # Shift the zero frequency component to the centre of the array
        A = fftpack.fftshift(A)

        # Generate fractal
        generate_fractal3D(self.nx, self.ny, self.nz, G.nthreads, self.b, self.weighting, v1, A, self.fractalvolume)

        # Shift the zero frequency component to the start of the array
        self.fractalvolume = fftpack.ifftshift(self.fractalvolume)
        # Take the real part (numerical errors can give rise to an imaginary part) of the IFFT
        self.fractalvolume = np.real(fftpack.ifftn(self.fractalvolume))
        # Bin fractal values
        bins = np.linspace(np.amin(self.fractalvolume), np.amax(self.fractalvolume), self.nbins)
        for j in range(self.ny):
            for k in range(self.nz):
                self.fractalvolume[:, j, k] = np.digitize(self.fractalvolume[:, j, k], bins, right=True)

    def generate_volume_mask(self):
        """
        Generate a 3D volume to use as a mask for adding rough surfaces, water and grass/roots.
        Zero signifies the mask is not set, one signifies the mask is set."""

        self.mask = np.zeros((self.nx, self.ny, self.nz), dtype=np.int8)
        maskxs = self.originalxs - self.xs
        maskxf = (self.originalxf - self.originalxs) + maskxs
        maskys = self.originalys - self.ys
        maskyf = (self.originalyf - self.originalys) + maskys
        maskzs = self.originalzs - self.zs

# Path: gprMax/constants.py

# 
# Path: gprMax/constants.py

# 
# Path: gprMax/utilities.py
# def round_value(value, decimalplaces=0):
#     """Rounding function.
# 
#     Args:
#         value (float): Number to round.
#         decimalplaces (int): Number of decimal places of float to represent rounded value.
# 
#     Returns:
#         rounded (int/float): Rounded value.
#     """
# 
#     # Rounds to nearest integer (half values are rounded downwards)
#     if decimalplaces == 0:
#         rounded = int(d.Decimal(value).quantize(d.Decimal('1'), rounding=d.ROUND_HALF_DOWN))
# 
#     # Rounds down to nearest float represented by number of decimal places
#     else:
#         precision = '1.{places}'.format(places='0' * decimalplaces)
#         rounded = float(d.Decimal(value).quantize(d.Decimal(precision), rounding=d.ROUND_FLOOR))
# 
#     return rounded


# Path: gprMax/fractals.py
import numpy as np
from scipy import fftpack
from gprMax.constants import floattype
from gprMax.constants import complextype
from gprMax.fractals_generate_ext import generate_fractal2D
from gprMax.fractals_generate_ext import generate_fractal3D
from gprMax.utilities import round_value


        # 3D FFT
        A = fftpack.fftn(A)
        # Shift the zero frequency component to the centre of the array
        A = fftpack.fftshift(A)

        # Generate fractal
        generate_fractal3D(self.nx, self.ny, self.nz, G.nthreads, self.b, self.weighting, v1, A, self.fractalvolume)

        # Shift the zero frequency component to the start of the array
        self.fractalvolume = fftpack.ifftshift(self.fractalvolume)
        # Take the real part (numerical errors can give rise to an imaginary part) of the IFFT
        self.fractalvolume = np.real(fftpack.ifftn(self.fractalvolume))
        # Bin fractal values
        bins = np.linspace(np.amin(self.fractalvolume), np.amax(self.fractalvolume), self.nbins)
        for j in range(self.ny):
            for k in range(self.nz):
                self.fractalvolume[:, j, k] = np.digitize(self.fractalvolume[:, j, k], bins, right=True)

    def generate_volume_mask(self):
        """
        Generate a 3D volume to use as a mask for adding rough surfaces, water and grass/roots.
        Zero signifies the mask is not set, one signifies the mask is set."""

        self.mask = np.zeros((self.nx, self.ny, self.nz), dtype=np.int8)
        maskxs = self.originalxs - self.xs
        maskxf = (self.originalxf - self.originalxs) + maskxs
        maskys = self.originalys - self.ys
        maskyf = (self.originalyf - self.originalys) + maskys
        maskzs = self.originalzs - self.zs

        maskzf = (self.originalzf - self.originalzs) + maskzs