Skip to content

Index

subsurfaceio.site_investigation.laboratory

Laboratory test models for borehole specimens.

Classes:

Name Description
AtterbergLimits

Atterberg limits (ASTM D4318).

AtterbergLimitsMetadata

Atterberg limits summary values for a specimen.

HydrometerAnalysis

Hydrometer analysis (ASTM D422).

HydrometerData

Single hydrometer reading over time.

HydrometerMetadata

Hydrometer analysis test metadata and corrections.

IndexTests

INDX-derived reported values (density, Gs, fines).

LiquidLimit

Liquid limit trials (ASTM D4318).

LiquidLimitTrialData

Liquid limit trial with blow count.

PlasticLimit

Plastic limit trials (ASTM D4318).

Sample

Borehole sample containing specimens.

SampleMetadata

Borehole sample identification and recovery metadata.

SieveAnalysis

Interpreted sieve curve / index props.

SieveAnalysisData

Sieve curve point (particle size vs percent finer).

SieveAnalysisMetadata

Interpolated sieve-analysis summary (percent passing, Cu, Cc).

SieveAnalysisSettings

Sieve curve interpretation settings (e.g. fine-end extrapolation for D-sizes).

SieveRetainedData

Single sieve retained-mass measurement.

SieveRetainedMetadata

Retained-mass sieve test metadata.

SieveRetainedTest

Raw sieve retained-mass trials.

Specimen

Laboratory specimen with optional lab test groups.

SpecimenMetadata

Laboratory specimen identification and classification metadata.

StrengthTests

Strength tests.

WaterContent

Water content (ASTM D2216).

WaterContentMetadata

Water content test summary.

WaterContentTrialData

Single water-content trial measurements.

AtterbergLimits pydantic-model

Bases: BaseModel

Atterberg limits (ASTM D4318).

Fields:

liquid_limit_test pydantic-field

liquid_limit_test: LiquidLimit | None = None

metadata pydantic-field

metadata: AtterbergLimitsMetadata

plastic_limit_test pydantic-field

plastic_limit_test: PlasticLimit | None = None

calculate

calculate() -> Self

Run liquid- and plastic-limit tests and fill metadata.

Returns:

Type Description
Self

This Atterberg-limits model.

AtterbergLimitsMetadata pydantic-model

Bases: BaseModel

Atterberg limits summary values for a specimen.

Fields:

liquid_limit pydantic-field

liquid_limit: NullableFloat = None

method pydantic-field

method: str | None = None

plastic_limit pydantic-field

plastic_limit: NullableFloat = None

plasticity_index pydantic-field

plasticity_index: NullableFloat = None

remarks pydantic-field

remarks: str | None = None

set_plasticity_index

set_plasticity_index() -> Self

Set plasticity index from reported liquid and plastic limits (ASTM D4318).

LL and PL are rounded to the nearest whole number; PI = LL − PL.

HydrometerAnalysis pydantic-model

Bases: BaseModel

Hydrometer analysis (ASTM D422).

Fields:

data pydantic-field

data: list[HydrometerData]

metadata pydantic-field

metadata: HydrometerMetadata

calculate

calculate() -> Self

Compute hydrometer particle size and percent finer for each reading.

Returns:

Type Description
Self

This hydrometer analysis.

plot

plot(
    plot_module: Literal["plotly", "mpl"] = "plotly",
) -> Any

Plot hydrometer results on the hydrometer reference figure.

Parameters:

Name Type Description Default
plot_module Literal['plotly', 'mpl']

Figure backend.

'plotly'

Returns:

Type Description
Any

Plotly or matplotlib figure.

HydrometerData pydantic-model

Bases: BaseModel

Single hydrometer reading over time.

Fields:

corrected_hydrometer_reading pydantic-field

corrected_hydrometer_reading: NullableFloat = None

effective_length pydantic-field

effective_length: NullableFloat = None

effective_length_corrected_reading pydantic-field

effective_length_corrected_reading: NullableFloat = None

hydrometer_reading pydantic-field

hydrometer_reading: float

hydrometer_time pydantic-field

hydrometer_time: float

particle_size pydantic-field

particle_size: NullableFloat = None

percent_finer pydantic-field

percent_finer: NullableFloat = None

percent_finer_uncorrected pydantic-field

percent_finer_uncorrected: NullableFloat = None

HydrometerMetadata pydantic-model

