From 90f8f803f76a1b77cea4cdc693f36cde5a110bb9 Mon Sep 17 00:00:00 2001 From: cdeline Date: Fri, 10 Nov 2023 10:09:25 -0700 Subject: [PATCH] load._exportTrackerDict updated to iterate on sceneNum. _getradfiles bug fixed. tests fixed, new functionality tested in test_1axis_gencumSky --- bifacial_radiance/load.py | 105 ++++++++++++++++---------------- bifacial_radiance/main.py | 15 +++-- bifacial_radiance/modelchain.py | 2 +- tests/test_bifacial_radiance.py | 16 ++--- 4 files changed, 72 insertions(+), 66 deletions(-) diff --git a/bifacial_radiance/load.py b/bifacial_radiance/load.py index f3151c75..65113c02 100644 --- a/bifacial_radiance/load.py +++ b/bifacial_radiance/load.py @@ -333,7 +333,7 @@ def _exportTrackerDict(trackerdict, savefile, reindex=False, monthlyyearly=False # add trackerdict Results (not all simulations will have results) try: results = pd.concat([df(data=value['Results'],index=[key]*len(value['Results'])) for (key,value) in trackerdict.items()]) - results = results[['rowWanted','modWanted','Wm2Front','Wm2Back']] + results = results[['rowWanted','modWanted','sceneNum','Wm2Front','Wm2Back']] d = results.join(d) except KeyError: pass @@ -357,57 +357,58 @@ def _exportTrackerDict(trackerdict, savefile, reindex=False, monthlyyearly=False D4join = pd.DataFrame() for rownum in d['rowWanted'].unique(): for modnum in d['modWanted'].unique(): - mask = (d['rowWanted']==rownum) & (d['modWanted']==modnum) - print(modnum) - # Gfront_mean.append(filledFront[mask].sum(axis=0).mean()) - D2 = d[mask].copy() - D2['timestamp'] = pd.to_datetime(D2['measdatetime'], format="%Y-%m-%d_%H%M") - D2 = D2.set_index('timestamp') - # D2 = D2.set_index(D2['timestamp']) - - # Determine if data is sub-hourly - if len(D2) > 1: - if (D2.index[1]-D2.index[0]).total_seconds() / 60 < 60.0: - # Subhourly to hourly data averages, doesn't sum - # So we get average hourly irradiance as well as Wh on - # results of power. - D2b = D2.copy() - D2b = D2b.groupby(pd.PeriodIndex(D2b.index, freq="H")).mean().reset_index() - D2b['BGG'] = D2b['Grear_mean']*100/D2b['Gfront_mean'] - D2b['BGE'] = (D2b['Pout']-D2b['Pout_Gfront'])*100/D2b['Pout'] - D2b['Mismatch'] = (D2b['Pout_raw']-D2b['Pout'])*100/D2b['Pout_raw'] - D2b['rowWanted'] = rownum - D2b['modWanted'] = modnum - D2b.drop(columns=['theta', 'surf_tilt', 'surf_azm'], inplace=True) - D2b=D2b.reset_index() - D2join = pd.concat([D2join, D2b], ignore_index=True, sort=False) - - D3 = D2.groupby(pd.PeriodIndex(D2.index, freq="M")).sum().reset_index() - D3['BGG'] = D3['Grear_mean']*100/D3['Gfront_mean'] - D3['BGE'] = (D3['Pout']-D3['Pout_Gfront'])*100/D3['Pout'] - D3['Mismatch'] = (D3['Pout_raw']-D3['Pout'])*100/D3['Pout_raw'] - D3['rowWanted'] = rownum - D3['modWanted'] = modnum - D3m = D2.groupby(pd.PeriodIndex(D2.index, freq="M")).mean().reset_index() - D3['temp_air'] = D3m['temp_air'] - D3['wind_speed'] = D3m['wind_speed'] - D3.drop(columns=['theta', 'surf_tilt', 'surf_azm'], inplace=True) - - D4 = D2.groupby(pd.PeriodIndex(D2.index, freq="Y")).sum().reset_index() - D4['BGG'] = D4['Grear_mean']*100/D4['Gfront_mean'] - D4['BGE'] = (D4['Pout']-D4['Pout_Gfront'])*100/D4['Pout'] - D4['Mismatch'] = (D4['Pout_raw']-D4['Pout'])*100/D4['Pout_raw'] - D4['rowWanted'] = rownum - D4['modWanted'] = modnum - D4m = D2.groupby(pd.PeriodIndex(D2.index, freq="Y")).mean().reset_index() - D4['temp_air'] = D4m['temp_air'] - D4['wind_speed'] = D4m['wind_speed'] - D4.drop(columns=['theta', 'surf_tilt', 'surf_azm'], inplace=True) - - D3=D3.reset_index() - D4=D4.reset_index() - D3join = pd.concat([D3join, D3], ignore_index=True, sort=False) - D4join = pd.concat([D4join, D4], ignore_index=True, sort=False) + for sceneNum in d['sceneNum'].unique():#TODO: is sceneNum iteration required here? + mask = (d['rowWanted']==rownum) & (d['modWanted']==modnum) & (d['sceneNum']==sceneNum) + print(modnum) + # Gfront_mean.append(filledFront[mask].sum(axis=0).mean()) + D2 = d[mask].copy() + D2['timestamp'] = pd.to_datetime(D2['measdatetime'], format="%Y-%m-%d_%H%M") + D2 = D2.set_index('timestamp') + # D2 = D2.set_index(D2['timestamp']) + + # Determine if data is sub-hourly + if len(D2) > 1: + if (D2.index[1]-D2.index[0]).total_seconds() / 60 < 60.0: + # Subhourly to hourly data averages, doesn't sum + # So we get average hourly irradiance as well as Wh on + # results of power. + D2b = D2.copy() + D2b = D2b.groupby(pd.PeriodIndex(D2b.index, freq="H")).mean().reset_index() + D2b['BGG'] = D2b['Grear_mean']*100/D2b['Gfront_mean'] + D2b['BGE'] = (D2b['Pout']-D2b['Pout_Gfront'])*100/D2b['Pout'] + D2b['Mismatch'] = (D2b['Pout_raw']-D2b['Pout'])*100/D2b['Pout_raw'] + D2b['rowWanted'] = rownum + D2b['modWanted'] = modnum + D2b.drop(columns=['theta', 'surf_tilt', 'surf_azm'], inplace=True) + D2b=D2b.reset_index() + D2join = pd.concat([D2join, D2b], ignore_index=True, sort=False) + + D3 = D2.groupby(pd.PeriodIndex(D2.index, freq="M")).sum().reset_index() + D3['BGG'] = D3['Grear_mean']*100/D3['Gfront_mean'] + D3['BGE'] = (D3['Pout']-D3['Pout_Gfront'])*100/D3['Pout'] + D3['Mismatch'] = (D3['Pout_raw']-D3['Pout'])*100/D3['Pout_raw'] + D3['rowWanted'] = rownum + D3['modWanted'] = modnum + D3m = D2.groupby(pd.PeriodIndex(D2.index, freq="M")).mean().reset_index() + D3['temp_air'] = D3m['temp_air'] + D3['wind_speed'] = D3m['wind_speed'] + D3.drop(columns=['theta', 'surf_tilt', 'surf_azm'], inplace=True) + + D4 = D2.groupby(pd.PeriodIndex(D2.index, freq="Y")).sum().reset_index() + D4['BGG'] = D4['Grear_mean']*100/D4['Gfront_mean'] + D4['BGE'] = (D4['Pout']-D4['Pout_Gfront'])*100/D4['Pout'] + D4['Mismatch'] = (D4['Pout_raw']-D4['Pout'])*100/D4['Pout_raw'] + D4['rowWanted'] = rownum + D4['modWanted'] = modnum + D4m = D2.groupby(pd.PeriodIndex(D2.index, freq="Y")).mean().reset_index() + D4['temp_air'] = D4m['temp_air'] + D4['wind_speed'] = D4m['wind_speed'] + D4.drop(columns=['theta', 'surf_tilt', 'surf_azm'], inplace=True) + + D3=D3.reset_index() + D4=D4.reset_index() + D3join = pd.concat([D3join, D3], ignore_index=True, sort=False) + D4join = pd.concat([D4join, D4], ignore_index=True, sort=False) savefile2 = savefile[:-4]+'_Hourly.csv' savefile3 = savefile[:-4]+'_Monthly.csv' diff --git a/bifacial_radiance/main.py b/bifacial_radiance/main.py index 0e9e4507..5eab160b 100644 --- a/bifacial_radiance/main.py +++ b/bifacial_radiance/main.py @@ -437,8 +437,11 @@ def _getradfiles(self, scenelist=None): scenelist = self.scenes a = [] for scene in scenelist: - for f in scene.radfiles: - a.append(f) + if type(scene.radfiles) == list: + for f in scene.radfiles: + a.append(f) + else: + a.append(scene.radfiles) return a def save(self, savefile=None): @@ -2195,7 +2198,7 @@ def makeOct1axis(self, trackerdict=None, singleindex=None, customname=None): print('\nMaking {} octfiles in root directory.'.format(indexlist.__len__())) for index in sorted(indexlist): # run through either entire key list of trackerdict, or just a single value try: #TODO: check if this works - filelist = self.materialfiles + trackerdict[index]['skyfile'] + self._getradfiles(trackerdict[index]['scenes']) + filelist = self.materialfiles + [trackerdict[index]['skyfile']] + self._getradfiles(trackerdict[index]['scenes']) octname = '1axis_%s%s'%(index, customname) trackerdict[index]['octfile'] = self.makeOct(filelist, octname) except KeyError as e: @@ -2700,7 +2703,7 @@ def makeScene1axis(self, trackerdict=None, module=None, sceneDict=None, name=f"Scene{trackerdict[theta]['scenes'].__len__()}" scene.name = name trackerdict[theta]['scenes'].append(scene) - except IndexError: + except KeyError: #either KeyError or maybe IndexError? trackerdict[theta]['scenes'] = [scene] print('{} Radfiles created in /objects/'.format(trackerdict.__len__())) @@ -2751,7 +2754,7 @@ def makeScene1axis(self, trackerdict=None, module=None, sceneDict=None, name=f"Scene{trackerdict[time]['scenes'].__len__()}" scene.name = name trackerdict[time]['scenes'].append(scene) - except IndexError: + except KeyError: #either KeyError or maybe IndexError? trackerdict[time]['scenes'] = [scene] count+=1 print('{} Radfiles created in /objects/'.format(count)) @@ -2999,7 +3002,7 @@ def calculateResults(self, CECMod=None, glassglass=False, bifacialityfactor=None rearMat.append(row_mod['AnalysisObj'].rearMat) rowWanted.append(row_mod['AnalysisObj'].rowWanted) modWanted.append(row_mod['AnalysisObj'].modWanted) - sceneNum.append(row_mod['AnalysisObj'].sceneNum) + sceneNum.append(row_mod['sceneNum']) if self.cumulativesky is False: temp_air.append(trackerdict[key]['temp_air']) wind_speed.append(trackerdict[key]['wind_speed']) diff --git a/bifacial_radiance/modelchain.py b/bifacial_radiance/modelchain.py index 4b0ee3c2..236832f2 100644 --- a/bifacial_radiance/modelchain.py +++ b/bifacial_radiance/modelchain.py @@ -287,7 +287,7 @@ def _getDesiredIndex(trackerdict): df = pd.DataFrame.from_dict(trackerdict, orient='index') try: - df = df[df['scenes'][0].notna()] #TODO: select which sceneNum + df = df[df['scenes'].notna()] except KeyError: print('Error in _getDesiredIndex - trackerdict has no scene defined.') return df.index[-1] diff --git a/tests/test_bifacial_radiance.py b/tests/test_bifacial_radiance.py index c6f3e692..dbd1fdbc 100644 --- a/tests/test_bifacial_radiance.py +++ b/tests/test_bifacial_radiance.py @@ -147,8 +147,8 @@ def test_Radiance_1axis_gendaylit_modelchains(): #V 0.2.5 fixed the gcr passed to set1axis. (since gcr was not being passd to set1axis, gcr was default 0.33 default). assert(demo2.CompiledResults.Gfront_mean[0] == pytest.approx(205.0, 0.01) ) # was 214 in v0.2.3 # was 205 in early v0.2.4 assert(demo2.CompiledResults.Grear_mean[0] == pytest.approx(43.0, 0.1) ) - assert demo2.trackerdict['2001-01-01_1100']['scene'].text.__len__() == 132 - assert demo2.trackerdict['2001-01-01_1100']['scene'].text[23:28] == " 2.0 " + assert demo2.trackerdict['2001-01-01_1100']['scenes'][0].text.__len__() == 132 + assert demo2.trackerdict['2001-01-01_1100']['scenes'][0].text[23:28] == " 2.0 " demo2.exportTrackerDict(savefile = 'results\exportedTrackerDict.csv', reindex=True) """ @@ -217,7 +217,7 @@ def test_1axis_gencumSky(): # Removing all of this other tests for hub_height and height since it's ben identified that # a new module to handle hub_height and height in sceneDict needs to be implemented # instead of checking inside of makeScene, makeSceneNxR, and makeScene1axis - assert trackerdict[-5.0]['radfile'][0:7] == 'objects' # 'objects\\1axis-5.0_1.825_11.42_5.0_10x3_origin0,0.rad' + assert trackerdict[-5.0]['scenes'][0].radfiles[0:7] == 'objects' # 'objects\\1axis-5.0_1.825_11.42_5.0_10x3_origin0,0.rad' sceneDict = {'pitch': pitch,'clearance_height':hub_height, 'nMods':10, 'nRows':3} # testing height filter too trackerdict = demo.makeScene1axis(sceneDict=sceneDict, module = 'test-module') @@ -230,18 +230,20 @@ def test_1axis_gencumSky(): # assert trackerdict[-5.0]['radfile'] == 'objects\\1axis-5.0_1.825_11.42_5.0_10x3_origin0,0.rad' sceneDict = {'pitch': pitch,'height':hub_height, 'hub_height':hub_height, 'nMods':10, 'nRows':3} # testing height filter too trackerdict = demo.makeScene1axis(sceneDict=sceneDict, module = 'test-module') + assert trackerdict[-5.0]['scenes'].__len__() == 5 + demo.exportTrackerDict(trackerdict, savefile = 'results\exportedTrackerDict2.csv') - assert trackerdict[-5.0]['radfile'][0:7] == 'objects' + assert trackerdict[-5.0]['scenes'][4].radfiles[0:7] == 'objects' #assert trackerdict[-5.0]['radfile'] == 'objects\\1axis-5.0_1.825_11.42_5.0_10x3_origin0,0.rad' minitrackerdict = {} minitrackerdict[list(trackerdict)[0]] = trackerdict[list(trackerdict.keys())[0]] trackerdict = demo.makeOct1axis(trackerdict=minitrackerdict) # just run this for one timestep: Jan 1 11am - trackerdict = demo.analysis1axis(trackerdict=trackerdict, modWanted=7, rowWanted=3, sensorsy=2) + trackerdict = demo.analysis1axis(trackerdict=trackerdict, modWanted=7, rowWanted=3, sensorsy=2, sceneNum=4) assert trackerdict[-5.0]['Results'][0]['AnalysisObj'].x[0] == -10.76304 modscanfront = {} modscanfront = {'xstart': -5} - trackerdict = demo.analysis1axis(trackerdict=trackerdict, modWanted=7, rowWanted=3, sensorsy=2, modscanfront=modscanfront ) - assert trackerdict[-5.0]['Results'][0]['AnalysisObj'].x[0] == -5 + trackerdict = demo.analysis1axis(trackerdict=trackerdict, modWanted=7, rowWanted=3, sensorsy=2, modscanfront=modscanfront, sceneNum=4) + assert trackerdict[-5.0]['Results'][1]['AnalysisObj'].x[0] == -5