Sonnt commited on
Commit
052f08d
·
1 Parent(s): 62ee75e

Upload 44 files

Browse files
Files changed (45) hide show
  1. packages.txt +2 -0
  2. .gitattributes +3 -0
  3. Antuns/__pycache__/p1_import_csv.cpython-39.pyc +0 -0
  4. Antuns/__pycache__/page_setting.cpython-39.pyc +0 -0
  5. Antuns/__pycache__/prediction_LGBM.cpython-39.pyc +0 -0
  6. Antuns/page_setting.py +14 -0
  7. Antuns/prediction_LGBM.py +21 -0
  8. app.py +62 -0
  9. backup/081222/Antuns/p1_import_csv.py +13 -0
  10. backup/081222/Antuns/page_setting.py +14 -0
  11. backup/081222/Antuns/prediction_LGBM.py +21 -0
  12. backup/081222/Homepage.py +10 -0
  13. backup/081222/models/LGBM_20221125.json +3 -0
  14. backup/081222/models/LightGBM_0.45.pbz2 +3 -0
  15. backup/model.json +0 -0
  16. data/LogoVPI.png +0 -0
  17. data/all_file_merged_updated_with_All_geometry.csv +3 -0
  18. data/merged/Training_data.csv +0 -0
  19. data/merged/merged_df.csv +0 -0
  20. mLogsFunctions/__init__.py +31 -0
  21. mLogsFunctions/__pycache__/__init__.cpython-39.pyc +0 -0
  22. mLogsFunctions/__pycache__/dataloading.cpython-39.pyc +0 -0
  23. mLogsFunctions/__pycache__/dataprocessing.cpython-39.pyc +0 -0
  24. mLogsFunctions/__pycache__/fx.cpython-39.pyc +0 -0
  25. mLogsFunctions/__pycache__/lightGBMPred.cpython-39.pyc +0 -0
  26. mLogsFunctions/__pycache__/rmOutliers.cpython-39.pyc +0 -0
  27. mLogsFunctions/__pycache__/viewCurves.cpython-39.pyc +0 -0
  28. mLogsFunctions/dataloading.py +32 -0
  29. mLogsFunctions/dataprocessing.py +14 -0
  30. mLogsFunctions/fx.py +360 -0
  31. mLogsFunctions/lightGBMPred.py +21 -0
  32. mLogsFunctions/rmOutliers.py +135 -0
  33. mLogsFunctions/viewCurves.py +102 -0
  34. models/05_13_2023_11_50_38_model_LGBM.json +0 -0
  35. pages/1_LAS_Exploratory.py +289 -0
  36. pages/2_Exploratory_Data_Analysis.py +92 -0
  37. pages/3_Fracture_Training_Models.py +388 -0
  38. pages/4_Fracture_Prediction.py +190 -0
  39. requirements.txt +13 -0
  40. ui/PageComponents.py +176 -0
  41. ui/UIConfigs.py +41 -0
  42. ui/__init__.py +18 -0
  43. ui/__pycache__/PageComponents.cpython-39.pyc +0 -0
  44. ui/__pycache__/UIConfigs.cpython-39.pyc +0 -0
  45. ui/__pycache__/__init__.cpython-39.pyc +0 -0
packages.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ freeglut3-dev
2
+ libgtk2.0-dev
.gitattributes CHANGED
@@ -33,3 +33,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ backup/081222/models/LGBM_20221125.json filter=lfs diff=lfs merge=lfs -text
37
+ backup/081222/models/LightGBM_0.45.pbz2 filter=lfs diff=lfs merge=lfs -text
38
+ data/all_file_merged_updated_with_All_geometry.csv filter=lfs diff=lfs merge=lfs -text
Antuns/__pycache__/p1_import_csv.cpython-39.pyc ADDED
Binary file (616 Bytes). View file
 
Antuns/__pycache__/page_setting.cpython-39.pyc ADDED
Binary file (726 Bytes). View file
 
Antuns/__pycache__/prediction_LGBM.cpython-39.pyc ADDED
Binary file (678 Bytes). View file
 
Antuns/page_setting.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+ img = Image.open("/work/2022_VPIMLogs_WebApp/data/LogoVPI.png")
4
+ def page_intro():
5
+ st.set_page_config(# Alternate names: setup_page, page, layout
6
+ layout="wide", # Can be "centered" or "wide". In the future also "dashboard", etc.
7
+ initial_sidebar_state="auto", # Can be "auto", "expanded", "collapsed"
8
+ page_title="VPI-MLogs", # String or None. Strings get appended with "• Streamlit".
9
+ page_icon=img, # String, anything supported by st.image, or None.
10
+ )
11
+ col_1, col_2, col_3, col_4, col_5, = st.columns(5)
12
+ with col_3:
13
+ st.image("https://i.ibb.co/Yd42K98/LogoVPI.png", width=250)
14
+ st.header("Welcome to VPI-MLOGS!")
Antuns/prediction_LGBM.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+
3
+ def Prediction_LGBM(trained_models:list=None, data:pd.DataFrame=None, feature_names:list=None):
4
+ """
5
+ mode: "predict", "predict_proba"
6
+ """
7
+ data_copy = data.copy()
8
+ # if mode == "predict":
9
+ # for i, model in enumerate(trained_models):
10
+ # y_preds = model.predict(data_copy[feature_names])
11
+ # data_copy[f"model_{i}"] = y_preds
12
+ #
13
+ # else:
14
+ for i, model in enumerate(trained_models):
15
+ y_preds = model.predict(data_copy[feature_names])
16
+ data_copy[f"model_{i}"] = y_preds
17
+
18
+ return data_copy
19
+
20
+ if __name__ == '__main__':
21
+ Prediction_LGBM()
app.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from ui.UIConfigs import *
3
+
4
+ #Streamlit dashboard------------------------------------------------------------------------------------------
5
+ set_page_config(page='home', logo_size=200)
6
+ hide_menu_button()
7
+ condense_layout()
8
+
9
+ st.sidebar.success("")
10
+ st.markdown("""
11
+ <style>
12
+ h2 {
13
+ text-align: left;
14
+ }
15
+ </style>
16
+ """, unsafe_allow_html=True)
17
+ # st.markdown("""
18
+ # <center><h2>VPI-MLOGs Web App</h2></center>
19
+ # <b>VPI-MLOGs</b> is a web app designed for log data analysis and visualization. It provides various functions to help users process, analyze, and visualize log data.<br>
20
+ # <h4>1. Read LAS Files and Convert to CSV Files</h4>
21
+
22
+ # <b>VPI-MLOGs</b> allows users to upload LAS files and convert them to CSV format. This feature makes it easy to work with log data in other programs, such as Excel or Python.
23
+
24
+ # <h4>2. Explore Data Analysis with Multiple Charts</h4>
25
+
26
+ # <b>VPI-MLOGs</b> provides several exploratory data analysis (EDA) functions, such as detecting missing data, generating histograms, and visualizing distribution. These functions help users understand the structure and characteristics of the log data.<br>
27
+
28
+ # <h4>3. Training LGBM Model</h4>
29
+
30
+ # <b>VPI-MLOGs</b> provides a machine learning feature that allows users to train a LGBM (Light Gradient Boosting Machine) model using their log data.
31
+
32
+ # <h4>4. Prediction</h4>
33
+
34
+ # <b>VPI-MLOGs</b> Users can also make predictions using the trained model.
35
+ # """
36
+ st.markdown("""
37
+ <center><h2>VPI-MLOGs Web App</h2></center>
38
+
39
+ **Read LAS Files and Convert to CSV Files**
40
+
41
+ VPI-MLOGs enables the reading of LAS files, a commonly used format for storing log data. Once uploaded, VPI-MLOGs can convert LAS files to the CSV format, which is more widely compatible with other programs like Excel or Python.
42
+
43
+ **Explore Data Analysis with Multiple Charts**
44
+
45
+ VPI-MLOGs offers various exploratory data analysis (EDA) functions to better understand the characteristics of log data. These EDA functions include:
46
+
47
+ - **Missing Data Detection**: Identifies any missing data points in the log data.
48
+ - **Histogram Generation**: Creates graphical representations of data value distributions.
49
+ - **Distribution Visualization**: Creates graphical representations showcasing the spread of data values.
50
+ - **Outliers Removal**: Identifies any data points that are significantly different from the rest of the data.
51
+
52
+ **Training LGBM Model**
53
+
54
+ VPI-MLOGs provides a machine learning feature that enables users to train a LGBM (Light Gradient Boosting Machine) model using their log data. LGBM is a versatile machine learning algorithm suitable for various tasks like classification and regression. Once trained, the LGBM model can be used to make predictions on new data.
55
+
56
+ **Prediction**
57
+
58
+ VPI-MLOGs allows users to make predictions using the trained model. These predictions can be applied to new data not present in the training set. This functionality proves beneficial for tasks like identifying potential drilling targets or predicting rock formation properties.
59
+
60
+ In summary, VPI-MLOGs is a powerful tool for processing, analyzing, and visualizing log data. It offers a diverse range of functions that aid users in gaining a deeper understanding of their data, enabling them to make more informed decisions.
61
+ """
62
+ ,unsafe_allow_html=True)
backup/081222/Antuns/p1_import_csv.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+
4
+ def upload_csv():
5
+ df = None
6
+ uploaded_file = st.file_uploader(label='Upload *csv file from your drive! Choose a file:', type='csv')
7
+ if uploaded_file is not None:
8
+ df = pd.read_csv(uploaded_file, na_values=-9999)
9
+ st.success("Loading finished!")
10
+ st.dataframe(df, width=1400, height=300)
11
+ st.write('---')
12
+ return df
13
+
backup/081222/Antuns/page_setting.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+ img = Image.open("data/LogoVPI.png")
4
+ def page_intro():
5
+ st.set_page_config(# Alternate names: setup_page, page, layout
6
+ layout="wide", # Can be "centered" or "wide". In the future also "dashboard", etc.
7
+ initial_sidebar_state="auto", # Can be "auto", "expanded", "collapsed"
8
+ page_title="VPI-MLogs", # String or None. Strings get appended with "• Streamlit".
9
+ page_icon=img, # String, anything supported by st.image, or None.
10
+ )
11
+ col_1, col_2, col_3, col_4, col_5, = st.columns(5)
12
+ with col_3:
13
+ st.image("https://i.ibb.co/Yd42K98/LogoVPI.png", width=250)
14
+ st.header("Welcome to VPI-MLOGS!")
backup/081222/Antuns/prediction_LGBM.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+
3
+ def Prediction_LGBM(trained_models:list=None, data:pd.DataFrame=None, feature_names:list=None):
4
+ """
5
+ mode: "predict", "predict_proba"
6
+ """
7
+ data_copy = data.copy()
8
+ # if mode == "predict":
9
+ # for i, model in enumerate(trained_models):
10
+ # y_preds = model.predict(data_copy[feature_names])
11
+ # data_copy[f"model_{i}"] = y_preds
12
+ #
13
+ # else:
14
+ for i, model in enumerate(trained_models):
15
+ y_preds = model.predict(data_copy[feature_names])
16
+ data_copy[f"model_{i}"] = y_preds
17
+
18
+ return data_copy
19
+
20
+ if __name__ == '__main__':
21
+ Prediction_LGBM()
backup/081222/Homepage.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from Antuns.page_setting import page_intro
3
+
4
+ #Streamlit dashboard------------------------------------------------------------------------------------------
5
+ page_intro()
6
+ st.sidebar.success("")
7
+ st.markdown("""
8
+ :flag-vn:
9
+ """
10
+ ,unsafe_allow_html=False)
backup/081222/models/LGBM_20221125.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:02b0cb118e7b9a39b3003abb0701c7be91f1acb1b0df30635a93a149a4968049
3
+ size 14032845
backup/081222/models/LightGBM_0.45.pbz2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e960d2e933f4884dc0df6a55c33819807ae4beb86a35489685dd209a7699aeab
3
+ size 1936897
backup/model.json ADDED
The diff for this file is too large to render. See raw diff
 
data/LogoVPI.png ADDED
data/all_file_merged_updated_with_All_geometry.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:58c41e72f17af5c6235cbd79ec9700d539c96303d998b0f33018bfaaad4402b1
3
+ size 12897889
data/merged/Training_data.csv ADDED
The diff for this file is too large to render. See raw diff
 
data/merged/merged_df.csv ADDED
The diff for this file is too large to render. See raw diff
 
mLogsFunctions/__init__.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .dataloading import *
2
+ from .dataprocessing import *
3
+ from .viewCurves import *
4
+ from .rmOutliers import *
5
+ from .lightGBMPred import *
6
+
7
+ __all__ = ['csv_uploader',
8
+ 'tweak_data',
9
+ 'columns_list',
10
+ 'well_filter',
11
+ 'view_curves',
12
+ 'rmOutliers',
13
+ 'Prediction_LGBM',
14
+
15
+ #FX
16
+ 'upload_csv',
17
+ 'selection_info',
18
+ 'interval_define',
19
+ 'make_selection',
20
+ 'bar_plot',
21
+ 'curve_plot',
22
+ 'missing_bar',
23
+ 'missing_box',
24
+ 'hist_line_plot',
25
+ 'crossplot',
26
+ 'pairplot',
27
+ 'heatmap',
28
+ 'plotly_3d',
29
+
30
+
31
+ ]
mLogsFunctions/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (541 Bytes). View file
 
mLogsFunctions/__pycache__/dataloading.cpython-39.pyc ADDED
Binary file (1.2 kB). View file
 
mLogsFunctions/__pycache__/dataprocessing.cpython-39.pyc ADDED
Binary file (647 Bytes). View file
 
mLogsFunctions/__pycache__/fx.cpython-39.pyc ADDED
Binary file (7.84 kB). View file
 
mLogsFunctions/__pycache__/lightGBMPred.cpython-39.pyc ADDED
Binary file (571 Bytes). View file
 
mLogsFunctions/__pycache__/rmOutliers.cpython-39.pyc ADDED
Binary file (4.17 kB). View file
 
mLogsFunctions/__pycache__/viewCurves.cpython-39.pyc ADDED
Binary file (11.3 kB). View file
 