Bases: BaseModel

Hydrometer analysis test metadata and corrections.

Fields:

a_parameter pydantic-field

a_parameter: NullableFloat = None

dry_soil_mass pydantic-field

dry_soil_mass: float

fines_content pydantic-field

fines_content: NullableFloat = None

hydrometer_type pydantic-field

hydrometer_type: HydrometerType

meniscus_correction pydantic-field

meniscus_correction: float

percent_clay pydantic-field

percent_clay: NullableFloat = None

percent_silt pydantic-field

percent_silt: NullableFloat = None

specific_gravity pydantic-field

specific_gravity: float

specific_gravity_correction pydantic-field

specific_gravity_correction: NullableFloat = None

temperature pydantic-field

temperature: float

temperature_correction pydantic-field

temperature_correction: NullableFloat = None

zero_correction pydantic-field

zero_correction: float

calculate

calculate() -> Self

Fill hydrometer correction factors from temperature and Gs.

Returns:

Type Description
Self

This hydrometer metadata.

IndexTests pydantic-model

Bases: BaseModel

INDX-derived reported values (density, Gs, fines).

Fields:

bulk_density pydantic-field

bulk_density: NullableFloat = None

dry_density pydantic-field

dry_density: NullableFloat = None

fines_content pydantic-field

fines_content: NullableFloat = None

method pydantic-field

method: str | None = None

remarks pydantic-field

remarks: str | None = None

specific_gravity pydantic-field

specific_gravity: NullableFloat = None

LiquidLimit pydantic-model

Bases: BaseModel

Liquid limit trials (ASTM D4318).

Fields:

data pydantic-field

data: list[LiquidLimitTrialData]

flow_index property

flow_index: float | None

Flow index from the liquid-limit series, when available.

liquid_limit property

liquid_limit: float | None

Interpreted liquid limit from the trial series.

liquid_limit_method pydantic-field

liquid_limit_method: LiquidLimitMethod = 'multi_point'

calculate

calculate() -> Self

Interpret liquid limit and flow index from trials.

Returns:

Type Description
Self

This liquid-limit test.

plot

plot(
    plot_module: Literal["plotly", "mpl"] = "plotly",
) -> Any

Plot liquid-limit trials on the Atterberg reference figure.

Parameters:

Name Type Description Default
plot_module Literal['plotly', 'mpl']

Figure backend.

'plotly'

Returns:

Type Description
Any

Plotly or matplotlib figure.

LiquidLimitTrialData pydantic-model

Bases: WaterContentTrialData

Liquid limit trial with blow count.

Fields:

liquid_limit_blows pydantic-field

liquid_limit_blows: int

PlasticLimit pydantic-model

Bases: BaseModel

Plastic limit trials (ASTM D4318).

Fields:

data pydantic-field

data: list[WaterContentTrialData]

plastic_limit property

plastic_limit: float | None

Mean water content of plastic-limit trials.

calculate

calculate() -> Self

Average trial water contents into plastic_limit.

Returns:

Type Description
Self

This plastic-limit test.

Sample pydantic-model

Bases: BaseModel

Borehole sample containing specimens.

Fields:

Validators:

metadata pydantic-field

metadata: SampleMetadata

specimens pydantic-field

specimens: list[Specimen]

add_specimen

add_specimen(specimen: Specimen) -> Self

Append a specimen. specimen_id must be unique on this sample.

Parameters:

Name Type Description Default
specimen Specimen

Specimen to add.

required

Returns:

Type Description
Self

This sample.

Raises:

Type Description
ValueError

When specimen_id is missing or duplicated.

get_specimen_by_id

get_specimen_by_id(specimen_id: str) -> Specimen

Return the specimen with specimen_id.

Parameters:

Name Type Description Default
specimen_id str

metadata.specimen_id to look up.

required

Returns:

Type Description
Specimen

The matching specimen.

Raises:

Type Description
KeyError

When no specimen has that id.

SampleMetadata pydantic-model

Bases: BaseModel

Borehole sample identification and recovery metadata.

Fields:

date pydantic-field

date: datetime | None = None

depth pydantic-field

depth: NullableFloat = None

depth_top pydantic-field

depth_top: NullableFloat = None

description pydantic-field

description: str | None = None

recovery pydantic-field

recovery: NullableFloat = None

remarks pydantic-field

remarks: str | None = None

