From 6b169b5183e0d25f1a08f6b4b71b4d0078789c7c Mon Sep 17 00:00:00 2001 From: Garrett Barter Date: Tue, 1 Feb 2022 17:16:56 -0700 Subject: [PATCH 1/3] fixing some of the deprecated syntax in the newest versions of pandas --- .../landbosse_omdao/WeatherWindowCSVReader.py | 2 +- landbosse/model/CollectionCost.py | 9 +++++---- landbosse/model/ErectionCost.py | 19 ++++++++++--------- landbosse/model/FoundationCost.py | 6 ++---- landbosse/model/Manager.py | 17 +++++++++-------- landbosse/model/SitePreparationCost.py | 11 ++++------- 6 files changed, 31 insertions(+), 33 deletions(-) diff --git a/landbosse/landbosse_omdao/WeatherWindowCSVReader.py b/landbosse/landbosse_omdao/WeatherWindowCSVReader.py index 90104262..bc5c93f7 100644 --- a/landbosse/landbosse_omdao/WeatherWindowCSVReader.py +++ b/landbosse/landbosse_omdao/WeatherWindowCSVReader.py @@ -114,7 +114,7 @@ def read_weather_window(weather_data, local_timezone="America/Denver"): weather_data.drop(columns=["Date", "Date UTC"]) # create time window for normal (8am to 6pm) versus long (24 hour) time window for operation - weather_data["Time window"] = weather_data["Hour"].between(8, 18, inclusive=True) + weather_data["Time window"] = weather_data["Hour"].between(8, 18, inclusive='both') boolean_dictionary = {True: "normal", False: "long"} weather_data["Time window"] = weather_data["Time window"].map(boolean_dictionary) diff --git a/landbosse/model/CollectionCost.py b/landbosse/model/CollectionCost.py index 90f237b6..6b087104 100644 --- a/landbosse/model/CollectionCost.py +++ b/landbosse/model/CollectionCost.py @@ -844,9 +844,10 @@ def calculate_costs(self, calculate_costs_input_dict, calculate_costs_output_dic # Combine all calculated cost items into the 'collection_cost' dataframe: collection_cost = pd.DataFrame([],columns = ['Type of cost', 'Cost USD', 'Phase of construction']) - collection_cost = collection_cost.append(trenching_equipment_rental_cost_df) - collection_cost = collection_cost.append(trenching_labor_cost_df) - collection_cost = collection_cost.append(cable_cost_usd_per_LF_df) + collection_cost = pd.concat( (collection_cost, + trenching_equipment_rental_cost_df, + trenching_labor_cost_df, + cable_cost_usd_per_LF_df) ) # Calculate Mobilization Cost and add to collection_cost dataframe. # For utility scale plants, mobilization is assumed to be 5% of the sum of labor, equipment, and material costs. @@ -864,7 +865,7 @@ def calculate_costs(self, calculate_costs_input_dict, calculate_costs_output_dic mobilization_cost = pd.DataFrame([['Mobilization', calculate_costs_output_dict['mob_cost'], 'Collection']], columns=['Type of cost', 'Cost USD', 'Phase of construction']) - collection_cost = collection_cost.append(mobilization_cost) + collection_cost = pd.concat((collection_cost, mobilization_cost)) calculate_costs_output_dict['total_collection_cost'] = collection_cost diff --git a/landbosse/model/ErectionCost.py b/landbosse/model/ErectionCost.py index d2059a32..83bdd1f1 100644 --- a/landbosse/model/ErectionCost.py +++ b/landbosse/model/ErectionCost.py @@ -15,7 +15,7 @@ class Point(object): def __init__(self, x, y): - if type(x) == type(pd.Series()): + if type(x) == type(pd.Series(dtype=np.float_)): self.x = float(x.values[0]) self.y = float(y.values[0]) elif type(x) == type(np.array([])): @@ -692,7 +692,7 @@ def calculate_crane_lift_polygons(self, crane_grouped): 'Max wind speed m per s', 'Setup time hr', 'Breakdown time hr', 'Hoist speed m per min', 'Speed of travel km per hr', 'Crew type ID', 'Crane poly']) - crane_poly = crane_poly.append(df, sort=True) + crane_poly = pd.concat((crane_poly, df), sort=True) return crane_poly def calculate_component_lift_max_wind_speed(self, *, component_group, crane_poly, component_max_speed, operation): @@ -762,7 +762,7 @@ def calculate_component_lift_max_wind_speed(self, *, component_group, crane_poly # Transform the "Lift boolean" indexes in the series to a list of booleans # that signify if the crane can lift a component. - bool_list = list() + bool_list = [] for component in component_group['Component']: if crane['Lift boolean {component}'.format(component=component)] is False: crane_bool = False @@ -787,7 +787,7 @@ def calculate_component_lift_max_wind_speed(self, *, component_group, crane_poly component_group_new['Boom system'] = crane['Boom system'] component_group_new['crane_bool'] = bool_list - component_max_speed = component_max_speed.append(component_group_new, sort=True) + component_max_speed = pd.concat((component_max_speed, component_group_new), sort=True) crane_poly_new = crane_poly.copy() crane_poly_new['Crane bool {}'.format(operation)] = min(bool_list) @@ -1033,14 +1033,15 @@ def find_minimum_cost_cranes(self): # find the crane that corresponds to the minimum cost for each operation crane = separate_basetop[separate_basetop['Total cost USD'] == min_val] cost = crane.groupby('Operation').min() - total_separate_cost = total_separate_cost.append(cost, sort=True) + total_separate_cost = pd.concat((total_separate_cost, cost), sort=True) # reset index for separate crane costs total_separate_cost = total_separate_cost.reset_index() # duplicate offload records because assuming two offload cranes are on site - total_separate_cost = total_separate_cost.append( - total_separate_cost.loc[total_separate_cost['Operation'] == 'Offload'], sort=True) + total_separate_cost = pd.concat((total_separate_cost, + total_separate_cost.loc[total_separate_cost['Operation'] == 'Offload']), + sort=True) # sum costs for separate cranes to get total for all cranes cost_chosen_separate = total_separate_cost['Total cost USD'].sum() @@ -1149,8 +1150,8 @@ def calculate_costs(self): # append data for offloading if len(offload_specs) != 0: - crane_specs_withoffload = crane_specs.append(offload_specs, sort=True) - operation_time_withoffload = operation_time.append(offload_time, sort=True) + crane_specs_withoffload = pd.concat((crane_specs, offload_specs), sort=True) + operation_time_withoffload = pd.concat((operation_time, offload_time), sort=True) else: raise Exception('ErectionCost calculate_costs(): offload_specs empty') diff --git a/landbosse/model/FoundationCost.py b/landbosse/model/FoundationCost.py index 59ec8086..3ca0bcb6 100644 --- a/landbosse/model/FoundationCost.py +++ b/landbosse/model/FoundationCost.py @@ -660,9 +660,7 @@ def calculate_costs(self, calculate_costs_input_dict, calculate_costs_output_dic columns=['Type of cost', 'Cost USD', 'Phase of construction']) # Append all cost items to foundation_cost - foundation_cost = foundation_cost.append(equipment_costs) - foundation_cost = foundation_cost.append(labor_costs) - foundation_cost = foundation_cost.append(material_costs) + foundation_cost = pd.concat( (foundation_cost,equipment_costs,labor_costs,material_costs) ) # Calculate mobilization cost as percentage of total foundation cost and add to foundation_cost # Assumed 5% of total foundation cost and add to foundation_cost for utility scale plant @@ -682,7 +680,7 @@ def calculate_costs(self, calculate_costs_input_dict, calculate_costs_output_dic mob_cost = pd.DataFrame([['Mobilization', mobilization_cost, 'Foundation']], columns=['Type of cost', 'Cost USD', 'Phase of construction']) - foundation_cost = foundation_cost.append(mob_cost) + foundation_cost = pd.concat((foundation_cost, mob_cost)) # todo: we add a separate tab in the output file for costs (all costs will be the same format but it's a different format than other data) # columns in cost tab would include project_id, module, operation_id, type_of_cost, total_or_per_turbine, cost_usd diff --git a/landbosse/model/Manager.py b/landbosse/model/Manager.py index ab41af45..6d62e4c8 100644 --- a/landbosse/model/Manager.py +++ b/landbosse/model/Manager.py @@ -10,6 +10,7 @@ from .ErectionCost import ErectionCost from .DevelopmentCost import DevelopmentCost +import pandas as pd class Manager: """ @@ -91,14 +92,14 @@ def execute_landbosse(self, project_name): road_cost.loc[index, 'Cost USD'] = other['Cost USD'] - amount_shorter_than_input_construction_time * 55500 self.output_dict['total_road_cost'] = road_cost - total_costs = self.output_dict['total_collection_cost'] - total_costs = total_costs.append(self.output_dict['total_road_cost'], sort=False) - total_costs = total_costs.append(self.output_dict['total_transdist_cost'], sort=False) - total_costs = total_costs.append(self.output_dict['total_substation_cost'], sort=False) - total_costs = total_costs.append(self.output_dict['total_foundation_cost'], sort=False) - total_costs = total_costs.append(self.output_dict['total_erection_cost'], sort=False) - total_costs = total_costs.append(self.output_dict['total_development_cost'], sort=False) - + total_costs = pd.concat( (self.output_dict['total_collection_cost'], + self.output_dict['total_road_cost'], + self.output_dict['total_transdist_cost'], + self.output_dict['total_substation_cost'], + self.output_dict['total_foundation_cost'], + self.output_dict['total_erection_cost'], + self.output_dict['total_development_cost'], + ) ) self.input_dict['project_value_usd'] = total_costs.sum(numeric_only=True)[0] self.input_dict['foundation_cost_usd'] = self.output_dict['total_foundation_cost'].sum(numeric_only=True)[0] diff --git a/landbosse/model/SitePreparationCost.py b/landbosse/model/SitePreparationCost.py index 634953d5..6f9536ef 100644 --- a/landbosse/model/SitePreparationCost.py +++ b/landbosse/model/SitePreparationCost.py @@ -360,7 +360,7 @@ def estimate_construction_time(self, estimate_construction_time_input, estimate_ for unit in list_units: unit_quantity = pd.DataFrame([[unit, material_quantity_dict[unit]]], columns=['Units', 'Quantity of material']) - material_needs = material_needs.append(unit_quantity) + material_needs = pd.concat((material_needs, unit_quantity)) estimate_construction_time_output['material_needs'] = material_needs @@ -655,10 +655,7 @@ def calculate_costs(self, calculate_cost_input_dict, calculate_cost_output_dict) additional_costs = pd.DataFrame([['Other', cost_adder, 'Roads']], columns=['Type of cost', 'Cost USD', 'Phase of construction']) - road_cost = road_cost.append(material_costs) - road_cost = road_cost.append(equipment_costs) - road_cost = road_cost.append(labor_costs) - road_cost = road_cost.append(additional_costs) + road_cost = pd.concat((road_cost,material_costs,equipment_costs,labor_costs,additional_costs)) # set mobilization cost equal to 5% of total road cost for utility scale model and function of # of turbine size for distributed wind: @@ -680,7 +677,7 @@ def calculate_costs(self, calculate_cost_input_dict, calculate_cost_output_dict) columns=['Type of cost', 'Cost USD', 'Phase of construction']) - road_cost = road_cost.append(mobilization_costs) + road_cost = pd.concat((road_cost, mobilization_costs)) total_road_cost = road_cost calculate_cost_output_dict['total_road_cost'] = total_road_cost calculate_cost_output_dict['siteprep_construction_months'] = siteprep_construction_months @@ -880,4 +877,4 @@ def run_module(self): except Exception as error: traceback.print_exc() print(f"Fail {self.project_name} SitePreparationCost") - return 1, error # module did not run successfully \ No newline at end of file + return 1, error # module did not run successfully From 413cad7d9e4cfd148369871bb2d12ccc85360587 Mon Sep 17 00:00:00 2001 From: Garrett Barter Date: Tue, 1 Feb 2022 17:30:19 -0700 Subject: [PATCH 2/3] including python 3.9 in tests --- .github/workflows/CI_LandBOSSE.yml | 6 +++--- landbosse/excelio/WeatherWindowCSVReader.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI_LandBOSSE.yml b/.github/workflows/CI_LandBOSSE.yml index c6b9bbbf..cd60c213 100644 --- a/.github/workflows/CI_LandBOSSE.yml +++ b/.github/workflows/CI_LandBOSSE.yml @@ -12,7 +12,7 @@ jobs: fail-fast: False matrix: os: ["ubuntu-latest", "windows-latest"] - python-version: [3.6, 3.7, 3.8] + python-version: [3.6, 3.7, 3.8, 3.9] steps: - uses: actions/checkout@v2 @@ -51,7 +51,7 @@ jobs: fail-fast: False matrix: os: ["ubuntu-latest", "windows-latest"] - python-version: [3.8] + python-version: [3.7, 3.8, 3.9] steps: - uses: actions/checkout@v2 @@ -60,7 +60,7 @@ jobs: with: miniconda-version: "latest" auto-update-conda: true - python-version: 3.8 + python-version: ${{ matrix.python-version }} environment-file: environment.yml # Install diff --git a/landbosse/excelio/WeatherWindowCSVReader.py b/landbosse/excelio/WeatherWindowCSVReader.py index fd25c761..629b5110 100644 --- a/landbosse/excelio/WeatherWindowCSVReader.py +++ b/landbosse/excelio/WeatherWindowCSVReader.py @@ -114,7 +114,7 @@ def read_weather_window(weather_data, local_timezone='America/Denver'): weather_data.drop(columns=['Date', 'Date UTC']) # create time window for normal (8am to 6pm) versus long (24 hour) time window for operation - weather_data['Time window'] = weather_data['Hour'].between(8, 18, inclusive=True) + weather_data['Time window'] = weather_data['Hour'].between(8, 18, inclusive='both') boolean_dictionary = {True: 'normal', False: 'long'} weather_data['Time window'] = weather_data['Time window'].map(boolean_dictionary) From c8307bb1d14ac2e9ebbd226a0a21bfc79473ddf2 Mon Sep 17 00:00:00 2001 From: Garrett Barter Date: Tue, 1 Feb 2022 21:07:22 -0700 Subject: [PATCH 3/3] seem to have fixed the issue although I do not know why the changes are necessary --- landbosse/model/Manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/landbosse/model/Manager.py b/landbosse/model/Manager.py index 6d62e4c8..0e29678c 100644 --- a/landbosse/model/Manager.py +++ b/landbosse/model/Manager.py @@ -100,8 +100,8 @@ def execute_landbosse(self, project_name): self.output_dict['total_erection_cost'], self.output_dict['total_development_cost'], ) ) - self.input_dict['project_value_usd'] = total_costs.sum(numeric_only=True)[0] - self.input_dict['foundation_cost_usd'] = self.output_dict['total_foundation_cost'].sum(numeric_only=True)[0] + self.input_dict['project_value_usd'] = float(total_costs['Cost USD'].sum()) + self.input_dict['foundation_cost_usd'] = self.output_dict['total_foundation_cost']['Cost USD'].sum() management_cost = ManagementCost(input_dict=self.input_dict, output_dict=self.output_dict, project_name=project_name) management_cost.run_module()