Skip to content
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

V0 4 4 release #565

Merged
merged 13 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: '3.7'
python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand All @@ -26,7 +26,7 @@ jobs:
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: dist
path: |
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/pytest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ jobs:
'-r requirements.txt .[all]',
'--upgrade --upgrade-strategy=eager .[all]'
]
include:
- python-version: "3.12"
env: '--upgrade --upgrade-strategy=eager .[all]'


steps:
- uses: actions/checkout@v4
Expand Down
6 changes: 5 additions & 1 deletion bifacial_radiance/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,11 @@ def save_inputfile(savetitle=None):
if savetitle is None:
savetitle = inputvariablefile

bifacial_radiance.load.savedictionariestoConfigurationIniFile(simulationParamsDict, sceneParamsDict, timeControlParamsDict, moduleParamsDict, trackingParamsDict, torquetubeParamsDict, analysisParamsDict, cellModuleDict, inifilename=savetitle)
bifacial_radiance.load.savedictionariestoConfigurationIniFile(simulationParamsDict, sceneParamsDict,
timeControlParamsDict, moduleParamsDict,
trackingParamsDict, torquetubeParamsDict,
analysisParamsDict, cellModuleDict,
inifilename=savetitle)
print("Saved all Values to %s " % savetitle)


Expand Down
16 changes: 8 additions & 8 deletions bifacial_radiance/load.py
Original file line number Diff line number Diff line change
Expand Up @@ -660,8 +660,8 @@ def boolConvert(d):
else:
print("Load Warning: no valid time to restrict weather data passed"
"Simulating default day 06/21 at noon")
timeControlParamsDict['starttime']='06_21_12_00'
timeControlParamsDict['endtime']='06_21_12_00'
timeControlParamsDict['starttime']='06_21_12'
timeControlParamsDict['endtime']='06_21_12'

#NEEDED sceneParamsDict parameters
sceneParamsDict={}
Expand Down Expand Up @@ -751,11 +751,11 @@ def boolConvert(d):
if config.has_section("analysisParamsDict"):
analysisParamsDict = boolConvert(confdict['analysisParamsDict'])
try:
analysisParamsDict['sensorsy']=ast.literal_eval(analysisParamsDict['sensorsy'])
except:
analysisParamsDict['sensorsy']=ast.literal_eval(str(analysisParamsDict['sensorsy']))
except ValueError:
print("Load Warning: improper analysisParamsDict['sensorsy']"
" passed: %s, setting to default value: 9" % analysisParamsDict['sensorsy'] )
analysisParamsDict['sensorsy'] = 9 #Default
print("Load Warning: improper or no analysisParamsDict['sensorsy']"
" passed, setting to default value: %s" % analysisParamsDict['sensorsy'] )
try:
analysisParamsDict['modWanted']=int(analysisParamsDict['modWanted'])
except:
Expand Down Expand Up @@ -794,13 +794,13 @@ def boolConvert(d):
try: cellModuleDict
except: cellModuleDict = None

#returnParams = Params(simulationParamsDict, sceneParamsDict, timeControlParamsDict, moduleParamsDict, trackingParamsDict, torquetubeParamsDict, analysisParamsDict, cellModuleDict)
#return returnParams
# end readconfigurationinputfile
return (simulationParamsDict, sceneParamsDict, timeControlParamsDict,
moduleParamsDict, trackingParamsDict, torquetubeParamsDict,
analysisParamsDict, cellModuleDict, frameParamsDict, omegaParamsDict)



