你已经派生过 gprMax
镜像自地址
https://gitee.com/sunhf/gprMax.git
已同步 2025-08-07 15:10:13 +08:00
183 行
6.4 KiB
Python
183 行
6.4 KiB
Python
# Copyright (C) 2015-2023: The University of Edinburgh, United Kingdom
|
|
# 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 <http://www.gnu.org/licenses/>.
|
|
|
|
import datetime
|
|
import decimal as d
|
|
import logging
|
|
import re
|
|
import textwrap
|
|
from shutil import get_terminal_size
|
|
|
|
import numpy as np
|
|
from colorama import Fore, Style, init
|
|
init()
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
try:
|
|
from time import thread_time as timer_fn
|
|
except ImportError:
|
|
from time import perf_counter as timer_fn
|
|
logger.debug('"thread_time" not currently available in macOS and bug'
|
|
' (https://bugs.python.org/issue36205) with "process_time", '
|
|
'so use "perf_counter".')
|
|
|
|
|
|
def get_terminal_width():
|
|
"""Gets/sets width of terminal being used.
|
|
|
|
Returns:
|
|
terminalwidth: int for the terminal width.
|
|
"""
|
|
|
|
terminalwidth = get_terminal_size()[0]
|
|
if terminalwidth == 0:
|
|
terminalwidth = 100
|
|
|
|
return terminalwidth
|
|
|
|
|
|
def logo(version):
|
|
"""Prints gprMax logo, version, and licencing/copyright information.
|
|
|
|
Args:
|
|
version: string for version number.
|
|
|
|
Returns:
|
|
str: string containing logo, version, and licencing/copyright info.
|
|
"""
|
|
|
|
description = ('\n=== Electromagnetic modelling software based on the '
|
|
'Finite-Difference Time-Domain (FDTD) method')
|
|
current_year = datetime.datetime.now().year
|
|
copyright = (f'Copyright (C) 2015-{current_year}: The University of '
|
|
'Edinburgh, United Kingdom')
|
|
authors = 'Authors: Craig Warren, Antonis Giannopoulos, and John Hartley'
|
|
licenseinfo1 = ('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.\n')
|
|
licenseinfo2 = ('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.')
|
|
licenseinfo3 = ('You should have received a copy of the GNU General Public '
|
|
'License along with gprMax. If not, '
|
|
'see www.gnu.org/licenses.')
|
|
|
|
logo = """ www.gprmax.com __ __
|
|
__ _ _ __ _ __| \/ | __ ___ __
|
|
/ _` | '_ \| '__| |\/| |/ _` \ \/ /
|
|
| (_| | |_) | | | | | | (_| |> <
|
|
\__, | .__/|_| |_| |_|\__,_/_/\_\\
|
|
|___/|_|
|
|
v""" + version + '\n\n'
|
|
|
|
str = f"{description} {'=' * (get_terminal_width() - len(description) - 1)}\n\n"
|
|
str += f'{Fore.CYAN}{logo}'
|
|
str += Style.RESET_ALL + textwrap.fill(copyright,
|
|
width=get_terminal_width() - 1,
|
|
initial_indent=' ') + '\n'
|
|
str += textwrap.fill(authors, width=get_terminal_width() - 1,
|
|
initial_indent=' ') + '\n\n'
|
|
str += textwrap.fill(licenseinfo1, width=get_terminal_width() - 1,
|
|
initial_indent=' ', subsequent_indent=' ') + '\n'
|
|
str += textwrap.fill(licenseinfo2, width=get_terminal_width() - 1,
|
|
initial_indent=' ', subsequent_indent=' ') + '\n'
|
|
str += textwrap.fill(licenseinfo3, width=get_terminal_width() - 1,
|
|
initial_indent=' ', subsequent_indent=' ')
|
|
|
|
return str
|
|
|
|
|
|
def round_value(value, decimalplaces=0):
|
|
"""Rounding function.
|
|
|
|
Args:
|
|
value: float of number to round.
|
|
decimalplaces: int for number of decimal places of float to represent
|
|
rounded value.
|
|
|
|
Returns:
|
|
rounded: int/float of 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 = f"1.{'0' * decimalplaces}"
|
|
rounded = float(d.Decimal(value).quantize(d.Decimal(precision),
|
|
rounding=d.ROUND_FLOOR))
|
|
|
|
return rounded
|
|
|
|
|
|
def round32(value):
|
|
"""Rounds up to nearest multiple of 32."""
|
|
return int(32 * np.ceil(float(value) / 32))
|
|
|
|
|
|
def fft_power(waveform, dt):
|
|
"""Calculates FFT of the given waveform of amplitude values;
|
|
converted to decibels and shifted so that maximum power is 0dB
|
|
|
|
Args:
|
|
waveform: array containing time domain waveform.
|
|
dt: float of time step.
|
|
|
|
Returns:
|
|
freq: array of frequency bins.
|
|
power: array containing power spectra.
|
|
"""
|
|
|
|
# Calculate magnitude of frequency spectra of waveform (ignore warning from
|
|
# taking a log of any zero values)
|
|
with np.errstate(divide='ignore'):
|
|
power = 10 * np.log10(np.abs(np.fft.fft(waveform))**2)
|
|
|
|
# Replace any NaNs or Infs from zero division
|
|
power[np.invert(np.isfinite(power))] = 0
|
|
|
|
# Frequency bins
|
|
freqs = np.fft.fftfreq(power.size, d=dt)
|
|
|
|
# Shift powers so that frequency with maximum power is at zero decibels
|
|
power -= np.amax(power)
|
|
|
|
return freqs, power
|
|
|
|
|
|
def timer():
|
|
"""Time in fractional seconds."""
|
|
return timer_fn()
|
|
|
|
|
|
def numeric_list_to_int_list(l):
|
|
"""List of int from a numerical list."""
|
|
return list(map(int, l))
|
|
|
|
|
|
def numeric_list_to_float_list(l):
|
|
"""List of float from a numerical list."""
|
|
return list(map(float, l)) |