-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Snow coverage model from SAM #764
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
CameronTStark
merged 163 commits into
pvlib:master
from
JPalakapillyKWH:snow_coverage_model
Mar 28, 2020
Merged
Changes from 8 commits
Commits
Show all changes
163 commits
Select commit
Hold shift + click to select a range
bea249f
added snow_model code. Needs formatting
JPalakapillyKWH a931096
starting numpy-ification
JPalakapillyKWH ca285d7
minor changes
JPalakapillyKWH f7acc74
added tests and made model faster
JPalakapillyKWH 9a7964b
finished tests.
JPalakapillyKWH 67cff8b
fixed lint errors.
JPalakapillyKWH 97565bf
fixed minor lint error
JPalakapillyKWH 78ac66a
fixed bug where model stopped prematurely
JPalakapillyKWH a2ccd92
docstring changes mostly. Changed the location of division by 10 for …
JPalakapillyKWH 4d65294
fixed tests to account for prev change
JPalakapillyKWH bcd8c37
fixed docstring for snow slide amount
JPalakapillyKWH 8edfffe
docstring edits, move some functions to private
cwhanse cf71e2a
Merge branch 'master' of https://github.com/pvlib/pvlib-python into s…
cwhanse 43d21cd
rewrite, reduce helpers, remove while loop
cwhanse 1b5dcb1
rename functions, review responses, add subhourly test
cwhanse 7b7edfe
fixes
cwhanse c5ac03b
temperature -> temp_air, test correction, fix default for m
cwhanse b9f1988
put m=-80 back
cwhanse 04a0b15
edits for threshold, use first data point
cwhanse 109fa7d
add initial snow, better logic for coverage events
cwhanse 436c8d1
lint, text fix
cwhanse 92d693c
workaround for py35/pandas 0.23.4
cwhanse b5a9fb9
move line
cwhanse 7116cd2
improve comments
cwhanse 54f7a5e
improvements from review
cwhanse 63c2f58
improve docstring
cwhanse c766e9a
reorder comparison, add missing inplace
cwhanse 4c25f2a
correct test, cut/paste error
cwhanse 6c6c663
vectorize
cwhanse 7689ef6
correct .clip
cwhanse 47c26da
function and file renaming
cwhanse ff2ca66
Merge branch 'master' of https://github.com/pvlib/pvlib-python into s…
cwhanse 3a04ccd
docstring corrections, replace hack with pandas offset
cwhanse 10cd8f2
refactor bifacial merge, improve merge tests (#747)
alexandermorgan 733e489
Implement IEC 61853 IAM calculations (#752)
adriesse 2f6376e
remove python 2 lines (#757)
alexandermorgan 16bdde9
fix rounding issue in linke turbidity lookup function (#755)
alexandermorgan c4091cc
edit DIRINDEX docstring (#760)
cwhanse 1ac666d
added snow_model code. Needs formatting
JPalakapillyKWH 0b6236a
starting numpy-ification
JPalakapillyKWH ad48714
minor changes
JPalakapillyKWH edb1b1e
added tests and made model faster
JPalakapillyKWH 8f59d8b
finished tests.
JPalakapillyKWH 0352814
fixed lint errors.
JPalakapillyKWH d970d20
fixed minor lint error
JPalakapillyKWH 6fa5c95
fixed bug where model stopped prematurely
JPalakapillyKWH 81f2c85
docstring changes mostly. Changed the location of division by 10 for …
JPalakapillyKWH 2e13c1b
fixed tests to account for prev change
JPalakapillyKWH 62f5df6
fixed docstring for snow slide amount
JPalakapillyKWH 2858799
Add recombination current params to all bishop88 functions (#763)
adriesse 539402c
Raise if no parameters provided to retrieve_sam() (#770) (#775)
Peque 04083bf
refactor cec test data into fixtures (#774)
Peque 3052442
remove functions marked for 0.7 removal (#772)
wholmgren bf79511
move celltemp functions to celltemp.py, expose celltemp.pvsyst in Mod…
cwhanse f5f776a
Update module and inverter files (#761) (#767)
Peque 81f78d5
refactor repeated code in ModelChain singlediode and LocalizedPVSyste…
Peque f1b0c5a
Create ivtools (#718)
cwhanse b75909c
clean up whatsnew after #718 merge (#778)
cwhanse 724ac68
ModelChain 0.7 deprecations, remove times kwarg (#773)
wholmgren cabc6c8
add timeout to get_psm3 (#741)
cwhanse fc179a4
Update forecast.py comment typo
aperetti 468e42d
Get rid of `re` deprecation warnings (#787)
Peque ee7ef7a
Fix documentation references to inverter/module data (#791)
veronicaguo 53d4654
Create iam.py, consistent naming for IAM functions (#783)
cwhanse 743a4fb
add bare environment CI tests (#790)
wholmgren 9d7683e
handle warnings from temperature model tests (#796)
cwhanse bf29887
replace Pandas item() implementation with numpy's using .values (#797)
CameronTStark 6bfc18b
mark xfail of test_get_psm3 (#803)
CameronTStark 029cf20
coefficient estimation method following DeSoto(2006) (#784)
tylunel dac54de
change tools._scalar_out/_array_out arg name to avoid collision with …
CameronTStark 1b6e62d
Implement IEC 61853 IAM calculations for diffuse irradiance (#793)
adriesse e6c33dd
add macOS 10.14 Mojave to Azure Pipelines CI (#812)
cwhanse 2305603
update readme docs to stable
wholmgren c0fda4f
Add note clearksky Ineichen term b (#814)
cedricleroy 4250d71
Drop DataFrame as option for `module` input to pvsystem.sapm (#811)
cwhanse 4f6584a
Don't expose model parameter dictionaries to users (#805)
veronicaguo f6b0e41
* Fix for issue #782 (#816)
tylunel bcbd29f
Add shield organization table with download shields (#820)
CameronTStark bef5866
fix reading MIDC files with mismatching header/data columns (#822)
alorenzo175 8792b60
Change units on SAPM effective irradiance from suns to W/m2 (#815)
cwhanse 69e340f
fix handful of documentation warnings (#819)
wholmgren 6a48f94
update contributing documentation, pr template (#818)
wholmgren 54d535b
import bifacial module in __init__.py (#826)
wholmgren b5bdcce
Put SAM product renaming code in a separate function, simplify, add w…
adriesse ad12c56
Create scaling.py and implement WVM model (#807)
jranalli 35daed1
Fix typo in TMY total sky cover uncertainty column name (#831)
hamiltonkibbe 673490c
Location object creation from epw metadata (#821)
tylunel c52bc77
Implement IEC 61853 module temperature model (#834)
adriesse dd72dcd
update to numpy-1.12.0 (#830)
mikofski 06de0aa
Docstring formatting (#833)
kevinsa5 2be01f0
* Formatting of ModelChain.diode_params in pandas.DataFrame (#832)
tylunel 3b6b7db
update whatsnew.rst, add contributors, v0.7.0 release date, address #…
CameronTStark 7b9f922
change overlooked irradiance.total_irrad references to irradiance.get…
kandersolar 92adcfc
refactor get_psm3 code into parse_psm3, read_psm3 (#842)
kandersolar cb131d6
Fix error in the irradiance unit checker. (#844)
dzimmanck 02a604d
Add gallery of examples using sphinx-gallery (#846)
kandersolar ae18625
add pvgis to iotools (#845)
mikofski 0b0f097
fix table line lengtsh, remove #noqa, use grid (#852)
mikofski dd504f6
Improves sapm deprecation warning checker (#854)
cwhanse c20d443
improve solpos tz requirements documentation (#853)
wholmgren 618fe26
DOC: remove superscript formatting for citation callouts (#855)
kandersolar b5ab200
reorganize tests into subfolders and use pathlib for conftest DATA_DI…
mikofski e981839
add Boyle/Coello (Humboldt State Univ) soiling model (#850)
nappaillav e124175
update whats new for #844 and other contributors (#851)
wholmgren 8da7354
add numfocus affiliation to sphinx docs (#862)
mikofski 18c475f
fix tmy3 leapyear in February handling, coerce_year raises exception …
mikofski 13500d2
Update for PySAM 2.0 (#874)
cwhanse 08f5f19
docstring edits, move some functions to private
cwhanse 1200266
make test_psm3.py robust to API overuse errors (#873)
CameronTStark 578a70f
Fix backwards path sep (#876)
mikofski 1c12459
forecast compat with pandas 1.0, fix bug in Location tz handling (#879)
wholmgren 6c2372f
remove needs_pandas decorator (#885)
CameronTStark 551331a
rewrite, reduce helpers, remove while loop
cwhanse 0c9f848
Add calcparams_desoto+singlediode example to gallery (#872)
kandersolar 8343212
fix documentation home page title (#890)
CameronTStark 3661d86
rename functions, review responses, add subhourly test
cwhanse f3a2eec
fixes
cwhanse e80763c
temperature -> temp_air, test correction, fix default for m
cwhanse b92efee
put m=-80 back
cwhanse da22506
add Kimber soiling model (#860)
mikofski 238acc6
move contents of 0.6.4 whatsnew into 0.7.0 whatsnew (#899)
wholmgren 7ee7cc6
compatibility for cftime==1.1 (#900)
wholmgren 76309cc
Use pytest remotedata (#896)
CameronTStark ea286cb
Include Python3.8 into Azure Pipelines (#904)
CameronTStark 4104062
eliminate some of the test suite warnings (#906)
wholmgren 1441d51
Add Contributing section about gallery examples (#905)
kandersolar 23e9ef7
Expose temperature.faiman in PVSystem and ModelChain (#897)
kandersolar 02926a5
Rename test_modelchain system fixture (#915)
veronicaguo f3d286c
BLD: build docs on Azure Pipelines (#909)
CameronTStark f70377b
fix read_tmy3 with year coerced not monotonic, breaks soiling (#910)
mikofski 5788223
add read pvgis tmy (#907)
mikofski a341fd2
TST: make iotools tests robust to API downtime (#919)
CameronTStark 891158a
Link to code of conduct (#922)
mikofski 67f6537
edits for threshold, use first data point
cwhanse 00bda7a
Fix most sphinx warnings (#912)
kandersolar 7524ba8
Fancy "view on github" links in documentation (#913)
kandersolar 52ff419
add initial snow, better logic for coverage events
cwhanse 649a6a5
lint, text fix
cwhanse d183fae
TST: Use templates in Azure Pipelines config file (#926)
wholmgren 06a3ae7
workaround for py35/pandas 0.23.4
cwhanse 380a576
move line
cwhanse 29e1772
improve comments
cwhanse 1c2ad4f
improvements from review
cwhanse 87288cf
improve docstring
cwhanse 9eb70a9
reorder comparison, add missing inplace
cwhanse bf42c8f
correct test, cut/paste error
cwhanse 82e94a4
vectorize
cwhanse b6919b2
correct .clip
cwhanse 14e1390
function and file renaming
cwhanse 21e1086
docstring corrections, replace hack with pandas offset
cwhanse 04ded05
Merge branch 'snow_coverage_model' of https://github.com/JPalakapilly…
cwhanse 4aaa6f1
update api.rst, whatsnew
cwhanse fc68b91
Merge branch 'master' of https://github.com/pvlib/pvlib-python into s…
cwhanse af1a2ac
fix headings
cwhanse aa6bbba
change to use pandas to_offset method
cwhanse 4989c02
Update docs/sphinx/source/api.rst
cwhanse a41561b
Update docs/sphinx/source/whatsnew/v0.7.2.rst
cwhanse 31ed477
Update pvlib/snow.py
cwhanse e37eda0
review comments
cwhanse 86599f4
Merge branch 'snow_coverage_model' of https://github.com/JPalakapilly…
cwhanse 21c6813
add snow to __init__.py
cwhanse bf66c37
add test for irregular times
cwhanse ae476ed
correct user name
cwhanse File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,229 @@ | ||||||
""" | ||||||
The ``snowcoverage`` module contains functions that model snow coverage on | ||||||
solar modules. The model was first proposed in Marion et al. 2013 and was | ||||||
later validated and implemented into NREL's SAM. | ||||||
""" | ||||||
|
||||||
import numpy as np | ||||||
import pandas as pd | ||||||
|
||||||
|
||||||
def snow_slide_amount(surface_tilt, sliding_coefficient=1.97): | ||||||
''' | ||||||
Calculates the amount of snow that slides off of the surface of a module | ||||||
following the model first described in [1] and later implemented with minor | ||||||
improvements in SAM [2]. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
surface_tilt : numeric | ||||||
Surface tilt angles in decimal degrees. Tilt must be >=0 and | ||||||
<=180. The tilt angle is defined as degrees from horizontal | ||||||
(e.g. surface facing up = 0, surface facing horizon = 90). | ||||||
|
||||||
|
||||||
sliding coefficient : numeric | ||||||
cwhanse marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
Another empirically determined coefficient used in [1]. It determines | ||||||
how much snow slides off of the panel if a sliding event occurs. | ||||||
|
||||||
Returns | ||||||
---------- | ||||||
slide_amount : numeric | ||||||
The amount of snow that slides off of the panel | ||||||
in tenths of the panel area at each time step. | ||||||
|
||||||
References | ||||||
---------- | ||||||
[1] Marion, B.; Schaefer, R.; Caine, H.; Sanchez, G. (2013). | ||||||
“Measured and modeled photovoltaic system energy losses from snow for | ||||||
Colorado and Wisconsin locations.” Solar Energy 97; pp.112-121. | ||||||
[2] Ryberg, D; Freeman, J. "Integration, Validation, and Application | ||||||
of a PV Snow Coverage Model in SAM" (2017) NREL Technical Report | ||||||
''' | ||||||
|
||||||
tilt_radians = np.radians(surface_tilt) | ||||||
slide_amount = sliding_coefficient * np.sin(tilt_radians) | ||||||
cwhanse marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
return slide_amount | ||||||
|
||||||
|
||||||
def snow_slide_event(poa_irradiance, temperature, | ||||||
m=-80): | ||||||
''' | ||||||
Calculates when snow sliding events will occur following the model first | ||||||
described in [1] and later implemented in SAM [2]. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
poa_irradiance : numeric | ||||||
Total in-plane irradiance (W/m^2) | ||||||
|
||||||
temperature : numeric | ||||||
Ambient air temperature at the surface (C) | ||||||
|
||||||
m : numeric | ||||||
cwhanse marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
A coefficient used in the model described in [1]. It is an | ||||||
empirically determined value given in W/m^2. | ||||||
|
||||||
Returns | ||||||
---------- | ||||||
slide_event : boolean array | ||||||
True if the condiditions are suitable for a snow slide event. | ||||||
False elsewhere. | ||||||
|
||||||
References | ||||||
---------- | ||||||
[1] Marion, B.; Schaefer, R.; Caine, H.; Sanchez, G. (2013). | ||||||
“Measured and modeled photovoltaic system energy losses from snow for | ||||||
Colorado and Wisconsin locations.” Solar Energy 97; pp.112-121. | ||||||
[2] Ryberg, D; Freeman, J. "Integration, Validation, and Application | ||||||
of a PV Snow Coverage Model in SAM" (2017) NREL Technical Report | ||||||
''' | ||||||
|
||||||
slide_event = temperature > poa_irradiance / m | ||||||
return slide_event | ||||||
|
||||||
|
||||||
def fully_covered_panel(snow_data, time_step_hours=1, | ||||||
snow_data_type="snowfall"): | ||||||
''' | ||||||
Calculates the timesteps where the panel is presumed to be fully covered | ||||||
by snow. Follows the same model first described in [1] and later | ||||||
implemented in SAM [2]. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
snow_data : numeric | ||||||
Time series data on either snowfall or ground snow depth. The type of | ||||||
data should be specified in snow_data_type. The original model was | ||||||
designed for ground snowdepth only. (cm/hr or cm) | ||||||
|
||||||
time_step_hours: float | ||||||
Period of the data in hours. (hours between data points) | ||||||
|
||||||
snow_data_type : string | ||||||
Defines what type of data is being passed as snow_data. Acceptable | ||||||
values are "snowfall" and "snow_depth". "snowfall" will be in units of | ||||||
cm/hr. "snow_depth" is in units of cm. | ||||||
|
||||||
Returns | ||||||
---------- | ||||||
fully_covered_mask : boolean array | ||||||
True where the snowfall exceeds the defined threshold to fully cover | ||||||
the panel. False elsewhere. | ||||||
|
||||||
References | ||||||
---------- | ||||||
[1] Marion, B.; Schaefer, R.; Caine, H.; Sanchez, G. (2013). | ||||||
“Measured and modeled photovoltaic system energy losses from snow for | ||||||
Colorado and Wisconsin locations.” Solar Energy 97; pp.112-121. | ||||||
''' | ||||||
if snow_data_type == "snow_depth": | ||||||
prev_data = snow_data.shift(1) | ||||||
prev_data[0] = 0 | ||||||
snowfall = snow_data - prev_data | ||||||
elif snow_data_type == "snowfall": | ||||||
snowfall = snow_data | ||||||
else: | ||||||
raise ValueError('snow_data_type was not specified or was not set to a' | ||||||
'valid option (snowfall, snow_depth).') | ||||||
|
||||||
time_adjusted = snowfall / time_step_hours | ||||||
fully_covered_mask = time_adjusted >= 1 | ||||||
return fully_covered_mask | ||||||
|
||||||
|
||||||
def snow_coverage_model(snow_data, snow_data_type, | ||||||
poa_irradiance, temperature, surface_tilt, | ||||||
time_step_hours=1, m=-80, sliding_coefficient=1.97): | ||||||
''' | ||||||
Calculates the fraction of a module covered by snow at every time step | ||||||
cwhanse marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
following the same model first described in [1] and later | ||||||
implemented in SAM [2]. Currently only implemented for fixed tilt systems | ||||||
cwhanse marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
but could be generalized for tracking systems. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
snow_data : numeric | ||||||
Time series data on either snowfall or ground snow depth. The type of | ||||||
data should be specified in snow_data_type. The original model was | ||||||
designed for ground snowdepth only. (cm/hr or cm) | ||||||
|
||||||
snow_data_type : string | ||||||
Defines what type of data is being passed as snow_data. Acceptable | ||||||
values are "snowfall" and "snow_depth". "snowfall" will be in units of | ||||||
cm/hr. "snow_depth" is in units of cm. | ||||||
|
||||||
poa_irradiance : numeric | ||||||
cwhanse marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
Total in-plane irradiance (W/m^2) | ||||||
|
||||||
temperature : numeric | ||||||
Ambient air temperature at the surface (C) | ||||||
|
||||||
surface_tilt : numeric | ||||||
Surface tilt angles in decimal degrees. Tilt must be >=0 and | ||||||
<=180. The tilt angle is defined as degrees from horizontal | ||||||
(e.g. surface facing up = 0, surface facing horizon = 90). | ||||||
|
||||||
time_step_hours: float | ||||||
cwhanse marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
Period of the data in hours. (hours between data points) | ||||||
|
||||||
sliding coefficient : numeric | ||||||
Another empirically determined coefficient used in [1]. It determines | ||||||
how much snow slides off of the panel if a sliding event occurs. | ||||||
m : numeric | ||||||
A coefficient used in the model described in [1]. It is an | ||||||
empirically determined value given in W/m^2. | ||||||
cwhanse marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
Returns | ||||||
------- | ||||||
snow_coverage : numeric | ||||||
The fraction of a module covered by snow at each time step. | ||||||
''' | ||||||
|
||||||
full_coverage_events = fully_covered_panel(snow_data, | ||||||
time_step_hours=time_step_hours, | ||||||
snow_data_type=snow_data_type) | ||||||
snow_coverage = pd.Series(np.full(len(snow_data), np.nan)) | ||||||
snow_coverage = snow_coverage.reindex(snow_data.index) | ||||||
snow_coverage[full_coverage_events] = 1 | ||||||
slide_events = snow_slide_event(poa_irradiance, temperature) | ||||||
slide_amount = snow_slide_amount(surface_tilt, sliding_coefficient) | ||||||
slidable_snow = ~np.isnan(snow_coverage) | ||||||
while(np.any(slidable_snow)): | ||||||
new_slides = np.logical_and(slide_events, slidable_snow) | ||||||
snow_coverage[new_slides] -= slide_amount*.1 | ||||||
new_snow_coverage = snow_coverage.fillna(method="ffill", limit=1) | ||||||
slidable_snow = np.logical_and(~np.isnan(new_snow_coverage), | ||||||
np.isnan(snow_coverage)) | ||||||
slidable_snow = np.logical_and(slidable_snow, new_snow_coverage > 0) | ||||||
snow_coverage = new_snow_coverage | ||||||
|
||||||
new_slides = np.logical_and(slide_events, slidable_snow) | ||||||
snow_coverage[new_slides] -= slide_amount | ||||||
|
||||||
snow_coverage = snow_coverage.fillna(method="ffill") | ||||||
snow_coverage = snow_coverage.fillna(value=0) | ||||||
snow_coverage[snow_coverage < 0] = 0 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
return snow_coverage | ||||||
|
||||||
|
||||||
def DC_loss_factor(snow_coverage, num_strings_per_row): | ||||||
''' | ||||||
Calculates the DC loss due to snow coverage. Assumes that if a string is | ||||||
even partially covered by snow, it produces 0W. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
snow_coverage : numeric | ||||||
The fraction of a module covered by snow at each time step. | ||||||
cwhanse marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
num_strings_per_row: int | ||||||
cwhanse marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
The number of separate strings per module/row. | ||||||
|
||||||
Returns | ||||||
------- | ||||||
loss : numeric | ||||||
DC loss due to snow coverage at each time step. | ||||||
''' | ||||||
loss = np.ceil(snow_coverage * num_strings_per_row) / num_strings_per_row | ||||||
return loss |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import numpy as np | ||
import pandas as pd | ||
|
||
from numpy.testing import assert_almost_equal | ||
|
||
from pandas.util.testing import assert_series_equal | ||
|
||
from pvlib import snowcoverage | ||
|
||
|
||
def test_snow_slide_amount(): | ||
tilt = 45 | ||
sc = 2 | ||
expected_specified = 2**.5 | ||
expected_default = 1.97/2*2**.5 | ||
actual_default = snowcoverage.snow_slide_amount(tilt) | ||
assert_almost_equal(expected_default, actual_default) | ||
actual_specified = snowcoverage.snow_slide_amount(tilt, | ||
sliding_coefficient=sc) | ||
assert_almost_equal(expected_specified, actual_specified) | ||
|
||
|
||
def test_snow_slide_event(): | ||
poa_irradiance = pd.Series([400, 200, 100, 1234, 134, 982]) | ||
temperature = pd.Series([10, 2, -10, 1234, 34, -982]) | ||
expected = pd.Series([True, True, False, True, True, False]) | ||
actual = snowcoverage.snow_slide_event(poa_irradiance, temperature) | ||
assert_series_equal(expected, actual) | ||
|
||
|
||
def test_fully_covered_panel(): | ||
snowfall_data = pd.Series([1, 5, .6, 4, .23, -5, 19]) | ||
expected_snowfall = pd.Series([True, True, False, True, | ||
False, False, True]) | ||
actual_snowfall = snowcoverage.fully_covered_panel(snowfall_data) | ||
assert_series_equal(actual_snowfall, expected_snowfall) | ||
|
||
snowdepth_data = pd.Series([.5, 1, 2, 4, .23, 4, 19]) | ||
expected_snowdepth = pd.Series([False, False, True, True, | ||
False, True, True]) | ||
actual = snowcoverage.fully_covered_panel(snowdepth_data, | ||
snow_data_type="snow_depth") | ||
assert_series_equal(actual, expected_snowdepth) | ||
|
||
|
||
def test_snow_coverage_model(): | ||
tilt = 45 | ||
poa_irradiance = pd.Series([400, 200, 100, 1234, 134, 982, 100, 100]) | ||
temperature = pd.Series([10, 2, 10, 1234, 34, 982, 10, 10]) | ||
slide = snowcoverage.snow_slide_amount(tilt)*.1 | ||
|
||
snowfall_data = pd.Series([1, .5, .6, .4, .23, -5, .1, .1]) | ||
snow_coverage = snowcoverage.snow_coverage_model(snowfall_data, "snowfall", | ||
poa_irradiance, | ||
temperature, | ||
tilt) | ||
expected = pd.Series(1-slide*np.array([1, 2, 3, 4, 5, 6, 7, 1.0/slide])) | ||
assert_series_equal(snow_coverage, expected) | ||
|
||
snowdepth_data = pd.Series([.5, 1, 2, 4, .23, 4, 11, .1]) | ||
snow_coverage = snowcoverage.snow_coverage_model(snowdepth_data, | ||
"snow_depth", | ||
poa_irradiance, | ||
temperature, | ||
tilt) | ||
expected = pd.Series(1-slide*np.array([1.0/slide, 1.0/slide, 1, | ||
1, 2, 1, 1, 2])) | ||
assert_series_equal(snow_coverage, expected) | ||
|
||
|
||
def test_DC_loss_factor(): | ||
num_strings = 8 | ||
snow_coverage = pd.Series([1, 1, .5, .6, .2, .4, 0]) | ||
expected = pd.Series([1, 1, .5, .625, .25, .5, 0]) | ||
actual = snowcoverage.DC_loss_factor(snow_coverage, num_strings) | ||
assert_series_equal(expected, actual) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.