def savedictionariestoConfigurationIniFile(simulationParamsDict, sceneParamsDict,
timeControlParamsDict=None, moduleParamsDict=None,
trackingParamsDict=None, torquetubeParamsDict=None,
Expand Down
43 changes: 28 additions & 15 deletions bifacial_radiance/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,8 @@ def _subhourlydatatoGencumskyformat(gencumskydata, label='right'):
tzinfo = gencumskydata.index.tzinfo
padstart = pd.to_datetime('%s-%s-%s %s:%s' % (gencumskydata.index.year[0],1,1,1,0 ) ).tz_localize(tzinfo)
padend = pd.to_datetime('%s-%s-%s %s:%s' % (gencumskydata.index.year[0]+1,1,1,0,0) ).tz_localize(tzinfo)
gencumskydata.iloc[0] = 0 # set first datapt to zero to forward fill w zeros
gencumskydata.iloc[-1] = 0 # set last datapt to zero to forward fill w zeros
#gencumskydata.iloc[0] = 0 # set first datapt to zero to forward fill w zeros
#gencumskydata.iloc[-1] = 0 # set last datapt to zero to forward fill w zeros
# check if index exists. I'm sure there is a way to do this backwards.
if any(gencumskydata.index.isin([padstart])):
print("Data starts on Jan. 01")
Expand Down Expand Up @@ -2747,8 +2747,8 @@ def __init__(self, materialOrAlbedo=None, material_file=None, silent=False):
f'{self._nonzeromean(self.ReflAvg):0.3f} avg\n'
f'{self.ReflAvg[self.ReflAvg != 0].__len__()} nonzero albedo values.')
except IndexError as e:
print('albedo.shape should be 3 column (N x 3)')
raise e
raise Exception('albedo.shape needs to be 3 column (N x 3)')


def printGroundMaterials(self, materialString=None):
"""
Expand Down Expand Up @@ -3529,7 +3529,7 @@ def _getTrackingAngles(self, azimuth=180, limit_angle=45,
def _roundArbitrary(x, base=angledelta):
# round to nearest 'base' value.
# mask NaN's to avoid rounding error message
return base * (x/float(base)).round()
return base * (x/float(base)).round() + 0 #remove negative zeros

if angledelta == 0:
raise ZeroDivisionError('Angledelta = 0. Use None instead')
Expand Down Expand Up @@ -4151,11 +4151,12 @@ def _checkSensors(sensors):
else:
print ("Module's z not set on sceneDict internal dictionary. Setting to default")
modulez = 0.02

if frontsurfaceoffset is None:
frontsurfaceoffset = 0.001
if backsurfaceoffset is None:
backsurfaceoffset = 0.001

# cdeline 20241014 remove this check - extraneous
#if frontsurfaceoffset is None:
# frontsurfaceoffset = 0.001
#if backsurfaceoffset is None:
# backsurfaceoffset = 0.001

# The Sensor routine below needs a "hub-height", not a clearance height.
# The below complicated check checks to see if height (deprecated) is passed,
Expand Down Expand Up @@ -4228,7 +4229,7 @@ def _checkSensors(sensors):

xstartfront = x1 + x2 + x3 + originx
xstartback = x1 + x2 + x4 + originx

ystartfront = y1 + y2 + y3 + originy
ystartback = y1 + y2 + y4 + originy

Expand Down Expand Up @@ -4291,10 +4292,22 @@ def _checkSensors(sensors):

firstsensorxstartfront = xstartfront+xinc_front
firstsensorxstartback = xstartback+xinc_back
firstsensorystartfront = ystartfront+yinc_front
firstsensorystartback = ystartback+yinc_back
firstsensorzstartfront = zstartfront + zinc_front
firstsensorzstartback = zstartback + zinc_back
# check to make sure sensorsy don't line up with gaps in between cellModule
if ((getattr(scene.module, 'cellModule', None)) and
(sensorsy_front == scene.module.cellModule.numcellsy-1)):
firstsensorystartfront = ystartfront+yinc_front/2
firstsensorzstartfront = zstartfront + zinc_front/2
else:
firstsensorystartfront = ystartfront+yinc_front
firstsensorzstartfront = zstartfront + zinc_front
if ((getattr(scene.module, 'cellModule', None)) and
(sensorsy_back == scene.module.cellModule.numcellsy-1)):
firstsensorystartback = ystartback+yinc_back/2
firstsensorzstartback = zstartback + zinc_back/2
else:
firstsensorystartback = ystartback+yinc_back
firstsensorzstartback = zstartback + zinc_back


## Correct positions for sensorsx other than 1
# TODO: At some point, this equations can include the case where
Expand Down
19 changes: 8 additions & 11 deletions bifacial_radiance/modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,20 +113,17 @@ def runModelChain(simulationParamsDict, sceneParamsDict, timeControlParamsDict=N
'axisofrotationTorqueTube']
"""
kwargs = moduleParamsDict
kwargs['rewriteModulefile'] = simulationParamsDict['rewriteModule']
if torquetubeParamsDict:
if not 'visible' in torquetubeParamsDict:
torquetubeParamsDict['visible'] = simulationParamsDict['torqueTube']
if 'axisofrotationTorqueTube' in simulationParamsDict:
torquetubeParamsDict['axisofrotation'] = simulationParamsDict[
'axisofrotationTorqueTube']

