diff --git a/gprMax/exceptions.py b/gprMax/exceptions.py
index e4d84d58..751260d8 100644
--- a/gprMax/exceptions.py
+++ b/gprMax/exceptions.py
@@ -17,11 +17,25 @@
# along with gprMax. If not, see .
+from colorama import init, Fore
+init()
+
+
class GeneralError(ValueError):
"""Handles general errors. Subclasses the ValueError class."""
- pass
+
+ def __init__(self, message, *args):
+
+ self.message = message
+ super(GeneralError, self).__init__(message, *args)
+ print(Fore.RED)
class CmdInputError(ValueError):
"""Handles errors in user specified commands. Subclasses the ValueError class."""
- pass
+
+ def __init__(self, message, *args):
+
+ self.message = message
+ super(CmdInputError, self).__init__(message, *args)
+ print(Fore.RED)
\ No newline at end of file
diff --git a/gprMax/gprMax.py b/gprMax/gprMax.py
index e1d2dca7..05677350 100644
--- a/gprMax/gprMax.py
+++ b/gprMax/gprMax.py
@@ -28,6 +28,8 @@ from shutil import get_terminal_size
import sys
from time import perf_counter
+from colorama import init, Fore, Style
+init()
import numpy as np
from terminaltables import AsciiTable
from tqdm import tqdm
@@ -56,13 +58,13 @@ def main():
logo(__version__ + ' (Bowmore)')
# Parse command line arguments
- parser = argparse.ArgumentParser(prog='gprMax', description='Electromagnetic modelling software based on the Finite-Difference Time-Domain (FDTD) method')
- parser.add_argument('inputfile', help='path to and name of inputfile')
- parser.add_argument('-n', default=1, type=int, help='number of times to run the input file')
+ parser = argparse.ArgumentParser(prog='gprMax')
+ parser.add_argument('inputfile', help='path to, and name of inputfile')
+ parser.add_argument('-n', default=1, type=int, help='number of times to run the input file, e.g. for creating B-scans')
parser.add_argument('-mpi', action='store_true', default=False, help='flag to switch on MPI task farm')
parser.add_argument('-benchmark', action='store_true', default=False, help='flag to switch on benchmarking mode')
parser.add_argument('--geometry-only', action='store_true', default=False, help='flag to only build model and produce geometry file(s)')
- parser.add_argument('--geometry-fixed', action='store_true', default=False, help='flag to not reprocess model geometry for multiple model runs')
+ parser.add_argument('--geometry-fixed', action='store_true', default=False, help='flag to not reprocess model geometry, e.g. for B-scans where the geometry is fixed')
parser.add_argument('--write-processed', action='store_true', default=False, help='flag to write an input file after any Python code and include commands in the original input file have been processed')
parser.add_argument('--opt-taguchi', action='store_true', default=False, help='flag to optimise parameters using the Taguchi optimisation method')
args = parser.parse_args()
@@ -151,8 +153,8 @@ def run_std_sim(args, numbermodelruns, inputfile, usernamespace, optparams=None)
modelusernamespace = usernamespace
run_model(args, modelrun, numbermodelruns, inputfile, modelusernamespace)
tsimend = perf_counter()
- print('\n{}\nSimulation completed in [HH:MM:SS]: {}'.format('-' * get_terminal_size()[0], datetime.timedelta(seconds=int(tsimend - tsimstart))))
- print('{}\n'.format('=' * get_terminal_size()[0]))
+ simcompletestr = '\n== Simulation completed in [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=int(tsimend - tsimstart)))
+ print('{} {}\n'.format(simcompletestr, '=' * (get_terminal_size()[0] - len(simcompletestr))))
def run_benchmark_sim(args, inputfile, usernamespace):
@@ -184,7 +186,8 @@ def run_benchmark_sim(args, inputfile, usernamespace):
threads = np.array(threads)
np.savez(os.path.splitext(inputfile)[0], threads=threads, benchtimes=benchtimes, version=__version__)
- print('\nSimulation completed\n{}\n'.format('=' * get_terminal_size()[0]))
+ simcompletestr = '\n== Simulation completed'
+ print('{} {}\n'.format(simcompletestr, '=' * (get_terminal_size()[0] - len(simcompletestr))))
def run_mpi_sim(args, numbermodelruns, inputfile, usernamespace, optparams=None):
@@ -263,8 +266,8 @@ def run_mpi_sim(args, numbermodelruns, inputfile, usernamespace, optparams=None)
comm.send(None, dest=0, tag=tags.EXIT.value)
tsimend = perf_counter()
- print('\n{}\nSimulation completed in [HH:MM:SS]: {}'.format('-' * get_terminal_size()[0], datetime.timedelta(seconds=int(tsimend - tsimstart))))
- print('{}\n'.format('=' * get_terminal_size()[0]))
+ simcompletestr = '\n== Simulation completed in [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=int(tsimend - tsimstart)))
+ print('{} {}\n'.format(simcompletestr, '=' * (get_terminal_size()[0] - len(simcompletestr))))
def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
@@ -289,11 +292,12 @@ def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
# Normal model reading/building process; bypassed if geometry information to be reused
if 'G' not in globals():
- print('{}\n\nInput file: {}\n'.format('-' * get_terminal_size()[0], inputfile))
+ inputfilestr = '\nModel {} of {}, input file: {}'.format(modelrun, numbermodelruns, inputfile)
+ print(Fore.GREEN + '{} {}\n'.format(inputfilestr, '-' * (get_terminal_size()[0] - len(inputfilestr))))
# Add the current model run to namespace that can be accessed by user in any Python code blocks in input file
usernamespace['current_model_run'] = modelrun
- print('Constants/variables available for Python scripting: {}\n'.format(usernamespace))
+ print(Style.RESET_ALL + 'Constants/variables available for Python scripting: {}\n'.format(usernamespace))
# Read input file and process any Python or include commands
processedlines = process_python_include_code(inputfile, usernamespace)
@@ -405,7 +409,7 @@ def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
raise GeneralError('No geometry views found.')
elif G.geometryviews:
print()
- for geometryview in tqdm(G.geometryviews, desc='Writing geometry file(s)'):
+ for geometryview in tqdm(G.geometryviews, desc='Writing geometry file(s)', unit='file'):
geometryview.write_vtk(modelrun, numbermodelruns, G)
# geometryview.write_xdmf(modelrun, numbermodelruns, G)
@@ -484,7 +488,7 @@ def run_model(args, modelrun, numbermodelruns, inputfile, usernamespace):
write_hdf5(outputfile, G.Ex, G.Ey, G.Ez, G.Hx, G.Hy, G.Hz, G)
if G.messages:
- print('\nMemory (RAM) used: ~{}'.format(human_size(p.memory_info().rss)))
+ print('Memory (RAM) used: ~{}'.format(human_size(p.memory_info().rss)))
##################################
# End - Main FDTD calculations #
diff --git a/gprMax/input_cmds_geometry.py b/gprMax/input_cmds_geometry.py
index edced2a0..aef59107 100644
--- a/gprMax/input_cmds_geometry.py
+++ b/gprMax/input_cmds_geometry.py
@@ -41,7 +41,7 @@ def process_geometrycmds(geometry, G):
"""
- for object in tqdm(geometry, desc='Processing geometry objects'):
+ for object in tqdm(geometry, desc='Processing geometry objects', unit='cmds'):
tmp = object.split()
if tmp[0] == '#geometry_objects_file:':
diff --git a/gprMax/optimisation_taguchi.py b/gprMax/optimisation_taguchi.py
index 54eb52cd..1d325f55 100644
--- a/gprMax/optimisation_taguchi.py
+++ b/gprMax/optimisation_taguchi.py
@@ -160,9 +160,9 @@ def run_opt_sim(args, numbermodelruns, inputfile, usernamespace):
pickle.dump(fitnessvalueshist, f)
pickle.dump(optparamsinit, f)
- print('{}\nTaguchi optimisation completed after {} iteration(s).\nHistory of optimal parameter values {} and of fitness values {}'.format('-' * get_terminal_size()[0], iteration, dict(optparamshist), fitnessvalueshist))
- print('Simulation completed in [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=int(tsimend - tsimstart))))
- print('{}\n'.format('=' * get_terminal_size()[0]))
+ print('\nTaguchi optimisation completed after {} iteration(s).\nHistory of optimal parameter values {} and of fitness values {}'.format(iteration, dict(optparamshist), fitnessvalueshist))
+ simcompletestr = '\n== Simulation completed in [HH:MM:SS]: {}'.format(datetime.timedelta(seconds=int(tsimend - tsimstart)))
+ print('{} {}\n'.format(simcompletestr, '=' * (get_terminal_size()[0] - len(simcompletestr))))
def taguchi_code_blocks(inputfile, taguchinamespace):
diff --git a/gprMax/utilities.py b/gprMax/utilities.py
index 4badda8c..dbe0323c 100644
--- a/gprMax/utilities.py
+++ b/gprMax/utilities.py
@@ -34,12 +34,12 @@ def logo(version):
version (str): Version number.
"""
- description = '"Electromagnetic modelling software based on the Finite-Difference Time-Domain (FDTD) method"'
+ description = 'Electromagnetic modelling software based on the Finite-Difference Time-Domain (FDTD) method'
copyright = 'Copyright (C) 2015-2016: The University of Edinburgh'
authors = 'Authors: Craig Warren and Antonis Giannopoulos'
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 .'
+ 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 __ __
__ _ _ __ _ __| \/ | __ ___ __
@@ -49,14 +49,9 @@ def logo(version):
|___/|_|
v""" + version
- print('\n{}'.format('=' * get_terminal_size()[0]))
-
-
- print(Fore.MAGENTA + '{}'.format(logo))
- print(Style.RESET_ALL + '{}'.format('-' * get_terminal_size()[0]))
- print(textwrap.fill(description, width=get_terminal_size()[0], initial_indent=' '))
- print()
- print(textwrap.fill(copyright, width=get_terminal_size()[0], initial_indent=' '))
+ print('\n== {} {}\n'.format(description, '=' * (get_terminal_size()[0] - (len(description)) - 4)))
+ print(Fore.CYAN + '{}\n'.format(logo))
+ print(Style.RESET_ALL + textwrap.fill(copyright, width=get_terminal_size()[0], initial_indent=' '))
print(textwrap.fill(authors, width=get_terminal_size()[0], initial_indent=' '))
print()
print(textwrap.fill(licenseinfo1, width=get_terminal_size()[0], initial_indent=' ', subsequent_indent=' '))