mLogsFunctions/dataloading.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import streamlit as st
3
+
4
+ def csv_uploader(label:str='', type:str='csv'):
5
+ uploaded_file = st.file_uploader(label=label, type=type)
6
+ loading_data = None
7
+ if uploaded_file is not None:
8
+ if type == 'csv':
9
+ loading_data = pd.read_csv(uploaded_file, na_values=-9999)
10
+ return loading_data
11
+
12
+ @st.cache_data
13
+ def tweak_data(data, reindex:bool=True, resample:bool=False, max_number:int=5000):
14
+ if data is not None:
15
+ data = data.rename(str.upper, axis='columns')
16
+ if len(data) > max_number and resample:
17
+ data = data.sample(max_number, random_state=42)
18
+ if set(["DEPTH", 'WELL']).issubset(data.columns.unique()):
19
+ data.assign(
20
+ DEPTH=data.DEPTH.astype('float64'),
21
+ WELL=data.WELL.astype("string"),
22
+ )
23
+ if "FRACTURE_ZONE" in data.columns.unique():
24
+ data = data.rename(columns={'FRACTURE_ZONE':'FRACTUREZONE'})
25
+ if "FRACTURE INTENSITY" in data.columns.unique():
26
+ data = data.rename(columns={'FRACTURE INTENSITY':'FRACTURE_INTENSITY'})
27
+ # if "FRACTUREZONE" in data.columns.unique():
28
+ # data = data.reset_index(drop=True).drop(["FRACTUREZONE"], axis=1)
29
+ if reindex:
30
+ data = data.reindex(sorted(data.columns), axis=1) #Reindex and sort columns name
31
+ return data
32
+
mLogsFunctions/dataprocessing.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import streamlit as st
3
+
4
+ def columns_list(data:pd.DataFrame, no_depth:bool=None, no_well:bool=None):
5
+ columns_list = list(data.columns.unique())
6
+ columns_list.sort()
7
+ if "DEPTH" in columns_list and no_depth == True:
8
+ columns_list.remove("DEPTH")
9
+ if "WELL" in columns_list and no_well == True:
10
+ columns_list.remove("WELL")
11
+ return columns_list
12
+
13
+ def well_filter(df, well_name):
14
+ return df[df.WELL == well_name]
mLogsFunctions/fx.py ADDED
@@ -0,0 +1,360 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+
4
+ # import matplotlib.pyplot as plt
5
+ import seaborn as sns
6
+ import plotly.express as px
7
+
8
+ import altair as alt
9
+
10
+ import streamlit as st
11
+ import streamlit_nested_layout
12
+ from streamlit_vega_lite import altair_component
13
+
14
+ from mLogsFunctions import *
15
+
16
+ #LOADING DATA------------------------------------------------------------------------------------------
17
+ def upload_csv():
18
+ df = None
19
+ uploaded_file = st.file_uploader(label='Upload *csv file from your drive! Choose a file:', type='csv')
20
+ if uploaded_file is not None:
21
+ df = pd.read_csv(uploaded_file, na_values=-9999)
22
+ st.success("Loading finished!")
23
+ st.write('---')
24
+ return df
25
+
26
+ #PLOTTING------------------------------------------------------------------------------------------
27
+ # Store the initial value of widgets in session state
28
+ def selection_info(df, method, option_w, option_x, option_y, option_c):
29
+ if "method" not in st.session_state:
30
+ st.session_state.method:str = "Single Well"
31
+ st.session_state.option_w:str = "15-1-SNN-3P"
32
+ st.session_state.option_x:str = "RHOB"
33
+ st.session_state.option_y:str = "DTC"
34
+ st.session_state.option_c:str = "WELL"
35
+ well_names = np.sort(df.WELL.unique())
36
+ st.radio("",
37
+ key=method,
38
+ options=["All Wells", "Single Well"],)
39
+ st.radio(
40
+ "WELL",
41
+ key=option_w,
42
+ options=well_names,)
43
+ st.selectbox(
44
+ "X Axis",
45
+ key=option_x,
46
+ options=(df.columns.sort_values().str.upper().drop(["WELL", "DEPTH"])),)
47
+ st.selectbox(
48
+ "Y Axis",
49
+ key=option_y,
50
+ options=(df.columns.sort_values().str.upper().drop(["WELL", "DEPTH"])),)
51
+ st.selectbox(
52
+ "Color Axis",
53
+ key=option_c,
54
+ options=df.columns.sort_values().str.upper())
55
+ return st.session_state
56
+
57
+ #Interactive Charts-----------------------------------------------------------------------
58
+ @st.cache_resource
59
+ def interval_define():
60
+ return alt.selection_interval()
61
+
62
+ @st.cache_resource
63
+ def make_selection(df, _interval, option_x, option_y, option_c):
64
+ def c_(df, _interval, option_x, option_y, x_log:str="linear", y_log:str="linear"):
65
+ return alt.Chart(df,
66
+ title="Crossplot "+option_x+" vs "+option_y+"",
67
+ ).mark_point().encode(
68
+ x = alt.X(option_x.upper(),
69
+ axis=alt.Axis(title=option_x),
70
+ scale= alt.Scale(zero=False, type=x_log
71
+ )
72
+ ),
73
+ y = alt.Y(option_y.upper(),
74
+ axis=alt.Axis(title=option_y),
75
+ scale=alt.Scale(zero=False,type=y_log
76
+ )
77
+ ),
78
+ color=alt.condition(_interval, option_c, alt.value('lightgray')),
79
+ ).properties(
80
+ selection=_interval,
81
+ height=570,
82
+ width=600)#.transform_regression(option_x.upper(), option_y.upper()).mark_line()
83
+
84
+ if option_x in ["LLD", "LLS"]:
85
+ x_log = "log"
86
+ else:
87
+ x_log = "linear"
88
+
89
+ if option_y in ["LLD", "LLS"]:
90
+ y_log = "log"
91
+ else:
92
+ y_log = "linear"
93
+ return c_(df, _interval, option_x, option_y, x_log, y_log)
94
+
95
+ #Histogram-----------------------------------------------------------------------
96
+ def bar_plot(data, option_x):
97
+ def c_(data, option_x, _log):
98
+ return alt.Chart(title="Histogram of "+option_x+"",
99
+ data=data
100
+ ).mark_bar().encode(
101
+ x = alt.X(option_x.upper(),
102
+ bin=alt.Bin(maxbins=30),
103
+ axis=alt.Axis(title=option_x),
104
+ scale=alt.Scale(zero=False)
105
+ ),
106
+ y = alt.Y('count()',
107
+ axis=alt.Axis(title='Number of Values'),
108
+ scale=alt.Scale(zero=False, type=_log),
109
+ ),
110
+ color = alt.Color('WELL', legend=None
111
+ )
112
+ ).properties(
113
+ height=250,
114
+ width=250
115
+ )
116
+ if option_x in ["LLD", "LLS"]:
117
+ return c_(data, option_x, "symlog")
118
+ else:
119
+ return c_(data, option_x, "linear")
120
+
121
+ #Curve View-----------------------------------------------------------------------
122
+ def curve_plot(data,filted_data, x_column):
123
+ def c_(data,filted_data, x_column, _log):
124
+ color_codes = {"GR":"lime",
125
+ "LLD":"red",
126
+ "LLS":"dodgerblue",
127
+ "NPHI":"blue",
128
+ "RHOB":"red",
129
+ "DTC":"red",
130
+ "DTS":"magenta",
131
+ "FRACTURE_ZONE":"lightcoral",
132
+ "FRACTURE_ZONE_PRED":"lightgreen"
133
+ }
134
+ if x_column in color_codes.keys():
135
+ color_ = color_codes[x_column]
136
+ else:
137
+ color_ = "blue"
138
+ return alt.Chart(data
139
+ ).mark_line(size=1,
140
+ orient='horizontal',
141
+ color=color_,
142
+ point=alt.OverlayMarkDef(color="", size=1) #Show raw points
143
+ ).encode(
144
+ x=alt.X(x_column.upper(),
145
+ scale=alt.Scale(zero=False, type=_log),
146
+ axis=alt.Axis(title=x_column.upper(),
147
+ titleAnchor='middle',
148
+ orient='top',
149
+ labelAngle=0,
150
+ titleColor=color_,
151
+ labelColor=color_,
152
+ tickColor=color_,
153
+ )
154
+ ),
155
+ y=alt.Y('DEPTH',
156
+ scale=alt.Scale(zero=False,
157
+ reverse=True,
158
+ ),
159
+ axis=alt.Axis(title=None,
160
+ labelColor=color_,
161
+ tickColor=color_,
162
+ )
163
+ )
164
+ ).properties(height=500,
165
+ width=129
166
+ )
167
+
168
+
169
+ if x_column in ["LLD", "LLS"]:
170
+ curve = c_(data,filted_data, x_column, "log")
171
+ else:
172
+ curve = c_(data,filted_data, x_column, "linear")
173
+
174
+ if filted_data is not None:
175
+ point_plot = alt.Chart(filted_data).mark_circle(size=20,
176
+ color='red',
177
+ opacity=1
178
+ ).encode(
179
+ x=x_column,
180
+ y='DEPTH'
181
+ )
182
+ return curve + point_plot
183
+ else:
184
+ return curve
185
+ # import altair as alt
186
+ # def curve_plot(data, filted_data, x_column):
187
+ # def c_(data, filted_data, x_column, _log):
188
+ # color_codes = {
189
+ # "GR": "lime",
190
+ # "LLD": "red",
191
+ # "LLS": "dodgerblue",
192
+ # "NPHI": "blue",
193
+ # "RHOB": "red",
194
+ # "DTC": "red",
195
+ # "DTS": "magenta",
196
+ # "FRACTURE_ZONE": "lightcoral",
197
+ # "FRACTURE_ZONE_PRED": "lightgreen"
198
+ # }
199
+ # if x_column in color_codes.keys():
200
+ # color_ = color_codes[x_column]
201
+ # else:
202
+ # color_ = "blue"
203
+ # return alt.Chart(data).mark_line(size=1, orient='horizontal', color=color_, point=alt.OverlayMarkDef(color="", size=1)).encode(
204
+ # y=alt.X(x_column.upper(),
205
+ # scale=alt.Scale(zero=False, type=_log),
206
+ # axis=alt.Axis(title=x_column.upper(),
207
+ # titleAnchor='middle',
208
+ # orient='top',
209
+ # labelAngle=0,
210
+ # titleColor=color_,
211
+ # labelColor=color_,
212
+ # tickColor=color_,
213
+ # )
214
+ # ),
215
+ # x=alt.Y('DEPTH',
216
+ # scale=alt.Scale(zero=False, reverse=True),
217
+ # axis=alt.Axis(title=None, labelColor=color_, tickColor=color_))
218
+ # ).properties(
219
+ # height=500,
220
+ # width=700
221
+ # )
222
+
223
+ # if x_column in ["LLD", "LLS"]:
224
+ # curve = c_(data, filted_data, x_column, "log")
225
+ # else:
226
+ # curve = c_(data, filted_data, x_column, "linear")
227
+
228
+ # if filted_data is not None:
229
+ # point_plot = alt.Chart(filted_data).mark_circle(size=20, color='red', opacity=1).encode(
230
+ # y=alt.X(x_column, scale=alt.Scale(zero=False)),
231
+ # x=alt.Y('DEPTH', scale=alt.Scale(zero=False, reverse=True))
232
+ # )
233
+ # return (curve + point_plot).resolve_scale(y='shared')
234
+ # else:
235
+ # return curve
236
+
237
+
238
+ #MissingBar-----------------------------------------------------------------------
239
+ def missing_bar(data, x_title):
240
+ return alt.Chart(data).mark_bar().encode(
241
+ x=alt.X('Columns', sort='-y', title=x_title),
242
+ y='Count missing (%)',
243
+ color=alt.condition(
244
+ alt.datum['Count missing (%)'] >10, # If count missing is > 10%, returns True,
245
+ alt.value('orange'), # which sets the bar orange.
246
+ alt.value('steelblue') # And if it's not true it sets the bar steelblue.
247
+ )
248
+ ).properties(
249
+ width=500,
250
+ height=250
251
+ ).configure_axis(
252
+ grid=False
253
+ )
254
+ #BoxPLot-----------------------------------------------------------------------
255
+ def missing_box(data, curve):
256
+ if curve in ["LLD", "LLS"]:
257
+ return alt.Chart(data).mark_boxplot(extent='min-max').encode(
258
+ x=alt.X('WELL:O', title=None,
259
+ ),
260
+ y=alt.Y(f'{curve}:Q', title=curve,scale=alt.Scale(zero=False, type="log")
261
+ ),
262
+ color='WELL:N'
263
+ ).properties(
264
+ width=500,
265
+ height=300
266
+ )
267
+ else:
268
+ return alt.Chart(data).mark_boxplot(extent='min-max').encode(
269
+ x=alt.X('WELL:O', title=None
270
+ ),
271
+ y=alt.Y(f'{curve}:Q', title=curve,scale=alt.Scale(zero=False)
272
+ ),
273
+ color='WELL:N'
274
+ ).properties(
275
+ width=500,
276
+ height=300
277
+ )
278
+ #Histogram Line-----------------------------------------------------------------------
279
+ def hist_line_plot(data, curve):
280
+ st.caption(f"Histogram of {curve}")
281
+ if curve in ["LLD", "LLS"]:
282
+ fig = sns.displot(data, x=curve, hue="WELL", kind="kde", height=5,aspect=1.2, log_scale=True)
283
+ fig.set(ylabel="Values")
284
+ st.pyplot(fig)
285
+ else:
286
+ fig = sns.displot(data, x=curve, hue="WELL", kind="kde", height=5,aspect=1.2)
287
+ fig.set(ylabel="Values")
288
+ st.pyplot(fig)
289
+ #CrossPlot-----------------------------------------------------------------------
290
+ def crossplot(data, x_curve, y_curve):
291
+ fig = sns.jointplot(data=data, x=x_curve, y=y_curve, hue="WELL")
292
+ if x_curve in ["LLD", "LLS"]:
293
+ fig.ax_joint.set_xscale('log')
294
+ fig.ax_marg_x.set_xscale('log')
295
+ if y_curve in ["LLD", "LLS"]:
296
+ fig.ax_joint.set_yscale('log')
297
+ fig.ax_marg_y.set_yscale('log')
298
+ st.pyplot(fig)
299
+ #PairPlot-----------------------------------------------------------------------
300
+ def pairplot(data, rows, cols,color_):
301
+ return alt.Chart(data).mark_circle().encode(
302
+ alt.X(alt.repeat("column"), type='quantitative', scale=alt.Scale(zero=False)),
303
+ alt.Y(alt.repeat("row"), type='quantitative', scale=alt.Scale(zero=False)),
304
+ color=color_
305
+ ).properties(
306
+ width=100,
307
+ height=100
308
+ ).repeat(
309
+ row = rows,
310
+ column = cols
311
+ ).configure_axis(
312
+ grid=False
313
+ )
314
+ #Heatmap----------------------------------------------------------------
315
+ def heatmap(df):
316
+ fig = sns.heatmap(df, annot=True)
317
+ st.pyplot(fig)
318
+ #Heatmap----------------------------------------------------------------
319
+ def plotly_3d(data, x, y, z, color, size, symbol, log_x, log_y, log_z):
320
+ #Data slicer
321
+ curvs_ = columns_list(data, no_well=True)
322
+ def slicer_(data, sli_key, val_key,):
323
+ slicer1_, slicer2_ = st.columns([4, 6])
324
+ # sli=curvs_[0]
325
+ with slicer1_:
326
+ sli = st.selectbox("Data slicer", key=sli_key, options=curvs_)
327
+ with slicer2_:
328
+ values = st.slider('Select a range of values',
329
+ min_value = float(data[sli].min()),
330
+ max_value = float(data[sli].max()),
331
+ value=(float(data[sli].min()), float(data[sli].max())),
332
+ key=val_key,
333
+ )
334
+ data = data.query(f"{sli} >= {values[0]} and {sli} <= {values[1]}")
335
+ return data
336
+ c1, c2, c3 = st.columns(3)
337
+ with c1:
338
+ data = slicer_(data, "slicer_1", "sli1_value")
339
+ with c2:
340
+ data = slicer_(data, "slicer_2", "sli2_value")
341
+ with c3:
342
+ data = slicer_(data, "slicer_3", "sli3_value")
343
+
344
+ fig = px.scatter_3d(data, x=x,
345
+ y=y,
346
+ z=z,
347
+ color=color,
348
+ size=size,
349
+ size_max=18,
350
+ symbol=symbol,
351
+ opacity=0.7,
352
+ log_x=log_x,
353
+ log_y=log_y,
354
+ log_z = log_z,
355
+ width=1000, height=700,
356
+ color_continuous_scale="blugrn")
357
+ fig.update_layout(margin=dict(l=0, r=0, b=0, t=0), #tight layout
358
+ # paper_bgcolor="LightSteelBlue"
359
+ template="none")
360
+ st.plotly_chart(fig)
mLogsFunctions/lightGBMPred.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+
3
+ def Prediction_LGBM(trained_models:list=None, data:pd.DataFrame=None, feature_names:list=None):
4
+ """
5
+ mode: "predict", "predict_proba"
6
+ """
7
+ data_copy = data.copy()
8
+ # if mode == "predict":
9
+ # for i, model in enumerate(trained_models):
10
+ # y_preds = model.predict(data_copy[feature_names])
11
+ # data_copy[f"model_{i}"] = y_preds
12
+ #
13
+ # else:
14
+ for i, model in enumerate(trained_models):
15
+ y_preds = model.predict(data_copy[feature_names])
16
+ data_copy[f"model_{i}"] = y_preds
17
+
18
+ return data_copy
19
+
20
+ if __name__ == '__main__':
21
+ Prediction_LGBM()
mLogsFunctions/rmOutliers.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import pandas as pd
3
+ import streamlit as st
4
+ import altair as alt
5
+ from streamlit_vega_lite import altair_component
6
+
7
+ from .fx import *
8
+ from mLogsFunctions import *
9
+
10
+ def rmOutliers(df):
11
+ _o1, _o2 = st.columns([1,8])
12
+ with _o1:
13
+ st.session_state = selection_info(df,"method", "option_w", "option_x", "option_y", "option_c")
14
+
15
+ #Crossplot and bar plot-----------------------------------------------------------------------
16
+ with _o2:
17
+ def rm_outliers(data):
18
+ interval = interval_define()
19
+ col21, col22 = st.columns(2)
20
+ with col21:
21
+ selected_points = altair_component(make_selection(data,
22
+ interval,
23
+ st.session_state.option_x,
24
+ st.session_state.option_y,
25
+ st.session_state.option_c,
26
+ )
27
+ )
28
+ if len(selected_points) > 0:
29
+ del[selected_points['name']]
30
+
31
+ with col22:
32
+ selected_df = None
33
+ if len(selected_points) != 0:
34
+ query = ' & '.join(
35
+ f'{crange[0]} <= `{col}` <= {crange[1]}'
36
+ for col, crange in selected_points.items())
37
+ selected_df = data.query(query)
38
+ st.write(f"Total selected points: {len(selected_df)}")
39
+ st.dataframe(selected_df, width=800, height=260,use_container_width=False)
40
+ else:
41
+ st.write("No Selection")
42
+
43
+ if selected_df is not None:
44
+ st.write("Histogram of selected data:")
45
+ histogram_x = bar_plot(selected_df, st.session_state.option_x)
46
+ histogram_y = bar_plot(selected_df, st.session_state.option_y)
47
+ st.write(alt.hconcat(histogram_x,histogram_y))
48
+ else:
49
+ st.write("Histogram of entire data:")
50
+ histogram_x = bar_plot(data, st.session_state.option_x)
51
+ histogram_y = bar_plot(data, st.session_state.option_y)
52
+ st.write(alt.hconcat(histogram_x,histogram_y))
53
+
54
+ #Outlier Removal-----------------------------------------------------------------------
55
+ st.write('---')
56
+ df_nomarlized = data.copy()
57
+ curve_editting = st.selectbox("Select curve to edit:",
58
+ key="selected_curve",
59
+ options=columns_list(data, no_depth=True, no_well=True),
60
+ )
61
+ n_value = int(st.text_input("Number of rows for Mean calculation ", "5"))
62
+
63
+ def normalize_outlier(df_nomarlized, selected_df, curve, n_value):
64
+ n=n_value//2
65
+ for i in selected_df.index:
66
+ df_nomarlized.loc[[i],curve.upper()] = df_nomarlized.loc[i-n:i+n,curve.upper()].mean()
67
+ return df_nomarlized
68
+ def remove_data_point(df_nomarlized, selected_df, curve):
69
+ for i in selected_df.index:
70
+ df_nomarlized[i, curve] = 0 #ERROR ALARM!!!!
71
+ # df_nomarlized = df_nomarlized.drop(index=i) #ERROR ALARM!!!!
72
+ return df_nomarlized
73
+
74
+ if st.button("Outliers Processing"):
75
+ st.session_state.fdata = normalize_outlier(df_nomarlized, selected_df, curve_editting, n_value)
76
+ _well = "".join((st.session_state.fdata.WELL.unique()).tolist())
77
+ st.session_state.loc_data = pd.concat([df[(df["WELL"] != _well)],st.session_state.fdata], axis=0)
78
+ selected_df = None
79
+ if st.button("Remove"):
80
+ st.session_state.fdata = remove_data_point(df_nomarlized, selected_df, curve_editting)
81
+ _well = "".join((st.session_state.fdata.WELL.unique()).tolist())
82
+ st.write(_well)
83
+ st.write(type(_well))
84
+ st.session_state.loc_data = pd.concat([df[(df["WELL"] != _well)],st.session_state.fdata], axis=0)
85
+ selected_df = None
86
+
87
+ #Curve View-----------------------------------------------------------------------
88
+ def plt_curs(data, option_w):
89
+ data_plt = data[data["WELL"] == option_w]
90
+ if plotting_curves != []:
91
+ for i, c in enumerate(plotting_curves):
92
+ charts_dict[i] = curve_plot(data=data_plt,filted_data=selected_df, x_column=c)
93
+
94
+ # with col2:
95
+ charts_dict={}
96
+ plotting_curves = st.multiselect("Select curves to plot:", key="curvs_plt", options=columns_list(data, no_depth=True, no_well=True))
97
+
98
+ if st.session_state.option_w is not None:
99
+ if 'loc_data' not in st.session_state:
100
+ plt_curs(df_nomarlized, st.session_state.option_w)
101
+ else:
102
+ plt_curs(st.session_state.loc_data, st.session_state.option_w)
103
+
104
+ #Show Curve-----------------------------------------------------------------------
105
+ st.write(alt.concat(*charts_dict.values()).configure(autosize='fit'))#.configure_concat(spacing=0))
106
+
107
+ #------------------------
108
+ def check_method(df):
109
+ if st.session_state.method == "Single Well":
110
+ data = df[df.WELL == st.session_state.option_w]
111
+ data = data.sort_values(by=['DEPTH'])
112
+ data = data.reset_index().drop(["index"], axis=1)
113
+ else:
114
+ data = df
115
+ return data
116
+ #------------------------
117
+
118
+ if 'loc_data' not in st.session_state:
119
+ data = check_method(df)
120
+ else:
121
+ data = check_method(st.session_state.loc_data)
122
+
123
+ rm_outliers(data)
124
+
125
+ # # Download --------------------------------------------------------------
126
+ st.write('---')
127
+ st.write("Download final result to csv file")
128
+ if "loc_data" not in st.session_state:
129
+ saving_df = df
130
+ else:
131
+ saving_df = st.session_state.loc_data
132
+ st.download_button(label='Download',
133
+ data = saving_df.to_csv(),
134
+ file_name='Query_data.csv',
135
+ mime='text/csv')
mLogsFunctions/viewCurves.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import streamlit as st
3
+ import plotly.graph_objects as go
4
+ from plotly.subplots import make_subplots
5
+ import json
6
+ #Curve View--------------------------------------------------------------------------------------------------------------
7
+ #OPERATIONS--------------------------------------------------------------------------------------------------------------
8
+ #Make subplots layout
9
+ def view_curves(data:pd.DataFrame=None, curves:list=[], log:list=[],
10
+ depth_col:str='DEPTH', new_color:dict={}, new_unit:dict={},
11
+ ):
12
+ #FUNCTIONS DESIGNING-------------------------------------------------------------------------------------------------
13
+ #Function of Plotting single curve
14
+ def add_trace(curv:str=None, color:str='#38a2e8', xaxis:str='x1', unit:str=None, id_subplt:int=1, log:list=None):
15
+ fig.add_trace(go.Scattergl(y=data[depth_col], x=data[curv], name=curv, mode="lines", line=dict(color=color, width=1.), xaxis=xaxis),1 ,id_subplt)\
16
+ .update_xaxes(title_text=f'{curv} ({unit})', row=1, col=id_subplt, color=color,
17
+ tickcolor=color, minor=dict(tickcolor=color), tickfont=dict(color=color))
18
+ if curv in log:
19
+ fig.update_xaxes(type='log', row=1, col=id_subplt)
20
+
21
+ #Function to update X-Axis parameters
22
+ def update_xaxes(type:str=None):
23
+ fig.update_xaxes(
24
+ title_font=dict(size=16, family='Arial'),
25
+ title_standoff = 0, side='top', nticks=5, fixedrange=True,
26
+ ticks="inside", tickwidth=1, ticklen=8, ticklabelstep=1,
27
+ tickfont=dict(family="Arial", size=12),
28
+ minor_ticks="inside", minor=dict(ticklen=4, showgrid=True),
29
+ showline=True, linewidth=1, linecolor='black', mirror=True,
30
+ showgrid=True, gridwidth=1, gridcolor='#d9d9d9',
31
+ showspikes=True, spikecolor="#8d9199", spikesnap="hovered data", spikemode="across", spikethickness=1, spikedash='solid',
32
+ )
33
+ if type is not None:
34
+ fig.update_xaxes(type=type)
35
+
36
+ #Function to update Y-Axis parameters
37
+ def update_yaxes(type:str=None):
38
+ fig.update_yaxes(
39
+ # title_font=dict(size=18, family='Arial', color='#393533'),
40
+ # matches='y'
41
+ title_standoff = 0,
42
+ autorange="reversed",
43
+ nticks=10,
44
+ ticks="outside", tickwidth=1, tickcolor='black', ticklen=8, ticklabelstep=1,
45
+ tickfont=dict(family="Arial", color='black', size=12),
46
+ minor_ticks="outside", minor=dict(ticklen=4, tickcolor="black", showgrid=False),
47
+ showline=True, linewidth=1, linecolor='black', mirror=True,
48
+ showgrid=True, gridwidth=1, gridcolor='#d9d9d9',
49
+ rangemode='nonnegative', #(normal or tozero or nonnegative)
50
+ showspikes=True, spikecolor="#8d9199", spikesnap="cursor", spikemode="across", spikethickness=1, spikedash='solid',
51
+ )
52
+ if type is not None:
53
+ fig.update_yaxes(type=type)
54
+
55
+ #Function to update FIGURE LAYOUT parameters
56
+ def update_layout(_size:list=[400,800]):
57
+ fig.update_layout(
58
+ width=_size[0], height=_size[1],
59
+ showlegend=False,
60
+ plot_bgcolor="white",
61
+ margin=dict(t=10,l=10,b=10,r=10),
62
+ hovermode="y", #"y unified", "y", "x", "closest"
63
+ )
64
+
65
+ #VARIABLES DEFINITION------------------------------------------------------------------------------------------------
66
+ #Sort dataframe by DEPTH
67
+ data = data.sort_values(by=depth_col)
68
+
69
+ #Default color codes
70
+ meta_info = '{"Unit":{"HCAL":"in","CALI":"in","CALS":"in","C1":"in","C2":"in","RHOB":"g\\/c3","RHO8":"g\\/c3","RHO8_filte":"g\\/c3","RHOZ":"g\\/c3","ZDEN":"g\\/c3","ZDNC":"g\\/c3","HDRA":"g\\/c3","DRHO":"g\\/c3","DSOZ":"g\\/c3","ECD_ARC":"g\\/c3","NPHI":"v\\/v","TNPH":"v\\/v","TNPH_CH":"v\\/v","HNPO":"v\\/v","HNPO_filte":"v\\/v","CNCF":"% (pu)","NPOR":"v\\/v","CH_NPHI":"v\\/v","CH_NPHIds":"v\\/v","CFTC":"Hz","CNTC":"Hz","DTC":"us\\/f","DTCO":"us\\/f","DT":"us\\/f","DT4P":"us\\/f","DT5":"us\\/f","DT_SPL":"us\\/f","DTS":"us\\/f","DTSM":"us\\/f","DT2":"us\\/f","DTSO":"us\\/f","DT4S":"us\\/f","GR":"GAPI","GR1":"GAPI","GR_ARC":"GAPI","CGR":"GAPI","EHGR":"GAPI","ECGR":"GAPI","SGR":"GAPI","GR_SPULSE_BHC":"GAPI","GR_IMP":"GAPI","GRM1":"GAPI","MWD_GR_BHC":"GAPI","GRAM":"GAPI","GR_SPL":"GAPI","GR_CDR":"GAPI","ARC_GR_RT":"GAPI","GR_LWD":"GAPI","POTA":"%","THOR":"ppm","URAN":"ppm","TPRA":"v\\/v","TURA":"v\\/v","UPRA":"v\\/v","LLD":"Ohmm","LLS":"Ohmm","DIL":"Ohmm","ILD":"Ohmm","ILM":"Ohmm","RILD":"Ohmm","RILM":"Ohmm","HRI":"Ohmm","RIDPH":"Ohmm","RIMPH":"Ohmm","RSFL":"Ohmm","HDRS":"Ohmm","HMRS":"Ohmm","LL3":"Ohmm","RIPD":"Ohmm","RIPM":"Ohmm","AT10":"Ohmm","AT20":"Ohmm","AT30":"Ohmm","AT60":"Ohmm","AT90":"Ohmm","AO10":"Ohmm","AO20":"Ohmm","AO30":"Ohmm","AO60":"Ohmm","AO90":"Ohmm","AF10":"Ohmm","AF20":"Ohmm","AF30":"Ohmm","AF60":"Ohmm","AF90":"Ohmm","AHO10":"Ohmm","AHO20":"Ohmm","AHO30":"Ohmm","AHO60":"Ohmm","AHO90":"Ohmm","M2RX":"Ohmm","M2R9":"Ohmm","M2R6":"Ohmm","M2R3":"Ohmm","M2R1":"Ohmm","P16H_UNC":"Ohmm","P22H_UNC":"Ohmm","P28H_UNC":"Ohmm","P34H_UNC":"Ohmm","P40H_UNC":"Ohmm","A28H_UNC":"Ohmm","A34H_UNC":"Ohmm","A40H_UNC":"Ohmm","P16L_UNC":"Ohmm","P22L_UNC":"Ohmm","P28L_UNC":"Ohmm","P34L_UNC":"Ohmm","P40L_UNC":"Ohmm","P22H_UNC_RT":"Ohmm","P40H_UNC_RT":"Ohmm","P40H_UNC_R":"Ohmm","P22H_UNC_R":"Ohmm","HLLD":"Ohmm","HLLS":"Ohmm","RES_DEEP":"Ohmm","RES_SHAL":"Ohmm","Rdeep":"Ohmm","Rshallow":"Ohmm","P33H_UNC":"Ohmm","P33L_UNC":"Ohmm","A33H_UNC":"Ohmm","A33L_UNC":"Ohmm","RACHM":"Ohmm","RACLM":"Ohmm","RPCHM":"Ohmm","RPCLM":"Ohmm","RPCSHM":"Ohmm","RPCSLM":"Ohmm","RACSHM":"Ohmm","RACSLM":"Ohmm","RAC1HM":"Ohmm","RAC1LM":"Ohmm","RPC1HM":"Ohmm","RPC1LM":"Ohmm","RAC2HM":"Ohmm","RAC2LM":"Ohmm","RPC2HM":"Ohmm","RPC2LM":"Ohmm","RAC3HM":"Ohmm","RAC3LM":"Ohmm","RPC3HM":"Ohmm","RPC3LM":"Ohmm","RAC4HM":"Ohmm","RAC4LM":"Ohmm","RPC4HM":"Ohmm","RPC4LM":"Ohmm","MSFL":"Ohmm","RXO8":"Ohmm","ATR":"Ohmm","PSR":"Ohmm","RT":"Ohmm","TAB_CDR_RES":"hr","TAB_ARC_RES":"s","TAB_RES":"s","PEF":"_","PEF8":"_","PERF":"_","PEFZ":"_","ROP5_RM":"m\\/hr","ROP":"m\\/hr","ROP5":"m\\/hr","ROPS":"m\\/hr","RXOZ":"Ohmm","RSOZ":"Ohmm","ITT":"s","TENS":"lbf","TTEN":"lbf","HTEN":"lbf","CDF":"lbf","ATMP":"degC","TEMP_MCR":"_","TVDE":"m","SP":"mV","VPVS":"v\\/v","LSN":"cps","SSN":"cps","APRS_ARC":"psi","ARTM":"_","AGTK":"_","ARTK":"_","Temp":"degC","TEMP_LWD":"degC","WTBH":"degC","WTBH1":"degC","TEMP_DNI_RT":"degC","HSTEMP":"degC","TCDM":"degC","RPTHM":"mins","CHT":"lbf","DPHI":"v\\/v","SPHI":"v\\/v","PHIE":"v\\/v","PR":"_","ICV":"m3","IHV":"m3","GTEM":"degC","DHTEMP":"degC","TTEM_CDR":"degC","SVEL":"m\\/s","TTSL":"us","TT":"us","CBSL":"mV","CBL":"mV","WF2":"_","WF1":"_","CBLF":"mV","CCL":"_","BS":"_","TGAS":"ppm","Oilshow":"_"},"Color":{"HCAL":"#bf2273","CALI":"#bf2273","CALS":"#bf2273","C1":"#bf2273","C2":"#bf2273","RHOB":"#f20a0a","RHO8":"#f20a0a","RHO8_filte":"#f20a0a","RHOZ":"#f20a0a","ZDEN":"#f20a0a","ZDNC":"#f20a0a","HDRA":"#f20a0a","DRHO":"#f20a0a","DSOZ":"#f20a0a","ECD_ARC":"#f20a0a","NPHI":"#0a44f2","TNPH":"#0a44f2","TNPH_CH":"#0a44f2","HNPO":"#0a44f2","HNPO_filte":"#0a44f2","CNCF":"#0a44f2","NPOR":"#0a44f2","CH_NPHI":"#0a44f2","CH_NPHIds":"#0a44f2","CFTC":"#0a44f2","CNTC":"#0a44f2","DTC":"#ea0af2","DTCO":"#ea0af3","DT":"#ea0af4","DT4P":"#ea0af5","DT5":"#ea0af6","DT_SPL":"#ea0af7","DTS":"#630af2","DTSM":"#630af3","DT2":"#630af4","DTSO":"#630af6","DT4S":"#630af7","GR":"#40f20a","GR1":"#40f20a","GR_ARC":"#40f20a","CGR":"#40f20a","EHGR":"#40f20a","ECGR":"#40f20a","SGR":"#40f20a","GR_SPULSE_BHC":"#40f20a","GR_IMP":"#40f20a","GRM1":"#40f20a","MWD_GR_BHC":"#40f20a","GRAM":"#40f20a","GR_SPL":"#40f20a","GR_CDR":"#40f20a","ARC_GR_RT":"#40f20a","GR_LWD":"#40f20a","POTA":"#0a0a0a","THOR":"#0a0a0a","URAN":"#0a0a0a","TPRA":"#0a0a0a","TURA":"#0a0a0a","UPRA":"#0a0a0a","LLD":"#f20a0a","LLS":"#0a44f2","DIL":"#0a44f2","ILD":"#f20a0a","ILM":"#0a44f2","RILD":"#f20a0a","RILM":"#0a44f2","HRI":"#f20a0a","RIDPH":"#0a44f2","RIMPH":"#eb0edc","RSFL":"#f20a0a","HDRS":"#0a44f2","HMRS":"#eb0edc","LL3":"#f20a0a","RIPD":"#0a44f2","RIPM":"#eb0edc","AT10":"#f20a0a","AT20":"#f20a0a","AT30":"#f20a0a","AT60":"#0a44f2","AT90":"#0a44f2","AO10":"#f20a0a","AO20":"#f20a0a","AO30":"#f20a0a","AO60":"#0a44f2","AO90":"#0a44f2","AF10":"#f20a0a","AF20":"#f20a0a","AF30":"#f20a0a","AF60":"#0a44f2","AF90":"#0a44f2","AHO10":"#f20a0a","AHO20":"#f20a0a","AHO30":"#f20a0a","AHO60":"#0a44f2","AHO90":"#0a44f2","M2RX":"#0a44f2","M2R9":"#0a44f2","M2R6":"#0a44f2","M2R3":"#f20a0a","M2R1":"#f20a0a","P16H_UNC":"#f20a0a","P22H_UNC":"#f20a0a","P28H_UNC":"#f20a0a","P34H_UNC":"#0a44f2","P40H_UNC":"#0a44f2","A28H_UNC":"#f20a0a","A34H_UNC":"#0a44f2","A40H_UNC":"#0a44f2","P16L_UNC":"#f20a0a","P22L_UNC":"#f20a0a","P28L_UNC":"#f20a0a","P34L_UNC":"#0a44f2","P40L_UNC":"#0a44f2","P22H_UNC_RT":"#f20a0a","P40H_UNC_RT":"#0a44f2","P40H_UNC_R":"#0a44f2","P22H_UNC_R":"#f20a0a","HLLD":"#f20a0a","HLLS":"#0a44f2","RES_DEEP":"#f20a0a","RES_SHAL":"#0a44f2","Rdeep":"#f20a0a","Rshallow":"#0a44f2","P33H_UNC":"#0a44f2","P33L_UNC":"#f20a0a","A33H_UNC":"#0a44f2","A33L_UNC":"#f20a0a","RACHM":"#0a44f2","RACLM":"#f20a0a","RPCHM":"#0a44f2","RPCLM":"#f20a0a","RPCSHM":"#0a44f2","RPCSLM":"#f20a0a","RACSHM":"#0a44f2","RACSLM":"#f20a0a","RAC1HM":"#0a44f2","RAC1LM":"#f20a0a","RPC1HM":"#0a44f2","RPC1LM":"#f20a0a","RAC2HM":"#0a44f2","RAC2LM":"#f20a0a","RPC2HM":"#0a44f2","RPC2LM":"#f20a0a","RAC3HM":"#0a44f2","RAC3LM":"#f20a0a","RPC3HM":"#0a44f2","RPC3LM":"#f20a0a","RAC4HM":"#0a44f2","RAC4LM":"#f20a0a","RPC4HM":"#0a44f2","RPC4LM":"#f20a0a","MSFL":"#0a44f2","RXO8":"#f20a0a","ATR":"#0a44f2","PSR":"#f20a0a","RT":"#f20a0a","TAB_CDR_RES":"#f20a0a","TAB_ARC_RES":"#f20a0a","TAB_RES":"#f20a0a","PEF":"#f70ad0","PEF8":"#f70ad1","PERF":"#f70ad2","PEFZ":"#f70ad3","ROP5_RM":"#f20a0a","ROP":"#f20a0a","ROP5":"#f20a0a","ROPS":"#f20a0a","RXOZ":"#0e33eb","RSOZ":"#0e33eb","ITT":"#2291f2","TENS":"#11f2f2","TTEN":"#11f2f3","HTEN":"#11f2f4","CDF":"#11f2f5","ATMP":"#fa0202","TEMP_MCR":"#fa0203","TVDE":"#0f1d29","SP":"#fa4402","VPVS":"#e102fa","LSN":"#ed0510","SSN":"#0533ed","APRS_ARC":"#ed0510","ARTM":"#f20a0a","AGTK":"#40f20a","ARTK":"#f20a0a","Temp":"#fa0202","TEMP_LWD":"#fa0203","WTBH":"#fa0204","WTBH1":"#fa0205","TEMP_DNI_RT":"#fa0206","HSTEMP":"#fa0207","TCDM":"#fa0208","RPTHM":"#454141","CHT":"#34fa02","DPHI":"#fa4402","SPHI":"#fa02e9","PHIE":"#fa0249","PR":"#fa02f6","ICV":"#9c959b","IHV":"#9c959b","GTEM":"#fa0202","DHTEMP":"#fa0203","TTEM_CDR":"#fa0205","SVEL":"#dd02fa","TTSL":"#dd02fa","TT":"#dd02fa","CBSL":"#fa0202","CBL":"#fa0203","WF2":"#630af2","WF1":"#630af2","CBLF":"#9c959b","CCL":"#9c959b","BS":"#9c959b","TGAS":"#fa0202","Oilshow":"#078238"}}'
71
+ curve_info = json.loads(meta_info)
72
+ curve_info['Unit'].update(new_unit) if len(new_unit) != 0 else curve_info['Unit']
73
+ curve_info['Color'].update(new_color) if len(new_color) != 0 else curve_info['Color']
74
+ log_type = ['LLD', 'LLS', 'DIL', 'ILD', 'ILM', 'RILD', 'RILM', 'HRI', 'RIDPH', 'RIMPH', 'RSFL', 'HDRS', 'HMRS', 'LL3', 'RIPD', 'RIPM', 'AT10', 'AT20', 'AT30', 'AT60', 'AT90', 'AO10', 'AO20', 'AO30', 'AO60', 'AO90', 'AF10', 'AF20', 'AF30', 'AF60', 'AF90', 'AHO10', 'AHO20', 'AHO30', 'AHO60', 'AHO90', 'M2RX', 'M2R9', 'M2R6', 'M2R3', 'M2R1', 'P16H_UNC', 'P22H_UNC', 'P28H_UNC', 'P34H_UNC', 'P40H_UNC', 'A28H_UNC', 'A34H_UNC', 'A40H_UNC', 'P16L_UNC', 'P22L_UNC', 'P28L_UNC', 'P34L_UNC', 'P40L_UNC', 'P22H_UNC_RT', 'P40H_UNC_RT', 'P40H_UNC_R', 'P22H_UNC_R', 'HLLD', 'HLLS', 'RES_DEEP', 'RES_SHAL', 'Rdeep', 'Rshallow', 'P33H_UNC', 'P33L_UNC', 'A33H_UNC', 'A33L_UNC', 'RACHM', 'RACLM', 'RPCHM', 'RPCLM', 'RPCSHM', 'RPCSLM', 'RACSHM', 'RACSLM', 'RAC1HM', 'RAC1LM', 'RPC1HM', 'RPC1LM', 'RAC2HM', 'RAC2LM', 'RPC2HM', 'RPC2LM', 'RAC3HM', 'RAC3LM', 'RPC3HM', 'RPC3LM', 'RAC4HM', 'RAC4LM', 'RPC4HM', 'RPC4LM', 'MSFL', 'RXO8', 'ATR', 'PSR', 'RT', 'RXOZ', 'RSOZ']
75
+ log_type_update = list(set(log_type + log))
76
+
77
+ #Define curves in columns list
78
+ if len(curves) != 0:
79
+ curves_list = curves
80
+ else:
81
+ curves_list = data.select_dtypes(include=['float64']).columns.drop(depth_col)
82
+
83
+ #Calculate numbers of plotting columns and size of whole figure
84
+ cols = len(curves_list); height= 800;
85
+ width = cols * 150 if cols*150 < 1300 else 1300
86
+ #Make subplots layout
87
+ fig = go.Figure()
88
+ fig = make_subplots(rows=1, cols=cols, shared_yaxes=True, horizontal_spacing=0.01)
89
+
90
+ #Check selected curves for plotting
91
+ for i, curve in enumerate(curves_list):
92
+ #Assign color code for single curve
93
+ color = curve_info['Color'][curve] if curve in curve_info['Color'].keys() else '#38a2e8'
94
+ unit = curve_info['Unit'][curve] if curve in curve_info['Unit'].keys() else '_'
95
+ #Add trace to subplots
96
+ add_trace(curv=curve, color=color, xaxis=f'x{i+1}', unit=unit, id_subplt=i+1, log=log_type_update)
97
+
98
+ #Setup the Axes and Layout parameters
99
+ update_xaxes(); update_yaxes(); update_layout([width, height])
100
+ #Show the main figure
101
+ # fig.show(config=dict(displayModeBar=True))
102
+ st.plotly_chart(fig)
models/05_13_2023_11_50_38_model_LGBM.json ADDED
The diff for this file is too large to render. See raw diff
 
