py-pilecore 0.4.1__py3-none-any.whl → 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of py-pilecore might be problematic. Click here for more details.

@@ -30,6 +30,7 @@ def create_soil_properties_payload(
30
30
  ]
31
31
  | None = None,
32
32
  individual_ocr: Mapping[Any, float] | None = None,
33
+ verbose: bool = False,
33
34
  ) -> Tuple[List[dict], Dict[str, dict]]:
34
35
  """
35
36
  Creates a dictionary with the `soil_properties` payload content for the PileCore
@@ -89,6 +90,8 @@ def create_soil_properties_payload(
89
90
  A dictionary, mapping ``CPTData.alias`` values to Over-Consolidation-Ratio [-]
90
91
  values of the foundation layer. This will overrule the general `ocr` setting for
91
92
  these specific CPTs only.
93
+ verbose:
94
+ If True, show progress bars and status messages in stdout.
92
95
 
93
96
  Returns
94
97
  -------
@@ -103,7 +106,15 @@ def create_soil_properties_payload(
103
106
  results_passover = {}
104
107
  soil_properties_list = []
105
108
 
106
- for cpt in tqdm(cptdata_objects, desc="Create soil properties payload"):
109
+ pbar = None
110
+ if verbose:
111
+ pbar = tqdm(total=len(cptdata_objects))
112
+ for cpt in cptdata_objects:
113
+ # Push verbose message
114
+ if pbar:
115
+ pbar.update()
116
+ pbar.set_description(f"Create soil properties payload for CPT: {cpt.alias}")
117
+
107
118
  # Construct the cpt_data payload
108
119
  cpt_data = dict(
109
120
  depth=np.array(cpt.data["depth"], dtype=float),
@@ -9,6 +9,7 @@ import natsort
9
9
  import numpy as np
10
10
  import pandas as pd
11
11
  from matplotlib import pyplot as plt
12
+ from matplotlib.axes import Axes
12
13
  from numpy.typing import NDArray
13
14
  from shapely import MultiPoint
14
15
 
@@ -184,7 +185,7 @@ class SingleClusterData:
184
185
  return pd.DataFrame(self.__dict__)
185
186
 
186
187
  def plot_variation_coefficient(
187
- self, axes: plt.Axes | None = None, **kwargs: Any
188
+ self, axes: Axes | None = None, **kwargs: Any
188
189
  ) -> None:
189
190
  """
190
191
  Plot the bearing capacity and variation coefficient in a subplot
@@ -206,7 +207,7 @@ class SingleClusterData:
206
207
  axes.set_xlabel("Variation coefficient [-]")
207
208
 
208
209
  def plot_bearing_capacity(
209
- self, axes: plt.Axes | None = None, pile_load_uls: float = 0.0, **kwargs: Any
210
+ self, axes: Axes | None = None, pile_load_uls: float = 0.0, **kwargs: Any
210
211
  ) -> None:
211
212
  """
212
213
  Plot the bearing capacity and variation coefficient in a subplot
@@ -7,13 +7,11 @@ import matplotlib.pyplot as plt
7
7
  import numpy as np
8
8
  import pandas as pd
9
9
  from matplotlib.axes import Axes
10
+ from matplotlib.patches import Patch
10
11
 
12
+ from pypilecore.common.piles import PileProperties
11
13
  from pypilecore.exceptions import UserError
12
14
  from pypilecore.results.load_settlement import get_load_settlement_plot
13
- from pypilecore.results.pile_properties import (
14
- PileProperties,
15
- create_pile_properties_from_api_response,
16
- )
17
15
  from pypilecore.results.single_cpt_results import SingleCPTBearingResults
18
16
 
19
17
  Number = Union[float, int]
@@ -473,7 +471,7 @@ class MultiCPTBearingResults:
473
471
  group_results = response_dict["group_results"]
474
472
  return cls(
475
473
  cpt_results=cpt_results_dict,
476
- pile_properties=create_pile_properties_from_api_response(
474
+ pile_properties=PileProperties.from_api_response(
477
475
  response_dict["pile_properties"]
478
476
  ),
479
477
  group_results_table=CPTGroupResultsTable(
@@ -548,6 +546,166 @@ class MultiCPTBearingResults:
548
546
  """The CPTGroupResultsTable dataclass, containing the group results."""
549
547
  return self._group_results_table
550
548
 
549
+ def boxplot(
550
+ self,
551
+ attribute: str,
552
+ axes: Axes | None = None,
553
+ figsize: Tuple[float, float] = (6.0, 6.0),
554
+ show_sqrt: bool = False,
555
+ **kwargs: Any,
556
+ ) -> Axes:
557
+ """
558
+ Plot a box and whisker plot for a given attribute.
559
+
560
+
561
+ .. code-block:: none
562
+
563
+ MIN Q1 median Q3 MAX
564
+ |-----:-----|
565
+ |--------| : |--------|
566
+ |-----:-----|
567
+
568
+ Parameters
569
+ ----------
570
+ attribute:
571
+ result attribute to create boxplot. Please note that the attribute name must be present in
572
+ the `CPTResultsTable` and `CPTGroupResultsTable` class.
573
+ axes:
574
+ Optional `Axes` object where the boxplot data can be plotted on.
575
+ If not provided, a new `plt.Figure` will be activated and the `Axes`
576
+ object will be created and returned.
577
+ figsize:
578
+ Size of the activate figure, as the `plt.figure()` argument.
579
+ show_sqrt:
580
+ Add sqrt(2) bandwidth to figure
581
+ **kwargs:
582
+ All additional keyword arguments are passed to the `pyplot.subplots()` call.
583
+
584
+ Returns
585
+ -------
586
+ axes:
587
+ The `Axes` object where the settlement curves were plotted on
588
+ """
589
+
590
+ # validate attribute
591
+ if (
592
+ attribute not in self.cpt_results.results[0].table.__dict__.keys()
593
+ or attribute not in self.group_results_table.__dict__.keys()
594
+ ):
595
+ raise ValueError(
596
+ f"""
597
+ {attribute} is not present in CPTResultsTable or CPTGroupResultsTable class.
598
+ Please select on of the following attributes:
599
+ {
600
+ set(self.cpt_results.results[0].table.__dict__.keys())
601
+ & set(self.group_results_table.__dict__.keys())
602
+ }
603
+ """
604
+ )
605
+
606
+ # Create axes objects if not provided
607
+ if axes is not None:
608
+ if not isinstance(axes, Axes):
609
+ raise ValueError(
610
+ "'axes' argument to boxplot() must be a `pyplot.axes.Axes` object or None."
611
+ )
612
+ else:
613
+ kwargs_subplot = {
614
+ "figsize": figsize,
615
+ "tight_layout": True,
616
+ }
617
+
618
+ kwargs_subplot.update(kwargs)
619
+
620
+ _, axes = plt.subplots(
621
+ 1,
622
+ 1,
623
+ **kwargs_subplot,
624
+ )
625
+
626
+ if not isinstance(axes, Axes):
627
+ raise ValueError(
628
+ "Could not create Axes objects. This is probably due to invalid matplotlib keyword arguments. "
629
+ )
630
+
631
+ # Collect data from single calculation
632
+ data = np.array(
633
+ [
634
+ item.table.__getattribute__(attribute)
635
+ for item in self.cpt_results.results
636
+ ]
637
+ )
638
+
639
+ # Draw a box and whisker plot
640
+ axes.boxplot(
641
+ np.flip(data, axis=0),
642
+ tick_labels=np.flip(self.group_results_table.pile_tip_level_nap),
643
+ whis=(0, 100),
644
+ autorange=True,
645
+ vert=False,
646
+ patch_artist=True,
647
+ showmeans=True,
648
+ zorder=0,
649
+ )
650
+
651
+ # ad additional bandwidth of sqrt(2) of the mean value
652
+ if show_sqrt:
653
+ axes.scatter(
654
+ np.flip(data.mean(axis=0)) * np.sqrt(2),
655
+ np.flip(
656
+ np.arange(len(self.group_results_table.pile_tip_level_nap)) + 1
657
+ ),
658
+ marker="^",
659
+ color="tab:purple",
660
+ zorder=1,
661
+ )
662
+ axes.scatter(
663
+ np.flip(data.mean(axis=0)) / np.sqrt(2),
664
+ np.flip(
665
+ np.arange(len(self.group_results_table.pile_tip_level_nap)) + 1
666
+ ),
667
+ marker="^",
668
+ color="tab:purple",
669
+ zorder=1,
670
+ )
671
+
672
+ # Draw group result over single result
673
+ axes.scatter(
674
+ np.flip(self.group_results_table.__getattribute__(attribute)),
675
+ np.flip(np.arange(len(self.group_results_table.pile_tip_level_nap)) + 1),
676
+ marker="o",
677
+ color="tab:red",
678
+ zorder=1,
679
+ )
680
+
681
+ # Draw group result over single result
682
+ for i, x in enumerate(data.mean(axis=0)):
683
+ axes.annotate(f"{x.round(2)}", xy=(x, i + 1))
684
+
685
+ # add legend to figure
686
+ axes.legend(
687
+ handles=[
688
+ Patch(color=clr, label=key)
689
+ for (key, clr) in {
690
+ "Single;min:max": "black",
691
+ "Single;Q25:Q75": "tab:blue",
692
+ "Single;Q50": "tab:orange",
693
+ "Single;mean": "tab:green",
694
+ "Single;mean;sqrt": "tab:purple",
695
+ "Group;normative": "tab:red",
696
+ }.items()
697
+ ],
698
+ loc="upper left",
699
+ bbox_to_anchor=(1, 1),
700
+ title=f"Bandwidth {attribute}",
701
+ )
702
+
703
+ # set label
704
+ axes.set_ylabel("Depth [m NAP]")
705
+ axes.set_xlabel(f"{attribute}")
706
+
707
+ return axes
708
+
551
709
  def plot_load_settlement(
552
710
  self,
553
711
  pile_tip_level_nap: float,
@@ -581,6 +739,12 @@ class MultiCPTBearingResults:
581
739
  axes:
582
740
  The `Axes` object where the settlement curves were plotted on
583
741
  """
