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

Merge of v0.4.4 branch into development #567

Open
wants to merge 19 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
bcc8120
fixes #256 - not useful error when trying to load a module not in .js…
cdeline Oct 7, 2024
04ab3bd
minor changes to gui documentation
cdeline Oct 8, 2024
334a638
GUI fixes: timestamp error in modelchain; sensorsy loading error in …
cdeline Oct 9, 2024
c5bb3e5
adjust scan by 1/2 a cell when sensorsY is equal to numCellsy-1.
cdeline Oct 9, 2024
553b32c
Gencumulativesky tracking bugfix - half of zero tilt data had been ne…
cdeline Oct 10, 2024
d2d1428
revert back to %.1f format for saving cumulative .csv file.
cdeline Oct 10, 2024
cb1c61b
Update scm-version fallback to v0.4.4 in setup.py; update workflows/d…
cdeline Oct 10, 2024
0b1c9d4
Merge pull request #563 from NREL/256_moduleNotFound
cdeline Oct 13, 2024
90017fd
Sphinx updates. Bump pytests to include py 3.12
cdeline Oct 13, 2024
2a54c7e
sphinx and requirements.txt updates
cdeline Oct 14, 2024
9a52a8d
requirements.txt sphinx version
cdeline Oct 14, 2024
5f2a2b3
update requirements.txt, pytest.yaml, setup.py versions
cdeline Oct 14, 2024
69b3d65
Tutorial notebook updates. Add py3.12 support
cdeline Oct 14, 2024
2980a91
more groundObj pytests
cdeline Oct 14, 2024
f341da2
more pytest. update release date.
cdeline Oct 14, 2024
bcab0bf
Merge pull request #565 from NREL/v0_4_4_Release
cdeline Oct 14, 2024
db4bb4a
module.json clear out pathnames
cdeline Oct 14, 2024
27cfebb
Merge remote-tracking branch 'remotes/NREL/main' into dev_merge
cdeline Oct 17, 2024
84e2b07
add pytest for where frontsurfaceoffset=None and backsurfaceoffset=None
cdeline Oct 17, 2024
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
2 changes: 1 addition & 1 deletion bifacial_radiance/data/module.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"test-module": {
"bifi": 1,
"glass": false,
"modulefile": "objects\\test-module.rad",
"modulefile": null,
"modulematerial": "black",
"numpanels": 1,
"offsetfromaxis": 0,
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 @@ -815,8 +815,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 @@ -908,11 +908,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']=ast.literal_eval(analysisParamsDict['modWanted'])
except:
Expand Down Expand Up @@ -1013,14 +1013,14 @@ def boolConvert(d):
try: omegaParamsDict
except: omegaParamsDict = None

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



def savedictionariestoConfigurationIniFile(simulationParamsDict, sceneParamsDict,
timeControlParamsDict=None, moduleParamsDict=None,
trackingParamsDict=None, torquetubeParamsDict=None,
Expand Down
32 changes: 22 additions & 10 deletions bifacial_radiance/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,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 @@ -3356,8 +3356,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 @@ -4276,7 +4276,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 @@ -5018,7 +5018,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 @@ -5091,10 +5091,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
22 changes: 8 additions & 14 deletions bifacial_radiance/modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,23 +123,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,
frameParams=frameParamsDict,
omegaParams=omegaParamsDict, **kwargs)
if (simulationParamsDict['moduletype'] in A) and not (kwargs['rewriteModulefile']):

module = simulationParamsDict['moduletype']
print("\nUsing Pre-determined Module Type: %s " %
simulationParamsDict['moduletype'])
else:
Expand Down Expand Up @@ -167,7 +161,7 @@ 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, customtext=customObject)
demo.genCumSky(demo.gencumsky_metfile)

Expand All @@ -179,9 +173,9 @@ def runModelChain(simulationParamsDict, sceneParamsDict, timeControlParamsDict=N

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 @@ -214,7 +208,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'], customtext=customObject)

Expand Down
2 changes: 1 addition & 1 deletion bifacial_radiance/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ def readModule(self, name=None):

return moduleDict
else:
print('Error: module name {} doesnt exist'.format(name))
raise Exception('Error: module name "{}" doesnt exist'.format(name))
return {}


Expand Down
20 changes: 11 additions & 9 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,10 +160,15 @@ def __getattr__(cls, name):
],
#"use_edit_page_button": True,
"show_toc_level": 1,
#"footer_items": ["copyright", "sphinx-version", "sidebar-ethical-ads"],
"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 @@ -197,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
1 change: 1 addition & 0 deletions docs/sphinx/source/manualapi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ Power and Mismatch
AnalysisObj.calculatePerformance
ModuleObj.addCEC
mismatch.mismatch_fit2
mismatch.mad_fn

AgriPV Ground Scans
-------------------
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