Skip to content

Commit b75e095

Browse files
authored
Merge pull request #159 from WISDEM/release-2.3.3
Release 2.3.3
2 parents 458333f + d91286e commit b75e095

File tree

4 files changed

+124
-52
lines changed

4 files changed

+124
-52
lines changed

landbosse/model/ErectionCost.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -865,9 +865,10 @@ def aggregate_erection_costs(self):
865865
866866
Returns
867867
-------
868-
(pd.DataFrame, pd.DataFrame)
869-
Two dataframes: First, utilizing the same crane for base and topping.
870-
Second, utilizing separate cranes for base and topping
868+
Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]
869+
Two dataframes: First, utilizing the separate cranes for base and topping.
870+
Second, utilizing same crane for base and topping,
871+
Third is crew cost.
871872
"""
872873
join_wind_operation = self.output_dict['join_wind_operation']
873874
overtime_multiplier = self.input_dict['overtime_multiplier']
@@ -925,6 +926,7 @@ def aggregate_erection_costs(self):
925926
crew_cost_grouped = crew_cost.groupby(['Crew type ID', 'Operation']).sum().reset_index()
926927

927928
# merge crane data with grouped crew costs
929+
928930
possible_crane_cost = pd.merge(possible_crane_cost, crew_cost_grouped, on=['Crew type ID', 'Operation'])
929931

930932
# calculate labor costs
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import pandas as pd
2+
3+
# The extended_landbosse_details dataframe includes all the details along side
4+
# all the project list inputs
5+
print("Reading extended details...")
6+
df = pd.read_csv("extended_landbosse_details.csv")
7+
8+
# Extract the crane choice data
9+
print("Selecting erection data...")
10+
erection_df = df.query("`Module` == 'ErectionCost'")[[
11+
"Project ID with serial",
12+
"Variable name",
13+
"Numeric value",
14+
"Non-numeric value",
15+
"Number of turbines",
16+
"Turbine rating MW",
17+
"Hub height m",
18+
"Labor cost multiplier",
19+
"Crane breakdown fraction",
20+
"Breakpoint between base and topping (percent)",
21+
"Total project construction time (months)"
22+
]]
23+
24+
aligned_erection_rows = []
25+
26+
print("Selecting unique projects...")
27+
unique_project_id_with_serial = erection_df['Project ID with serial'].unique()
28+
29+
print("Rearranging crane detail data from rows into columns...")
30+
for project_id_with_serial in unique_project_id_with_serial:
31+
print(f"\t{project_id_with_serial}")
32+
33+
# Crane data output
34+
crane_data_df = erection_df.query(
35+
"`Project ID with serial` == @project_id_with_serial and `Variable name` == 'crane_data_output: crane_boom_operation_concat - variable - value'"
36+
)
37+
top_wind_multiplier_row = crane_data_df[crane_data_df["Non-numeric value"].str.contains("Top - Wind multiplier")]
38+
base_wind_multiplier_row = crane_data_df[crane_data_df["Non-numeric value"].str.contains("Base - Wind multiplier")]
39+
offload_wind_multiplier_row = crane_data_df[crane_data_df["Non-numeric value"].str.contains("Offload - Wind multiplier")]
40+
top_wind_multiplier = top_wind_multiplier_row["Numeric value"].values[0]
41+
offload_wind_multiplier = offload_wind_multiplier_row["Numeric value"].values[0]
42+
if len(base_wind_multiplier_row) > 0:
43+
base_wind_multiplier = base_wind_multiplier_row["Numeric value"].values[0]
44+
else:
45+
base_wind_multiplier = None
46+
47+
# Re-using crane_data_df from above, operation time for all turbines
48+
top_operation_time_hours_row = crane_data_df[
49+
crane_data_df["Non-numeric value"].str.contains("Top - Operation time all turbines hrs")]
50+
offload_operation_time_hours_row = crane_data_df[
51+
crane_data_df["Non-numeric value"].str.contains("Offload - Operation time all turbines hrs")]
52+
base_operation_time_hours_row = crane_data_df[
53+
crane_data_df["Non-numeric value"].str.contains("Base - Operation time all turbines hrs")]
54+
top_operation_time_hours = top_operation_time_hours_row["Numeric value"].values[0]
55+
offload_operation_time_hours = offload_operation_time_hours_row["Numeric value"].values[0]
56+
if len(base_operation_time_hours_row) > 0:
57+
base_operation_time_hours = base_operation_time_hours_row["Numeric value"].values[0]
58+
else:
59+
base_operation_time_hours = None
60+
61+
# Crane cost details
62+
crane_cost_df = erection_df.query(
63+
"`Project ID with serial` == @project_id_with_serial and `Variable name` == 'crane_cost_details: Operation ID - Type of cost - Cost'"
64+
)
65+
top_total_cost_row = crane_cost_df[crane_cost_df["Non-numeric value"].str.contains("Top - Total cost USD")]
66+
base_total_cost_row = crane_cost_df[crane_cost_df["Non-numeric value"].str.contains("Base - Total cost USD")]
67+
offload_total_cost_row = crane_cost_df[crane_cost_df["Non-numeric value"].str.contains("Offload - Total cost USD")]
68+
top_total_cost = top_total_cost_row["Numeric value"].values[0]
69+
offload_total_cost = offload_total_cost_row["Numeric value"].values[0]
70+
if len(base_total_cost_row) > 0:
71+
base_total_cost = base_total_cost_row["Numeric value"].values[0]
72+
else:
73+
base_total_cost = None
74+
75+
# Crane choice
76+
crane_choice_rows_df = erection_df.query(
77+
"`Project ID with serial` == @project_id_with_serial and `Variable name` == 'crane_choice: Crew name - Boom system - Operation'"
78+
)
79+
top_row = crane_choice_rows_df[crane_choice_rows_df["Non-numeric value"].str.contains("Top")]
80+
base_row = crane_choice_rows_df[crane_choice_rows_df["Non-numeric value"].str.contains("Base")]
81+
offload_row = crane_choice_rows_df[crane_choice_rows_df["Non-numeric value"].str.contains("Offload")]
82+
offload = " ".join(offload_row["Non-numeric value"].values[0].split(" - ")[:-1])
83+
top = " ".join(top_row["Non-numeric value"].values[0].split(" - ")[:-1])
84+
if len(base_row) > 0:
85+
base = " ".join(base_row["Non-numeric value"].values[0].split(" - ")[:-1])
86+
else:
87+
base = None
88+
89+
aligned_erection_row = {
90+
"Project ID with serial": project_id_with_serial,
91+
"Number of turbines": top_row["Number of turbines"].values[0],
92+
"Breakpoint between base and topping (percent)": \
93+
top_row["Breakpoint between base and topping (percent)"].values[0],
94+
"Turbine rating MW": top_row["Turbine rating MW"].values[0],
95+
"Crane breakdown fraction": top_row["Crane breakdown fraction"].values[0],
96+
"Labor cost multiplier": top_row["Labor cost multiplier"].values[0],
97+
"Hub height m": top_row["Hub height m"].values[0],
98+
"Base crane choice": base,
99+
"Offload crane choice": offload,
100+
"Top crane choice": top,
101+
"Base total cost":
102+
round(float(base_total_cost), 0) if base_total_cost is not None else None,
103+
"Offload total cost": round(float(offload_total_cost), 0),
104+
"Top total cost": round(float(top_total_cost), 0),
105+
"Base wind multiplier":
106+
round(float(base_wind_multiplier), 2) if base_wind_multiplier is not None else None,
107+
"Offload wind multiplier": round(float(offload_wind_multiplier), 2),
108+
"Top wind multiplier": round(float(top_wind_multiplier), 2),
109+
"Base operation time all turbines (hours)":
110+
round(float(base_operation_time_hours), 0) if base_operation_time_hours is not None else None,
111+
"Offload operation time all turbines (hours)": round(float(offload_operation_time_hours), 0),
112+
"Top operation time all turbines (hours)": round(float(top_operation_time_hours), 0)
113+
}
114+
115+
aligned_erection_rows.append(aligned_erection_row)
116+
117+
print("Writing crane choices...")
118+
aligned_crane_choice_df = pd.DataFrame(aligned_erection_rows)
119+
aligned_crane_choice_df.to_csv("crane_details.csv", index=False)

post_processing_scripts/sql_queries/everything_against_baseline.sql

Lines changed: 0 additions & 47 deletions
This file was deleted.

setup.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@
2828
'scipy',
2929
'xlsxwriter',
3030
'xlrd',
31-
'psycopg2-binary',
32-
'sqlalchemy',
3331
'pytest'
3432
],
3533
command_options={

0 commit comments

Comments
 (0)