pages/1_LAS_Exploratory.py ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import matplotlib.pyplot as plt
3
+ import lasio, os
4
+ import numpy as np
5
+ import os
6
+ import streamlit as st
7
+
8
+ import altair as alt
9
+ from streamlit_vega_lite import altair_component
10
+
11
+ from io import StringIO
12
+
13
+ from ui import *
14
+ from Antuns.page_setting import page_intro
15
+ from mLogsFunctions import *
16
+ from mLogsFunctions.fx import *
17
+ #-----------------------------------------------------------------------------
18
+ page_intro()
19
+
20
+ #1_LOADINGDATA-----------------------------------------------------------------
21
+ st.write("Log ASCII standard (LAS) is a standard file format common in the oil-and-gas and water well industries to store well log information. Well logging is used to investigate and characterize the subsurface stratigraphy in a well.")
22
+ # pagetile = """<center><h1>LAS EXPLORATORY</h1></center>"""
23
+ # st.markdown(pagetile, unsafe_allow_html=True)
24
+ st.subheader('To begin using the app, load your LAS file using the file upload option below.')
25
+ st.subheader("1. LAS File Loading:")
26
+ #------------------------------------------------------------------------------
27
+ #Streamlit Dashboard------------------------------------------------------------------------------------------
28
+
29
+ # set_page_config(page='custom')
30
+ hide_menu_button()
31
+ condense_layout()
32
+ #-----------------------------------------------------------------------------
33
+ @st.cache_data() #allow_output_mutation=True, suppress_st_warning=True
34
+ def upload_las(uploaded_files):
35
+ dataframes = {}
36
+ las_data_list = []
37
+ las_data = []
38
+ if uploaded_files is not None:
39
+ for file in uploaded_files:
40
+ try:
41
+ bytes_data = file.read()
42
+ str_io = StringIO(bytes_data.decode('Windows-1252'))
43
+ las_data = lasio.read(str_io)
44
+ well_data = las_data.df()
45
+ well_data['WELL'] = las_data.well.WELL.value
46
+ if well_data.index.name == 'DEPT':
47
+ well_data.reset_index('DEPT', inplace=True) # Set 'DEPT' as the new index
48
+ well_data.index.name = 'DEPT'
49
+ if len(well_data) > 0: # Kiểm tra xem dataframe có dữ liệu không
50
+ dataframes[file.name] = well_data
51
+ las_data_list.append(las_data)
52
+ else:
53
+ st.warning(f"No data in file {file.name}")
54
+ else:
55
+ well_data.index.name == 'DEPTH'
56
+ well_data.reset_index('DEPTH', inplace=True) # Set 'DEPTH' as the new index
57
+ well_data.index.name = 'DEPTH'
58
+ if len(well_data) > 0: # Kiểm tra xem dataframe có dữ liệu không
59
+ dataframes[file.name] = well_data
60
+ las_data_list.append(las_data)
61
+ except Exception as e:
62
+ st.error(f"Error loading {file.name}: {e}")
63
+ return dataframes, las_data_list, las_data
64
+
65
+ # Sidebar Options & File Upload
66
+ uploaded_files = st.file_uploader(label='Upload LAS files:', accept_multiple_files=True, type='las')
67
+
68
+ dataframes, las_data_list, las_data = upload_las(uploaded_files)
69
+ # print("print las data", las_data_list)
70
+ well_names = {}
71
+ if dataframes:
72
+ merged_df = []
73
+ for file_name, df in dataframes.items():
74
+ well_name = file_name.split(".")[0]
75
+ # Lấy danh sách các tên giếng
76
+ well_names = list(dataframes.keys())
77
+
78
+ # Cho phép người dùng chọn giếng và hiển thị DataFrame tương ứng
79
+ selected_well = st.selectbox("Select Well", well_names, key = "selected_well_1")
80
+
81
+ # st.write(f"Data for {selected_well}:")
82
+ st.write(dataframes[selected_well])
83
+ # Tạo một danh sách các DataFrame
84
+ dfs = [df for _, df in dataframes.items()]
85
+ merged_df = pd.concat([df for df in dfs])
86
+ # Hiển thị DataFrame tổng thể
87
+ st.write("Merged DataFrame:")
88
+ st.write(merged_df)
89
+ else:
90
+ print ("Please select LAS files for uploading ")
91
+ st.warning('No valid LAS files were uploaded.')
92
+
93
+ curves = []
94
+ wellname = []
95
+ las = las_data
96
+ list_well = []
97
+ if las:
98
+
99
+ for las_data in las_data_list:
100
+ well_name = las_data.well['WELL'].value
101
+ list_well.append(well_name)
102
+ # print(list_well)
103
+
104
+ st.success('File Uploaded Successfully')
105
+ st.write(f'<b>Well Name</b>: {list_well}', unsafe_allow_html=True)
106
+ # 2_CURVES_INFOMATION-----------------------------------------------------------------
107
+ if las:
108
+
109
+ st.subheader("2. Curve logs details:")
110
+ selected_well = st.selectbox("Select Well", well_names, key = "selected_well_2")
111
+ st.caption("All curve logs in data:")
112
+
113
+ curves = []
114
+
115
+ for well, las_file in zip(well_names, las_data_list):
116
+ if well == selected_well:
117
+ las = las_file
118
+ break
119
+
120
+
121
+ # print("in ra las:", las)
122
+ for curve in las.curves:
123
+ st.write(curve.mnemonic)
124
+ curves.append(curve.mnemonic)
125
+
126
+ for count, curve in enumerate(las.curves):
127
+ st.write("---")
128
+ st.write(f"Curve: {curve.mnemonic}, \t Units: {curve.unit}, \t Description: {curve.descr}")
129
+ st.write(f"There are a total of: {count+1} curves present within this file")
130
+
131
+ #3_DATAFRAME-----------------------------------------------------------------
132
+ if "selected_well" not in st.session_state:
133
+ st.session_state.selected_well = None
134
+ st.session_state.selected_well_multi = None
135
+ st.subheader("3. Converting LAS to DataFrame:")
136
+ st.caption("3.1 Preview of all Dataframe")
137
+
138
+ selected_well = st.selectbox("Select Well", well_names, key = "selected_well_5")
139
+ # print("Well_name", well_names)
140
+ # print("las_data_list", las_data_list)
141
+ for well, las_file in zip(well_names, las_data_list):
142
+ if well == selected_well:
143
+ las = las_file
144
+ break
145
+ # break
146
+ well = las.df()
147
+ well['WELL'] = las.well.WELL.value
148
+ well['DEPTH'] = well.index
149
+ well = well.reset_index(drop=True)
150
+ well = well.reindex(columns=['DEPTH'] + [col for col in well.columns if col != 'DEPTH'])
151
+ st.write(well.head())
152
+ st.caption("3.2 Well curves Statistics")
153
+ st.write(well.describe())
154
+ # print("in ra danh sách giếng", list_well)
155
+ # create a selectbox to choose the well
156
+
157
+ selected_well_multi = st.multiselect(" 3.3 Select well for download", list_well)
158
+ st.session_state.changename = st.button("Create", key="create_curve")
159
+ if st.session_state.changename:
160
+ dataframes_df = pd.concat(dataframes.values(), ignore_index=True)
161
+ st.session_state.selected_well_multi = dataframes_df.loc[dataframes_df['WELL'].isin(selected_well_multi)].reset_index(drop=True)
162
+ st.dataframe(st.session_state.selected_well_multi)
163
+ st.write(" Download DataFrame")
164
+ st.download_button(label='Download CSV File',
165
+ data = st.session_state.selected_well_multi.to_csv(),
166
+ file_name=f"{selected_well_multi}.csv",
167
+ mime='text/csv')
168
+
169
+ #4_Data Preprocessing-----------------------------------------------------------------
170
+ st.subheader("4. Data Preprocessing:")
171
+ st.session_state.old_name:str
172
+ st.session_state.new_name:str
173
+ st.session_state.changename:bool
174
+ st.session_state.well = None
175
+
176
+ st.write("4.1 Rename curves")
177
+
178
+ st.session_state.selected_well_rename = None
179
+ selected_well_rename = st.selectbox("Select Well", list_well, key="well_selectbox")
180
+
181
+ well_to_las = {}
182
+ well = []
183
+ data_rename_1 =[]
184
+ df_all_full = pd.DataFrame()
185
+ st.session_state.selected_well_rename = None
186
+ for i in range(len(well_names)):
187
+ well_to_las[well_names[i]] = las_data_list[i]
188
+ # print("key: ",well_names[i][:len(selected_well_rename)], " value: ",las_data_list[i])
189
+ if selected_well_rename == well_names[i][:len(selected_well_rename)]:
190
+ las = las_data_list[i]
191
+ break
192
+ # print("In ra las:", las)
193
+ well = las.df()
194
+ well['WELL'] = las.well.WELL.value
195
+ # print("In ra well2:", well)
196
+ curves = well.columns.tolist()
197
+ # print ("print ra cuvers:", curves) # save the number of curves for the selected well in session state
198
+ st.session_state.num_curves = len(curves)
199
+ df_rename = pd.DataFrame()
200
+ st.session_state.selected_well_rename = df_rename
201
+ st.session_state.selected_well_rename = well
202
+
203
+ import pandas as pd
204
+
205
+ # Khởi tạo DataFrame từ dữ liệu có sẵn
206
+ # Khởi tạo thuộc tính selected_well_rename trong st.session_state
207
+ st.session_state.setdefault('selected_well_rename', 'Default value')
208
+ # Truy cập thuộc tính selected_well_rename
209
+
210
+ data = st.session_state.selected_well_rename
211
+ if 'columns' in data:
212
+ n_cols = 4
213
+ n_rows = -(-len(data.columns) // n_cols) # Round up division
214
+ for i in range(n_rows):
215
+ cols = st.columns(n_cols)
216
+ for j in range(n_cols):
217
+ idx = i * n_cols + (j-1)
218
+ if idx < len(data.columns):
219
+ col = data.columns[idx]
220
+ # Lưu trữ tên cũ trong biến old_col
221
+ old_col = col
222
+ # new_col == well_names[i][:len(col)]
223
+ new_col = cols[j-1].text_input(f"Enter new name for '{col}'", key=f"input_{cols}")
224
+ # Kiểm tra nếu người dùng không nhập tên mới
225
+ if not new_col:
226
+ # Sử dụng tên cũ thay thế
227
+ new_col = old_col
228
+ data = data.rename(columns={col: new_col})
229
+ data["DEPTH"] = well.index
230
+ data.insert(0, 'DEPTH', data.pop('DEPTH'))
231
+ data = data.reset_index(drop=True)
232
+ st.dataframe(data)
233
+ else:
234
+ print ("Please select LAS files for input data")
235
+ # Hiển thị lại bảng
236
+
237
+ def my_function(data):
238
+ # Lưu trữ DataFrame khi người dùng nhấn vào nút "L��u"
239
+ if st.button("Lưu", key="saved_rename"):
240
+ # Tạo tên file CSV dựa trên biến selected_well_rename
241
+ file_name = f"/work/2022_VPIMLogs_WebApp/data/change_name_logs/{selected_well_rename}.csv"
242
+ # Lưu trữ DataFrame vào tệp CSV với tên file tương ứng
243
+ data.to_csv(file_name, index=False)
244
+ # Trả về giá trị của biến result
245
+ return data
246
+ result = my_function(data)
247
+
248
+ # for name in selected_well_multi:
249
+ # # dataframe_merged_df = pd.DataFrame()
250
+ # merged_df = pd.read_csv("data/change_name_logs/merged_df.csv")
251
+ # dataframe_merged_df.append(merged_df[merged_df.WELL==name])
252
+ # dataframe_merged_df.to_csv("data/change_name_logs/merged_df.csv")
253
+ # st.dataframe(dataframe_merged_df, width=1400)
254
+
255
+
256
+ selected_well_multi= st.multiselect(" 4.3 Select well for download", list_well, key = 'selected_well_multi_lasts')
257
+ # dowload_dataframes_df = pd.DataFrame()
258
+ st.session_state.changename_download = st.button("Create", key="selected_well_multi_rename_curve_111")
259
+ # Đường dẫn đến thư mục chứa các file csv
260
+ dir_path = '/work/2022_VPIMLogs_WebApp/data/change_name_logs/'
261
+ if st.session_state.changename_download:
262
+ # Tạo một DataFrame rỗng để chứa dữ liệu
263
+ merged_df = pd.DataFrame()
264
+ dataframe_merged_df = pd.DataFrame()
265
+ # Duyệt qua tất cả các file trong thư mục và gộp chúng vào DataFrame
266
+ for filename in os.listdir(dir_path):
267
+ if filename.endswith('.csv'):
268
+ filepath = os.path.join(dir_path, filename)
269
+ df = pd.read_csv(filepath)
270
+ merged_df = pd.concat([merged_df, df], ignore_index=True).reset_index(drop=True)
271
+ merged_df.to_csv(f"/work/2022_VPIMLogs_WebApp/data/merged/{selected_well_multi}_merged_df.csv")
272
+ dataframes_df = pd.read_csv(f"/work/2022_VPIMLogs_WebApp/data/merged/{selected_well_multi}_merged_df.csv")
273
+ st.session_state.selected_well_multi = dataframes_df.loc[dataframes_df['WELL'].isin(selected_well_multi)].reset_index(drop=True).drop('Unnamed: 0', axis = 1)
274
+
275
+ st.dataframe(st.session_state.selected_well_multi , width=1400)
276
+ # 4.3_DOWNLOAD-----------------------------------------------------------------
277
+ st.write("4.3 Download well curves with renamed names")
278
+ st.download_button(label='Download CSV File',
279
+ data = st.session_state.selected_well_multi.to_csv(),
280
+ file_name=f"{selected_well_multi}.csv",
281
+ mime='text/csv')
282
+ for filename in os.listdir(dir_path):
283
+ if filename.endswith('.csv'):
284
+ os.remove(os.path.join(dir_path, filename))
285
+ #'''Adding the ‘download’ tag attribute as shown below allows you to provide a file name and extension.
286
+ #f'<a href="data:file/csv;base64,{b64}" download="myfilename.csv">Download csv file</a>'''
287
+
288
+ hide_menu_button()
289
+ condense_layout()
pages/2_Exploratory_Data_Analysis.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import streamlit as st
3
+ import pandas as pd
4
+ import os
5
+ from ui import *
6
+ from mLogsFunctions import *
7
+
8
+ #Streamlit Dashboard------------------------------------------------------------------------------------------
9
+ pagetile = """<center><h1>EXPLORATORY DATA ANALYSIS</h1></center>"""
10
+ set_page_config(page='custom')
11
+ hide_menu_button()
12
+ condense_layout()
13
+
14
+ logo_site, info_site = st.columns([1.5, 8.5])
15
+ with logo_site:
16
+ st.image("https://i.ibb.co/Yd42K98/LogoVPI.png", use_column_width='auto')
17
+ with info_site:
18
+ # st.set_option('deprecation.showfileUploaderEncoding', False)
19
+ # st.set_option('maxUploadSize', 200*1024) # 200 MB
20
+ st.markdown(pagetile, unsafe_allow_html=True)
21
+ # Option 1: CSV File Loading
22
+ st.write('You can load your csv file using the file upload or selection from LAS Exploration option below.')
23
+ st.subheader("1. CSV File Loading")
24
+ df = csv_uploader()
25
+ df = tweak_data(df,resample=False, reindex=True)
26
+
27
+ # Option 2: CSV from LAS Exploration
28
+ st.subheader("2. CSV from LAS Exploration")
29
+ dir_path = '/work/2022_VPIMLogs_WebApp/data/merged/'
30
+ csv_files = [filename for filename in os.listdir(dir_path) if filename.endswith('.csv')]
31
+ selected_csv_file= st.multiselect('Select a CSV file', csv_files, key = 'st.session_state.selected_well_multi')
32
+
33
+ # # Đọc file csv được chọn vào DataFrame
34
+ if selected_csv_file: # Nếu người dùng đã chọn file CSV
35
+ # Đọc file csv được chọn vào DataFrame
36
+ file_path = '/work/2022_VPIMLogs_WebApp/data/merged/'
37
+ merged_data = pd.concat([pd.read_csv(file_path + f) for f in selected_csv_file])
38
+ df = tweak_data(merged_data, resample=False, reindex=True)
39
+ else: # Nếu người dùng không chọn file CSV
40
+ merged_data = df
41
+ df = tweak_data(merged_data, resample=False, reindex=True)
42
+ #|CHECK DATA EXISTENCE-----------------------------------------------------------------------------------------
43
+ if df is not None:
44
+ curves = columns_list(df, no_depth=True, no_well=True)
45
+ well_names = np.sort(df.WELL.unique())
46
+ #|TABS-ESTABLISHING-----------------------------------------------------------------------------------------
47
+ tab1, tab2, tab3, tab4, tab5 = st.tabs(['DataFrame',
48
+ 'DataStatistics',
49
+ '3D Scatter Points',
50
+ 'CurvesView',
51
+ 'OutliersRemoval'
52
+ ])
53
+ #|TABS-1-----------------------------------------------------------------------------------------
54
+ st.write('---')
55
+ with tab1:
56
+ st.dataframe(df, width=1400, height=500)
57
+
58
+ #|TABS-2-----------------------------------------------------------------------------------------
59
+ with tab2:
60
+ st.radio('DataVisualizationMethod',
61
+ key='displayTab2',
62
+ options=['DataStatistics',
63
+ 'Missing Statistic',
64
+ 'Curve Distribution',
65
+ 'Histogram Overlay',
66
+ 'Cross-Plot',
67
+ 'PairPlot'],
68
+ horizontal=True)
69
+ if st.session_state.displayTab2 == 'DataStatistics':
70
+ subtab21(df, well_names)
71
+ elif st.session_state.displayTab2 == 'Missing Statistic':
72
+ subtab22(df)
73
+ elif st.session_state.displayTab2 == 'Curve Distribution':
74
+ subtab23(df, curves)
75
+ elif st.session_state.displayTab2 == 'Histogram Overlay':
76
+ subtab24(df, curves)
77
+ elif st.session_state.displayTab2 == 'Cross-Plot':
78
+ subtab25(df, curves)
79
+ elif st.session_state.displayTab2 == 'PairPlot':
80
+ subtab26(df, curves)
81
+ else:
82
+ subtab21(df, well_names)
83
+
84
+ #|TABS-3-----------------------------------------------------------------------------------------
85
+ with tab3:
86
+ scatterPoint3D(df)
87
+ #|TABS-4-----------------------------------------------------------------------------------------
88
+ with tab4:
89
+ stViewCurves(df)
90
+ #|TABS-5-----------------------------------------------------------------------------------------
91
+ with tab5:
92
+ rmOutliers(df)
pages/3_Fracture_Training_Models.py ADDED
@@ -0,0 +1,388 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import pandas as pd
3
+
4
+ import altair as alt
5
+ import lightgbm as lgb
6
+ import matplotlib.pyplot as plt
7
+ import pickle, os, datetime
8
+ import bz2file as bz2
9
+
10
+ from sklearn.model_selection import train_test_split, StratifiedShuffleSplit
11
+ from sklearn.metrics import roc_auc_score, balanced_accuracy_score, f1_score, recall_score, precision_score
12
+ from sklearn.metrics import roc_curve, precision_recall_curve, auc
13
+
14
+ import streamlit as st
15
+
16
+ from ui import *
17
+ from mLogsFunctions import *
18
+
19
+
20
+ #------------------------------------------------------------------------------------------
21
+ # processing pipeline
22
+ def remove_negative_val(df, col):
23
+ return df.drop(index=df[df[col] < 0].index)
24
+ def rel_depth(df):
25
+ dfx = []
26
+ for well in df.WELL.unique():
27
+ df_ = df[df.WELL==well].sort_values(by="DEPTH", ascending=True)
28
+ dfx.append(df_.assign(rel_depth=df_.DEPTH / df_.DEPTH.values[0]))
29
+ return pd.concat(dfx).reset_index(drop=True)
30
+
31
+ def tweak_data_S(df):
32
+ return (
33
+ df.assign(
34
+ FRACTURE_ZONE=df.FRACTURE_ZONE.replace({-9999: 0, np.nan: 0}).astype('int8'),
35
+ GR=df.GR.replace({-9999.:0.}).astype('float32'),
36
+ DCALI_FINAL=df.DCALI_FINAL.replace({-9999.:0.}).astype('float32'),
37
+ LLD=df.LLD.replace({-9999.:0.}).astype('float32'),
38
+ LLS=df.LLS.replace({-9999.:0.}).astype('float32'),
39
+ NPHI=df.NPHI.replace({-9999.:0.}).astype('float32'),
40
+ RHOB=df.RHOB.replace({-9999.:0.}).astype('float32'),
41
+ DTC=df.DTC.replace({-9999.:0.}).astype('float32'),
42
+ DTS=df.DTS.replace({-9999.:0.}).astype('float32'),
43
+ DEPTH=df.DEPTH.astype('float32')
44
+ )
45
+ .pipe(remove_negative_val, "RHOB")
46
+ .pipe(remove_negative_val, "DTC")
47
+ .pipe(remove_negative_val, "DTS")
48
+ .pipe(remove_negative_val, "GR")
49
+ .pipe(remove_negative_val, "LLD")
50
+ ).pipe(rel_depth)
51
+
52
+ #Streamlit Dashboard------------------------------------------------------------------------------------------
53
+ pagetile = """<center><h1>TRAINING SITE</h1></center>"""
54
+ set_page_config(page='custom')
55
+ hide_menu_button()
56
+ condense_layout()
57
+
58
+ logo_site, info_site = st.columns([1.5, 8.5])
59
+ with logo_site:
60
+ st.image("https://i.ibb.co/Yd42K98/LogoVPI.png", use_column_width='auto')
61
+ with info_site:
62
+ st.set_option('deprecation.showfileUploaderEncoding', False)
63
+ # st.set_option('maxUploadSize', 200*1024) # 200 MB
64
+ st.markdown(pagetile, unsafe_allow_html=True)
65
+ # Option 1: CSV File Loading
66
+ st.write('You can load your csv file using the file upload or selection from LAS Exploration option below.')
67
+
68
+ st.subheader("1. CSV File Loading")
69
+ df = csv_uploader()
70
+ # df = tweak_data(df,resample=False, reindex=True)
71
+
72
+ # Option 2: CSV from LAS Exploration
73
+ st.subheader("2. CSV from LAS Exploration")
74
+ dir_path = '/work/2022_VPIMLogs_WebApp/data/merged/'
75
+ csv_files = [filename for filename in os.listdir(dir_path) if filename.endswith('.csv')]
76
+ selected_csv_file= st.multiselect('Select a CSV file', csv_files, key = 'st.session_state.selected_well_multi')
77
+
78
+ # # Đọc file csv được chọn vào DataFrame
79
+ if selected_csv_file: # Nếu người dùng đã chọn file CSV
80
+ # Đọc file csv được chọn vào DataFrame
81
+ file_path = '/work/2022_VPIMLogs_WebApp/data/merged/'
82
+ merged_data = pd.concat([pd.read_csv(file_path + f) for f in selected_csv_file])
83
+ # df = tweak_data_S(merged_data, resample=False, reindex=True)
84
+ df = merged_data
85
+ else: # Nếu người dùng không chọn file CSV
86
+ merged_data = df
87
+
88
+ # df = tweak_data(merged_data, resample=False, reindex=True)
89
+ #------------------------------------------------------------------------------------------
90
+ if df is not None:
91
+ st.caption("Data Preparation")
92
+ # Processing data
93
+ # df = tweak_data_S(df)
94
+ try:
95
+ df = tweak_data_S(df)
96
+ except AttributeError as e:
97
+ print(" ")
98
+ st.info("Tweak Data")
99
+ i1, i2 = st.columns(2)
100
+ for i, v in enumerate(["FRACTURE_ZONE", "GR", "DCAL", "LLD", "LLS", "NPHI", "RHOB", "DTC", "DTS", "DEPTH"]):
101
+ if i%2==0:
102
+ with i1:
103
+ st.success(f"{v}: Replaced nan values by 0")
104
+ if i%2==1:
105
+ with i2:
106
+ st.success(f"{v}: Replaced nan values by 0")
107
+ st.info(" Negative values removal in RHOB, DTC, DTS, GR, LLD: Done!")
108
+ st.write("---")
109
+
110
+ #--------------------------------------------------------------------------------------
111
+ # define training/testing data
112
+ st.write("Please to slectect Curves input for Traning Model")
113
+ feature_names_dict = [col for col in df.columns if col not in ["WELL",
114
+ "DEPTH",
115
+ # "Fracture Intensity",
116
+ # "FRACTURE_ZONE",
117
+ ]]
118
+ feature_names = st.multiselect('Select curves', feature_names_dict, key = 'st.session_state.selected_well_multi_curves')
119
+ feature_names_label = [col for col in df.columns if col not in ["WELL",
120
+ "DEPTH",
121
+ # "Fracture Intensity",
122
+ # "FRACTURE_ZONE",
123
+ ]]
124
+ st.write("Please to slectect a Label input for Traning Model")
125
+ feature_names_label = st.selectbox('Select a curves', feature_names_label, key = 'st.session_state.selected_well_multi_label')
126
+
127
+ label_name = feature_names_label
128
+ st.caption("Features Selection")
129
+ st.info(f"Label names: {label_name}")
130
+ st.info(f"Feature names: {feature_names}")
131
+ st.write("---")
132
+ #--------------------------------------------------------------------------------------
133
+ st.caption("Split Data")
134
+
135
+ ## split data
136
+ ### some data for test model after deploy
137
+ ss = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
138
+
139
+ for _train_inx, _test_inx in ss.split(df, df["WELL"]):
140
+ train_df, test_df = df.loc[_train_inx, :], df.loc[_test_inx, :]
141
+
142
+ X_train, X_test, y_train, y_test = train_test_split(
143
+ train_df[feature_names],
144
+ train_df[label_name],
145
+ stratify=train_df[label_name],
146
+ train_size=0.9,
147
+ random_state=42,
148
+ )
149
+
150
+ ### create lgb dataset
151
+ train_set = lgb.Dataset(X_train,
152
+ label=y_train,
153
+ feature_name=feature_names,
154
+ )
155
+ valid_set = lgb.Dataset(X_test,
156
+ label=y_test,
157
+ reference=train_set,
158
+ feature_name=feature_names,
159
+ )
160
+
161
+ st.info(f"Size of FULL Dataset: {len(df)}")
162
+ st.info(f"Size of TRAINING set: {train_set.construct().num_data()}")
163
+ st.info(f"Size of VALIDATION set: {valid_set.construct().num_data()}")
164
+ st.info(f"Size of TESTING set: {len(test_df)}")
165
+ st.write("---")
166
+ #Traning model--------------------------------------------------------------------------------------
167
+ if st.button("Start Train"):
168
+ # Modeling
169
+ ## custom metric
170
+ st.caption("Training")
171
+ from sklearn.metrics import recall_score, precision_score, accuracy_score, f1_score, roc_auc_score, precision_recall_curve
172
+ model = lgb.train(
173
+ params={"boosting_type": "gbdt",
174
+ "objective": "cross_entropy",
175
+ "metric": ["rmse","recall"],
176
+ "is_unbalance": True,
177
+ },
178
+ train_set=lgb.Dataset(data=X_train, label=y_train,
179
+ feature_name=feature_names),
180
+ num_boost_round=2000,
181
+ valid_sets=lgb.Dataset(data=X_test, label=y_test,
182
+ feature_name=feature_names),
183
+ early_stopping_rounds=5,
184
+ verbose_eval=0,
185
+ )
186
+ st.success("Finished Training!")
187
+ st.success("Saved Model!")
188
+ st.write("---")
189
+
190
+ now = datetime.datetime.now()
191
+ current_time = now.strftime("%m_%d_%Y_%H_%M_%S")
192
+ link= f"/work/2022_VPIMLogs_WebApp/models/{current_time}_model_LGBM.json"
193
+ model.save_model(filename= link)
194
+
195
+ with open(link, 'r') as f:
196
+ file_content = f.read()
197
+ if st.download_button(label='Download JSON File',
198
+ data=file_content,
199
+ file_name=link,
200
+ mime='application/json'):
201
+ pass
202
+ else:
203
+ st.text(" ")
204
+ #Scores--------------------------------------------------------------------------------------
205
+ ## using model to make prediction
206
+ st.caption("Modeling Scores")
207
+
208
+ threshold = 0.5
209
+ #Make label Prediction
210
+ predictions = (model.predict(df[feature_names])> threshold).astype(int)
211
+ df['FRACTURE_ZONE_PRED'] = predictions
212
+ test_preds = model.predict(test_df[feature_names])
213
+ train_preds = model.predict(X_train)
214
+ valid_preds = model.predict(X_test)
215
+
216
+ valid_recall = recall_score(y_test, valid_preds >= threshold, average = 'weighted')
217
+ valid_precision = precision_score(y_test, valid_preds >= threshold, average = 'weighted')
218
+ valid_acc = accuracy_score(y_test, valid_preds >= threshold)
219
+ valid_f1 = f1_score(y_test, valid_preds >= threshold, average = 'weighted')
220
+ valid_aoc = roc_auc_score(y_test, valid_preds >= threshold)
221
+
222
+ train_recall = recall_score(y_train, train_preds >= threshold, average = 'weighted')
223
+ train_precision = precision_score(y_train, train_preds >= threshold, average = 'weighted')
224
+ train_acc = accuracy_score(y_train, train_preds >= threshold)
225
+ train_aoc = roc_auc_score(y_train, train_preds >= threshold)
226
+ train_f1 = f1_score(y_train, train_preds >= threshold, average = 'weighted')
227
+
228
+ test_recall = recall_score(test_df[label_name], test_preds >= threshold, average = 'weighted')
229
+ test_precision = precision_score(test_df[label_name], test_preds >= threshold, average = 'weighted')
230
+ test_acc = accuracy_score(test_df[label_name], test_preds >= threshold)
231
+ test_aoc = roc_auc_score(test_df[label_name], test_preds >= threshold)
232
+ test_f1 = f1_score(test_df[label_name], test_preds >= threshold, average = 'weighted')
233
+
234
+ sc1, sc2, sc3 = st.columns(3)
235
+ with sc1:
236
+ st.info(f"Training score (RECALL): {train_recall}")
237
+ st.info(f"Training score (PRECISION): {train_precision}")
238
+ st.info(f"Training score (ACC): {train_acc}")
239
+ st.info(f"Training score (F1): {train_f1}")
240
+ st.info(f"Training score (AOC): {train_aoc}")
241
+
242
+ with sc2:
243
+ st.info(f"Validation score (RECALL): {valid_recall}")
244
+ st.info(f"Validation score (PRECISION): {valid_precision}")
245
+ st.info(f"Validation score (ACC): {valid_acc}")
246
+ st.info(f"Validation score (F1): {valid_f1}")
247
+ st.info(f"Validation score (AOC): {valid_aoc}")
248
+
249
+ with sc3:
250
+ st.info(f"Testing score (RECALL): {test_recall}")
251
+ st.info(f"Testing score (PRECISION): {test_precision}")
252
+ st.info(f"Testing score (ACC): {test_acc}")
253
+ st.info(f"Testing score (F1): {test_f1}")
254
+ st.info(f"Testing score (AOC): {test_aoc}")
255
+ st.write("---")
256
+ #Measure Scores--------------------------------------------------------------------------------------
257
+ st.caption("Scores plotting charts")
258
+
259
+ ## roc valid
260
+ fpr_valid, tpr_valid, threshold_valid = roc_curve(y_test, valid_preds)
261
+ roc_auc_valid = auc(fpr_valid, tpr_valid)
262
+ ## precision recall valid
263
+ pr_valid, rc_valid, threshold_valid= precision_recall_curve(y_test, valid_preds)
264
+ ## roc training
265
+ tfpr_train, ttpr_train, tthreshold_train = roc_curve(y_train, train_preds)
266
+ troc_auc_train = auc(tfpr_train, ttpr_train)
267
+ ## precision recall training
268
+ tpr_train, trc_train, tthreshold_train = precision_recall_curve(y_train, train_preds)
269
+ ## roc test
270
+ tfpr_test, ttpr_test, tthreshold = roc_curve(test_df[label_name], test_preds)
271
+ troc_auc_test = auc(tfpr_test, ttpr_test)
272
+ ## precision recall testing
273
+ tpr_test, trc_test, tthreshold_test = precision_recall_curve(test_df[label_name], test_preds)
274
+
275
+ #Plot Scores--------------------------------------------------------------------------------------
276
+ fig, ax = plt.subplots(figsize=(40,40))
277
+ ax1 = plt.subplot2grid((7,7), (0,0), rowspan=1, colspan = 1)
278
+ ax2 = plt.subplot2grid((7,7), (0,1), rowspan=1, colspan = 1)
279
+ ax3 = plt.subplot2grid((7,7), (0,2), rowspan=1, colspan = 1)
280
+ ax4 = plt.subplot2grid((7,7), (1,0), rowspan=1, colspan = 1)
281
+ ax5 = plt.subplot2grid((7,7), (1,1), rowspan=1, colspan = 1)
282
+ ax6 = plt.subplot2grid((7,7), (1,2), rowspan=1, colspan = 1)
283
+
284
+ def set_ax(ax,
285
+ x, y, color, label, legend,
286
+ line:bool=False,
287
+ title:str=None,
288
+ x_label:str=None,
289
+ y_label:str=None,
290
+ ):
291
+ ax.plot(x, y, color, label=label)
292
+ ax.set_title(title)
293
+ ax.legend(loc = legend)
294
+ if line == True:
295
+ ax.plot([0, 1], [0, 1],'r--')
296
+ ax.set_xlim([0, 1])
297
+ ax.set_ylim([0, 1])
298
+ ax.set_ylabel(y_label)
299
+ ax.set_xlabel(x_label)
300
+ p1, p2, p3 = st.columns([1,14,1])
301
+ with p2:
302
+ ## roc valid
303
+ set_ax(ax2, fpr_valid, tpr_valid, 'b',
304
+ label = 'AUC = %0.2f' % roc_auc_valid,
305
+ legend='lower right',
306
+ title='Receiver Operating Characteristic - Validation',
307
+ line=True,
308
+ x_label='False Positive Rate',
309
+ y_label='True Positive Rate',
310
+ )
311
+
312
+ ## precision recall valid
313
+ set_ax(ax5, pr_valid, rc_valid, 'orange',
314
+ label = 'PR Curve',
315
+ legend='lower right',
316
+ title='Precision Recall Curve - Validation',
317
+ line=True,
318
+ x_label='Recall',
319
+ y_label='Precision',
320
+ )
321
+
322
+ ## roc training
323
+ set_ax(ax1, tfpr_train, ttpr_train, 'b',
324
+ label = 'AUC = %0.2f' % troc_auc_train,
325
+ legend='lower right',
326
+ title='Receiver Operating Characteristic - Training',
327
+ line=True,
328
+ x_label='False Positive Rate',
329
+ y_label='True Positive Rate',
330
+ )
331
+
332
+ ## precision recall training
333
+ set_ax(ax4, tpr_train, trc_train, 'orange',
334
+ label = 'PR Curve',
335
+ legend='lower right',
336
+ title='Precision Recall Curve - Training',
337
+ line=True,
338
+ x_label='Recall',
339
+ y_label='Precision',
340
+ )
341
+
342
+ ## roc test
343
+ set_ax(ax3, tfpr_test, ttpr_test, 'b',
344
+ label = 'AUC = %0.2f' % troc_auc_test,
345
+ legend='lower right',
346
+ title='Receiver Operating Characteristic - Blind test',
347
+ line=True,
348
+ x_label='False Positive Rate',
349
+ y_label='True Positive Rate',
350
+ )
351
+
352
+ ## precision recall testing
353
+ set_ax(ax6, tpr_test, trc_test, 'orange',
354
+ label = 'PR Curve',
355
+ legend='lower right',
356
+ title='Precision Recall Curve - Blind test',
357
+ line=True,
358
+ x_label='Recall',
359
+ y_label='Precision',
360
+ )
361
+
362
+ st.pyplot(fig)
363
+
364
+ #Plot Data------------------------------------------------------------------
365
+ plotting_curves = [c for c in df.columns.unique() if c not in ["DEPTH", "WELL", "TVD", "DCALI_FINAL", "INCL", "AZIM_TN", "rel_depth"]]
366
+ plotting_curves.sort()
367
+ if "FRACTURE_ZONE_PRED" in df.columns.unique():
368
+ plotting_curves.append("FRACTURE_ZONE_PRED")
369
+ for well in df.WELL.unique():
370
+ st.write('---')
371
+ st.write(f"{well} Logs: \n")
372
+ well_plot = df[df.WELL == well]
373
+ charts_dict={}
374
+ for i, c in enumerate(plotting_curves):
375
+ charts_dict[i] = curve_plot(data=well_plot,filted_data=None, x_column=c)
376
+ #Show Curve-----------------------------------------------------------------------
377
+ st.write(alt.concat(*charts_dict.values(), columns = 12).configure(autosize='fit'))
378
+ # st.snow()
379
+ #DOWNLOAD-----------------------------------------------------------------
380
+ # Define the download button
381
+
382
+ # if st.download_button('Download Modeling (with format JSON)'):
383
+ # with open(filename, 'r') as f:
384
+ # data = json.load(f)
385
+ # href = f"data:text/json;charset=utf-8,{json.dumps(data, indent=2)}"
386
+ # st.markdown(f'<a href="{href}" download="{filename}">Download Modeling (with format JSON)</a>')
387
+ hide_menu_button()
388
+ condense_layout()
pages/4_Fracture_Prediction.py ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import lightgbm as lgb
3
+
4
+ import pickle, os
5
+ import bz2file as bz2
6
+
7
+ import altair as alt
8
+
9
+ import streamlit as st
10
+
11
+ from ui import *
12
+ from mLogsFunctions import *
13
+ from mLogsFunctions.fx import *
14
+
15
+
16
+ #ignore version warnings
17
+ import warnings
18
+ warnings.filterwarnings("ignore")
19
+
20
+ #Global variables
21
+ THRESHOLD_GLOBAL = 0.5
22
+
23
+ #All wells to be trained
24
+ wells_name = ["01-97-HXS-1X", "15-1-SN-1X", "15-1-SN-2X", "15-1-SN-3XST", "15-1-SN-4X", "15-1-SNN-1P",
25
+ "15-1-SNN-2P", "15-1-SNN-3P", "15-1-SNN-4P", "15-1-SNS-1P", "15-1-SNS-2P", "15-1-SNS-4P"]
26
+ #Obtain data and label of wells
27
+ name_features = ["GR", "LLD", "LLS", "NPHI", "RHOB", "DTC", "DTS"]
28
+ label = "FRACTURE_ZONE"
29
+ #-----------------------------------------------------------------
30
+ # processing pipeline
31
+ def remove_negative_val(df, col):
32
+ return df.drop(index=df[df[col] < 0].index)
33
+ def rel_depth(df):
34
+ dfx = []
35
+ for well in df.WELL.unique():
36
+ df_ = df[df.WELL==well].sort_values(by="DEPTH", ascending=True)
37
+ dfx.append(df_.assign(rel_depth=df_.DEPTH / df_.DEPTH.values[0]))
38
+ return pd.concat(dfx).reset_index(drop=True)
39
+
40
+ def tweak_data_S(df):
41
+ return (
42
+ df.assign(
43
+ # FRACTURE_ZONE=df.FRACTURE_ZONE.replace({-9999: 0, np.nan: 0}).astype('int8'),
44
+ GR=df.GR.replace({-9999.:0.}).astype('float32'),
45
+ DCALI_FINAL=df.DCALI_FINAL.replace({-9999.:0.}).astype('float32'),
46
+ LLD=df.LLD.replace({-9999.:0.}).astype('float32'),
47
+ LLS=df.LLS.replace({-9999.:0.}).astype('float32'),
48
+ NPHI=df.NPHI.replace({-9999.:0.}).astype('float32'),
49
+ RHOB=df.RHOB.replace({-9999.:0.}).astype('float32'),
50
+ DTC=df.DTC.replace({-9999.:0.}).astype('float32'),
51
+ DTS=df.DTS.replace({-9999.:0.}).astype('float32'),
52
+ DEPTH=df.DEPTH.astype('float32')
53
+ )
54
+ .pipe(remove_negative_val, "RHOB")
55
+ .pipe(remove_negative_val, "DTC")
56
+ .pipe(remove_negative_val, "DTS")
57
+ .pipe(remove_negative_val, "GR")
58
+ .pipe(remove_negative_val, "LLD")
59
+ ).pipe(rel_depth)
60
+ # Calculate the confusion matrix of applying model on dataframe (including features and label) df with threshold
61
+ def calculate_confusion_matrix (model = None, df= None, threshold=None):
62
+ model_prediction = [model]
63
+ # Apply model on dataframe
64
+ proba = Prediction_LGBM(trained_models=model_prediction, data = df, feature_names=name_features)
65
+ proba_well = proba.loc[:, "model_0"]
66
+ # Apply threshold
67
+ if threshold==None: threshold = 0.5
68
+ # Get label from dataframe df
69
+ well_proba = proba_well.apply(lambda x: 1 if x >= threshold else 0)
70
+ return well_proba
71
+
72
+ #------------------------------------------------------------------
73
+ # Load any compressed pickle file
74
+ file = "/work/2022_VPIMLogs_WebApp/models/LightGBM_0.45.pbz2"
75
+ def decompress_pickle(file):
76
+ data = bz2.BZ2File(file, 'rb')
77
+ data = pickle.load(data)
78
+ return data
79
+ # model_best = decompress_pickle(file)
80
+
81
+ # Loading Modeling
82
+ # model_best = lgb.Booster(model_file="/work/2022_VPIMLogs_WebApp/models/LGBM_20221125.json")
83
+
84
+ #Loading data from browser:----------------------------------------
85
+ #Streamlit Dashboard------------------------------------------------------------------------------------------
86
+ pagetile = """<center><h1>PREDICTION SITE</h1></center>"""
87
+ st.markdown(pagetile, unsafe_allow_html=True)
88
+ # set_page_config(page='custom')
89
+
90
+ hide_menu_button()
91
+ condense_layout()
92
+
93
+ logo_site, info_site = st.columns([1.5, 8.5])
94
+ with logo_site:
95
+ st.image("https://i.ibb.co/Yd42K98/LogoVPI.png", use_column_width='auto')
96
+ with info_site:
97
+ # Option 1: CSV File Loading
98
+ st.write('You can load your csv file using the file upload or selection from LAS Exploration option below.')
99
+ st.subheader("1. CSV File Loading")
100
+ st.caption('## 1.1. CSV from Uploader')
101
+ df = csv_uploader()
102
+
103
+ # Option 2: CSV from LAS Exploration
104
+ st.caption('## 1.2. CSV from LAS Exploration')
105
+ dir_path = '/work/2022_VPIMLogs_WebApp/data/merged/'
106
+ csv_files = [filename for filename in os.listdir(dir_path) if filename.endswith('.csv')]
107
+ selected_csv_file= st.multiselect('Select a CSV file', csv_files, key = 'st.session_state.selected_well_multi')
108
+ if selected_csv_file: # Nếu người dùng đã chọn file CSV
109
+ # Đọc file csv được chọn vào DataFrame
110
+ file_path = '/work/2022_VPIMLogs_WebApp/data/merged/'
111
+ wells_df_predict = pd.concat([pd.read_csv(file_path + f) for f in selected_csv_file])
112
+ # wells_df_predict = tweak_data_S(wells_df_predict)
113
+ else: # Nếu người dùng không chọn file CSV
114
+ wells_df_predict = df
115
+ # wells_df_predict = tweak_data_S(wells_df_predict)
116
+
117
+ st.write('You can load your json file using the file upload or selection from TRAINING SECTION below.')
118
+
119
+ st.subheader("2. JSON File Loading")
120
+ st.caption('## 2.1. JSON from Uploader')
121
+ model_best_uploader = None
122
+ uploaded_file = st.file_uploader("Choose a JSON file", type="json")
123
+ # Kiểm tra xem có file được upload hay không
124
+ if uploaded_file is not None:
125
+ # Lưu file JSON tạm thời
126
+ with open("temp.json", "w") as f:
127
+ f.write(uploaded_file.read().decode("utf-8"))
128
+ # Đường dẫn tới file JSON tạm thời
129
+ temp_file_path = os.path.abspath("temp.json")
130
+ # Tạo Booster từ file JSON
131
+ model_best_uploader = lgb.Booster(model_file=temp_file_path)
132
+
133
+ # Xóa file tạm sau khi sử dụng
134
+ os.remove(temp_file_path)
135
+ # Option 2: JSON from TRAINING SECTION
136
+ st.caption('## 2.2. JSON from TRANING SECTION')
137
+ dir_path = '/work/2022_VPIMLogs_WebApp/models/'
138
+ json_files = [filename for filename in os.listdir(dir_path) if filename.endswith('.json')]
139
+ selected_json_file= st.multiselect('Select a JSON file', json_files, key = 'st.session_state.selected_well_multi_JSON')
140
+ if selected_json_file: # Nếu người dùng đã chọn file json
141
+ # Đọc file json được chọn vào Booster
142
+ file_path = '/work/2022_VPIMLogs_WebApp/models/'
143
+ model_files = "/work/2022_VPIMLogs_WebApp/models/05_13_2023_11_50_38_model_LGBM.json"
144
+ model_best = lgb.Booster(model_file=model_files)
145
+ else: # Nếu người dùng không chọn file json
146
+ model_best = model_best_uploader
147
+
148
+ if wells_df_predict is not None:
149
+ wells_df_predict = tweak_data_S(wells_df_predict)
150
+ wells_df_predict = wells_df_predict.replace({-9999: np.nan}).dropna(how='any', subset = "FRACTURE_ZONE")
151
+ st.write("Data Input:")
152
+ st.dataframe(wells_df_predict.sort_index(), width=1400, height=300)
153
+ st.write('---')
154
+ st.write("Selected Prediction Model:")
155
+ st.write(model_best)
156
+ #------------------------------------------------------------------
157
+ feature_names = [col for col in wells_df_predict.columns if col not in ["WELL", "DEPTH","FRACTURE_ZONE"]]
158
+ # Full data for export data
159
+ st.session_state.pred = st.button("Predict Fracture Zone")
160
+ if st.session_state.pred:
161
+ threshold = 0.5
162
+ #Make label Prediction
163
+ predictions = (model_best.predict(wells_df_predict[feature_names])> threshold).astype(int)
164
+ wells_df_predict['FRACTURE_ZONE_PRED'] = predictions
165
+ st.dataframe(wells_df_predict, width=1400, height=300)
166
+ #Plot Data------------------------------------------------------------------
167
+ plotting_curves = [c for c in wells_df_predict.columns.unique() if c not in ["DEPTH", "WELL", "TVD", "FRACTURE_ZONE", "FRACTURE_ZONE_PRED", "DCALI_FINAL", "INCL", "AZIM_TN", "rel_depth"]]
168
+ plotting_curves.sort()
169
+ if "FRACTURE_ZONE_PRED" in wells_df_predict.columns.unique():
170
+ plotting_curves.append("FRACTURE_ZONE_PRED")
171
+ for well in wells_df_predict.WELL.unique():
172
+ st.write('---')
173
+ st.write(f"{well} Logs: \n")
174
+ well_plot = wells_df_predict[wells_df_predict.WELL == well]
175
+ charts_dict={}
176
+ for i, c in enumerate(plotting_curves):
177
+ charts_dict[i] = curve_plot(data=well_plot,filted_data=None, x_column=c)
178
+ #Show Curve-----------------------------------------------------------------------
179
+ st.write(alt.concat(*charts_dict.values(), columns = 12).configure(autosize='fit'))
180
+ # Download --------------------------------------------------------------
181
+ st.write('---')
182
+ st.write("Download final result to csv file")
183
+
184
+ st.download_button(label='Download All Wells',
185
+ data = wells_df_predict.to_csv(),
186
+ file_name='FracturePredictionALL.csv',
187
+ mime='text/csv')
188
+
189
+ hide_menu_button()
190
+ condense_layout()
requirements.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ altair==4.2.0
2
+ bz2file==0.98
3
+ lasio==0.30
4
+ matplotlib==3.4.3
5
+ numpy==1.21.6
6
+ pandas==1.4.3
7
+ seaborn==0.11.2
8
+ streamlit==1.22.0
9
+ streamlit_vega_lite==0.1.0
10
+ streamlit-nested-layout==0.1.1
11
+ lightgbm==3.3.2
12
+ plotly==5.10.0
13
+ scikit-learn==1.1.2
ui/PageComponents.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import streamlit as st
3
+ from mLogsFunctions.fx import *
4
+ from mLogsFunctions import *
5
+
6
+ def subtab21(df, well_names):
7
+ col1, col2 = st.columns([1,8])
8
+ if "method_eda" not in st.session_state:
9
+ st.session_state.method_eda:str = "Single Well"
10
+ st.session_state.well_eda:str = well_names[0]
11
+ with col1:
12
+ st.radio("",
13
+ key="method_eda",
14
+ options=["All Wells", "Single Well"])
15
+ st.radio("WELL",
16
+ key="well_eda",
17
+ options=well_names)
18
+ with col2:
19
+ st.write('Data Description:')
20
+ if st.session_state.method_eda == "All Wells":
21
+ st.dataframe(df.describe(),width=1400, height=300)
22
+ elif st.session_state.method_eda == "Single Well":
23
+ df_single_w = df[df.WELL == st.session_state.well_eda]
24
+ st.dataframe(df_single_w.describe(),width=1400, height=300)
25
+ else:
26
+ pass
27
+
28
+ def subtab22(df,):
29
+ def missing_count(df):
30
+ missing = df.isnull().sum()*100/df.isnull().sum().sum()
31
+ missing = missing[missing >= 0].reset_index()
32
+ missing.columns = ['Columns', 'Count missing (%)']
33
+ return missing
34
+
35
+ mt1, mt2, mt3 = st.columns(3)
36
+
37
+ with mt1:
38
+ st.caption("Missing data rate of whole wells")
39
+ st.write(missing_bar(missing_count(df), "ALL WELLS"))
40
+ for i, w in enumerate(df.WELL.unique()):
41
+ if i%3 == 0:
42
+ st.caption(f"Missing data rate of {w}")
43
+ st.write(missing_bar(missing_count(well_filter(df, w)), f"WELL {w}"))
44
+ with mt2:
45
+ for i, w in enumerate(df.WELL.unique()):
46
+ if i%3 == 1:
47
+ st.caption(f"Missing data rate of {w}")
48
+ st.write(missing_bar(missing_count(well_filter(df, w)), f"WELL {w}"))
49
+ with mt3:
50
+ for i, w in enumerate(df.WELL.unique()):
51
+ if i%3 == 2:
52
+ st.caption(f"Missing data rate of {w}")
53
+ st.write(missing_bar(missing_count(well_filter(df, w)), f"WELL {w}"))
54
+
55
+ def subtab23(df, curves):
56
+ mb1, mb2, mb3 = st.columns(3)
57
+ for i, c in enumerate(curves):
58
+ if i%3 == 0:
59
+ with mb1:
60
+ st.caption(f"Distribution of {c}")
61
+ st.write(missing_box(df, c))
62
+ if i%3 == 1:
63
+ with mb2:
64
+ st.caption(f"Distribution of {c}")
65
+ st.write(missing_box(df, c))
66
+ if i%3 == 2:
67
+ with mb3:
68
+ st.caption(f"Distribution of {c}")
69
+ st.write(missing_box(df, c))
70
+
71
+ def subtab24(df, curves):
72
+ #Histogram Line----------------------------------------------------------------
73
+ h1, h2, h3 = st.columns(3)
74
+ for i, c in enumerate(curves):
75
+ if i%3 == 0:
76
+ with h1:
77
+ hist_line_plot(df,c)
78
+ if i%3 == 1:
79
+ with h2:
80
+ hist_line_plot(df,c)
81
+ if i%3 == 2:
82
+ with h3:
83
+ hist_line_plot(df,c)
84
+
85
+ def subtab25(df, curves):
86
+ #CrossPlot----------------------------------------------------------------
87
+ pair_curv = [(a, b) for idx, a in enumerate(curves) for b in curves[idx + 1:]]
88
+ cp0, cp1, cp2, cp3, cp4 = st.columns(5)
89
+ for i, c in enumerate(pair_curv):
90
+ if i%5 == 0:
91
+ with cp0:
92
+ crossplot(df, pair_curv[i][0], pair_curv[i][1])
93
+ if i%5 == 1:
94
+ with cp1:
95
+ crossplot(df, pair_curv[i][0], pair_curv[i][1])
96
+ if i%5 == 2:
97
+ with cp2:
98
+ crossplot(df, pair_curv[i][0], pair_curv[i][1])
99
+ if i%5 == 3:
100
+ with cp3:
101
+ crossplot(df, pair_curv[i][0], pair_curv[i][1])
102
+ if i%5 == 4:
103
+ with cp4:
104
+ crossplot(df, pair_curv[i][0], pair_curv[i][1])
105
+
106
+ def subtab26(df, curves):
107
+ #Pairpot----------------------------------------------------------------
108
+ _p1, _p2, _p3 = st.columns([2,2,2])
109
+ if "pair_opt" not in st.session_state:
110
+ st.session_state.pair_opt:str = "ALL WELLS"
111
+ st.session_state.color_pair:str = "WELL"
112
+ st.session_state.well_pair:str = list(df.WELL.unique())[0]
113
+ with _p1:
114
+ pair_opt_ = st.radio("Displayed objects", key="pair_opt", options=["ALL WELLS", "SINGLE WELL"], horizontal=True)
115
+ with _p2:
116
+ well_pair_ = st.selectbox("WELL", key="well_pair", options=list(df.WELL.unique()))
117
+ with _p3:
118
+ colorp_ = st.selectbox("COLOR", key="color_pair", options=columns_list(df))
119
+ if pair_opt_ == "ALL WELLS":
120
+ st.write(pairplot(df, curves, curves, colorp_))
121
+ elif pair_opt_ == "SINGLE WELL":
122
+ st.write(pairplot(df[df["WELL"]==well_pair_], curves, curves, colorp_))
123
+ else:
124
+ st.write("Undefined Error!")
125
+
126
+ def scatterPoint3D(df,):
127
+ #3D Plotly----------------------------------------------------------------
128
+ wells_ = list(df.WELL.unique())
129
+ curvs_ = columns_list(df, no_well=True)
130
+ colors_ = columns_list(df)
131
+ sizes_ = ["WELL", "FRACTURE_INTENSITY", "DEPTH", None]
132
+ symbols_ = ["WELL", "FRACTURE_INTENSITY", None]
133
+
134
+ if "well_3d" not in st.session_state:
135
+ st.session_state.w_opt:str = "ALL WELLS"
136
+ st.session_state.well_3d:str = wells_[0]
137
+ st.session_state.x_3d:str = curvs_[0]
138
+ st.session_state.y_3d:str = curvs_[0]
139
+ st.session_state.z_3d:str = curvs_[0]
140
+ st.session_state.color_3d:str = "WELL"
141
+ st.session_state.size_3d:str = "DEPTH"
142
+ st.session_state.symbol_3d:str = "WELL"
143
+
144
+ p1_, p2_ = st.columns([1,7])
145
+ with p1_:
146
+ w_opt = st.radio("DisplayType", key="w_opt", options=["ALL WELLS", "SINGLE WELL"])
147
+ well_ = st.selectbox("WELL", key="well_3d", options=wells_)
148
+ x_ = st.selectbox("X", key="x_3d", options=curvs_)
149
+ y_ = st.selectbox("Y", key="y_3d", options=curvs_)
150
+ z_ = st.selectbox("Z", key="z_3d", options=curvs_)
151
+ color_ = st.selectbox("COLOR", key="color_3d", options=colors_)
152
+ size_ = st.selectbox("SIZE", key="size_3d", options=sizes_)
153
+ symbol_ = st.selectbox("SYMBOL", key="symbol_3d", options=symbols_)
154
+ with p2_:
155
+ log_x, log_y, log_z = [False, False, False]
156
+ if x_ in ["LLD", "LLS"]:
157
+ log_x = True
158
+ if y_ in ["LLD", "LLS"]:
159
+ log_y = True
160
+ if z_ in ["LLD", "LLS"]:
161
+ log_z = True
162
+ if w_opt == "ALL WELLS":
163
+ plotly_3d(df, x_, y_, z_, color_, size_, symbol_, log_x, log_y, log_z)
164
+ else:
165
+ df_3d_plt = df[df["WELL"]==well_]
166
+ plotly_3d(df_3d_plt, x_, y_, z_, color_, size_, symbol_, log_x, log_y, log_z)
167
+
168
+
169
+ def stViewCurves(df):
170
+ _w = st.selectbox(label='Select WELL', options=list(df.WELL.unique()), key='w_plot')
171
+ if st.session_state.w_plot is not None:
172
+ df_plot = df[df['WELL']== _w]
173
+ _c = st.multiselect("Select curves for plotting:", key="curv_plt", options=columns_list(df, no_depth=True, no_well=True))
174
+ if len(_c) != 0:
175
+ view_curves(df_plot, curves=_c)
176
+
ui/UIConfigs.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+
4
+ def hide_menu_button():
5
+ st.markdown(""" <style>
6
+ #MainMenu {visibility: hidden;}
7
+ footer {visibility: hidden;}
8
+ </style> """, unsafe_allow_html=True
9
+ )
10
+
11
+ def condense_layout():
12
+ padding = 0
13
+ st.markdown(f""" <style>
14
+ .reportview-container .main .block-container{{
15
+ padding-top: {padding}rem;
16
+ padding-right: {padding}rem;
17
+ padding-left: {padding}rem;
18
+ padding-bottom: {padding}rem;
19
+ }} </style> """, unsafe_allow_html=True
20
+ )
21
+
22
+ def set_page_config(page:str='home', logo_size:str=200, pagetile:str=None):
23
+ img = Image.open("/work/LogoVPI.png")
24
+ st.set_page_config(# Alternate names: setup_page, page, layout
25
+ layout="wide", # Can be "centered" or "wide". In the future also "dashboard", etc.
26
+ initial_sidebar_state="auto", # Can be "auto", "expanded", "collapsed"
27
+ page_title="VPI-MLogs", # String or None. Strings get appended with "• Streamlit".
28
+ page_icon=img, # String, anything supported by st.image, or None.
29
+ )
30
+ if page == 'home':
31
+ col_1, col_2, col_3, col_4, col_5, = st.columns(5)
32
+ with col_3:
33
+ st.image("https://i.ibb.co/Yd42K98/LogoVPI.png", width=logo_size)
34
+ elif page == 'sub':
35
+ logo, info = st.columns([3, 7])
36
+ with logo:
37
+ st.image("https://i.ibb.co/Yd42K98/LogoVPI.png", width=logo_size)
38
+ with info:
39
+ st.markdown(pagetile, unsafe_allow_html=True)
40
+
41
+
ui/__init__.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .UIConfigs import *
2
+ from .PageComponents import *
3
+
4
+ __all__ = ['hide_menu_button',
5
+ 'condense_layout',
6
+ 'set_page_config',
7
+
8
+ 'subtab21',
9
+ 'subtab22',
10
+ 'subtab23',
11
+ 'subtab24',
12
+ 'subtab25',
13
+ 'subtab26',
14
+
15
+ 'scatterPoint3D',
16
+ 'stViewCurves',
17
+
18
+ ]
ui/__pycache__/PageComponents.cpython-39.pyc ADDED
Binary file (6 kB). View file
 
ui/__pycache__/UIConfigs.cpython-39.pyc ADDED
Binary file (1.67 kB). View file
 
ui/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (347 Bytes). View file