if simulationParamsDict['moduletype'] in A:
if simulationParamsDict['rewriteModule'] is True:

module = demo.makeModule(name=simulationParamsDict['moduletype'],
tubeParams=torquetubeParamsDict,
cellModule=cellModule, **kwargs)
if (simulationParamsDict['moduletype'] in A) and not (kwargs['rewriteModulefile']):

module = simulationParamsDict['moduletype']
print("\nUsing Pre-determined Module Type: %s " %
simulationParamsDict['moduletype'])
else:
Expand All @@ -142,14 +139,14 @@ def runModelChain(simulationParamsDict, sceneParamsDict, timeControlParamsDict=N

if simulationParamsDict['tracking'] == False and simulationParamsDict['cumulativeSky'] == True:
# Fixed gencumsky condition
scene = demo.makeScene(module=simulationParamsDict['moduletype'],
scene = demo.makeScene(module=module,
sceneDict=sceneParamsDict)
demo.genCumSky(demo.gencumsky_metfile)
octfile = demo.makeOct(demo.getfilelist())
analysis = bifacial_radiance.AnalysisObj(octfile, demo.name)
frontscan, backscan = analysis.moduleAnalysis(scene, analysisParamsDict['modWanted'],
analysisParamsDict['rowWanted'],
analysisParamsDict['sensorsy'])
frontscan, backscan = analysis.moduleAnalysis(scene, modWanted=analysisParamsDict['modWanted'],
rowWanted=analysisParamsDict['rowWanted'],
sensorsy=analysisParamsDict['sensorsy'])
analysis.analysis(octfile, demo.name, frontscan, backscan)
print('Bifacial ratio yearly average: %0.3f' %
(np.mean(analysis.Wm2Back) / np.mean(analysis.Wm2Front)))
Expand Down Expand Up @@ -182,7 +179,7 @@ def runModelChain(simulationParamsDict, sceneParamsDict, timeControlParamsDict=N
trackerdict = demo.gendaylit1axis()

trackerdict = demo.makeScene1axis(trackerdict=trackerdict,
module=simulationParamsDict['moduletype'],
module=module,
sceneDict=sceneParamsDict,
cumulativesky=simulationParamsDict['cumulativeSky'])

Expand Down
19 changes: 11 additions & 8 deletions docs/sphinx/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def __getattr__(cls, name):

# General information about the project.
project = u'bifacial_radiance'
copyright = u'2019, NREL'
copyright = u'2024, NREL'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down Expand Up @@ -145,10 +145,7 @@ def __getattr__(cls, name):
# https://pydata-sphinx-theme.rtfd.io/en/latest/user_guide/configuring.html
html_theme_options = {
"github_url": "https://github.com/NREL/bifacial_radiance",
"sphinx-favicon": [
{"rel": "icon", "sizes": "16x16", "href": "favicon-16x16.png"},
{"rel": "icon", "sizes": "32x32", "href": "favicon-32x32.png"},
],

"icon_links": [
{
"name": "StackOverflow",
Expand All @@ -163,9 +160,15 @@ def __getattr__(cls, name):
],
#"use_edit_page_button": True,
"show_toc_level": 1,
"footer_start": ["copyright", "sphinx-version", "sidebar-ethical-ads"],
#"left_sidebar_end": [],
#"footer_start": ["copyright"],
#"footer_center": ["sphinx-version"],
}
# Add favicons from extension sphinx_favicon
favicons = [
{"rel": "icon", "sizes": "16x16", "href": "favicon-16x16.png"},
{"rel": "icon", "sizes": "32x32", "href": "favicon-32x32.png"},
]


# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
Expand Down Expand Up @@ -196,7 +199,7 @@ def __getattr__(cls, name):
'tutorials/6 - Exploring Trackerdict Structure': '_images/bifacial_radiance.png',
'tutorials/7 - Multiple Scene Objects':'_images/MultipleSceneObject_AnalysingSceneObj2_Row1_Module4.PNG',
'tutorials/8 - Electrical Mismatch Method':'_images/Mismatch_Definition_Example.PNG',
'tutorials/9 - Torquetube Shading':'_images/tutorials_9_-_Torquetube_Shading_23_1.png',
'tutorials/9 - Torquetube Shading':'_images/tutorials_9_-_Torquetube_Shading_24_1.png',
'tutorials/11 - AgriPV Systems': '_images/AgriPV_2.PNG',
'tutorials/13 - Modeling Modules with Glass': '_images/Glass_tilted_reflection.PNG',
'tutorials/14 - Cement Racking Albedo Improvements': '_images/Pavers.PNG',
Expand Down
2 changes: 2 additions & 0 deletions docs/sphinx/source/manualapi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ Mismatch
:toctree: generated/
:caption: Mismatch Analysis

mismatch.mad_fn
mismatch.mismatch_fit2
mismatch.analysisIrradianceandPowerMismatch

Support
Expand Down
2 changes: 1 addition & 1 deletion docs/sphinx/source/user_guide/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Alternative Installation: Windows Subsystem for Linux:

PYTHON
-------
You will need python installed to run bifacial_radiance. We suggest using the latest release of `Anaconda with Python 3.9 <https://www.anaconda.com/distribution/>`_ (Python 3.7 is still supported but in the process of being deprecated). Anaconda will install ``Spyder`` to work with the python scripts, and also it will install ``Jupyter``, which is the tool we use for our `tutorial trainings <https://github.com/NREL/bifacial_radiance/tree/master/docs/tutorials>`_
You will need python installed to run bifacial_radiance. We suggest using the latest release of `Anaconda with Python 3.11 <https://www.anaconda.com/download/>`_ . Anaconda will install ``Spyder`` to work with the python scripts, and also it will install ``Jupyter``, which is the tool we use for our `tutorial trainings <https://github.com/NREL/bifacial_radiance/tree/master/docs/tutorials>`_


Alternative Installation: Windows Subsystem for Linux:
Expand Down
22 changes: 11 additions & 11 deletions docs/sphinx/source/whatsnew/v0.4.3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,42 @@

v0.4.3 (Aug 27 2024)
------------------------
Bugfix Release ...
Bugfix Release


API Changes
~~~~~~~~~~~~
* A new function can now be called to compile results and report out final irradiance and performance data: :func:`bifacial_radiance.RadianceObj.compileResults`. (This is a temporary function soon to be deprecated)
* A new function can now be called to compile results and report out final irradiance and performance data: ``RadianceObj.compileResults``. (This is a temporary function soon to be deprecated)
* Multiple modules and rows can now be selected in a single analysis scan. ``modWanted`` and ``rowWanted`` inputs in :py:class:`~bifacial_radiance.RadianceObj.analysis1axis` can now be a list, to select multiple rows and modules for scans. (:issue:`405`)(:pull:`408`)
* To support multiple modules and row scans for 1axis simulations, outputs like Wm2Front are now stored in ``trackerdict``.``Results`` (:issue:`405`)(:pull:`408`)
* :func:`.mismatch.mad_fn` has new functionality and input parameter `axis`. If a 2D matrix or dataframe is passed in as data, MAD is calculated along the row (default) or along the columns by passing 'axis=1'
* :func:`bifacial_radiance.mismatch.mismatch_fit3` has been deprecated in favour of :func:`bifacial_radiance.mismatch.mismatch_fit2` which has a greater agreement with anual energy yield data (:issue:`520`)
* To support multiple modules and row scans for 1axis simulations, outputs like Wm2Front are now stored in ``trackerdict.Results`` (:issue:`405`)(:pull:`408`)
* ``mismatch.mismatch.mad_fn`` has new functionality and input parameter ``axis``. If a 2D matrix or dataframe is passed in as data, MAD is calculated along the row (default) or along the columns by passing 'axis=1'
* ``mismatch.mismatch_fit3`` has been deprecated in favour of ``mismatch.mismatch_fit2`` which has a greater agreement with anual energy yield data (:issue:`520`)

Enhancements
~~~~~~~~~~~~
* Added :func:`bifacial_radiance.mismatch.mismatch_fit2`, similar to :func:`bifacial_radiance.mismatch.mismatch_fit3`, with the recommended coefficients of the original publication. (:pull:`520`)
* Added ``mismatch.mismatch_fit2``, similar to ``mismatch.mismatch_fit3``, with the recommended coefficients of the original publication. (:pull:`520`)
* Including `pyRadiance` as a requirement to help streamline RADIANCE installation and calls in a future release. (:pull:`532`)

Bug fixes
~~~~~~~~~
* Fixed error passing all of `sceneDict` into :func:`~bifacial_radiance.RadianceObj.makeScene1axis`. (:issue:`502`)
* Fixed Pandas 2.0 errors by re-factoring :func:`.mismatch.mad_fn` (:issue:`449`)
* Fixed error passing all of ``sceneDict`` into py:class:`~bifacial_radiance.RadianceObj.makeScene1axis`. (:issue:`502`)
* Fixed Pandas 2.0 errors by re-factoring py:class:`bifacial_radiance.mismatch.mad_fn` (:issue:`449`)
* Switch from un-supported Versioneer to setuptools_scm (:issue:`519`)
* Numpy 2.0 compatibility bug (:issue:`521`)
* Fixed bug in :func:`bifacial_radiance.mismatch.mismatch_fit3` where the function was not returning the correct values. It has also been deprecated in favour of :func:`bifacial_radiance.mismatch.mismatch_fit2` which has a greater agreement with anual energy yield data (:issue:`520`)
* Fixed bug in ``mismatch.mismatch_fit3`` where the function was not returning the correct values. It has also been deprecated in favour of ``mismatch.mismatch_fit2`` which has a greater agreement with anual energy yield data (:issue:`520`)
* Updated Github Actions to use Node20: checkout@v4, setup-python@v5, coactions/setup-xvfb, setup-buildx-action@v3 (:pull:`517`)
* Updated Github Actions to make Coveralls fail silently if it has an internal server error (:pull:`517`)
* Fix PerformanceWarning and SettingWithCopyWarning (:issue:`515`)
* Switch from Versioneer to setuptools_scm (:pull:`522`)
* Enable `coerce_year`=None if the TMYfile is all the same year (:issue:`526`)
* Enable ``coerce_year=None`` if the TMYfile is all the same year (:issue:`526`)

Documentation
~~~~~~~~~~~~~~
* Edge effects evaluation tutorial 23, with the new functionality of multiple modules/rows on the same analysis scan.
* Updates to example notebooks
* Reduce number of digits in makeScene .rad file titles. (:pull:`503`)
* Reduce number of digits saved to files in \results (:pull:`534`)
* In the sceneDict reported in the trackerdict, save both `clearance_height` and `hub_height` parameters. (:pull:`503`)
* In the sceneDict reported in the trackerdict, save both ``clearance_height`` and ``hub_height`` parameters. (:pull:`503`)

Contributors
~~~~~~~~~~~~
Expand Down
Loading
Loading