SPT Subaccessor#

In this guide, the basics of the spt subaccessor methods are presented. The spt subaccessor is a collection of methods related to standard penetration test (SPT) calculations for each sample of each point in the DataFrame. For information about the columns used by this subaccessor, see SPT Columns.

First, we import the necessary libraries,

In [1]: import pandas as pd

In [2]: import geotech_pandas

Next, we create a DataFrame with the following data,

In [3]: df = pd.DataFrame(
   ...:     {
   ...:         "point_id": ["BH-1", "BH-1", "BH-1", "BH-1", "BH-1", "BH-1", "BH-1", "BH-1"],
   ...:         "bottom": [1.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.0],
   ...:         "sample_type": ["spt", "spt", "spt", "spt", "spt", "spt", "spt", "spt"],
   ...:         "sample_number": [1, 2, 3, 4, 5, 6, 7, 8],
   ...:         "blows_1": [0, 10, 14, 18, 25, 33, 40, 50],
   ...:         "blows_2": [0, 12, 13, 20, 29, 35, 45, None],
   ...:         "blows_3": [0, 15, 13, 23, 27, 37, 50, None],
   ...:         "pen_1": [150, 150, 150, 150, 150, 150, 150, 10],
   ...:         "pen_2": [150, 150, 150, 150, 150, 150, 150, None],
   ...:         "pen_3": [150, 150, 150, 150, 150, 150, 50, None],
   ...:     }
   ...: )
   ...: 

In [4]: df = df.convert_dtypes()

In [5]: df
Out[5]: 
  point_id  bottom sample_type  sample_number  ...  blows_3  pen_1  pen_2  pen_3
0     BH-1     1.0         spt              1  ...        0    150    150    150
1     BH-1     1.5         spt              2  ...       15    150    150    150
2     BH-1     3.0         spt              3  ...       13    150    150    150
3     BH-1     4.5         spt              4  ...       23    150    150    150
4     BH-1     6.0         spt              5  ...       27    150    150    150
5     BH-1     7.5         spt              6  ...       37    150    150    150
6     BH-1     9.0         spt              7  ...       50    150    150     50
7     BH-1    10.0         spt              8  ...     <NA>     10   <NA>   <NA>

[8 rows x 10 columns]

Note

Notice that the df is reassigned with the result of convert_dtypes() method. This method converts the columns of df to the best possible dtypes that support NA to consistently represent missing data.

Use the dtypes property to show the current dtypes of df,

In [6]: df.dtypes
Out[6]: 
point_id         string[python]
bottom                  Float64
sample_type      string[python]
sample_number             Int64
blows_1                   Int64
blows_2                   Int64
blows_3                   Int64
pen_1                     Int64
pen_2                     Int64
pen_3                     Int64
dtype: object

Getting the seating penetration#

The get_seating_pen() method returns a Series of penetration measurements in the first increment, where the measurements are exactly 150 mm. Measurements that do not meet the requirements are masked with NA.

In [7]: df.geotech.in_situ.spt.get_seating_pen()
Out[7]: 
0     150
1     150
2     150
3     150
4     150
5     150
6     150
7    <NA>
Name: seating_pen, dtype: Int64

Getting the main penetration#

The get_main_pen() method returns a Series with the sum of the penetration in the second and third 150 mm increment for each sample/layer.

In [8]: df.geotech.in_situ.spt.get_main_pen()
Out[8]: 
0     300
1     300
2     300
3     300
4     300
5     300
6     200
7    <NA>
Name: main_pen, dtype: Int64

Getting the total penetration#

One of the methods under spt is the ability to get the total penetration of each SPT increment. The get_total_pen() method returns a Series with the sum of the penetration per inteval in each sample/layer.

In [9]: df.geotech.in_situ.spt.get_total_pen()
Out[9]: 
0    450
1    450
2    450
3    450
4    450
5    450
6    350
7     10
Name: total_pen, dtype: Int64

Getting the seating drive#

It is also possible to get the seating drive, which is, by definition, the number of blows required to penetrate the first 150 mm increment. The get_seating_drive() method returns such a result for each sample/layer.

In [10]: df.geotech.in_situ.spt.get_seating_drive()
Out[10]: 
0       0
1      10
2      14
3      18
4      25
5      33
6      40
7    <NA>
Name: seating_drive, dtype: Int64

Note

Notice that the last value is NA, this is because the first increment didn’t reach the full 150 mm requirement. Such cases are usually considered as invalid tests or hint to the start of a hard layer of soil or rock.

Getting the main drive#

The main drive, which is the total number of blows in the second and third 150 mm increment, can also be returned by the get_main_drive() method for each sample/layer.