742
+ # Validate required properties are present
743
+ if self._pp.pile_type.settlement_curve is None:
744
+ raise ValueError(
745
+ "No settlement curve is defined for the pile-type. "
746
+ "Please define a settlement curve in the pile-type properties."
747
+ )
584
748
 
585
749
  # Validate axes
586
750
  if (axes is not None) and (not isinstance(axes, Axes)):
@@ -608,8 +772,8 @@ class MultiCPTBearingResults:
608
772
  )
609
773
 
610
774
  return get_load_settlement_plot(
611
- settlement_curve=self._pp.settlement_curve,
612
- d_eq=self._pp.equiv_base_diameter,
775
+ settlement_curve=self._pp.pile_type.settlement_curve,
776
+ d_eq=self._pp.geometry.equiv_diameter_pile_tip,
613
777
  s_b=self.group_results_table.s_b[idx],
614
778
  f_c_k=self.group_results_table.F_c_k[idx],
615
779
  f_nk_k=self.group_results_table.F_nk_k[idx],
@@ -1,24 +0,0 @@
1
- pypilecore/__init__.py,sha256=T2Uuao6fboVhrzKI_Sa7jXbcNAUl_PKk9BFdsozOG98,78
2
- pypilecore/_version.py,sha256=0_HYvCjqXJ8bLPFLe6E2tkYlW15w7EOTtTD9FQ5jQGM,175
3
- pypilecore/api.py,sha256=dXgjfttEUcQHUCMkTX9eYip0dd3bf_ppE6cdx87ouHY,6822
4
- pypilecore/exceptions.py,sha256=-MZOfsxyHLCI0k1-wZFfVsMxc1lya5buuhLks5rxlCo,89
5
- pypilecore/plot_utils.py,sha256=rK5_067-4-x7LzZgt_t6ahcGrZInxNrqHqsy0RzCnq8,954
6
- pypilecore/utils.py,sha256=ib9LgJBIgWukL7zd_Zk1LP27UTMIZTRJ4RBB6ubn97o,1186
7
- pypilecore/input/__init__.py,sha256=tlmThdPtO8e6L6pqxuRQ7EOHRxYwuIcaNNGlZyAnzig,606
8
- pypilecore/input/grouper_properties.py,sha256=qOc-SNYSPdOcZZ9DsRE-sBNVOKHbUD044EWRsWDu_kc,10893
9
- pypilecore/input/multi_cpt.py,sha256=Ua5IN9-m1jgCwa5xFNAYrMcxkVe2L1LIW907CWLJBW0,19577
10
- pypilecore/input/pile_properties.py,sha256=6O7iH-f7_G9PZbBsbzSWT_zUF2RtwYLfF5GRtUFvhHk,8404
11
- pypilecore/input/soil_properties.py,sha256=oqZWeSvhGyIKl4j0ZlGr923qyxkBjYxbVKBckG2rLAw,7687
12
- pypilecore/results/__init__.py,sha256=ggTI2QzILhX_oNx1YMOih6IVCkBFg8I5-Jyn9Sw3_h0,389
13
- pypilecore/results/grouper_result.py,sha256=wQxWSJRrgh7aO5pglrCNTPvCNdERBMDXAlm6YZE3v-s,30927
14
- pypilecore/results/load_settlement.py,sha256=EbfTrSvH_g96KE-x8ZjmO8D0mt5KFaQ_-AR8u4blLsU,9752
15
- pypilecore/results/multi_cpt_results.py,sha256=dzNpP3hu0Sl00gNPHT37DcQqLbfp8IYci46QLSycyqA,25398
16
- pypilecore/results/pile_properties.py,sha256=z1R5UNoYjBem2rS8LMJ_ye2J5ejDoSilU5fCjUrNdUg,28592
17
- pypilecore/results/post_processing.py,sha256=UWXcdff5dhPFDwzKbVIayEIp3HX6pxW8oQR3Z7AHPn0,22262
18
- pypilecore/results/single_cpt_results.py,sha256=irNqsL_cBKUh-QEmWC216KZjkv9MAZkaiLTvDDlEt20,17448
19
- pypilecore/results/soil_properties.py,sha256=Mcwz23PcaIW1xKLabMUSfIeKCTBli7ouuZPfT5dfrb4,20722
20
- py_pilecore-0.4.1.dist-info/LICENSE,sha256=3OCAZXffN0Bettjeya8uF_ZYegyvvCfH1WUt6CrHb_0,1061
21
- py_pilecore-0.4.1.dist-info/METADATA,sha256=oQzHxa-c_UofjtUdg5FCaFWsqvanEgxCxuAkn3M_A3g,5834
22
- py_pilecore-0.4.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
23
- py_pilecore-0.4.1.dist-info/top_level.txt,sha256=7BKIWZuSkbQtJ0ho5P1JvcaEbHzqADCcBuOduZmIaiI,11
24
- py_pilecore-0.4.1.dist-info/RECORD,,
@@ -1,213 +0,0 @@
1
- from __future__ import annotations
2
-
3
-
4
- def create_pile_properties_payload(
5
- pile_type: str,
6
- specification: str,
7
- installation: str,
8
- pile_shape: str,
9
- diameter_base: float | None = None,
10
- diameter_shaft: float | None = None,
11
- width_base_large: float | None = None,
12
- width_base_small: float | None = None,
13
- width_shaft_large: float | None = None,
14
- width_shaft_small: float | None = None,
15
- height_base: float | None = None,
16
- settlement_curve: float | None = None,
17
- adhesion: float | None = None,
18
- alpha_p: float | None = None,
19
- alpha_s_clay: float | None = None,
20
- alpha_s_sand: float | None = None,
21
- beta_p: float | None = None,
22
- pile_tip_factor_s: float | None = None,
23
- elastic_modulus: float | None = None,
24
- is_auger: float | None = None,
25
- is_low_vibrating: float | None = None,
26
- negative_fr_delta_factor: float | None = None,
27
- ) -> dict:
28
- """
29
- Creates a dictionary with the `pile_properties` payload content for the PileCore
30
- endpoints.
31
-
32
- Note
33
- ----
34
- The dictionary should be converted to a jsonifyable message before it can be passed
35
- to a `requests` call directly, for instance with
36
- `nuclei.client.utils.python_types_to_message()`.
37
-
38
- Parameters
39
- ----------
40
- pile_type:
41
- The equaly named entry in the "pile_type_specification" settings.
42
- Accepted values are: ["A","B","C""D","E","F","G"]
43
- specification:
44
- The equaly named entry in the "pile_type_specification" settings.
45
- Accepted values are: ["concrete","steel","micro","wood"]
46
- installation:
47
- The equaly named entry in the "pile_type_specification" settings.
48
- Accepted values are: ["1","2","3","4","5","6","7"]
49
- pile_shape:
50
- The shape of the pile.
51
- Accepted values are: ["round", "rect"]
52
- diameter_base:
53
- Pile base diameter [m].
54
- Only relevant if `shape`="round".
55
- diameter_shaft:
56
- Pile shaft diameter [m].
57
- Only relevant if `shape`="round".
58
- width_base_large:
59
- Largest dimension of the pile base [m].
60
- Only relevant if `shape`="rect".
61
- width_base_small:
62
- Smallest dimension of the pile base [m].
63
- Only relevant if `shape`="rect".
64
- width_shaft_large:
65
- Largest dimension of the pile shaft [m].
66
- Only relevant if `shape`="rect".
67
- width_shaft_small:
68
- Smallest dimension of the pile shaft [m].
69
- Only relevant if `shape`="rect".
70
- height_base:
71
- Height of pile base [m]. If None, a pile with constant dimension is inferred.
72
- Cannot be None if diameter_base and diameter_shaft are unequal.
73
- settlement_curve:
74
- Settlement lines for figures 7.n and 7.o of NEN-9997-1 As defined in table 7.c
75
- of NEN-9997-1. The value is inferred from the pile_type_specifications, but can
76
- be overwritten.
77
- adhesion:
78
- Optional adhesion value [kPa], use it if the pile shaft has undergone a special
79
- treatment. Examples: - adhesion = 50 kN/m2 for synthetic coating - adhesion = 20
80
- kN/m2 for bentonite - adhesion = 10 kN/m2 for bitumen coating See 7.3.2.2(d) of
81
- NEN 9997-1 for examples.
82
- alpha_p:
83
- Alpha p factor used in pile tip resistance calculation. The value is inferred
84
- from the pile_type_specifications, but can be overwritten.
85
- alpha_s_clay:
86
- Alpha s factor for soft layers used in the positive friction calculation. If
87
- None the factor is determined as specified in table 7.d of NEN 9997-1.
88
- alpha_s_sand:
89
- Alpha s factor for coarse layers used in the positive friction calculation. The
90
- value is inferred from the pile_type_specifications, but can be overwritten.
91
- beta_p:
92
- Factor s used in pile tip resistance calculation as per NEN 9997-1 7.6.2.3 (h).
93
- The value is inferred from the pile dimension properties, but can be overwritten.
94
- pile_tip_factor_s:
95
- Factor s used in pile tip resistance calculation as per NEN 9997-1 7.6.2.3 (h).
96
- The value is inferred from the pile dimension properties, but can be overwritten.
97
- elastic_modulus:
98
- Modulus of elasticity of the pile [Mpa]. The value is inferred from the
99
- pile_type_specifications, but can be overwritten.
100
- is_auger:
101
- Determines weather the pile the pile is an auger pile or not. The value is
102
- inferred from the pile_type_specifications, but can be overwritten.
103
- is_low_vibrating:
104
- Determines weather the pile has an installation type with low vibration. The
105
- value is inferred from the pile_type_specifications, but can be overwritten.
106
- negative_fr_delta_factor:
107
- factor * φ = δ. This parameter will be multiplied with phi to get the delta
108
- parameter used in negative friction calculation according to NEN-9997-1 7.3.2.2
109
- (e). Typically values are 1.0 for piles cast in place, and 0.75 for other pile
110
- types. The value is inferred from the pile_type_specifications, but can be
111
- overwritten.
112
-
113
- Returns
114
- -------
115
- pile_properties:
116
- The `pile_properties` payload content of the PileCore-API endpoints.
117
-
118
- Raises
119
- ------
120
- ValueError:
121
- - if `pile_shape`=="round" & `diameter_base` is None
122
- - if `pile_shape`=="rect" & `width_base_large` is None
123
- - if `pile_shape` not in ["rect", "round"]
124
- """
125
- pile_properties: dict = dict(
126
- props=dict(
127
- pile_type_specification=dict(
128
- pile_type=pile_type,
129
- specification=specification,
130
- installation=installation,
131
- )
132
- ),
133
- type=pile_shape,
134
- )
135
-
136
- if pile_shape == "round":
137
- if diameter_base is None:
138
- raise ValueError(
139
- 'A value for `diameter_base` is required for `pile_shape`=="round"'
140
- )
141
-
142
- pile_properties["props"]["diameter_base"] = diameter_base
143
-
144
- if diameter_shaft is not None:
145
- if height_base is None:
146
- raise ValueError(
147
- "A value for `height_base` is required when the base and shaft dimensions are unequal"
148
- )
149
-
150
- pile_properties["props"]["diameter_shaft"] = diameter_shaft
151
-
152
- elif pile_shape == "rect":
153
- if width_base_large is None:
154
- raise ValueError(
155
- 'A value for `width_base_large` is required for `pile_shape`=="rect"'
156
- )
157
- pile_properties["props"]["width_base_large"] = width_base_large
158
-
159
- if width_base_small is not None:
160
- pile_properties["props"]["width_base_small"] = width_base_small
161
-
162
- if (
163
- width_shaft_large is not None or width_shaft_small is not None
164
- ) and height_base is None:
165
- raise ValueError(
166
- "A value for `height_base` is required when the base and shaft dimensions are unequal"
167
- )
168
- if width_shaft_large is not None:
169
- pile_properties["props"]["width_shaft_large"] = width_shaft_large
170
-
171
- if width_shaft_small is not None:
172
- pile_properties["props"]["width_shaft_small"] = width_shaft_small
173
-
174
- else:
175
- raise ValueError('pile_shape should be one of ["round", "rect"]')
176
-
177
- if height_base is not None:
178
- pile_properties["props"]["height_base"] = height_base
179
-
180
- if settlement_curve is not None:
181
- pile_properties["props"]["settlement_curve"] = settlement_curve
182
-
183
- if adhesion is not None:
184
- pile_properties["props"]["adhesion"] = adhesion
185
-
186
- if alpha_p is not None:
187
- pile_properties["props"]["alpha_p"] = alpha_p
188
-
189
- if alpha_s_clay is not None:
190
- pile_properties["props"]["alpha_s_clay"] = alpha_s_clay
191
-
192
- if alpha_s_sand is not None:
193
- pile_properties["props"]["alpha_s_sand"] = alpha_s_sand
194
-
195
- if beta_p is not None:
196
- pile_properties["props"]["beta_p"] = beta_p
197
-
198
- if pile_tip_factor_s is not None:
199
- pile_properties["props"]["pile_tip_factor_s"] = pile_tip_factor_s
200
-
201
- if elastic_modulus is not None:
202
- pile_properties["props"]["elastic_modulus"] = elastic_modulus
203
-
204
- if is_auger is not None:
205
- pile_properties["props"]["is_auger"] = is_auger
206
-
207
- if is_low_vibrating is not None:
208
- pile_properties["props"]["is_low_vibrating"] = is_low_vibrating
209
-
210
- if negative_fr_delta_factor is not None:
211
- pile_properties["props"]["negative_fr_delta_factor"] = negative_fr_delta_factor
212
-
213
- return pile_properties