I am using PVLib modeling to estimate soiling for my project. I am checking both HSU and Kimber models to compare and identify the best result. The problem is, I would expect outputs to be somewhat similar, but there are huge discrepancies between the two. This is making me think I must have made a mistake in implementation. Code is copied below. Input data is SolarAnywhere export including PM2.5 and PM10 data. import pathlib from matplotlib import pyplot as plt from pvlib import soiling from pvlib import snow import pvlib import pandas as pd import statistics csv_data = pd.read_csv('../Weather Data/wasco_solar.csv',parse_dates=['ObservationTime(LST)']) csv_data.set_index('ObservationTime(LST)',inplace=True) # User Note: before using data, make sure you # (a) are using SolarAnywhere data, # (b) have removed the first line of metadata, # (c) have converted all years to the same year for data in chronological order, and # (d) save as CSV UTF-8 # Calculate Soiling using Humboldt State University method ## Extract data and establish variables rain_mm = csv_data['Liquid Precipitation (kg/m2)'] ### Note: 1 kg/m2 of rain = 1 mm of rain cleaning_threshold_hsu = 0.5 ##TODO: Check this value panel_tilt = 0 ### Note: taking most conservative assumption with flat modules pm_10 = csv_data['Particulate Matter 10 (µg/m3)']/1000000 pm_2_5 = csv_data['Particulate Matter 2.5 (µg/m3)']/1000000 depo_veloc = {'2_5': 0.0009, '10': 0.004} rain_accum_period = pd.Timedelta(1,"h") ### Note: choosing to use default values for depo_veloc and rain_accum_period ## Calculate Soiling ratios soiling_ratio_hsu = soiling.hsu(rain_mm, cleaning_threshold_hsu, panel_tilt, pm_2_5, pm_10, depo_veloc=depo_veloc, rain_accum_period = rain_accum_period) ## Calculate average values by month monthly_soiling_ratio_hsu = soiling_ratio_hsu.resample('ME').mean() # Calculate soiling using Kimber model ## Define variables cleaning_threshold_kimber = 6 #TODO: Check this value soiling_loss_rate = 0.0019 #TODO: Check this value measured_soiling_loss_rate = { "Central Valley": { "Rural": 0.0011, "Suburban": 0.0019, "Urban/Highway/Airport": 0.0020, }, "Northern CA": { "Rural": 0.0011, "Suburban": 0.0010, "Urban/Highway/Airport": 0.0016, }, "Southern CA": { "Rural": 0, "Suburban": 0.0016, "Urban/Highway/Airport": 0.0019, }, "Desert": { "Rural": 0.0030, "Suburban": 0.0030, "Urban/Highway/Airport": 0.0030, }, } grace_period = 14 #TODO: Check this value max_soiling = 0.3 #TODO: Check this value manual_wash_dates = [] initial_soiling = 0 rain_accum_period = 24 ## Calculate soiling soiling_loss_kimber = soiling.kimber(rain_mm, cleaning_threshold = cleaning_threshold_kimber, soiling_loss_rate = soiling_loss_rate) ##Condense to monthly soiling values, % monthly_soiling_loss_kimber = soiling_loss_kimber.resample('ME').mean() df = monthly_soiling_loss_kimber.to_frame() df['soiling'] = df['soiling']*100 # Combine results for HSU and Kimber into single dataframe results_df = df.rename(columns={'soiling':'Kimber Model %'}) results_df['HSU Model %'] = (1-monthly_soiling_ratio_hsu)*100 print(results_df) Continue reading...