From f2203541bc4d91609080dfd1966d1ebec4a27de0 Mon Sep 17 00:00:00 2001 From: Craig Warren Date: Fri, 7 Jan 2022 14:46:14 +0000 Subject: [PATCH] Cleanup of user_libs especially docs. --- .gitignore | 5 - docs/source/references.rst | 1 + gprMax/hash_cmds_file.py | 2 - gprMax/hash_cmds_multiuse.py | 105 +----- tools/convert_png2h5.py | 11 +- tools/plot_antenna_params.py | 16 +- tools/plot_source_wave.py | 16 +- user_libs/AustinManWoman/docs/README.rst | 8 +- user_libs/DebyeFit/Debye_Fit.py | 2 +- user_libs/DebyeFit/Readme.rst | 356 ------------------ user_libs/DebyeFit/__init__.py | 8 - user_libs/DebyeFit/docs/README.rst | 246 ++++++++++++ .../DebyeFit/docs/{ => images}/epsilon.png | Bin .../{optimization.md => optimization.rst} | 16 +- user_libs/DebyeFit/docs/relaxation.md | 69 ---- user_libs/DebyeFit/docs/relaxation.rst | 71 ++++ user_libs/DebyeFit/examples/Readme.md | 33 -- user_libs/DebyeFit/optimization.py | 2 +- user_libs/antenna_patterns/docs/README.rst | 10 +- user_libs/antennas/docs/README.rst | 10 +- user_libs/landmines/PMA_1x1x1.h5 | Bin 0 -> 593504 bytes user_libs/landmines/PMA_2x2x2.h5 | Bin 0 -> 73824 bytes user_libs/landmines/PMA_materials.txt | 5 + user_libs/landmines/PMN_1x1x1.h5 | Bin 0 -> 1775552 bytes user_libs/landmines/PMN_2x2x2.h5 | Bin 0 -> 219296 bytes user_libs/landmines/PMN_materials.txt | 6 + user_libs/landmines/PMN_materials2.txt | 6 + user_libs/landmines/TS50_1x1x1.h5 | Bin 0 -> 714944 bytes user_libs/landmines/TS50_2x2x2.h5 | Bin 0 -> 91244 bytes user_libs/landmines/TS50_materials.txt | 7 + user_libs/landmines/can_1x1x1.h5 | Bin 0 -> 1249760 bytes user_libs/landmines/can_2x2x2.h5 | Bin 0 -> 158096 bytes user_libs/landmines/can_materials.txt | 2 + user_libs/landmines/docs/README.rst | 87 +++++ user_libs/landmines/docs/images/PMA.png | Bin 0 -> 140844 bytes user_libs/landmines/docs/images/PMN.png | Bin 0 -> 313088 bytes user_libs/materials/docs/README.rst | 6 +- user_libs/stltovoxel/docs/README.rst | 14 +- .../old => old-Kartik}/Mont_Blanc.py | 0 .../old => old-Kartik}/Mont_Blanc.vtr | Bin .../{examples/old => old-Kartik}/amphora.py | 0 .../{examples/old => old-Kartik}/amphora.vtr | Bin .../{docs => old-Kartik}/docs_lasoMax.ipynb | 0 .../docs_laso_images/Bunny_PointCloud_Stl.png | Bin .../docs_laso_images/alp_stl.png | Bin .../docs_laso_images/alps_point_cloud.png | Bin .../docs_laso_images/amphora.png | Bin .../docs_laso_images/amphora_stl.png | Bin .../docs_laso_images/bunny_pointcloud.png | Bin .../docs_laso_images/bunny_voxel.png | Bin .../docs_laso_images/dubai.png | Bin .../docs_laso_images/dubai_stl.png | Bin .../docs_laso_images/house.png | Bin .../docs_laso_images/house_stl.png | Bin .../docs_laso_images/mont_blanc.png | Bin .../docs_laso_images/mont_blanc_2.png | Bin .../docs_laso_images/mont_blanc_stl.png | Bin .../docs_laso_images/saint_michel_island.png | Bin .../saint_michel_island_stl.png | Bin .../docs_laso_images/saint_michel_real.jpeg | Bin .../{examples/old => old-Kartik}/dubai.py | 0 .../{examples/old => old-Kartik}/dubai.vtr | Bin .../{examples/old => old-Kartik}/house.py | 0 .../{examples/old => old-Kartik}/house.vtr | Bin .../old => old-Kartik}/newyorkcity.py | 0 .../old => old-Kartik}/newyorkcity.vtr | Bin user_libs/stltovoxel/stltovoxel.py | 1 - 67 files changed, 490 insertions(+), 631 deletions(-) delete mode 100644 user_libs/DebyeFit/Readme.rst create mode 100644 user_libs/DebyeFit/docs/README.rst rename user_libs/DebyeFit/docs/{ => images}/epsilon.png (100%) rename user_libs/DebyeFit/docs/{optimization.md => optimization.rst} (59%) delete mode 100644 user_libs/DebyeFit/docs/relaxation.md create mode 100644 user_libs/DebyeFit/docs/relaxation.rst delete mode 100644 user_libs/DebyeFit/examples/Readme.md create mode 100644 user_libs/landmines/PMA_1x1x1.h5 create mode 100644 user_libs/landmines/PMA_2x2x2.h5 create mode 100644 user_libs/landmines/PMA_materials.txt create mode 100644 user_libs/landmines/PMN_1x1x1.h5 create mode 100644 user_libs/landmines/PMN_2x2x2.h5 create mode 100644 user_libs/landmines/PMN_materials.txt create mode 100644 user_libs/landmines/PMN_materials2.txt create mode 100644 user_libs/landmines/TS50_1x1x1.h5 create mode 100644 user_libs/landmines/TS50_2x2x2.h5 create mode 100644 user_libs/landmines/TS50_materials.txt create mode 100644 user_libs/landmines/can_1x1x1.h5 create mode 100644 user_libs/landmines/can_2x2x2.h5 create mode 100644 user_libs/landmines/can_materials.txt create mode 100644 user_libs/landmines/docs/README.rst create mode 100644 user_libs/landmines/docs/images/PMA.png create mode 100644 user_libs/landmines/docs/images/PMN.png rename user_libs/stltovoxel/{examples/old => old-Kartik}/Mont_Blanc.py (100%) rename user_libs/stltovoxel/{examples/old => old-Kartik}/Mont_Blanc.vtr (100%) rename user_libs/stltovoxel/{examples/old => old-Kartik}/amphora.py (100%) rename user_libs/stltovoxel/{examples/old => old-Kartik}/amphora.vtr (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_lasoMax.ipynb (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/Bunny_PointCloud_Stl.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/alp_stl.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/alps_point_cloud.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/amphora.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/amphora_stl.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/bunny_pointcloud.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/bunny_voxel.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/dubai.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/dubai_stl.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/house.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/house_stl.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/mont_blanc.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/mont_blanc_2.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/mont_blanc_stl.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/saint_michel_island.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/saint_michel_island_stl.png (100%) rename user_libs/stltovoxel/{docs => old-Kartik}/docs_laso_images/saint_michel_real.jpeg (100%) rename user_libs/stltovoxel/{examples/old => old-Kartik}/dubai.py (100%) rename user_libs/stltovoxel/{examples/old => old-Kartik}/dubai.vtr (100%) rename user_libs/stltovoxel/{examples/old => old-Kartik}/house.py (100%) rename user_libs/stltovoxel/{examples/old => old-Kartik}/house.vtr (100%) rename user_libs/stltovoxel/{examples/old => old-Kartik}/newyorkcity.py (100%) rename user_libs/stltovoxel/{examples/old => old-Kartik}/newyorkcity.vtr (100%) diff --git a/.gitignore b/.gitignore index 3cc11ce1..bc19bbe2 100644 --- a/.gitignore +++ b/.gitignore @@ -25,10 +25,5 @@ docs/.buildinfo # Craig's files .vscode -user_libs/landmines/* -user_libs/rocks/* -user_models/GPU-paper-landmines/ -user_models/IWAGPR2017-challenge/ -user_models/to-update/ tests/*.out tests/*.png diff --git a/docs/source/references.rst b/docs/source/references.rst index bb812bf1..50eb158e 100644 --- a/docs/source/references.rst +++ b/docs/source/references.rst @@ -14,6 +14,7 @@ References .. [GIA1997] Giannopoulos, A. (1997). The investigation of Transmission-Line Matrix and Finite-Difference Time-Domain Methods for the Forward Problem of Ground Probing Radar, D.Phil thesis, Department of Electronics, University of York, UK. (http://etheses.whiterose.ac.uk/id/eprint/2443) .. [GIA2012] Giannopoulos, A. (2012). Unsplit implementation of higher order PMLs. Antennas and Propagation, IEEE Transactions on, 60(3), 1479-1485. (http://dx.doi.org/10.1109/tap.2011.2180344) .. [IRE2013] Ireland, D., & Abbosh, A. (2013). Modeling human head at microwave frequencies using optimized Debye models and FDTD method. Antennas and Propagation, IEEE Transactions on, 61(4), 2352-2355. (http://dx.doi.org/10.1109/tap.2013.2242037) +.. [KEL2007] Kelley, D. F., Destan, T. J., & Luebbers, R. J. (2007). Debye function expansions of complex permittivity using a hybrid particle swarm-least squares optimization approach. IEEE Transactions on Antennas and propagation, 55(7), 1999-2005. (https://doi.org/10.1109/TAP.2007.900230) .. [KUN1993] Kunz, K. S., & Luebbers, R. J. (1993). The finite difference time domain method for electromagnetics. CRC press. .. [LI2013] Li, J., Guo, L. X., Jiao, Y. C., & Wang, R. (2013). Composite scattering of a plasma-coated target above dispersive sea surface by the ADE-FDTD method. Geoscience and Remote Sensing Letters, IEEE, 10(1), 4-8. (http://dx.doi.org/10.1109/lgrs.2012.2189751) .. [LUE1994] Luebbers, R., Steich, D., & Kunz, K. (1993). FDTD calculation of scattering from frequency-dependent materials. Antennas and Propagation, IEEE Transactions on, 41(9), 1249-1257. (http://dx.doi.org/10.1109/8.247751) diff --git a/gprMax/hash_cmds_file.py b/gprMax/hash_cmds_file.py index 7f8652c7..f32efffd 100644 --- a/gprMax/hash_cmds_file.py +++ b/gprMax/hash_cmds_file.py @@ -210,8 +210,6 @@ def check_cmd_names(processedlines, checkessential=True): # - these will be lists within the dictionary multiplecmds = {key: [] for key in ['#geometry_view', '#geometry_objects_write', '#material', - '#havriliak_negami', '#jonscher', - '#crim', '#raw_data', '#soil_peplinski', '#add_dispersion_debye', '#add_dispersion_lorentz', diff --git a/gprMax/hash_cmds_multiuse.py b/gprMax/hash_cmds_multiuse.py index e3a386bd..bfb7d6db 100644 --- a/gprMax/hash_cmds_multiuse.py +++ b/gprMax/hash_cmds_multiuse.py @@ -17,12 +17,8 @@ # along with gprMax. If not, see . import logging -import os -os.path.join(os.path.dirname(__file__), '..', 'user_libs', 'DebyeFit') -from user_libs.DebyeFit import (HavriliakNegami, Jonscher, Crim, Rawdata) - -from .cmds_multiuse import (PMLCFS, AddDebyeDispersion, AddDrudeDispersion, +from .cmds_multiuse import (AddDebyeDispersion, AddDrudeDispersion, AddLorentzDispersion, GeometryObjectsWrite, GeometryView, HertzianDipole, MagneticDipole, Material, Rx, RxArray, Snapshot, SoilPeplinski, @@ -174,105 +170,6 @@ def process_multicmds(multicmds): scene_objects.append(snapshot) - cmdname = '#havriliak_negami' - if multicmds[cmdname] is not None: - for cmdinstance in multicmds[cmdname]: - tmp = cmdinstance.split() - - if len(tmp) != 12 and len(tmp) != 13: - logger.exception("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires either twelve or thirteen parameters') - raise ValueError - seed = None - if len(tmp) == 13: - seed = int(tmp[12]) - - setup = HavriliakNegami(f_min=float(tmp[0]), f_max=float(tmp[1]), - alpha=float(tmp[2]), beta=float(tmp[3]), - e_inf=float(tmp[4]), de=float(tmp[5]), tau_0=float(tmp[6]), - sigma=float(tmp[7]), mu=float(tmp[8]), mu_sigma=float(tmp[9]), - number_of_debye_poles=int(tmp[10]), material_name=tmp[11], - optimizer_options={'seed': seed}) - _, properties = setup.run() - - multicmds['#material'].append(properties[0].split(':')[1].strip(' \t\n')) - multicmds['#add_dispersion_debye'].append(properties[1].split(':')[1].strip(' \t\n')) - - cmdname = '#jonscher' - if multicmds[cmdname] is not None: - for cmdinstance in multicmds[cmdname]: - tmp = cmdinstance.split() - - if len(tmp) != 11 and len(tmp) != 12: - logger.exception("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires either eleven or twelve parameters') - raise ValueError - seed = None - if len(tmp) == 12: - seed = int(tmp[11]) - - setup = Jonscher(f_min=float(tmp[0]), f_max=float(tmp[1]), - e_inf=float(tmp[2]), a_p=float(tmp[3]), - omega_p=float(tmp[4]), n_p=float(tmp[5]), - sigma=float(tmp[6]), mu=float(tmp[7]), mu_sigma=float(tmp[8]), - number_of_debye_poles=int(tmp[9]), material_name=tmp[10], - optimizer_options={'seed': seed}) - _, properties = setup.run() - - multicmds['#material'].append(properties[0].split(':')[1].strip(' \t\n')) - multicmds['#add_dispersion_debye'].append(properties[1].split(':')[1].strip(' \t\n')) - - cmdname = '#crim' - if multicmds[cmdname] is not None: - for cmdinstance in multicmds[cmdname]: - tmp = cmdinstance.split() - - if len(tmp) != 10 and len(tmp) != 11: - logger.exception("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires either ten or eleven parameters') - raise ValueError - seed = None - if len(tmp) == 11: - seed = int(tmp[10]) - - if (tmp[3][0] != '[' and tmp[3][-1] != ']') or (tmp[4][0] != '[' and tmp[4][-1] != ']'): - logger.exception("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires list at 6th and 7th position') - raise ValueError - vol_frac = [float(i) for i in tmp[3].strip('[]').split(',')] - material = [float(i) for i in tmp[4].strip('[]').split(',')] - if len(material) % 3 != 0: - logger.exception("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' each material requires three parameters: e_inf, de, tau_0') - raise ValueError - materials = [material[n:n+3] for n in range(0, len(material), 3)] - - setup = Crim(f_min=float(tmp[0]), f_max=float(tmp[1]), a=float(tmp[2]), - volumetric_fractions=vol_frac, materials=materials, - sigma=float(tmp[5]), mu=float(tmp[6]), mu_sigma=float(tmp[7]), - number_of_debye_poles=int(tmp[8]), material_name=tmp[9], - optimizer_options={'seed': seed}) - _, properties = setup.run() - - multicmds['#material'].append(properties[0].split(':')[1].strip(' \t\n')) - multicmds['#add_dispersion_debye'].append(properties[1].split(':')[1].strip(' \t\n')) - - cmdname = '#raw_data' - if multicmds[cmdname] is not None: - for cmdinstance in multicmds[cmdname]: - tmp = cmdinstance.split() - - if len(tmp) != 6 and len(tmp) != 7: - logger.exception("'" + cmdname + ': ' + ' '.join(tmp) + "'" + ' requires either six or seven parameters') - raise ValueError - seed = None - if len(tmp) == 7: - seed = int(tmp[6]) - - setup = Rawdata(filename=tmp[0], sigma=float(tmp[1]), - mu=float(tmp[2]), mu_sigma=float(tmp[3]), - number_of_debye_poles=int(tmp[4]), material_name=tmp[5], - optimizer_options={'seed': seed}) - _, properties = setup.run() - - multicmds['#material'].append(properties[0].split(':')[1].strip(' \t\n')) - multicmds['#add_dispersion_debye'].append(properties[1].split(':')[1].strip(' \t\n')) - cmdname = '#material' if multicmds[cmdname] is not None: for cmdinstance in multicmds[cmdname]: diff --git a/tools/convert_png2h5.py b/tools/convert_png2h5.py index 1e6a5567..3fe64411 100644 --- a/tools/convert_png2h5.py +++ b/tools/convert_png2h5.py @@ -17,6 +17,7 @@ # along with gprMax. If not, see . import argparse +import logging import os import h5py @@ -24,6 +25,8 @@ import matplotlib.image as mpimg import matplotlib.pyplot as plt import numpy as np +logger = logging.getLogger(__name__) + class Cursor(object): """Get RGB(A) value of pixel at x,y coordinate of button press and store in a list.""" @@ -50,7 +53,7 @@ class Cursor(object): pixel = np.floor(pixel * 255).astype(np.int16) # Convert pixel values from float (0-1) to integer (0-255) match = pixel_match(materials, pixel) if match is False: - print('x, y: {} {} px; RGB: {}; material ID: {}'.format(int(x), int(y), pixel[:-1], len(self.materials))) + logger.info('x, y: {} {} px; RGB: {}; material ID: {}'.format(int(x), int(y), pixel[:-1], len(self.materials))) materials.append(pixel) def pixel_match(pixellist, pixeltest): @@ -87,8 +90,8 @@ if __name__ == "__main__": imdata = np.rot90(im, k=3) # Rotate 90CW imdata = np.floor(imdata * 255).astype(np.int16) # Convert pixel values from float (0-1) to integer (0-255) - print('Reading PNG image file: {}'.format(os.path.split(args.imagefile)[1])) - print(' 1. Select discrete material colours by clicking on parts of the image.\n 2. When all materials have been selected close the image.') + logger.info('Reading PNG image file: {}'.format(os.path.split(args.imagefile)[1])) + logger.info(' 1. Select discrete material colours by clicking on parts of the image.\n 2. When all materials have been selected close the image.') # List to hold selected RGB values from image materials = [] @@ -123,4 +126,4 @@ if __name__ == "__main__": # Write data to file fout.create_dataset('data', data=data) - print('Written HDF5 file: {}'.format(os.path.split(hdf5file)[1])) + logger.info('Written HDF5 file: {}'.format(os.path.split(hdf5file)[1])) diff --git a/tools/plot_antenna_params.py b/tools/plot_antenna_params.py index 213723b8..8ed09f89 100644 --- a/tools/plot_antenna_params.py +++ b/tools/plot_antenna_params.py @@ -54,9 +54,9 @@ def calculate_antenna_params(filename, tltxnumber=1, tlrxnumber=None, rxnumber=N time = np.linspace(0, (iterations - 1) * dt, num=iterations) df = 1 / np.amax(time) - print(f'Time window: {np.amax(time):g} s ({iterations} iterations)') - print(f'Time step: {dt:g} s') - print(f'Frequency bin spacing: {df:g} Hz') + logger.info(f'Time window: {np.amax(time):g} s ({iterations} iterations)') + logger.info(f'Time step: {dt:g} s') + logger.info(f'Frequency bin spacing: {df:g} Hz') # Read/calculate voltages and currents from transmitter antenna tltxpath = '/tls/tl' + str(tltxnumber) + '/' @@ -175,11 +175,11 @@ def mpl_plot(filename, time, freqs, Vinc, Vincp, Iinc, Iincp, Vref, Vrefp, Iref, # Print some useful values from s11, and input impedance s11minfreq = np.where(s11[pltrange] == np.amin(s11[pltrange]))[0][0] - print(f's11 minimum: {np.amin(s11[pltrange]):g} dB at {freqs[s11minfreq + pltrangemin]:g} Hz') - print(f'At {freqs[s11minfreq + pltrangemin]:g} Hz...') - print(f'Input impedance: {np.abs(zin[s11minfreq + pltrangemin]):.1f}{zin[s11minfreq + pltrangemin].imag:+.1f}j Ohms') - # print(f'Input admittance (mag): {np.abs(yin[s11minfreq + pltrangemin]):g} S') - # print(f'Input admittance (phase): {np.angle(yin[s11minfreq + pltrangemin], deg=True):.1f} deg') + logger.info(f's11 minimum: {np.amin(s11[pltrange]):g} dB at {freqs[s11minfreq + pltrangemin]:g} Hz') + logger.info(f'At {freqs[s11minfreq + pltrangemin]:g} Hz...') + logger.info(f'Input impedance: {np.abs(zin[s11minfreq + pltrangemin]):.1f}{zin[s11minfreq + pltrangemin].imag:+.1f}j Ohms') + # logger.info(f'Input admittance (mag): {np.abs(yin[s11minfreq + pltrangemin]):g} S') + # logger.info(f'Input admittance (phase): {np.angle(yin[s11minfreq + pltrangemin], deg=True):.1f} deg') # Figure 1 # Plot incident voltage diff --git a/tools/plot_source_wave.py b/tools/plot_source_wave.py index 5eabcf94..07ad432b 100644 --- a/tools/plot_source_wave.py +++ b/tools/plot_source_wave.py @@ -81,23 +81,23 @@ def mpl_plot(w, timewindow, dt, iterations, fft=False): waveform[timeiter.index] = w.calculate_value(timeiter[0], dt) timeiter.iternext() - print('Waveform characteristics...') - print(f'Type: {w.type}') - print(f'Maximum (absolute) amplitude: {np.max(np.abs(waveform)):g}') + logger.info('Waveform characteristics...') + logger.info(f'Type: {w.type}') + logger.info(f'Maximum (absolute) amplitude: {np.max(np.abs(waveform)):g}') if w.freq and not w.type == 'gaussian': - print(f'Centre frequency: {w.freq:g} Hz') + logger.info(f'Centre frequency: {w.freq:g} Hz') if (w.type == 'gaussian' or w.type == 'gaussiandot' or w.type == 'gaussiandotnorm' or w.type == 'gaussianprime' or w.type == 'gaussiandoubleprime'): delay = 1 / w.freq - print(f'Time to centre of pulse: {delay:g} s') + logger.info(f'Time to centre of pulse: {delay:g} s') elif w.type == 'gaussiandotdot' or w.type == 'gaussiandotdotnorm' or w.type == 'ricker': delay = np.sqrt(2) / w.freq - print(f'Time to centre of pulse: {delay:g} s') + logger.info(f'Time to centre of pulse: {delay:g} s') - print(f'Time window: {timewindow:g} s ({iterations} iterations)') - print(f'Time step: {dt:g} s') + logger.info(f'Time window: {timewindow:g} s ({iterations} iterations)') + logger.info(f'Time step: {dt:g} s') if fft: # FFT diff --git a/user_libs/AustinManWoman/docs/README.rst b/user_libs/AustinManWoman/docs/README.rst index c9a4a92b..37107339 100644 --- a/user_libs/AustinManWoman/docs/README.rst +++ b/user_libs/AustinManWoman/docs/README.rst @@ -17,7 +17,7 @@ Information `AustinMan and AustinWoman `_ are open source electromagnetic voxel models of the human body, which are developed by the `Computational Electromagnetics Group `_ at `The University of Texas at Austin `_. The models are based on data from the `National Library of Medicine’s Visible Human Project `_. -.. figure:: images/user_libs/AustinMan_head.png +.. figure:: images/AustinMan_head.png :width: 600 px FDTD geometry mesh showing the head of the AustinMan model (2x2x2mm :math:`^3`). @@ -37,7 +37,7 @@ AustinWoman 2x2x2 342 x 187 x 865 AustinWoman 1x1x1 683 x 374 x 1730 =========== ========================== ================== -Package overview +Package contents ================ .. code-block:: none @@ -56,8 +56,8 @@ Package overview * ``head_only_h5.py`` is a script to assist with creating a model of only the head from a full body AustinMan/Woman model. -How to use the models -===================== +How to use the package +====================== The AustinMan and AustinWoman models themselves are not included in the user libraries sub-package. diff --git a/user_libs/DebyeFit/Debye_Fit.py b/user_libs/DebyeFit/Debye_Fit.py index 98155d4e..91149ae5 100644 --- a/user_libs/DebyeFit/Debye_Fit.py +++ b/user_libs/DebyeFit/Debye_Fit.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015-2021, Iraklis Giannakis and Sylwia Majchrowska +# Copyright (C) 2015-2022, Iraklis Giannakis and Sylwia Majchrowska # # This module is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. # To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/. diff --git a/user_libs/DebyeFit/Readme.rst b/user_libs/DebyeFit/Readme.rst deleted file mode 100644 index 8523afe7..00000000 --- a/user_libs/DebyeFit/Readme.rst +++ /dev/null @@ -1,356 +0,0 @@ -Fitting multi-pole Debye model to dielectric data -================================================= - -All electromagnetic phenomena are governed by the Maxwell's equations, which describing how electric and magnetic fields are distributed due to charges and currents, -and how they are changing in time. gprMax is open source software that simulates electromagnetic wave propagation by using -Yee's algorithm to solve (3+1)D Maxwell’s equations with Finite-Difference Time-Domain (FDTD) method. -The behavior of the electromagnetic wave is closely dependent on the material in which it propagates. -Some dispersive media have quite complex electromagnetic properties depending on the wavelength. -This, for example, means that for different frequencies the wave can propagate with a different speed in different materials. -This significantly affects the solver’s output. The main goal of the GSoC 2021 project was to enhance series of scripts, -which modelled electromagnetic properties of the variety range of materials. - -Multi-pole Debye model -====================== - -Electric permittivity is a complex function with both real and imaginary parts. -In general, as a hard and fast rule, the real part dictates the velocity of the medium while the imaginary part is related to the electromagnetic losses. -The generic form of dispersive media takes a form of - -.. math:: - - \epsilon(\omega) = \epsilon^{'}(\omega) - j\epsilon^{''}(\omega), - -where :math:`\omega` is the angular frequency, :math:`\epsilon^{'}` and :math:`\epsilon^{''}` are the real and imaginary parts of the permittivity respectively. - -In the ``user_libs`` sub-package is a module called ``DebyeFit`` which can be used to fit a multi-Debye expansion to dielectric data, defined as - -.. math:: - - \epsilon(\omega) = \epsilon_{\infty} + \sum_{i=1}^{N}\frac{\Delta\epsilon_{i}}{1+j\omega t_{0,i}}, - -where :math:`\epsilon(\omega)` is frequency dependent dielectric permittivity, :math:`\Delta\epsilon` - difference between the real permittivity at zero and infinity frequency. -:math:`\tau_{0}` is relaxation time (s), :math:`\epsilon_{\infty}` - real part of relative permittivity at infinity frequency, and :math:`N` is number of the Debye poles. - -The user can choose between Havriliak-Negami, Jonscher, Complex Refractive Index Mixing models, and arbitrary dielectric data derived experimentally -or calculated using some other function to fit the data to a multi-Debye expansion. - -
- -
- -License -======= - -``DebyeFit`` sub-package is currently released under the `GNU General Public License v3 or higher `_. - -Code structure -============== - -The ``DebyeFit`` sub-package contains two main scripts: - -* ```Debye_fit.py``` with definition of all Relaxation functions classes, -* ```optimization.py``` with definition of three choosen global optimization methods. - - -Class Relaxation -################ - -This class is designed for modelling different relaxation functions, like Havriliak-Negami (```Class HavriliakNegami```), Jonscher (```Class Jonscher```), Complex Refractive Index Mixing (```Class CRIM```) models, and arbitrary dielectric data derived experimentally -or calculated using some other function (```Class Rawdata```). - -More about ``Class Relaxation`` structure can be found in [relaxation.md](docs/relaxation.md). - -Havriliak-Negami Function -************************* - -The Havriliak–Negami relaxation is an empirical modification of the Debye relaxation model in electromagnetism, which in additionto the Debye equation has two exponential parameters - -.. math:: - - \epsilon(\omega) = \epsilon_{\infty} + \frac{\Delta\epsilon}{\left(1+\left(j\omega t_{0}\right)^{a}\right)^{b}} - - -The ``HavriliakNegami`` class has the following structure: - -.. code-block:: none - - HavriliakNegami(f_min, f_max, - alpha, beta, e_inf, de, tau_0, - sigma, mu, mu_sigma, material_name, - number_of_debye_poles=-1, f_n=50, - plot=False, save=True, - optimizer=PSO_DLS, - optimizer_options={}) - - -* ``f_min`` is first bound of the frequency range used to approximate the given function (Hz), -* ``f_max`` is second bound of the frequency range used to approximate the given function (Hz), -* ``alpha`` is real positive float number which varies 0 < $\alpha$ < 1, -* ``beta`` is real positive float number which varies 0 < $\beta$ < 1, -* ``e_inf`` is a real part of relative permittivity at infinity frequency, -* ``de`` is a difference between the real permittivity at zero and infinity frequency, -* ``tau_0`` is a relaxation time (s), -* ``sigma`` is a conductivity (Siemens/metre), -* ``mu`` is a relative permeability, -* ``mu_sigma`` is a magnetic loss (Ohms/metre), -* ``material_name`` is definition of material name, -* ``number_of_debye_poles`` is choosen number of Debye poles, -* ``f_n`` is choosen number of frequences, -* ``plot`` is a switch to turn on the plotting, -* ``save`` is a switch to turn on the saving final material properties, -* ``optimizer`` is a choosen optimizer to fit model to dielectric data, -* ``optimizer_options`` is a dict for options of choosen optimizer. - -Jonscher Function -**************** - -Jonscher function is mainly used to describe the dielectric properties of concrete and soils. The frequency domain expression of Jonscher -function is given by - -.. math:: - - \epsilon(\omega) = \epsilon_{\infty} + a_{p}*\left( -j*\frac{\omega}{\omega_{p}} \right)^{n} - - -The ``Jonscher`` class has the following structure: - -.. code-block:: none - - Jonscher(f_min, f_max, - e_inf, a_p, omega_p, n_p, - sigma, mu, mu_sigma, - material_name, number_of_debye_poles=-1, - f_n=50, plot=False, save=True, - optimizer=PSO_DLS, - optimizer_options={}) - - -* ``f_min`` is first bound of the frequency range used to approximate the given function (Hz), -* ``f_max`` is second bound of the frequency range used to approximate the given function (Hz), -* ``e_inf`` is a real part of relative permittivity at infinity frequency, -* ``a_p``` is a Jonscher parameter. Real positive float number, -* ``omega_p`` is a Jonscher parameter. Real positive float number, -* ``n_p`` Jonscher parameter, 0 < n_p < 1. - -Complex Refractive Index Mixing (CRIM) Function -*********************************************** - -CRIM is the most mainstream approach for estimating the bulk permittivity of heterogeneous materials and has been widely applied for GPR applications. The function takes form of - -.. math:: - - \epsilon(\omega)^{d} = \sum_{i=1}^{m}f_{i}\epsilon_{m,i}(\omega)^{d} - - -The ``CRIM`` class has the following structure: - -.. code-block:: none - - CRIM(f_min, f_max, a, volumetric_fractions, - materials, sigma, mu, mu_sigma, material_name, - number_of_debye_poles=-1, f_n=50, - plot=False, save=True, - optimizer=PSO_DLS, - optimizer_options={}) - - -* ``f_min`` is first bound of the frequency range used to approximate the given function (Hz), -* ``f_max`` is second bound of the frequency range used to approximate the given function (Hz), -* ``a`` is a shape factor, -* ``volumetric_fractions`` is a volumetric fraction for each material, -* ``materials`` are arrays of materials properties, for each material [e_inf, de, tau_0]. - -Rawdata Class -************* - -The present package has the ability to model dielectric properties obtained experimentally by fitting multi-Debye functions to data given from a file. -The format of the file should be three columns. The first column contains the frequencies (Hz) associated with the electric permittivity point. -The second column contains the real part of the relative permittivity. The third column contains the imaginary part of the relative permittivity. -The columns should separated by coma by default (is it posible to define different separator). - -The ``Rawdata`` class has the following structure: - -.. code-block:: none - - Rawdata(self, filename, - sigma, mu, mu_sigma, - material_name, number_of_debye_poles=-1, - f_n=50, delimiter =',', - plot=False, save=True, - optimizer=PSO_DLS, - optimizer_options={}) - - -* ``filename`` is a path to text file which contains three columns, -* ``delimiter`` is a separator for three data columns. - -Class Optimizer -############### - -This class supports global optimization algorithms (particle swarm, duall annealing, evolutionary algorithms) for finding an optimal set of relaxation times that minimise the error between the actual and the approximated electric permittivity and calculate optimised weights for the given relaxation times. -Code written here is mainly based on external libraries, like ```scipy``` and ```pyswarm```. - -More about ``Class Optimizer`` structure can be found in [optimization.md](docs/optimization.md). - -PSO_DLS Class -************* - -Creation of hybrid Particle Swarm-Damped Least Squares optimisation object with predefined parameters. -The current code is a modified edition of the pyswarm package which can be found at https://pythonhosted.org/pyswarm/. - -DA_DLS Class -************ - -Creation of Dual Annealing-Damped Least Squares optimisation object with predefined parameters. The current class is a modified edition of the scipy.optimize package which can be found at: -https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.dual_annealing.html#scipy.optimize.dual_annealing. - -DE_DLS Class -************ - -Creation of Differential Evolution-Damped Least Squares object with predefined parameters. The current class is a modified edition of the scipy.optimize package which can be found at: -https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.differential_evolution.html#scipy.optimize.differential_evolution. - -DLS function -************ - -Finding the weights using a non-linear least squares (LS) method, the Levenberg–Marquardt algorithm (LMA or just LM), also known as the damped least-squares (DLS) method. - -Examples -######## - -In directory [examples](./examles), we provided jupyter notebooks, scripts and data to show how use stand alone script ```DebyeFit.py```: - -* ```example_DebyeFitting.ipynb```: simple cases of using all available implemented relaxation functions, -* ```example_BiologicalTissues.ipynb```: simple cases of using Cole-Cole function for biological tissues, -* ```example_ColeCole.py```: simple cases of using Cole-Cole function in case of 3, 5 and automatically chosen number of Debye poles, -* ```Test.txt```: raw data for testing ```Rawdata Class```, file contains 3 columns: the first column contains the frequencies (Hz) associated with the value of the permittivity, second column contains the real part of the relative permittivity, and the third one the imaginary part of the relative permittivity. The columns should separated by comma. - -Dispersive material commands -============================ - -gprMax has implemented an optimisation approach to fit a multi-Debye expansion to dielectric data. -The user can choose between Havriliak-Negami, Johnsher and Complex Refractive Index Mixing models, fit arbitrary dielectric data derived experimentally or calculated using some other function. -Notice that Havriliak-Negami is an inclusive function that holds as special cases the widely-used **Cole-Cole** and **Cole-Davidson** functions. - -.. note:: - - The technique employed here as a default is a hybrid linear-nonlinear optimisation proposed by Kelley et. al (2007). - Their method was slightly adjusted to overcome some instability issues and thus making the process more robust and faster. - In particular, in the case of negative weights we inverse the sign in order to introduce a large penalty in the optimisation process thus indirectly constraining the weights - to be always positive. This made dumbing factors unnecessary and consequently they were removed from the algorithm. Furthermore we added the real part to the cost action - to avoid possible instabilities to arbitrary given functions that does not follow the Kramers–Kronig relationship. - -.. warning:: - - * The fitting accuracy depends on the number of the Debye poles as well as the fitted function. It is advised to check if the resulted accuracy is sufficient for your application. - - * Increasing the number of Debye poles will make the approximation more accurate but it will increase the overall computational resources of FDTD. - -#havriliak_negami: -################## - -Allows you to model dielectric properties by fitting multi-Debye functions to Havriliak-Negami function. The syntax of the command is: - -.. code-block:: none - - #havriliak_negami: f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 i1 str1 [i2] - -* ``f1`` is the lower frequency bound (Hz). -* ``f2`` is the upper frequency bound (Hz). -* ``f3`` is the :math:`\alpha` parameter beetwen bonds :math:`\left(0 < \alpha < 1 \right)`. -* ``f4`` is the :math:`\beta` parameter beetwen bonds :math:`\left(0 < \beta < 1 \right)`. -* ``f5`` is the real relative permittivity at infinity frequency, :math:`\epsilon_{\infty}`. -* ``f6`` is the difference between the real permittivity at zero and infinity frequency, :math:`\Delta\epsilon`. -* ``f7`` is the relaxation time (s), :math:`t_{0}`. -* ``f8`` is the conductivity (Siemens/metre), :math:`\sigma` -* ``f9`` is the relative permeability, :math:`\mu_r` -* ``f10`` is the magnetic loss (Ohms/metre), :math:`\sigma_*` -* ``i1`` is the number of Debye poles, set to -1 will be automatically calculated tends to minimize the relative absolut error. -* ``str1`` is an identifier for the material. -* ``i2`` is an optional parameter which controls the seeding of the random number generator used in stochastic global optimizator. By default (if you don't specify this parameter) the random number generator will be seeded by trying to read data from ``/dev/urandom`` (or the Windows analogue) if available or from the clock otherwise. - - -For example ``#havriliak_negami: 1e4 1e11 0.3 1 3.4 2.7 0.8e-10 4.5e-4 1 0 5 dry_sand`` creates a material called ``dry_sand``, and approximates using five Debye poles a Cole-Cole function with :math:`\epsilon_{\infty}=3.4`, :math:`\Delta\epsilon=2.7`, :math:`t_{0}=8^{-9}` and :math:`a=0.3`. -The resulting output is the set of gprMax commands and optional a plot with the actual and the approximated Cole-Cole function. - -#jonscher: -########## - -Allows you to model dielectric properties by fitting multi-Debye functions to Jonscher function. The syntax of the command is: - -.. code-block:: none - - #jonscher: f1 f2 f3 f4 f5 f6 f7 f8 f9 i1 str1 [i2] - -* ``f1`` is the lower frequency bound (in Hz). -* ``f2`` is the upper frequency bound (in Hz). -* ``f3`` is the real relative permittivity at infinity frequency, :math:`\epsilon_{\infty}`. -* ``f4`` is the :math:`a_{p}` parameter. -* ``f5`` is the :math:`\omega_{p}` parameter. -* ``f6`` is the :math:`n_{p}` parameter. -* ``f7`` is the conductivity (Siemens/metre), :math:`\sigma` -* ``f8`` is the relative permeability, :math:`\mu_r` -* ``f9`` is the magnetic loss (Ohms/metre), :math:`\sigma_*` -* ``i1`` is the number of Debye poles, set to -1 will be automatically calculated tends to minimize the relative absolut error. -* ``str1`` is an identifier for the material. -* ``i2`` is an optional parameter which controls the seeding of the random number generator used in stochastic global optimizator. By default (if you don't specify this parameter) the random number generator will be seeded by trying to read data from ``/dev/urandom`` (or the Windows analogue) if available or from the clock otherwise. - -For example ``#jonscher: 1e6 1e-5 4.39 7.49 5e-10 0.4 0.1 1 0.1 4 Material_Jonscher`` creates a material called ``Material_Jonscher``, and approximates using four Debye poles a Johnsher function with :math:`\epsilon_{\infty}=4.39`, :math:`a_{p}=7.49`, :math:`\omega_{p}=0.5\times 10^{9}` and :math:`n=0.4`. -The resulting output is the set of gprMax commands and optional a plot with the actual and the approximated Johnsher function. - -#crim: -###### - -Allows you to model dielectric properties by fitting multi-Debye functions to CRIM function. The syntax of the command is: - -.. code-block:: none - - #crim: f1 f2 f3 v1 v2 f4 f5 f6 i1 str1 [i2] - -* ``f1`` is the lower frequency bound (in Hz). -* ``f2`` is the upper frequency bound (in Hz). -* ``f3`` is the shape factor, :math:`a` -* ``v1`` is the vector (paramiter given in input file with `[]`) of volumetric fractions [f1, f2 .... ]. The nuber of paramiters depend on number of materials. -* ``v2`` is the vector (paramiter given in input file with `[]`) containing the materials properties [:math:`\epsilon_{1\infty}`, :math:`\Delta\epsilon_{1}`, :math:`t_{0}_{1}`, :math:`\epsilon_{2\infty}`, :math:`\Delta\epsilon_{2}`, :math:`t_{0}_{2}` .... ]. The number of material vector must be divisible by three. -* ``f4`` is the conductivity (Siemens/metre), :math:`\sigma` -* ``f5`` is the relative permeability, :math:`\mu_r` -* ``f6`` is the magnetic loss (Ohms/metre), :math:`\sigma_*` -* ``i1`` is the number of Debye poles, set to -1 will be automatically calculated tends to minimize the relative absolut error. -* ``str1`` is an identifier for the material. -* ``i2`` is an optional parameter which controls the seeding of the random number generator used in stochastic global optimizator. By default (if you don't specify this parameter) the random number generator will be seeded by trying to read data from ``/dev/urandom`` (or the Windows analogue) if available or from the clock otherwise. - -For example ``#crim: 1e-1 1e-9 0.5 [0.5,0.1,0.4] [3,25,1e-8,3,25,1e-9,1,10,1e-10] 0 1 0 5 CRIM`` creates a material called ``CRIM``, and approximates using five Debye poles the following CRIM function - -.. math:: - \epsilon(\omega)^{0.5} = \sum_{i=1}^{m}f_{i}\epsilon_{m,i}(\omega)^{0.5} -.. math:: - f = [0.5, 0.1, 0.4] -.. math:: - \epsilon_{m,1} = 3 + \frac{25}{1+j\omega\times 10^{-8}} -.. math:: - \epsilon_{m,2} = 3 + \frac{25}{1+j\omega\times 10^{-9}} -.. math:: - \epsilon_{m,3} = 1 + \frac{10}{1+j\omega\times 10^{-10}} - -The resulting output is the set of gprMax commands and optional a plot with the actual and the approximated CRIM function. - -#raw_data: -########## - -Allows you to model dielectric properties obtained experimentally by fitting multi-Debye functions to data given from a file. The syntax of the command is: - -.. code-block:: none - - #raw_data: file1 f1 f2 f3 i1 str1 [i2] - -* ``file1`` is an path to text file with experimental data points. -* ``f1`` is the conductivity (Siemens/metre), :math:`\sigma` -* ``f2`` is the relative permeability, :math:`\mu_r` -* ``f3`` is the magnetic loss (Ohms/metre), :math:`\sigma_*` -* ``i1`` is the number of Debye poles, set to -1 will be automatically calculated tends to minimize the relative absolut error. -* ``str1`` is an identifier for the material. -* ``i2`` is an optional parameter which controls the seeding of the random number generator used in stochastic global optimizator. By default (if you don't specify this parameter) the random number generator will be seeded by trying to read data from ``/dev/urandom`` (or the Windows analogue) if available or from the clock otherwise. - -For example ``#raw_data: user_libs/DebyeFit/examples/Test.txt 0.1 1 0.1 3 Experimental`` creates a material called ``Experimental`` which model dielectric properties obtained experimentally by fitting three Debye poles function to data given from a ``user_libs/DebyeFit/examples/Test.txt`` file. -The resulting output is the set of gprMax commands and optional a plot with the actual and the approximated function. diff --git a/user_libs/DebyeFit/__init__.py b/user_libs/DebyeFit/__init__.py index 30ec0b31..e69de29b 100644 --- a/user_libs/DebyeFit/__init__.py +++ b/user_libs/DebyeFit/__init__.py @@ -1,8 +0,0 @@ -import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__))) -from .Debye_Fit import Crim, HavriliakNegami, Jonscher, Rawdata - -__all__ = [ - 'HavriliakNegami', 'Jonscher', 'Crim', - 'Rawdata' - ] - diff --git a/user_libs/DebyeFit/docs/README.rst b/user_libs/DebyeFit/docs/README.rst new file mode 100644 index 00000000..c24470bc --- /dev/null +++ b/user_libs/DebyeFit/docs/README.rst @@ -0,0 +1,246 @@ +User libraries is a sub-package where useful Python modules contributed by users are stored. + +******** +DebyeFit +******** + +Information +=========== + +**Author/Contact**: Iraklis Giannakis (iraklis.giannakis@abdn.ac.uk), University of Aberdeen, UK and Sylwia Majchrowska (Sylwia.Majchrowska1993@gmail.com) + +This module was created as part of the `Google Summer of Code `_ programme 2021 which gprMax participated. + +**License**: `Creative Commons Attribution-ShareAlike 4.0 International License `_ + +**Attribution/cite**: Giannakis, I., & Giannopoulos, A. (2014). A novel piecewise linear recursive convolution approach for dispersive media using the finite-difference time-domain method. *IEEE Transactions on Antennas and Propagation*, 62(5), 2669-2678. (http://dx.doi.org/10.1109/TAP.2014.2308549) + +Electric permittivity is a complex function with both real and imaginary parts. +In general, as a hard and fast rule, the real part dictates the velocity of the medium while the imaginary part is related to the electromagnetic losses. +The generic form of dispersive media is + +.. math:: + + \epsilon(\omega) = \epsilon^{'}(\omega) - j\epsilon^{''}(\omega), + +where :math:`\omega` is the angular frequency, :math:`\epsilon^{'}` and :math:`\epsilon^{''}` are the real and imaginary parts of the permittivity respectively. + +This package provides scripts and tools which can be used to fit a multi-Debye expansion to dielectric data, defined as + +.. math:: + + \epsilon(\omega) = \epsilon_{\infty} + \sum_{i=1}^{N}\frac{\Delta\epsilon_{i}}{1+j\omega t_{0,i}}, + +where :math:`\epsilon(\omega)` is frequency dependent dielectric permittivity, :math:`\Delta\epsilon` - difference between the real permittivity at zero and infinite frequency. +:math:`\tau_{0}` is relaxation time (seconds), :math:`\epsilon_{\infty}` - real part of relative permittivity at infinite frequency, and :math:`N` is number of the Debye poles. + +To fit the data to a multi-Debye expansion, you can choose between Havriliak-Negami, Jonscher, or Complex Refractive Index Mixing (CRIM) models, as well as arbitrary dielectric data derived experimentally or calculated using a different function. + +.. figure:: images/epsilon.png + :width: 600 px + + Real and imaginary parts of frequency-dependent permittivity + + +Package contents +================ + +There are two main scripts: + +* ```Debye_fit.py``` contains definitions of all Relaxation functions classes +* ```optimization.py``` contains definitions of three choosen global optimization methods + + +Relaxation Class +---------------- + +This class is designed for modelling different relaxation functions, like Havriliak-Negami (```HavriliakNegami```), Jonscher (```Jonscher```), Complex Refractive Index Mixing (```CRIM```) models, and arbitrary dielectric data derived experimentally or calculated using some other function (```Rawdata```). + +More about the ``Relaxation`` class structure can be found in the :doc:`Relaxation doc `. + +Havriliak-Negami Function +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Havriliak-Negami relaxation is an empirical modification of the Debye relaxation model in electromagnetism, which in addition to the Debye equation has two exponential parameters + +.. math:: + + \epsilon(\omega) = \epsilon_{\infty} + \frac{\Delta\epsilon}{\left(1+\left(j\omega t_{0}\right)^{a}\right)^{b}} + + +The ``HavriliakNegami`` class has the following structure: + +.. code-block:: none + + HavriliakNegami(f_min, f_max, + alpha, beta, e_inf, de, tau_0, + sigma, mu, mu_sigma, material_name, + number_of_debye_poles=-1, f_n=50, + plot=False, save=True, + optimizer=PSO_DLS, + optimizer_options={}) + + +* ``f_min`` is first bound of the frequency range used to approximate the given function (Hz), +* ``f_max`` is second bound of the frequency range used to approximate the given function (Hz), +* ``alpha`` is real positive float number which varies 0 < $\alpha$ < 1, +* ``beta`` is real positive float number which varies 0 < $\beta$ < 1, +* ``e_inf`` is a real part of relative permittivity at infinite frequency, +* ``de`` is a difference between the real permittivity at zero and infinite frequency, +* ``tau_0`` is a relaxation time (seconds), +* ``sigma`` is a conductivity (Siemens/metre), +* ``mu`` is a relative permeability, +* ``mu_sigma`` is a magnetic loss (Ohms/metre), +* ``material_name`` is the material name, +* ``number_of_debye_poles`` is the chosen number of Debye poles, +* ``f_n`` is the chosen number of frequences, +* ``plot`` is a switch to turn on the plotting, +* ``save`` is a switch to turn on saving final material properties, +* ``optimizer`` is a chosen optimizer to fit model to dielectric data, +* ``optimizer_options`` is a dict for options of chosen optimizer. + +Jonscher Function +^^^^^^^^^^^^^^^^^ + +Jonscher function is mainly used to describe the dielectric properties of concrete and soils. The frequency domain expression of Jonscher +function is given by + +.. math:: + + \epsilon(\omega) = \epsilon_{\infty} + a_{p}*\left( -j*\frac{\omega}{\omega_{p}} \right)^{n} + + +The ``Jonscher`` class has the following structure: + +.. code-block:: none + + Jonscher(f_min, f_max, + e_inf, a_p, omega_p, n_p, + sigma, mu, mu_sigma, + material_name, number_of_debye_poles=-1, + f_n=50, plot=False, save=True, + optimizer=PSO_DLS, + optimizer_options={}) + + +* ``f_min`` is first bound of the frequency range used to approximate the given function (Hz), +* ``f_max`` is second bound of the frequency range used to approximate the given function (Hz), +* ``e_inf`` is a real part of relative permittivity at infinite frequency, +* ``a_p``` is a Jonscher parameter. Real positive float number, +* ``omega_p`` is a Jonscher parameter. Real positive float number, +* ``n_p`` Jonscher parameter, 0 < n_p < 1. + +Complex Refractive Index Mixing (CRIM) Function +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +CRIM is the most mainstream approach for estimating the bulk permittivity of heterogeneous materials and has been widely applied for GPR applications. The function takes form of + +.. math:: + + \epsilon(\omega)^{d} = \sum_{i=1}^{m}f_{i}\epsilon_{m,i}(\omega)^{d} + + +The ``CRIM`` class has the following structure: + +.. code-block:: none + + CRIM(f_min, f_max, a, volumetric_fractions, + materials, sigma, mu, mu_sigma, material_name, + number_of_debye_poles=-1, f_n=50, + plot=False, save=True, + optimizer=PSO_DLS, + optimizer_options={}) + + +* ``f_min`` is first bound of the frequency range used to approximate the given function (Hz), +* ``f_max`` is second bound of the frequency range used to approximate the given function (Hz), +* ``a`` is a shape factor, +* ``volumetric_fractions`` is a volumetric fraction for each material, +* ``materials`` are arrays of materials properties, for each material [e_inf, de, tau_0]. + +Rawdata Class +^^^^^^^^^^^^^ + +This package also has the ability to model dielectric properties obtained experimentally by fitting multi-Debye functions to data given from a file. +The format of the file should be three columns: the first column contains the frequencies (Hz) associated with the electric permittivity; the second column contains the real part of the relative permittivity; the third column contains the imaginary part of the relative permittivity. The columns should separated by a coma by default, but it is also possible to define a different separator. + +The ``Rawdata`` class has the following structure: + +.. code-block:: none + + Rawdata(self, filename, + sigma, mu, mu_sigma, + material_name, number_of_debye_poles=-1, + f_n=50, delimiter =',', + plot=False, save=True, + optimizer=PSO_DLS, + optimizer_options={}) + + +* ``filename`` is a path to text file which contains three columns, +* ``delimiter`` is a separator for three data columns. + +Class Optimizer +--------------- + +This class supports global optimization algorithms (particle swarm, dual annealing, evolutionary algorithms) for finding an optimal set of relaxation times that minimise the error between the actual and the approximated electric permittivity, and calculates optimised weights for the given relaxation times. +Code written here is mainly based on external libraries, like ```scipy``` and ```pyswarm```. + +More about the ``Optimizer`` class structure can be found in the :doc:`Optimisation doc `. + +PSO_DLS Class +^^^^^^^^^^^^^ + +Creation of hybrid Particle Swarm-Damped Least Squares optimisation object with predefined parameters. +The code is a modified version of the pyswarm package which can be found at https://pythonhosted.org/pyswarm/. + +DA_DLS Class +^^^^^^^^^^^^ + +Creation of Dual Annealing-Damped Least Squares optimisation object with predefined parameters. The class is a modified version of the scipy.optimize package which can be found at: +https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.dual_annealing.html#scipy.optimize.dual_annealing. + +DE_DLS Class +^^^^^^^^^^^^ + +Creation of Differential Evolution-Damped Least Squares object with predefined parameters. The class is a modified version of the scipy.optimize package which can be found at: +https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.differential_evolution.html#scipy.optimize.differential_evolution. + +DLS function +^^^^^^^^^^^^ + +Finding the weights using a non-linear least squares (LS) method, the Levenberg-Marquardt algorithm (LMA or just LM), also known as the damped least-squares (DLS) method. + +Examples +-------- + +In the examples directory you will find Jupyter notebooks, scripts, and data that demonstrate different cases of how to use the main script ```DebyeFit.py```: + +* ```example_DebyeFitting.ipynb```: simple cases of using all available implemented relaxation functions, +* ```example_BiologicalTissues.ipynb```: simple cases of using Cole-Cole function for biological tissues, +* ```example_ColeCole.py```: simple cases of using Cole-Cole function in case of 3, 5 and automatically chosen number of Debye poles, +* ```Test.txt```: raw data for testing ```Rawdata``` class, file contains 3 columns: the first column contains the frequencies (Hz) associated with the value of the permittivity; the second column contains the real part of the relative permittivity; and the third column contains the imaginary part of the relative permittivity. + +The following code shows a basic example of how to use the Havriliak-Negami function: + +.. code-block:: python + + # set Havrilak-Negami function with initial parameters + setup = HavriliakNegami(f_min=1e4, f_max=1e11, + alpha=0.3, beta=1, + e_inf=3.4, de=2.7, tau_0=.8e-10, + sigma=0.45e-3, mu=1, mu_sigma=0, + material_name="dry_sand", f_n=100, + plot=True, save=False, + number_of_debye_poles=3, + optimizer_options={'swarmsize':30, + 'maxiter':100, + 'omega':0.5, + 'phip':1.4, + 'phig':1.4, + 'minstep':1e-8, + 'minfun':1e-8, + 'seed': 111, + 'pflag': True}) + # run optimization + setup.run() \ No newline at end of file diff --git a/user_libs/DebyeFit/docs/epsilon.png b/user_libs/DebyeFit/docs/images/epsilon.png similarity index 100% rename from user_libs/DebyeFit/docs/epsilon.png rename to user_libs/DebyeFit/docs/images/epsilon.png diff --git a/user_libs/DebyeFit/docs/optimization.md b/user_libs/DebyeFit/docs/optimization.rst similarity index 59% rename from user_libs/DebyeFit/docs/optimization.md rename to user_libs/DebyeFit/docs/optimization.rst index 6055a761..f53b8499 100644 --- a/user_libs/DebyeFit/docs/optimization.md +++ b/user_libs/DebyeFit/docs/optimization.rst @@ -1,6 +1,7 @@ -# Optimization methods of multi-Debye fitting +Optimization methods of multi-Debye fitting +------------------------------------------- -``Class Optimizer`` supports global optimization algorithms (particle swarm, duall annealing, evolutionary algorithms) for finding an optimal set of relaxation times that minimise the error between the actual and the approximated electric permittivity and calculate optimised weights for the given relaxation times. +The ``Optimizer`` class supports global optimization algorithms (particle swarm, dual annealing, evolutionary algorithms) for finding an optimal set of relaxation times that minimise the error between the actual and the approximated electric permittivity, and calculates optimised weights for the given relaxation times. Code written here is mainly based on external libraries, like ```scipy``` and ```pyswarm```. Supported methods: @@ -8,9 +9,10 @@ Supported methods: - [x] hybrid Dual Annealing-Damped Least Squares - [x] hybrid Differential Evolution-Damped Least Squares -## Methods +Methods +^^^^^^^ -1. __constructor__ - it is called in all childern classes. +1. __constructor__ - is called in all child classes. It takes the following arguments: - `maxiter`: maximum number of iterations for the optimizer, @@ -22,21 +24,21 @@ Supported methods: - `calc_weights` (used to fit weight, non-linear least squares (LS) method is used as a default) are set. -2. __fit__ - it is inherited by all children classes. It calls the optimization function that tries to find an optimal set of relaxation times that minimise the error between the actual and the approximated electric permittivity and calculate optimised weights for the given relaxation times. +2. __fit__ - is inherited by all children classes. It calls the optimization function that tries to find an optimal set of relaxation times that minimise the error between the actual and the approximated electric permittivity and calculate optimised weights for the given relaxation times. It takes the following arguments: - `func`: objective function to be optimized, - `lb`: the lower bounds of the design variable(s), - `ub`: the upper bounds of the design variable(s), - `funckwargs`: optional arguments takien by objective function. -3. __cost_function__ - it is inherited by all children classes. It calculate cost function as the average error between the actual and the approximated electric permittivity (sum of real and imaginary part). +3. __cost_function__ - is inherited by all child classes. It calculates the cost function as the average error between the actual and the approximated electric permittivity (sum of real and imaginary part). It takes the following arguments: - `x`: the logarithm with base 10 of relaxation times of the Debyes poles, - `rl`: real parts of chosen relaxation function for given frequency points, - `im`: imaginary parts of chosen relaxation function for given frequency points, - `freq`: the frequencies vector for defined grid. -4. __calc_relaxation_times__ - it find an optimal set of relaxation times that minimise an objective function using appropriate optimization procedure. +4. __calc_relaxation_times__ - it finds an optimal set of relaxation times that minimise an objective function using appropriate optimization procedure. It takes the following arguments: - `func`: objective function to be optimized, - `lb`: the lower bounds of the design variable(s), diff --git a/user_libs/DebyeFit/docs/relaxation.md b/user_libs/DebyeFit/docs/relaxation.md deleted file mode 100644 index 03c1b434..00000000 --- a/user_libs/DebyeFit/docs/relaxation.md +++ /dev/null @@ -1,69 +0,0 @@ -# Relaxation classes for multi-Debye fitting - -This class is designed for modelling different relaxation functions, like Havriliak-Negami (```Class HavriliakNegami```), Jonscher (```Class Jonscher```), Complex Refractive Index Mixing (```Class CRIM```) models, and arbitrary dielectric data derived experimentally or calculated using some other function (```Class Rawdata```). - -Supported relaxation classes: - -- [x] Havriliak-Negami, -- [x] Jonscher, -- [x] Complex Refractive Index Mixing, -- [x] Experimental data, - -## Methods - -1. __constructor__ - it is called in all childern classes, creates Relaxation function object for complex material. - - It takes the following arguments: - - ``sigma`` is a conductivity (Siemens/metre), - - ``mu`` is a relative permeability, - - ``mu_sigma`` is a magnetic loss (Ohms/metre), - - ``material_name`` is definition of material name, - - ``number_of_debye_poles`` is choosen number of Debye poles, - - ``f_n`` is choosen number of frequences, - - ``plot`` is a switch to turn on the plotting, - - ``save`` is a switch to turn on the saving final material properties, - - ``optimizer`` is a choosen optimizer to fit model to dielectric data, - - ``optimizer_options`` is a dict for options of choosen optimizer. - - Additional parameters: - - ``rl`` calculated real part of chosen relaxation function for given frequency points, - - ``im`` calculated imaginary part of chosen relaxation function for given frequency points. - -2. __set_freq__ - it is inherited by all childern classes, interpolates frequency vector using n equally logarithmicaly spaced frequencies. - It takes the following arguments: - - `f_min_`: first bound of the frequency range used to approximate the given function (Hz), - - `f_max`: second bound of the frequency range used to approximate the given function (Hz), - - `f_n`: the number of frequency points in frequency grid (Default: 50). - -3. __run__ - it is inherited by all childern classes, solves the problem described by the given relaxation function (main operational method). - It consists of following steps: - 1) Check the validity of the inputs using ```check_inputs``` method. - 2) Print information about chosen approximation settings using ```print_info``` method. - 3) Calculate both real and imaginary parts using ```calculation``` method, and then set ```self.rl``` and ```self.im``` properties. - 4) Calling the main optimisation module using ```optimize``` method and calculate error based on ```error``` method. - a) [OPTIONAL] If number of debye poles is set to -1 optimization procedure is repeted until percentage error goes smaller than 5% or 20 Debye poles is reached. - 5) Print the results in gprMax format style using ```print_output``` method. - 6) [OPTIONAL] Save results in gprMax style using ```save_result``` method. - 7) [OPTIONAL] Plot the actual and the approximate dielectric properties using ```plot_result``` method. - -4. __check_inputs__ - it is called in all childern classes, finds an optimal set of relaxation times that minimise an objective function using appropriate optimization procedure. - -5. __calculation__ - it is inherited by all childern classes, should be definied in all new children classes, approximates the given relaxation function. - -6. __print_info__ - it is inherited by all childern classes, prints readable string of parameters for given approximation settings. - -7. __optimize__ - it is inherited by all childern classes, calls the main optimisation module with defined lower and upper boundaries of search. - -8. __print_output__ - it is inherited by all childern classes, prints out the resulting Debye parameters in a gprMax format. - -9. __plot_result__ - it is inherited by all childern classes, plots the actual and the approximated electric permittivity, along with relative error for real and imaginary parts using a semilogarithm X axes. - -10. __save_result__ - it is inherited by all childern classes, saves the resulting Debye parameters in a gprMax format. - -11. __error__ - it is inherited by all childern classes, calculates the average fractional error separately for relative permittivity (real part) and conductivity (imaginary part). - -Each new class of relaxation object should: - -- define constructor with appropriate arguments, -- define __check_inputs__ method to check relaxation class specific parameters, -- overload __calculation__ method. diff --git a/user_libs/DebyeFit/docs/relaxation.rst b/user_libs/DebyeFit/docs/relaxation.rst new file mode 100644 index 00000000..3e335276 --- /dev/null +++ b/user_libs/DebyeFit/docs/relaxation.rst @@ -0,0 +1,71 @@ +Relaxation classes for multi-Debye fitting +------------------------------------------ + +This class is designed for modelling different relaxation functions, like Havriliak-Negami (```HavriliakNegami```), Jonscher (```Jonscher```), Complex Refractive Index Mixing (```CRIM```) models, and arbitrary dielectric data derived experimentally or calculated using some other function (```Rawdata```). + +Supported relaxation classes: + +- [x] Havriliak-Negami, +- [x] Jonscher, +- [x] Complex Refractive Index Mixing, +- [x] Experimental data, + +Methods +^^^^^^^ + +1. __constructor__ - is called in all child classes, creates Relaxation function object for complex material. + + It takes the following arguments: + - ``sigma`` is a conductivity (Siemens/metre), + - ``mu`` is a relative permeability, + - ``mu_sigma`` is a magnetic loss (Ohms/metre), + - ``material_name`` is definition of material name, + - ``number_of_debye_poles`` is choosen number of Debye poles, + - ``f_n`` is the chosen number of frequences, + - ``plot`` is a switch to turn on the plotting, + - ``save`` is a switch to turn on the saving final material properties, + - ``optimizer`` is a chosen optimizer to fit model to dielectric data, + - ``optimizer_options`` is a dict for options of chosen optimizer. + + Additional parameters: + - ``rl`` calculated real part of chosen relaxation function for given frequency points, + - ``im`` calculated imaginary part of chosen relaxation function for given frequency points. + +2. __set_freq__ - is inherited by all child classes, interpolates frequency vector using n equally logarithmicaly spaced frequencies. + It takes the following arguments: + - `f_min_`: first bound of the frequency range used to approximate the given function (Hz), + - `f_max`: second bound of the frequency range used to approximate the given function (Hz), + - `f_n`: the number of frequency points in frequency grid (Default: 50). + +3. __run__ - is inherited by all child classes, solves the problem described by the given relaxation function (main operational method). + It consists of following steps: + 1) Check the validity of the inputs using ```check_inputs``` method. + 2) Print information about chosen approximation settings using ```print_info``` method. + 3) Calculate both real and imaginary parts using ```calculation``` method, and then set ```self.rl``` and ```self.im``` properties. + 4) Calling the main optimisation module using ```optimize``` method and calculate error based on ```error``` method. + a) [OPTIONAL] If number of debye poles is set to -1 optimization procedure is repeated until the percentage error is les than 5% or 20 Debye poles is reached. + 5) Print the results in gprMax format style using ```print_output``` method. + 6) [OPTIONAL] Save results in gprMax style using ```save_result``` method. + 7) [OPTIONAL] Plot the actual and the approximate dielectric properties using ```plot_result``` method. + +4. __check_inputs__ - is called in all child classes, finds an optimal set of relaxation times that minimise an objective function using appropriate optimization procedure. + +5. __calculation__ - is inherited by all child classes, should be definied in all new chil classes, approximates the given relaxation function. + +6. __print_info__ - is inherited by all child classes, prints readable string of parameters for given approximation settings. + +7. __optimize__ - is inherited by all child classes, calls the main optimisation module with defined lower and upper boundaries of search. + +8. __print_output__ - is inherited by all child classes, prints out the resulting Debye parameters in a gprMax format. + +9. __plot_result__ - is inherited by all child classes, plots the actual and the approximated electric permittivity, along with relative error for real and imaginary parts using a semilogarithm X axes. + +10. __save_result__ - is inherited by all child classes, saves the resulting Debye parameters in a gprMax format. + +11. __error__ -is inherited by all child classes, calculates the average fractional error separately for relative permittivity (real part) and conductivity (imaginary part). + +Each new class of relaxation object should: + +- define constructor with appropriate arguments, +- define __check_inputs__ method to check relaxation class specific parameters, +- overload __calculation__ method. diff --git a/user_libs/DebyeFit/examples/Readme.md b/user_libs/DebyeFit/examples/Readme.md deleted file mode 100644 index e2e529b6..00000000 --- a/user_libs/DebyeFit/examples/Readme.md +++ /dev/null @@ -1,33 +0,0 @@ -# Getting started - -Please see provided examples for the basic usage of ``DebyeFit`` module. We provide jupyter tutorials, and full guidance for quick run with existing relaxation functions and optimizers: - -* ```example_DebyeFitting.ipynb```: simple cases of using all available implemented relaxation functions, -* ```example_BiologicalTissues.ipynb```: simple cases of using Cole-Cole function for biological tissues, -* ```example_ColeCole.py```: simple cases of using Cole-Cole function in case of 3, 5 and automatically chosen number of Debye poles. - -Main usage of the specific relaxation fucntion based on creation of choosen relaxation model and then calling run method. - -```python - - # set Havrilak-Negami function with initial parameters - setup = HavriliakNegami(f_min=1e4, f_max=1e11, - alpha=0.3, beta=1, - e_inf=3.4, de=2.7, tau_0=.8e-10, - sigma=0.45e-3, mu=1, mu_sigma=0, - material_name="dry_sand", f_n=100, - plot=True, save=False, - number_of_debye_poles=3, - optimizer_options={'swarmsize':30, - 'maxiter':100, - 'omega':0.5, - 'phip':1.4, - 'phig':1.4, - 'minstep':1e-8, - 'minfun':1e-8, - 'seed': 111, - 'pflag': True}) - # run optimization - setup.run() - -``` diff --git a/user_libs/DebyeFit/optimization.py b/user_libs/DebyeFit/optimization.py index f536ce19..793dfe31 100644 --- a/user_libs/DebyeFit/optimization.py +++ b/user_libs/DebyeFit/optimization.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015-2021, Iraklis Giannakis and Sylwia Majchrowska +# Copyright (C) 2015-2022, Iraklis Giannakis and Sylwia Majchrowska # # This module is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. # To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/. diff --git a/user_libs/antenna_patterns/docs/README.rst b/user_libs/antenna_patterns/docs/README.rst index ad85052e..fb41adc0 100644 --- a/user_libs/antenna_patterns/docs/README.rst +++ b/user_libs/antenna_patterns/docs/README.rst @@ -13,7 +13,7 @@ Information **Attribution/cite**: Warren, C., Giannopoulos, A. (2016). Characterisation of a Ground Penetrating Radar Antenna in Lossless Homogeneous and Lossy Heterogeneous Environments. *Signal Processing* (http://dx.doi.org/10.1016/j.sigpro.2016.04.010) -The package features contains modules to help calculate, process, and visualise field patterns from simulations that contain models of antennas. +The package contains scripts to help calculate, process, and visualise field patterns from simulations that contain models of antennas. .. warning:: @@ -23,8 +23,8 @@ The package features contains modules to help calculate, process, and visualise * Requires knowledge of Python to contruct input files with antenna models and positioning of receivers, as well as to edit/modify the saving and processing modules * Can require simulations that demand significant computational resource depending on the distance from the antenna at which the field patterns are observed, e.g. the example models, set with a maximum observation distance of 0.6m, require ~30GB of RAM -Module overview -=============== +Package contents +================ * ``initial_save.py`` is a module that calculates and stores (in a Numpy file) the field patterns from the output file of a simulation. * ``plot_fields.py`` is a module that plots the field patterns. It should be used after the field pattern data has been processed and stored using the ``initial_save.py`` module. @@ -35,8 +35,8 @@ The package has been designed to work with input files that follow examples foun * ``antenna_like_GSSI_1500_patterns_H.in`` is an input file that includes an antenna model similar to a GSSI 1.5 GHz antenna and receivers to calculate a field pattern in the principal H-plane of the antenna -How to use the module -===================== +How to use the package +====================== * Firstly you should familiarise yourself with the example model input file. Edit the input file as desired and run one of the simulations for either E-plane or H-plane patterns. * Whilst the simulation is running edit the 'user configurable parameters' sections of the ``initial_save.py`` and ``plot_fields.py`` modules to match the setup of the simulation. diff --git a/user_libs/antennas/docs/README.rst b/user_libs/antennas/docs/README.rst index 2d3c812c..9ee95317 100644 --- a/user_libs/antennas/docs/README.rst +++ b/user_libs/antennas/docs/README.rst @@ -7,7 +7,7 @@ GPR antenna models Information =========== -The module features models of antennas similar to commercial GPR antennas. The following antenna models are included: +The package features models of antennas similar to commercial GPR antennas. The following antenna models are included: ======================== ============= ============= ========================================================================================================================================================================================================================= ================ Manufacturer/Model Dimensions Resolution(s) Author/Contact Attribution/Cite @@ -25,16 +25,16 @@ GSSI 400MHz 300x300x170mm 0.5, 1, 2mm Sam Stadler (Sam.Stadler@li 2. Giannakis, I., Giannopoulos, A., & Warren, C. (2019). Realistic FDTD GPR antenna models optimised using a novel linear/non-linear Full Waveform Inversion. *IEEE Transactions on Geoscience and Remote Sensing*, 57(3), 1768-1778. (https://doi.org/10.1109/TGRS.2018.2869027) 3. Stadler. S., Igel J. (2018). A Numerical Study on Using Guided GPR Waves Along Metallic Cylinders in Boreholes for Permittivity Sounding. 17th International Conference on GPR. (https://tinyurl.com/y6vdab22) -Module overview -=============== +Package contents +================ * ``GSSI.py`` is a module containing models of antennas similar to those manufactured by `Geophysical Survey Systems, Inc. (GSSI) `_. * ``MALA.py`` is a module containing models of antennas similar to those manufactured by `MALA Geoscience `_. Descriptions of how the models were created can be found in the aforementioned attributions. -How to use the module -===================== +How to use the package +====================== The antenna models can be accessed from within a block of Python code in an input file. The models are inserted at location x,y,z. The coordinates are relative to the geometric centre of the antenna in the x-y plane and the bottom of the antenna skid in the z direction. The models must be used with cubic spatial resolutions of either 0.5mm (GSSI 400MHz antenna only), 1mm (default), or 2mm by setting the keyword argument, e.g. ``resolution=0.002``. The antenna models can be rotated 90 degrees counter-clockwise (CCW) in the x-y plane by setting the keyword argument ``rotate90=True``. diff --git a/user_libs/landmines/PMA_1x1x1.h5 b/user_libs/landmines/PMA_1x1x1.h5 new file mode 100644 index 0000000000000000000000000000000000000000..6881b26ddd1eba9454f8ce76a3b379fc0e319b0f GIT binary patch literal 593504 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 literal 0 HcmV?d00001 diff --git a/user_libs/landmines/PMA_2x2x2.h5 b/user_libs/landmines/PMA_2x2x2.h5 new file mode 100644 index 0000000000000000000000000000000000000000..d858b0c0f7161795e26d235653a38680d2b449cd GIT binary patch literal 73824 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 literal 0 HcmV?d00001 diff --git a/user_libs/landmines/PMA_materials.txt b/user_libs/landmines/PMA_materials.txt new file mode 100644 index 00000000..40dd8d16 --- /dev/null +++ b/user_libs/landmines/PMA_materials.txt @@ -0,0 +1,5 @@ +## PMA landmine material properties +#material: 1 inf 1 0 pec +#material: 1 0 1 0 freespace +#material: 2.5 0 1 0 plastic +#material: 6 0 1 0 rubber diff --git a/user_libs/landmines/PMN_1x1x1.h5 b/user_libs/landmines/PMN_1x1x1.h5 new file mode 100644 index 0000000000000000000000000000000000000000..33e6daed8f29a5aa76bf9851e410b887c200280a GIT binary patch literal 1775552 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

Pf%Pa5E~;-T%ICpPO~d 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