sample_diameter pydantic-field

sample_diameter: NullableFloat = None

sample_id pydantic-field

sample_id: str

sample_name pydantic-field

sample_name: str | None = None

sampler_type pydantic-field

sampler_type: SamplerType | None = None

SieveAnalysis pydantic-model

Bases: BaseModel

Interpreted sieve curve / index props.

Fields:

data pydantic-field

data: list[SieveAnalysisData]

metadata pydantic-field

metadata: SieveAnalysisMetadata

retained_test pydantic-field

retained_test: SieveRetainedTest | None = None

settings pydantic-field

settings: SieveAnalysisSettings

calculate

calculate() -> Self

Build the sieve curve from retained masses when present, then metadata.

Returns:

Type Description
Self

This sieve analysis.

calculate_metadata

calculate_metadata() -> Self

Interpolate D-sizes, Cu, Cc, and percent passing into metadata.

Returns:

Type Description
Self

This sieve analysis.

plot

plot(
    plot_module: Literal["plotly", "mpl"] = "plotly",
) -> Any

Plot the sieve curve on the sieve reference figure.

Parameters:

Name Type Description Default
plot_module Literal['plotly', 'mpl']

Figure backend.

'plotly'

Returns:

Type Description
Any

Plotly or matplotlib figure.

SieveAnalysisData pydantic-model

Bases: BaseModel

Sieve curve point (particle size vs percent finer).

Fields:

particle_size pydantic-field

particle_size: NullableFloat = None

percent_finer pydantic-field

percent_finer: NullableFloat = None

SieveAnalysisMetadata pydantic-model

Bases: BaseModel

Interpolated sieve-analysis summary (percent passing, Cu, Cc).

Fields:

curvature_coefficient pydantic-field

curvature_coefficient: NullableFloat = None

diameter_at_10_percent_finer pydantic-field

diameter_at_10_percent_finer: NullableFloat = None

diameter_at_30_percent_finer pydantic-field

diameter_at_30_percent_finer: NullableFloat = None

diameter_at_50_percent_finer pydantic-field

diameter_at_50_percent_finer: NullableFloat = None

diameter_at_60_percent_finer pydantic-field

diameter_at_60_percent_finer: NullableFloat = None

fines_content pydantic-field

fines_content: NullableFloat = None

method pydantic-field

method: str | None = None

percent_gravel pydantic-field

percent_gravel: NullableFloat = None

percent_passing_3in4 pydantic-field

percent_passing_3in4: NullableFloat = None

percent_passing_no10 pydantic-field

percent_passing_no10: NullableFloat = None

percent_passing_no4 pydantic-field

percent_passing_no4: NullableFloat = None

percent_passing_no40 pydantic-field

percent_passing_no40: NullableFloat = None

percent_sand pydantic-field

percent_sand: NullableFloat = None

remarks pydantic-field

remarks: str | None = None

uniformity_coefficient pydantic-field

uniformity_coefficient: NullableFloat = None

SieveAnalysisSettings pydantic-model

Bases: BaseModel

Sieve curve interpretation settings (e.g. fine-end extrapolation for D-sizes).

Fields:

extrapolate_max_percent_finer pydantic-field

extrapolate_max_percent_finer: float | None = None

SieveRetainedData pydantic-model

Bases: BaseModel

Single sieve retained-mass measurement.

Fields:

cumulative_mass_retained pydantic-field

cumulative_mass_retained: NullableFloat = None

mass_retained_sieve pydantic-field

mass_retained_sieve: float

particle_size pydantic-field

particle_size: NullableFloat = None

percent_finer pydantic-field

percent_finer: NullableFloat = None

sieve_number pydantic-field

sieve_number: SieveNumber

calculate

calculate() -> Self

Set particle_size from sieve_number.

Returns:

Type Description
Self

This retained-mass row.

SieveRetainedMetadata pydantic-model

Bases: BaseModel

Retained-mass sieve test metadata.

Fields:

dry_soil_mass pydantic-field

dry_soil_mass: NullableFloat = None

SieveRetainedTest pydantic-model

Bases: BaseModel

Raw sieve retained-mass trials.

Fields:

data pydantic-field

data: list[SieveRetainedData]

metadata pydantic-field

metadata: SieveRetainedMetadata

calculate

calculate() -> Self

Accumulate retained masses and percent finer.

Returns:

