universal waste handling enabled#18
Conversation
| @@ -1,9 +1,9 @@ | |||
| generator_size,max_storage_kg,max_storage_years,waste_generation_limit_kg,state | |||
There was a problem hiding this comment.
Changed the storage time to use days in line with the state regulations.
| @@ -0,0 +1,5 @@ | |||
| generator_size,max_storage_kg,max_storage_days,waste_generation_limit_kg,state | |||
There was a problem hiding this comment.
Currently this is only used to set the storage time limit for universal waste.
| Okon Recycling,Texas,Dallas,32.779167,-96.808891,FALSE | ||
| Powerhouse Recycling,North Carolina,Salisbury,35.671,-80.4742,FALSE | ||
| FabTech Solar Solutions,Arizona,Gilbert,33.352763,-111.78904,FALSE No newline at end of file | ||
| Recycler Name,State,City,Latitude,Longitude,RCRA permit,Universal Waste Permit |
There was a problem hiding this comment.
Added a new column for UW to distinguish between recycling facilities.
| @@ -0,0 +1,58 @@ | |||
| ,Facility Name,Longitude,Latitude,$/ Ton | |||
There was a problem hiding this comment.
Added UW landfills in a separate input file
There was a problem hiding this comment.
If I understand correctly the list of hazardous landfills is "Landfill_data_SA.csv" and costs are $175/ton and this new file has a longer list of UW landfills with costs of $114/ton. I can't remember what is the source for this new dataset (both list and associated costs) but we will have to document.
| @@ -0,0 +1,9 @@ | |||
| Recycler Name,State,City,Longitude,Latitude,RCRA permit,Universal Waste Permit | |||
There was a problem hiding this comment.
Added UW recyclers in a separate input file
There was a problem hiding this comment.
Same comment as for the UW landfill file, we will need to document source of those.
|
|
||
| self.update_product_storage_hazardous() | ||
| if self.is_hazardous_waste_storage_limit_exceeded(): | ||
| if self.is_hazardous_waste_storage_limit_exceeded() or \ |
There was a problem hiding this comment.
Since UW is considered as a subset of hazardous waste, it shares the tracking variables.
| # if not universal_waste_thresholds: | ||
| # # If no thresholds are provided, default to SMALL generator size | ||
| # self.generator_size = GeneratorSize.SMALL | ||
| past_year_index = len(self.new_products_hard_copy) - self.model.timestep.value |
There was a problem hiding this comment.
Gets the past 1 year's waste depending on the time step selected.
There was a problem hiding this comment.
I am not sure why self.new_products_hard_copy is being used... I think this variable is a list of installed capacity in W at each time step? It's not the amount of waste stored... why not using a variable linked to the waste generated at each time step? I think this method needs to be revised. Were we using the same logic for Hazardous waste? If so it would also need to be changed.
Looking at the update_universal_waste_generator_size method just above this one. I understand the logic and I think it works well. I am not sure why the logic is so different for update_universal_waste_generator_size. Can't we use the same as for regular hazardous waste?
| # based on the TCLP test results. | ||
| self.hazardous = self.model.tclp_test() | ||
| self.tclp_test_result = int(self.hazardous) | ||
| is_tclp_positive = self.model.tclp_test() |
There was a problem hiding this comment.
We do the TCLP first and if it is hazardous, then we check for universal waste.
| if regulator_thresholds[self.generator_size].max_storage_kg is not None: | ||
| self.max_storage_hazardous_kg = regulator_thresholds[self.generator_size].max_storage_kg | ||
|
|
||
| def _find_closest_recycler_name(self, distance_df): |
There was a problem hiding this comment.
Used to get the recycler name and the agent id based on the distance. Currently it is used to update the recycler name in case of universal waste.
|
|
||
| return df_expanded | ||
|
|
||
| def get_number_of_days_in_timestep(timestep: TIMESTEP) -> int: |
There was a problem hiding this comment.
This is used to calculate the storage time limit based on the time step selected. For example using Quarterly time step: 180 days / 90 =2 days = 2 time steps.
There was a problem hiding this comment.
Minor comment: 180 days / 90 days per time step = 2 time steps
|
@purboday, I will work on this review on Tuesday. |
| @@ -996,7 +1009,7 @@ def update_product_storage_hazardous(self): | |||
| """ | |||
| Update the storage of hazardous products based on the purchase choice. | |||
There was a problem hiding this comment.
Minor edit: I think "based on the purchase choice" should be "based on the EoL choice"
| return True | ||
| return False | ||
|
|
||
| def is_universal_waste_storage_limit_exceeded(self): |
There was a problem hiding this comment.
Could we combine both function (universal waste and hazardous waste limit exceeded checks?). For now let's keep as two separate functions for interest of time but we can revisit later.
| """ | ||
| if self.hazardous: | ||
| return self.hazardous_landfill_cost + \ | ||
| self.model.hazardous_waste_management_cost['landfill'] / 1E3 * self.model.dynamic_product_average_wght |
There was a problem hiding this comment.
self.model.hazardous_waste_management_cost['landfill'] is 0 right now. I imagine this is some sort of premium? We know that the total premium (including landfill fee premium and longer distances) should lead to 5-10 times higher total costs. In our notes we found that we needed to change transportation costs to $0.395/t.km instead of $0.095/t.km.
However, if we want to deal with the cost premium differently we could set the self.model.hazardous_waste_management_cost['landfill'] to $300/ton. I think that would be the best way to model the cost premium (i.e. leave transportation costs untouched at $0.095/t.km, use the hazardous and UW landfill fees we have from the csv files and add this cost premium of $300/ton). For UW this cost premium could be $150/ton instead (as we said we can assume a midlle ground value). This cost premium would represent permit costs, aditional skilled labor to handle hazardous waste, etc. for both UW and hazardous waste (with UW representing a lesser burden since permits and so on are easier to deal with).
To make those modifications we could create a new PR once this one is merged as is or just push a new commit before we merge.
| return self.hazardous_landfill_cost + \ | ||
| self.model.hazardous_waste_management_cost['landfill'] / 1E3 * self.model.dynamic_product_average_wght | ||
| elif self.universal_waste: | ||
| return self.universal_waste_landfill_cost |
There was a problem hiding this comment.
Half the premium should be added here: self.universal_waste_landfill_cost + (self.model.hazardous_waste_management_cost['landfill'] / 2) / 1E3 * self.model.dynamic_product_average_wght
| landfill_solar_waste_acceptance_ratio=0.4, | ||
| last_step=31, | ||
| sa_landfill_costs=(False, 0.0037), | ||
| file_name={'Landfill data': "Landfills_data_2023.csv", |
There was a problem hiding this comment.
I can't find the Landfills_data_2023.csv in the TEMP file. Is it because we have it in the gitignore file (becaus eit is proprietary)?
| if not hazardous_recycler_row.empty and hazardous_recycler_row['RCRA permit'].values[0]: | ||
| self.hazardous = True | ||
| # Check if the recycler is a universal waste recycler | ||
| universal_waste_recycler_row = self.model.recycler_data[self.model.recycler_data['Recycler Name'] == self.recycler_name] |
There was a problem hiding this comment.
It looks like it is using the same variable as for hazardous recyclers: self.model.recycler_data. Checking the ABM_CE_PV_Model.py file, the "Universal_Waste_Recyclers_data.csv" file seems to never be used.
jwalzberg
left a comment
There was a problem hiding this comment.
@purboday, this is really really good! I like all the new pieces that have beed added. I have left several comments that I think need to be addressed (or explained) before we can proceed to the merge though. We can meeto quickly to discuss them at any time although the RTN work is probably more important right now.
This PR extends the ABM circular economy model to support universal waste regulations and infrastructure, enabling differentiated waste routing based on regulatory classification (hazardous, universal waste, or regular waste).
Changes
Universal_Waste_Landfills_data.csv- dedicated landfill sitesUniversal_Waste_Recyclers_data.csv- certified recycling facilities