import pickle from pathlib import Path import streamlit as st import pandas as pd import plotly.graph_objects as go from plotly.subplots import make_subplots from streamlit_plotly_events import plotly_events import streamlit as st import pandas as pd import numpy as np from sklearn import preprocessing import pywt def convert_pumping_data_to_df(uploaded_file): df = pd.read_excel(uploaded_file) # convert the date column to datatime try: #convert the first column to datetime df.iloc[:,0] = pd.to_datetime(df.iloc[:,0]) except Exception as e: st.warning(f"An error occurred while converting the date column to datetime: {e}") return df def convert_ms_to_df(uploaded_file): df = pd.read_excel(uploaded_file) # convert the date column to datatime try: #convert the first column to datetime df.iloc[:,0] = pd.to_datetime(df.iloc[:,0]) except Exception as e: st.warning(f"An error occurred while converting the date column to datetime: {e}") return df def plot_pumping_data(df, date_col, pressure_col, rate_col): fig = make_subplots(specs=[[{"secondary_y": True}]]) fig.add_trace(go.Scatter(x=df[date_col], y=df[pressure_col], mode='lines', name='Pressure', line=dict(color='blue')), secondary_y=False) fig.add_trace(go.Scatter(x=df[date_col], y=df[rate_col], mode='lines', name='Rate', line=dict(color='red')), secondary_y=True) fig.update_layout(title_text="Pumping Data") fig.update_xaxes(title_text="Date") fig.update_yaxes(title_text="Pressure", secondary_y=False) fig.update_yaxes(title_text="Rate", secondary_y=True) #update the legend to be horizonal at the top fig.update_layout(legend=dict( orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1 )) #remove secondary axis gridlines fig.update_yaxes(showgrid=False, secondary_y=True) #click event on the chart to get the x axis value # Attempt to capture click events using streamlit-plotly-events (install required) return fig def calculate_cwt(df,time_col,pressure_col): #convert first column in both data frame pumping and microseismic to datetime df[time_col] = pd.to_datetime(df[time_col]) norm_coef2_a,period,time_data,scales_a,coef_a, freqs_a,pressure_data = continous_wavelet_transformer(df[pressure_col],df[time_col]) #transpose norm_coef2_a norm_coef2_a = norm_coef2_a.T #merge the norm_coef2_a with time_data as date time and pressure data and QC_LOC_X,Y,Z and remove the nulls in time_data norm_coef2_a = pd.DataFrame(norm_coef2_a,columns=scales_a) norm_coef2_a['t'] = df[time_col] norm_coef2_a['p'] = df[pressure_col] norm_coef2_a = norm_coef2_a.dropna(subset=['t']) return norm_coef2_a def continous_wavelet_transformer(pressure_data,time_data): scales_a = np.linspace(1, 256, 256) coef_a, freqs_a = pywt.cwt(pressure_data, scales_a, "cmor1.5-1.0") energy = np.sqrt(coef_a.real**2 + coef_a.imag**2) coef2_a = np.log2(energy) period = 1.0 / freqs_a scaler=preprocessing.MinMaxScaler(feature_range=(0,1)).fit(coef2_a) norm_coef2_a=scaler.transform(coef2_a) return norm_coef2_a,period,time_data,scales_a,coef_a, freqs_a,pressure_data def reload_DT_model(): # Load the model from the file with open(Path('DecisionTree.pkl'), 'rb') as file: model = pickle.load(file) return model def import_min_max(): #import min max from txt file with open(Path('max_min.txt'),'r') as f: min_max = f.readlines() min_max = [x.strip() for x in min_max] min_max = [x.split(',') for x in min_max] min_max = [[float(y) for y in x] for x in min_max] min_max = np.array(min_max) return min_max def predict_microseismic_events(df,x_names,y_names,east_perf,north_perf,depth_perf): model = reload_DT_model() #predict the microseismic events df.reset_index(drop=True, inplace=True) df.rename(columns=dict(zip(df.columns[:256], x_names)), inplace=True) ds_test = df[x_names] # Convert example_data to a DataFrame with column names (cont_names) example_data_df = pd.DataFrame(ds_test, columns=x_names) # Make predictions on the example data predictions = model.predict(example_data_df) # convert the predictions to dataframe predictions_df = pd.DataFrame(predictions, columns=y_names) # trail the column names with _pred predictions_df.columns = [ str(col) + '_pred' for col in predictions_df.columns] final_df = predictions_df.reset_index(drop=True) # denormalize the pred columns using min max min_max = import_min_max() final_df['delta_east_pred_denormalized'] = final_df['delta_east_pred'] * \ (min_max[0][1] - min_max[0][0]) + min_max[0][0] final_df['delta_north_pred_denormalized'] = ( final_df['delta_north_pred'] * (min_max[1][1] - min_max[1][0]) + min_max[1][0]) final_df['delta_depth_pred_denormalized'] = final_df['delta_depth_pred'] * \ (min_max[2][1] - min_max[2][0]) + min_max[2][0] final_df['east_pred'] = final_df['delta_east_pred_denormalized'] + east_perf final_df['north_pred'] = final_df['delta_north_pred_denormalized'] + north_perf final_df['depth_pred'] = final_df['delta_depth_pred_denormalized'] + depth_perf final = pd.concat([df, final_df], axis=1) return final def plot_microseismic_events(final): fig = go.Figure(data=[go.Scatter3d( x=final['east_pred'], y=final['north_pred'], z=final['depth_pred'], mode='markers', marker=dict( size=3, opacity=1, color='red' ), name='Predicted' )]) # #add the predicted # fig.add_trace(go.Scatter3d( # x=final['east_pred'], # y=final['north_pred'], # z=final['depth_pred'], # mode='markers', # marker=dict( # size=2, # opacity=0.2, # color='red' # ), # name='predicted' # )) fig.update_layout(title=f"Predicted Micro Seismic Events", xaxis_title="east", yaxis_title="north",height=800) return fig def compare_microseismic_events(final,actual,east,north,depth,depth_shift): # #convert first column in final to datetime64[ns] # final['t'] = pd.to_datetime(final['t']) # st.write(actual[time_col]) # st.write(final.t) # #write the type of final.t column and actual[time_col] column # st.write(f"actual[time_col] column type: {actual[time_col].dtype}") # st.write(f"final.t column type: {final.t.dtype}") # #join the final and actual depending on column zero # # joined_df = pd.merge(final, actual, left_on='t', right_on=time_col, how='outer') # st.write(joined_df) actual[depth] = depth_shift - actual[depth] fig = go.Figure(data=[go.Scatter3d( x=final['east_pred'], y=final['north_pred'], z=final['depth_pred'], mode='markers', marker=dict( size=2, opacity=0.3, color='red' ), name='Predicted' )]) #add the actual fig.add_trace(go.Scatter3d( x=actual[east], y=actual[north], z=actual[depth], mode='markers', marker=dict( size=3, opacity=1, color='navy' ), name='Actual' )) fig.update_layout(title=f"Predicted Micro Seismic Events", xaxis_title="east", yaxis_title="north",height=800) return fig