Source code for pycsamt.geodrill.structural
# -*- coding: utf-8 -*-
# Created on Sat Nov 28 21:19:13 2020
# Author: Kouadio K.Laurent<etanoyau@gmail.com>
# Licence: LGPL
"""
.. _module-Structural::`pycsamt.geodrill.structural`
:synopsis:class for geological structural analysis. It
contains some conventional structures and properties
"""
import os
import warnings
import numpy as np
from pycsamt.utils.geo_utils import mapping_stratum as strato
from pycsamt.utils import exceptions as CSex
from pycsamt.utils._csamtpylog import csamtpylog
_logger=csamtpylog.get_csamtpy_logger(__name__)
[docs]class geo_pattern:
"""
Singleton class to deal with geopattern with other modules. It
is and exhaustive pattern dict, can be add and change. This pattern
will be depreacted later , to create for pyCSAMT,its owwn geological
pattern in coformity with the conventional geological swatches .
deal with USGS(US Geological Survey ) swatches- references and FGDC
(Digital cartographic Standard for Geological Map Symbolisation
-FGDCgeostdTM11A2_A-37-01cs2.eps)
make _pattern:{'/', '\', '|', '-', '+', 'x', 'o', 'O', '.', '*'}
/ - diagonal hatching
\ - back diagonal
| - vertical
- - horizontal
+ - crossed
x - crossed diagonal
o - small circle
O - large circle
. - dots
* - stars
"""
pattern={
"basement rocks" : ['.+++++.', (.25, .5, .5)],
"igneous rocks": ['.o.o.', (1., 1., 1.)],
"duricrust" : ['+.+',(1., .2, .36)],
"gravel" : ['oO',(.75,.86,.12)],
"sand": ['....',(.23, .36, .45)],
"conglomerate" : ['.O.', (.55, 0., .36)],
"dolomite" : ['.-.', (0., .75, .23)],
"limestone" : ['//.',(.52, .23, .125)],
"permafrost" : ['o.', (.2, .26, .75)],
"metamorphic rocks" : ['*o.', (.2, .2, .3)],
"tills" : ['-.', (.7, .6, .9)],
"standstone ": ['..', (.5, .6, .9)],
"lignite coal": ['+/.',(.5, .5, .4)],
"coal": ['*.', (.8, .9, 0.)],
"shale" : ['=', (0., 0., 0.7)],
"clay" : ['=.',(.9, .8, 0.8)],
"saprolite" : ['*/',(.3, 1.2, .4)],
"sedimentary rocks": ['...',(.25, 0., .25)],
"fresh water" : ['.-.',(0., 1.,.2)],
"salt water" : ['o.-',(.2, 1., .2)],
"massive sulphide" : ['.+O',(1.,.5, .5 )],
"sea water" : ['.--',(.0, 1., 0.)],
"ore minerals" : ['--|',(.8, .2, .2)],
"graphite" : ['.++.',(.2, .7, .7)],
}
[docs]class Structure :
"""
Class for typical geological strutural conventions
for AGSO_STCODES . All geological structural informations are
geostructral object.
Holds the following information:
========================== =============== ===================================
Attributes Type Explanation
========================== =============== ===================================
boudin_axis geos_obj boudin
fold_axial_plane geos_obj axial plam of structural fold.
banding_gneissosity geos_obj gneissossity of boudin plan
s_fabric geos_obj fabric plan
fault_plane geos_obj fault plan
fracture_joint_set geos_obj fracture joint
undifferentiated_plane geos_obj unnamed geological structure
sharp_contact geos_obj sharp contact `various discrepancy`
contact `stratigraphy discrepancy`
fracture or fault discrepancies
========================== =============== ====================================
More attributes can be added by inputing a key word dictionary
:Example:
>>> from pycsamt.geodrill.geoCore.structural import Structure
>>> structural=Structure()
>>> boudin=boudin_axis()
>>> print(boudin.code)
>>> print(structural.boudin_axis.name)
>>> print(structural.boudin_axis.color)
"""
_logger.info('Set Structural main geological informations. ')
def __init__(self, **kwargs):
self.boudin_axis =boudin_axis()
self.fold_axial_plane=fold_axial_plane()
self.banding_gneissosity=banding_gneissosity()
self.s_fabric=s_fabric()
self.fault_plane=fault_plane()
self.fracture_joint_set=fracture_joint_set()
self.undifferentiated_plane=undifferentiated_plane()
self.sharp_contact=sharp_contact()
for keys in list(kwargs.keys()):
setattr(self, keys, kwargs[keys])
#====================================================
# geological structural objects
#=====================================================
[docs]class boudin_axis(object):
"""
Special class for boudins_axis
Holds the following information:
================= ============= ========================================
Attributes Type Explanation
================= ============= ========================================
code str conventional code
label str named label
size str drawing size
pattern str drawing pattern
density str elmts density
thickness str drawing thickness
color str color set
================= ============= ========================================
More attributes can be added by inputing a key word dictionary
"""
def __init__(self, **kwargs):
self.code =None
self.label=None
self.name=None
self.pattern=None
self.size =None
self.density=None
self.thickness=None
self.color =None
for keys in list(kwargs.keys()):
self.__setattr__(keys, kwargs[keys])
self._set_boudin_axis()
def _set_boudin_axis(self):
"""
methode to populates attributes
"""
baxis=strato()[1]
for keys, values in baxis.items():
if keys == self.__class__.__name__:
self.code =values.__getitem__('code')
self.label=values.__getitem__('label')
self.name=values.__getitem__('name')
self.pattern=values.__getitem__('pattern')
self.size=values.__getitem__('size')
self.color=values.__getitem__('color')
self.density=values.__getitem__('density')
self.thickess=values.__getitem__('thickness')
[docs]class fold_axial_plane(object):
"""
Special class for fold_axial_plane
Holds the following information:
================= ============= ========================================
Attributes Type Explanation
================= ============= ========================================
code str conventional code
label str named label
size str drawing size
pattern str drawing pattern
density str elmts density
thickness str drawing thickness
color str color set
================= ============= ========================================
More attributes can be added by inputing a key word dictionary
"""
def __init__(self, **kwargs):
self.code =None
self.label=None
self.name=None
self.pattern=None
self.size =None
self.density=None
self.thickness=None
self.color =None
self._set_fold_axial_plane()
for keys in list(kwargs.keys()):
self.__setattr__(keys, kwargs[keys])
def _set_fold_axial_plane(self):
"""
Methode to populates attributes.
"""
baxis=strato()[1]
for keys, values in baxis.items():
if keys == self.__class__.__name__:
self.code =values.__getitem__('code')
self.label=values.__getitem__('label')
self.name=values.__getitem__('name')
self.pattern=values.__getitem__('pattern')
self.size=values.__getitem__('size')
self.color=values.__getitem__('color')
self.density=values.__getitem__('density')
self.thickess=values.__getitem__('thickness')
[docs]class banding_gneissosity(object):
"""
Special class for banding_gneissosity
Holds the following information:
================= ============= ========================================
Attributes Type Explanation
================= ============= ========================================
code str conventional code
label str named label
size str drawing size
pattern str drawing pattern
density str elmts density
thickness str drawing thickness
color str color set
================= ============= ========================================
More attributes can be added by inputing a key word dictionary
"""
def __init__(self, **kwargs):
self.code =None
self.label=None
self.name=None
self.pattern=None
self.size =None
self.density=None
self.thickness=None
self.color =None
self._set_banding_gneissosity()
for keys in list(kwargs.keys()):
self.__setattr__(keys, kwargs[keys])
def _set_banding_gneissosity(self):
"""
methode to populates attributes
"""
baxis=strato()[1]
# print(baxis)
for keys, values in baxis.items():
if keys == self.__class__.__name__:
self.code =values.__getitem__('code')
self.label=values.__getitem__('label')
self.name=values.__getitem__('name')
self.pattern=values.__getitem__('pattern')
self.size=values.__getitem__('size')
self.color=values.__getitem__('color')
self.density=values.__getitem__('density')
self.thickess=values.__getitem__('thickness')
[docs]class s_fabric(object):
"""
Special class for s_fabric
Holds the following information:
================= ============= ========================================
Attributes Type Explanation
================= ============= ========================================
code str conventional code
label str named label
size str drawing size
pattern str drawing pattern
density str elmts density
thickness str drawing thickness
color str color set
================= ============= ========================================
More attributes can be added by inputing a key word dictionary
"""
def __init__(self, **kwargs):
self.code =None
self.label=None
self.name=None
self.pattern=None
self.size =None
self.density=None
self.thickness=None
self.color =None
self._set_s_fabric()
for keys in list(kwargs.keys()):
self.__setattr__(keys, kwargs[keys])
def _set_s_fabric(self):
"""methode to populates attributes"""
baxis=strato()[1]
# print(baxis)
for keys, values in baxis.items():
if keys == self.__class__.__name__:
self.code =values.__getitem__('code')
self.label=values.__getitem__('label')
self.name=values.__getitem__('name')
self.pattern=values.__getitem__('pattern')
self.size=values.__getitem__('size')
self.color=values.__getitem__('color')
self.density=values.__getitem__('density')
self.thickess=values.__getitem__('thickness')
[docs]class fault_plane(object):
"""
Special class for fault_plane
Holds the following information:
================= ============= ========================================
Attributes Type Explanation
================= ============= ========================================
code str conventional code
label str named label
size str drawing size
pattern str drawing pattern
density str elmts density
thickness str drawing thickness
color str color set
================= ============= ========================================
More attributes can be added by inputing a key word dictionary
"""
def __init__(self, **kwargs):
self.code =None
self.label=None
self.name=None
self.pattern=None
self.size =None
self.density=None
self.thickness=None
self.color =None
self._set_fault_plane()
for keys in list(kwargs.keys()):
self.__setattr__(keys, kwargs[keys])
def _set_fault_plane(self):
"""
methode to populates attributes
"""
baxis=strato()[1]
# print(baxis)
for keys, values in baxis.items():
if keys == self.__class__.__name__:
self.code =values.__getitem__('code')
self.label=values.__getitem__('label')
self.name=values.__getitem__('name')
self.pattern=values.__getitem__('pattern')
self.size=values.__getitem__('size')
self.color=values.__getitem__('color')
self.density=values.__getitem__('density')
self.thickess=values.__getitem__('thickness')
[docs]class fracture_joint_set(object):
"""
Special class for fracture_joint_set
Holds the following information:
================= ============= ========================================
Attributes Type Explanation
================= ============= ========================================
code str conventional code
label str named label
size str drawing size
pattern str drawing pattern
density str elmts density
thickness str drawing thickness
color str color set
================= ============= ========================================
More attributes can be added by inputing a key word dictionary
"""
def __init__(self, **kwargs):
self.code =None
self.label=None
self.name=None
self.pattern=None
self.size =None
self.density=None
self.thickness=None
self.color =None
self._set_fracture_joint_set()
for keys in list(kwargs.keys()):
self.__setattr__(keys, kwargs[keys])
def _set_fracture_joint_set(self):
"""methode to populates attributes
"""
baxis=strato()[1]
# print(baxis)
for keys, values in baxis.items():
if keys == self.__class__.__name__:
self.code =values.__getitem__('code')
self.label=values.__getitem__('label')
self.name=values.__getitem__('name')
self.pattern=values.__getitem__('pattern')
self.size=values.__getitem__('size')
self.color=values.__getitem__('color')
self.density=values.__getitem__('density')
self.thickess=values.__getitem__('thickness')
[docs]class undifferentiated_plane(object):
"""
Special class for undifferentiated_plane
Holds the following information:
================= ============= ========================================
Attributes Type Explanation
================= ============= ========================================
code str conventional code
label str named label
size str drawing size
pattern str drawing pattern
density str elmts density
thickness str drawing thickness
color str color set
================= ============= ========================================
More attributes can be added by inputing a key word dictionary
"""
def __init__(self, **kwargs):
self.code =None
self.label=None
self.name=None
self.pattern=None
self.size =None
self.density=None
self.thickness=None
self.color =None
self._set_undifferentiated_plane()
for keys in list(kwargs.keys()):
self.__setattr__(keys, kwargs[keys])
def _set_undifferentiated_plane(self):
"""
methode to populates attributes
"""
baxis=strato()[1]
# print(baxis)
for keys, values in baxis.items():
if keys == self.__class__.__name__:
self.code =values.__getitem__('code')
self.label=values.__getitem__('label')
self.name=values.__getitem__('name')
self.pattern=values.__getitem__('pattern')
self.size=values.__getitem__('size')
self.color=values.__getitem__('color')
self.density=values.__getitem__('density')
self.thickess=values.__getitem__('thickness')
[docs]class sharp_contact(object):
"""
Special class for sharp_contact
Holds the following information:
================= ============= ========================================
Attributes Type Explanation
================= ============= ========================================
code str conventional code
label str named label
size str drawing size
pattern str drawing pattern
density str elmts density
thickness str drawing thickness
color str color set
================== ============= ========================================
More attributes can be added by inputing a key word dictionary
"""
def __init__(self, **kwargs):
self.code =None
self.label=None
self.name=None
self.pattern=None
self.size =None
self.density=None
self.thickness=None
self.color =None
self._set_sharp_contact()
for keys in list(kwargs.keys()):
self.__setattr__(keys, kwargs[keys])
def _set_sharp_contact(self):
"""
methode to populates attributes
"""
baxis=strato()[1]
# print(baxis)
for keys, values in baxis.items():
if keys == self.__class__.__name__:
self.code =values.__getitem__('code')
self.label=values.__getitem__('label')
self.name=values.__getitem__('name')
self.pattern=values.__getitem__('pattern')
self.size=values.__getitem__('size')
self.color=values.__getitem__('color')
self.density=values.__getitem__('density')
self.thickess=values.__getitem__('thickness')
[docs]class Geo_formation (object):
"""
This class is an axilliary class to supplement geodatabase ,
if the GeodataBase doesnt reply to SQL request , then use this class
to secah information about structures . If SQL is done as well ,
program won't call this class as rescure .
Containers of more than 150 geological strutures.
.. note:: replace in attributes param "**" by the *name of struture*
================== ============ =========================================
Attributes Type Explanation
================== ============ =========================================
names array_like names of all geological strutures
codes array_like names of all geological codes
**code str code of specific geological structure
**label str label of specific structure
**name str label of specific structure
**pattern str pattern of specific structure
**pat_size str pattern size of specific structure
**pat_density str pattern density l of specific structure
**pat_thickness str pttern thickess of specific structure
**color str color of specific structure
================== ============ =========================================
1. To see the names of strutures , write the script below
:Example:
>>> from pycsamt.geodrill.geoCore.strutural import Geo_formation as gf
>>> geo_structure = gf()
>>> geo_structure.names
2. To extract color and to get the code of structure like amphibolite
:Example:
>>> from pycsamt.geodrill.geoCore.strutural import Geo_formation as gf
>>> geo_structure = gf()
>>> geo_structure.amphibolite['color']
>>> geo_structure.amphibolite['code']
>>> geoformation_obj.AMP['color']
... 'R128G128'
"""
codef =['code','label','__description','pattern', 'pat_size', 'pat_density',
'pat_thickness','color']
def __init__(self, agso_file =None , **kwargs) :
self._logging = csamtpylog.get_csamtpy_logger(self.__class__.__name__)
self._agso_fn =agso_file
for key in list(kwargs.keys()):
self.__setattr__(key, kwargs[key])
if self.agso_fn is not None :
self._set_geo_formation()
@property
def agso_fn (self):
if self._agso_fn is None :
self._agso_fn = os.path.join(os.path.abspath('.'),
'pycsamt', 'geodrill',
'_geocodes','agso'.upper() + '.csv' )
if self._agso_fn is not None :
if os.path.isfile(self._agso_fn) :
with open(self._agso_fn, 'r', encoding ='utf8') as _fags0:
agso_lines = _fags0.readlines()
_secags0 = agso_lines[0].strip().split(',')
_secags0 =[_code.lower() for _code in _secags0]
self._AGS0_DATA =agso_lines[1:]
if _secags0 != self.codef :
warnings.warn(
' !Trouble occurs while decoding the geostructures!')
raise CSex.pyCSAMTError_structural(
'Geostructures files provided is wrong !')
else :
warnings.warn(
'No Geostructure file detected.It seems the file'
' is moved or deleted from its home folder'
' <pycsamt/geodrill/_geocodes>')
raise CSex.pyCSAMTError_structural(
'pyCSAMT inner geocodes not found '
'in <pycsamt/geodrill/_geocodes> folder.'
' Please provide the right structures codes.')
return self._AGS0_DATA
def _set_geo_formation(self, agso_fn =None):
"""
Read and set attributes and decode agso geostructures .
:param agso_fn: full path geological structural file.
:type agso_fn: str
:Example:
>>> geoformation_obj =Geo_formation()
>>> DATA = geoformation_obj._AGS0_DATA
>>> print( geoformation_obj.argillite['name'])
>>> print( geoformation_obj.argillite['color'])
>>> print( geoformation_obj.wood['color'])
>>> print( geoformation_obj.amphibolite['code'])
>>> print( geoformation_obj.names)
"""
self._logging.info('Read & and decodes geostructures files . ')
if agso_fn is not None :
self.agso_fn= agso_fn
#split the code files
self._AGS0_DATA = [ geos.strip().split(',') for ii, geos in enumerate(self._AGS0_DATA)]
self._AGS0_DATA= np.array (self._AGS0_DATA)
# sanitize the geonames .
self.__setattr__('names',
np.array( [name.replace('"', '') for name in self._AGS0_DATA[:, 2]] ))
self.__setattr__('codes', self._AGS0_DATA[:, 0])
# set for all values in geofomations codes
for ii, codeff in enumerate(self.codef [1:],1) : # count starting from one .
if codeff.find('pat') >=0 :
for jj, pp in enumerate(self._AGS0_DATA[:, ii]):
if pp == '' or pp ==' ' : # repalec all None value by 0. later will filled it
self._AGS0_DATA[:, ii][jj]=0.
self.__setattr__(codeff,
np.array([float(pp) for pp in self._AGS0_DATA[:, ii]]))
else :
self.__setattr__(codeff,
np.array( [name.replace('"', '') for name in self._AGS0_DATA[:, ii]] ))
DECODE ={}
# change RGBA color palette into Matplotlib color
self.mpl_colorsp= [ get_color_palette(rgb) for rgb in self._AGS0_DATA[:,-1]]
for jj, decode in enumerate(self._AGS0_DATA):
for ii, codec in enumerate( self.codef) :
if codec =='__description' : codec = 'name'
if codec =='color':
DECODE[codec]= self.mpl_colorsp[jj]
else : DECODE [codec]= decode[ii]
self.__setattr__(decode[2].strip().replace('"', '').replace(' ', '_'),
DECODE)
self.__setattr__(decode[0].strip().replace('"', '').replace(' ', '_'),
DECODE)
DECODE ={}
[docs]def get_color_palette (RGB_color_palette):
"""
Convert RGB color into matplotlib color palette. In the RGB color system two bits
of data are used for each color, red, green, and blue. That means that each color runs
on a scale from 0 to 255. Black would be 00,00,00, while white would be 255,255,255.
Matplotlib has lots of pre-defined colormaps for us . They are all normalized to 255,
so they run from 0 to 1. So you need only normalize data, then we can manually
select colors from a color map
:param RGB_color_palette: str value of RGB value
:type RGB_color_palette: str
:returns: rgba, tuple of (R, G, B)
:rtype: tuple
:Example:
>>> from pycsamt.geodrill.geoCore.structural import get_color_palette
>>> get_color_palette (RGB_color_palette ='R128B128')
"""
def ascertain_cp (cp):
if cp >255. :
warnings.warn(' !RGB value is range 0 to 255 pixels , '
'not beyond !. Your input values is = {0}.'.format(cp))
raise CSex.pyCSAMTError_parameter_number('Error color RGBA value ! '
'RGB value provided is = {0}.'
' It is larger than 255 pixels.'.format(cp))
return cp
if isinstance(RGB_color_palette,(float, int, str)):
try :
float(RGB_color_palette)
except :
RGB_color_palette= RGB_color_palette.lower()
else : return ascertain_cp(float(RGB_color_palette))/255.
rgba = np.zeros((3,))
if 'r' in RGB_color_palette :
knae = RGB_color_palette .replace('r', '').replace('g', '/').replace('b', '/').split('/')
try :
_knae = ascertain_cp(float(knae[0]))
except :
rgba[0]=1.
else : rgba [0] = _knae /255.
if 'g' in RGB_color_palette :
knae = RGB_color_palette .replace('g', '/').replace('b', '/').split('/')
try :
_knae =ascertain_cp(float(knae[1]))
except :
rgba [1]=1.
else :rgba[1]= _knae /255.
if 'b' in RGB_color_palette :
knae = knae = RGB_color_palette .replace('g', '/').split('/')
try :
_knae =ascertain_cp(float(knae[1]))
except :
rgba[2]=1.
else :rgba[2]= _knae /255.
return tuple(rgba)
if __name__=="__main__":
# structural=Structure()
# boudin=boudin_axis()
# # print(boudin.code)
# print(structural.boudin_axis.name)
# print(structural.boudin_axis.color)
geoformation_obj =Geo_formation()
DATA = geoformation_obj._AGS0_DATA
rgb= geoformation_obj.amphibolite['color']
print(rgb)