Create a 3D survey from 2D lines

In this notebook we will see how to use a set of 2D lines (regularly spaced or not) to create a full 3D survey (Project.create3DSurvey()). Note that you can also invert the 2D lines separately and view them in 3D (this latter is called ‘pseudo3D’, see separate notebook). In this example, the datasets of all lines are combined together in one single 3D survey.

import warnings # just to make it cleaner in the notebook
warnings.filterwarnings('ignore')
import os
import sys
sys.path.append((os.path.relpath('../src'))) # add here the relative path of the API folder
testdir = '../src/examples/'
from resipy import Project
API path =  /media/jkl/data/phd/tmp/resipy/src/resipy
ResIPy version =  3.2.0
cR2.exe found and up to date.
R3t.exe found and up to date.
cR3t.exe found and up to date.

You can specify a lineSpacing if your lines are parallel, otherwise, custom electrodes location can be provided using Project.importElec(). In this case the ‘label’ column of the .csv should be formated 3D-like with <lineNumber> <electrodeNumber>. Each <lineNumber> corresponding to one 2D surveys.

If surveys have been imported based on a directory, the surveys are sorted by alphabetical order. Otherwise, you can provide a list of filenames to Project.create3DSurvey() and the order of the list will be respected.

# 3D survey from 2D perpendicular line with one common elec
# we are using the directory pseudo3d but it's not what we refer to as 'pseudo3D' project
# (see separate notebook for pseudo3D inversion)
k = Project(typ='R3t')
k.create3DSurvey(testdir + 'dc-3d-pseudo3d-synthetic/data', lineSpacing=1,
                 zigzag=False, name='mergedSurvey', ftype='ProtocolDC')
k.importElec(testdir + 'dc-3d-pseudo3d-synthetic/lines-elec.csv')
k.elec.head() # note the <lineNumber> <elecNumber> formatting of the 'label' column
Working directory is: /media/jkl/data/phd/tmp/resipy/src/resipy
clearing dirname
0/140 reciprocal measurements found.
0/140 reciprocal measurements found.
merging electrodes positionned at the same location.
label x y z remote buried
0 1 1 -11.0 0.0 0.0 False False
1 1 2 -10.0 0.0 0.0 False False
2 1 3 -9.0 0.0 0.0 False False
3 1 4 -8.0 0.0 0.0 False False
4 1 5 -7.0 0.0 0.0 False False
k.createMesh(cl=0.5)
k.invert()
Creating tetrahedral mesh...fmd in gmshWrap.py: 7.666667
writing .geo to file completed, save location:
/media/jkl/data/phd/tmp/resipy/src/resipy/invdir

Reading mesh3d.msh
Gmsh version == 3.x
reading node coordinates...
Determining element type...Tetrahedra
Reading connection matrix...
ignoring 18645 elements in the mesh file, as they are not required for R2/R3t
Finished reading .msh file
interpolating topography onto mesh using triangulate interpolation...done
Done
ResIPy Estimated RAM usage = 0.259909 Gb
done
Writing .in file and protocol.dat... done!

--------------------- MAIN INVERSION ------------------


 >> R 3 t     E R T    M o d e l    v 2.30 <<

 >> Date: 20-01-2021
 >> My beautiful 3D survey
 >> I n v e r s e   S o l u t i o n   S e l e c t e d <<
 >> A d v a n c e d   M e s h   I n p u t <<
 >> T e t r a h e d r a l   E l e m e n t   M e s h <<

 >> Reading mesh file
 >> Determining storage needed for finite element conductance matrix
 >> Generating index array for finite element conductance matrix
 >> Reading resistivity model from res0.dat

 >> L o g - D a t a   I n v e r s i o n <<
 >> N o r m a l   R e g u l a r i s a t i o n <<

 >> Memory estimates:
    For   1000 measurements the memory needed is:          0.857 Gb
    For   2000 measurements the memory needed is:          1.689 Gb
    For   5000 measurements the memory needed is:          4.184 Gb
    For  10000 measurements the memory needed is:          8.341 Gb

 >> Forming roughness matrix

 >> Number of measurements read:  280

 >> Total Memory required is:          0.259 Gb


 Processing frame   1 - output to file f001.dat

   Iteration   1
     Initial RMS Misfit:        19.16      Number of data ignored:     0
     Alpha:         126.387   RMS Misfit:        1.86  Roughness:       10.699
     Alpha:          58.664   RMS Misfit:        1.79  Roughness:       11.244
     Alpha:          27.229   RMS Misfit:        1.27  Roughness:       16.642
     Alpha:          12.639   RMS Misfit:        1.04  Roughness:       20.599
     Alpha:           5.866   RMS Misfit:        0.92  Roughness:       24.775
     Step length set to      1.000
     Final RMS Misfit:        0.92
     Final RMS Misfit:        1.00

 Solution converged - Outputing results to file

 Calculating sensitivity map

 End of data:  Terminating


 >> Program ended normally

1/1 results parsed (1 ok; 0 failed)
k.showResults()
Converting np.character to a dtype is deprecated. The current result is np.dtype(np.str_) which is not strictly correct. Note that np.character is generally deprecated and 'S1' should be used.
Converting np.character to a dtype is deprecated. The current result is np.dtype(np.str_) which is not strictly correct. Note that np.character is generally deprecated and 'S1' should be used.
../_images/nb_3d-from-2d-lines_0.png
k.showResults(pvslices=[[0],[0],[]])
../_images/nb_3d-from-2d-lines_1.png

Download python script: nb_3d-from-2d-lines.py

Download Jupyter notebook: nb_3d-from-2d-lines.ipynb

View the notebook in the Jupyter nbviewer

Run this example interactively: binder