Skip to content

Commit

Permalink
Merge pull request #565 from NREL/v0_4_4_Release
Browse files Browse the repository at this point in the history
V0 4 4 release
  • Loading branch information
cdeline authored Oct 14, 2024
2 parents 0b1c9d4 + f341da2 commit bcab0bf
Show file tree
Hide file tree
Showing 26 changed files with 401 additions and 336 deletions.
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

0 comments on commit bcab0bf

Please sign in to comment.