In [11]: df.geotech.in_situ.spt.get_main_drive()
Out[11]: 
0       0
1      27
2      26
3      43
4      56
5      72
6      95
7    <NA>
Name: main_drive, dtype: Int64

Note

This method simply sums up the second and third increment regardless if the increments are completely penetrated or not. Due to this, the main drive may not always correspond to the reported N-value.

Getting the total drive#

It is also possible to calculate the total number of blows in all three 150 mm increments for each sample/layer through the get_total_drive() method.

In [12]: df.geotech.in_situ.spt.get_total_drive()
Out[12]: 
0      0
1     37
2     40
3     61
4     81
5    105
6    135
7     50
Name: total_drive, dtype: Int64

Checking for refusal samples#

It is possible to check for which samples refused penetration through is_refusal(). This method will return True for any sample that may be considered a refusal.

A sample is considered a refusal when any of the following is true:

  • a total of 50 blows or more have been applied during any of the three 150 mm increments;

  • a total of 100 blows or more have been applied; and

  • partial penetration, which signifies that the sampler can no longer penetrate through the strata, is present in any of the increments.

In [13]: df.geotech.in_situ.spt.is_refusal()
Out[13]: 
0    False
1    False
2    False
3    False
4    False
5     True
6     True
7     True
Name: is_refusal, dtype: boolean

Checking for hammer weight samples#

It is also possible to check which samples are hammer weights through is_hammer_weight(). This method will return True for any sample that may be considered hammer weight.

A sample is considered hammer weight when all of the following are true:

  • a total of 450 mm or more was penetrated by the sampler through sinking; and

  • each 150 mm increment has 0 blows recorded.

This can be defined in a DataFrame similar to how the first sample is recorded. The blow counts and penetration measurements for all three increments are 0 and 150, respectively.

In [14]: df.geotech.in_situ.spt.is_hammer_weight()
Out[14]: 
0     True
1    False
2    False
3    False
4    False
5    False
6    False
7    False
Name: is_hammer_weight, dtype: boolean

Getting the N-value#

The SPT is mainly done to calculate the N-value. This can easily be calculated using the get_n_value() method for each sample/layer.

In [15]: df.geotech.in_situ.spt.get_n_value()
Out[15]: 
0     0
1    27
2    26
3    43
4    56
5    50
6    50
7    50
Name: n_value, dtype: Int64

As you can see, the N-values for the last three samples are set to 50, but why? This is because these samples are refusals and are assumed to have an N-value of 50; however, this behavior can be customized.

Setting the assumed refusal N-value#

The assumed refusal N-value can easily be changed by setting the refusal parameter like so,

In [16]: df.geotech.in_situ.spt.get_n_value(refusal=100)
Out[16]: 
0      0
1     27
2     26
3     43
4     56
5    100
6    100
7    100
Name: n_value, dtype: Int64

You can also set it to NA if you don’t want to assume a refusal N-value,

In [17]: df.geotech.in_situ.spt.get_n_value(refusal=pd.NA)
Out[17]: 
0       0
1      27
2      26
3      43
4      56
5    <NA>
6    <NA>
7    <NA>
Name: n_value, dtype: Int64

Limiting the N-values#

The limit parameter is also available if you wish to limit the non-refusal N-values to the refusal N-value. To limit the N-values, just set the limit parameter to True,

In [18]: df.geotech.in_situ.spt.get_n_value(limit=True)
Out[18]: 
0     0
1    27
2    26
3    43
4    50
5    50
6    50
7    50
Name: n_value, dtype: Int64

As you can see, the N-value at index 4 was limited from 56 to 50.

Warning

Setting limit to True while also setting refusal to NA will have a similar output to Out[16] above. That is to say, the refusal N-value will change as expected, however, since it is essentially nothing, nothing will get limited as well.

In [19]: df.geotech.in_situ.spt.get_n_value(refusal=pd.NA, limit=True)
Out[19]: 
0       0
1      27
2      26
3      43
4      56
5    <NA>
6    <NA>
7    <NA>
Name: n_value, dtype: Int64

Don’t worry if you forget about this warning, since geotech-pandas will warn you when it detects you using such settings.

Getting a simple SPT report#

A simple descriptive report of the blow counts and the N-value can be obtained through the get_report() method,

In [20]: df.geotech.in_situ.spt.get_report()
Out[20]: 
0                  0,0,0 N=0(HW)
1                  10,12,15 N=27
2                  14,13,13 N=26
3                  18,20,23 N=43
4                  25,29,27 N=56
5               33,35,37 N=72(R)
6    40,45,50/50mm N=95/200mm(R)
7              50/10mm,-,- N=(R)
Name: spt_report, dtype: string