Intro to gwrefpy#

This notebook introduces the objects models and wells and how they are used in gwrefpy.

This notebook can be downloaded from the source code here.

Models and wells are important and they build the foundation of gwrefpy. Models are used to represent a site or area of interest, and wells are used to represent locations where groundwater data is collected. There is no limit to the number of models or wells that can be created in gwrefpy, nor is there a restriction on the order in which they are created. Models and wells can be created independently of one another, and they can be linked together later.

We will start by importing the necessary packages and then begin with creating a model. For this notebook we besides the gwrefpy also need the pandas package.

import gwrefpy as gr
import pandas as pd

Creating a Model#

A model is typically a representation of a site or area of interest. Models can be made up of any number of wells. In this case we create a model with the name ‘My First gwrefpy Model’

model = gr.Model(name="My First gwrefpy Model")

Creating Wells#

Models are made up of wells. A well is typically a location where groundwater data is collected. Wells can be created independently of models, and they can be linked to models later. Wells can either be an observation well or a reference well.

Reference wells#

Wells that are used to represent natural conditions.

Observation wells#

Wells that the user is interested in to see if they are influenced by anthropogenic activities.

In this notebook we create one observation wells and one reference wells to later include in our existing model.

Creating data timeseries#

To create our wells, we first need to convert our groundwater data to pandas timeseries for each well. In this example this is made by using CSV-files.

Tip

Data types can be other than CSV. Check the pandas documentation for inspiration.

df_obs1 = pd.read_csv(r'https://github.com/andersretznerSGU/gwrefpy/raw/dev/docs/user_guide/data/obs1_mod_wel.csv',sep=';', index_col=0, parse_dates=True)
df_ref1 = pd.read_csv(r'https://github.com/andersretznerSGU/gwrefpy/raw/dev/docs/user_guide/data/obs1_mod_wel.csv',sep=';', index_col=0, parse_dates=True)
df_obs2 = pd.read_csv(r'https://github.com/andersretznerSGU/gwrefpy/raw/dev/docs/user_guide/data/obs1_mod_wel.csv',sep=';', index_col=0, parse_dates=True)
df_ref2 = pd.read_csv(r'https://github.com/andersretznerSGU/gwrefpy/raw/dev/docs/user_guide/data/obs1_mod_wel.csv',sep=';', index_col=0, parse_dates=True)

#Create pandas series from the dataframes.

obs1_series = df_obs1.iloc[:, 0] 
ref1_series = df_ref1.iloc[:, 0]
obs2_series = df_obs2.iloc[:, 0]
ref2_series = df_ref2.iloc[:, 0]

Next we create well objects and add our timeseries to them.

The well object

The well object takes three input arguments. A name as a string. A boolean to decide if it´s a reference or observation well. And the last argument is the pandas timeseries we created earlier.

Important

Wells must have unique names. However the model will check that aswell and you´ll receive an error if that’s not the case.

obs1= gr.Well(name="obs1", is_reference=False, timeseries=obs1_series)
ref1= gr.Well(name="ref1", is_reference=True, timeseries=ref1_series)
obs2= gr.Well(name="obs2", is_reference=False, timeseries=obs2_series)
ref2= gr.Well(name="ref2", is_reference=True, timeseries=ref2_series)

Now we move on to adding our newly created wells to our model.

Add wells to the model#

Next we add the wells to the model by using the add_well function. A model can have any number of wells. This can either be done through by entering a list as an input argument or by entering a single well.

#Adding wells from a list
model.add_well([obs1,ref1,obs2])

#Adding single well
model.add_well(ref2)

After adding the wells to the model, we can now doublecheck to see that they´re actually included in the model we’ve created.

Check which wells are included in the model#

Now we check that our wells are stored in the model by using the function get_wells to see which wells are reference wells and which are observation wells.

model.obs_wells
[Well(name=obs1), Well(name=obs2)]

Check reference wells

model.ref_wells
[Well(name=ref1), Well(name=ref2)]

We can also check if a specific well is in the model

model.get_wells('obs1')
model.get_wells(['obs1','ref1'])
[Well(name=obs1), Well(name=ref1)]

We can also check the names of the wells that are included in our model.

model.well_names
['obs1', 'ref1', 'obs2', 'ref2']

Now we have checked that the model contains two observation wells and two reference wells, which later can be used for further analysis.

We can also get a summary of the wells in the model.

model.wells_summary()
name well_type data_points start_date end_date mean_level latest_value latest_date latitude longitude elevation best_fit_ref_well best_rmse num_fits avg_rmse
0 obs1 observation 2078 2020-01-01 2025-09-08 15.467492 14.877 2025-09-08 None None None None None NaN NaN
1 obs2 observation 2078 2020-01-01 2025-09-08 15.467492 14.877 2025-09-08 None None None None None NaN NaN
2 ref1 reference 2078 2020-01-01 2025-09-08 15.467492 14.877 2025-09-08 None None None NaN NaN 0.0 None
3 ref2 reference 2078 2020-01-01 2025-09-08 15.467492 14.877 2025-09-08 None None None NaN NaN 0.0 None

Delete wells from the model#

We can also remove wells from the model by using the function delete_well. This function takes a single input argument, the name of the well.

model.delete_well([ref1])

# and check that it is deleted
model.well_names
['obs1', 'obs2', 'ref2']

This is all for the intro to gwrefpy notebook.

In future notebooks we will explore using a model to a explore the other parts of gwrefpy such as pairing of observation- and reference wells and fitting and then plotting.