Type Description
Self

This retained-mass test.

Raises:

Type Description
ValueError

When dry_soil_mass is missing.

plot

plot(
    plot_module: Literal["plotly", "mpl"] = "plotly",
) -> Any

Plot retained-mass points on the sieve reference figure.

Parameters:

Name Type Description Default
plot_module Literal['plotly', 'mpl']

Figure backend.

'plotly'

Returns:

Type Description
Any

Plotly or matplotlib figure.

Specimen pydantic-model

Bases: BaseModel

Laboratory specimen with optional lab test groups.

Fields:

atterberg_limits pydantic-field

atterberg_limits: AtterbergLimits | None = None

hydrometer_analysis pydantic-field

hydrometer_analysis: HydrometerAnalysis | None = None

index_tests pydantic-field

index_tests: IndexTests | None = None

metadata pydantic-field

metadata: SpecimenMetadata

sieve_analysis pydantic-field

sieve_analysis: SieveAnalysis | None = None

strength_tests pydantic-field

strength_tests: StrengthTests | None = None

water_content pydantic-field

water_content: WaterContent | None = None

calculate_soil_classification

calculate_soil_classification(language: str = 'en') -> Self

Run USCS classification when required inputs are present.

Parameters:

Name Type Description Default
language str

Language for the USCS description.

'en'

Returns:

Type Description
Self

This specimen. Unchanged when fines/sand/gravel are missing.

calculate_tests

calculate_tests(
    classification_language: str = "en",
) -> Self

Run all present laboratory tests and USCS classification.

Parameters:

Name Type Description Default
classification_language str

Language for the USCS description.

'en'

Returns:

Type Description
Self

This specimen.

SpecimenMetadata pydantic-model

Bases: BaseModel

Laboratory specimen identification and classification metadata.

Fields:

color pydantic-field

color: str | None = None

crew pydantic-field

crew: str | None = None

depth pydantic-field

depth: NullableFloat = None

depth_top pydantic-field

depth_top: NullableFloat = None

description pydantic-field

description: str | None = None

has_organic_fines pydantic-field

has_organic_fines: bool = False

non_plastic pydantic-field

non_plastic: bool = False

remarks pydantic-field

remarks: str | None = None

specimen_id pydantic-field

specimen_id: str

specimen_reference pydantic-field

specimen_reference: str | None = None

uscs_symbol pydantic-field

uscs_symbol: USCSSymbol | None = None

StrengthTests pydantic-model

Bases: BaseModel

Strength tests.

Fields:

unconfined_compressive_strength pydantic-field

unconfined_compressive_strength: NullableFloat = None

unconfined_compressive_strength_pocket_penetrometer pydantic-field

unconfined_compressive_strength_pocket_penetrometer: (
    NullableFloat
) = None

undrained_shear_strength_torvane pydantic-field

undrained_shear_strength_torvane: NullableFloat = None

WaterContent pydantic-model

Bases: BaseModel

Water content (ASTM D2216).

Fields:

data pydantic-field

data: list[WaterContentTrialData]

metadata pydantic-field

metadata: WaterContentMetadata

calculate

calculate() -> Self

Run trials and store mean water content in metadata.

Returns:

Type Description
Self

This water-content test.

plot

plot(
    plot_module: Literal["plotly", "mpl"] = "plotly",
) -> None

Water content has no dedicated figure; returns None.

Parameters:

Name Type Description Default
plot_module Literal['plotly', 'mpl']

Unused; kept for a uniform lab plot signature.

'plotly'

WaterContentMetadata pydantic-model

Bases: BaseModel

Water content test summary.

Fields:

water_content pydantic-field

water_content: NullableFloat = None

WaterContentTrialData pydantic-model

Bases: BaseModel

Single water-content trial measurements.

Fields:

can_mass pydantic-field

can_mass: float

can_plus_dry_soil_mass pydantic-field

can_plus_dry_soil_mass: float

can_plus_wet_soil_mass pydantic-field

can_plus_wet_soil_mass: float

dry_soil_mass pydantic-field

dry_soil_mass: NullableFloat = None

moisture_mass pydantic-field

moisture_mass: NullableFloat = None

water_content_trials pydantic-field

water_content_trials: NullableFloat = None

calculate

calculate() -> Self

Compute moisture mass, dry soil mass, and trial water content.

Returns:

Type Description
Self

This trial row.