bifacial-radiance 0.5.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bifacial_radiance/HPCScripts/BasicSimulations/addNewModule.py +15 -0
- bifacial_radiance/HPCScripts/BasicSimulations/dask_on_node.sh +11 -0
- bifacial_radiance/HPCScripts/BasicSimulations/run_sbatch.sbatch +51 -0
- bifacial_radiance/HPCScripts/BasicSimulations/simulate_fixedtilt_gencumsky.py +110 -0
- bifacial_radiance/HPCScripts/BasicSimulations/simulate_fixedtilt_gendaylit.py +102 -0
- bifacial_radiance/HPCScripts/BasicSimulations/simulate_tracking_gendaylit.py +126 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/PuertoRico.py +168 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/PuertoRico_2.py +166 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/PuertoRico_Original.py +195 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/basic_module_sampling.py +154 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_B.py +162 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_Cases.py +122 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_CasesMonth.py +142 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_PRNew.py +91 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_PRNewP2.py +95 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_TreeResults.py +108 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/compile_basic_module_sampling.py +103 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/simulate_JackHourly.py +160 -0
- bifacial_radiance/HPCScripts/Other Examples (unorganized)/simulate_improvedArray_Oct2127.py +623 -0
- bifacial_radiance/TEMP/.gitignore +4 -0
- bifacial_radiance/__init__.py +24 -0
- bifacial_radiance/data/CEC Modules.csv +16860 -0
- bifacial_radiance/data/default.ini +65 -0
- bifacial_radiance/data/falsecolor.exe +0 -0
- bifacial_radiance/data/gencumsky/License.txt +54 -0
- bifacial_radiance/data/gencumsky/Makefile +17 -0
- bifacial_radiance/data/gencumsky/README.txt +9 -0
- bifacial_radiance/data/gencumsky/Solar Irradiation Modelling.doc +0 -0
- bifacial_radiance/data/gencumsky/Sun.cpp +118 -0
- bifacial_radiance/data/gencumsky/Sun.h +45 -0
- bifacial_radiance/data/gencumsky/average_val.awk +3 -0
- bifacial_radiance/data/gencumsky/cPerezSkyModel.cpp +238 -0
- bifacial_radiance/data/gencumsky/cPerezSkyModel.h +57 -0
- bifacial_radiance/data/gencumsky/cSkyVault.cpp +536 -0
- bifacial_radiance/data/gencumsky/cSkyVault.h +86 -0
- bifacial_radiance/data/gencumsky/climateFile.cpp +312 -0
- bifacial_radiance/data/gencumsky/climateFile.h +37 -0
- bifacial_radiance/data/gencumsky/cumulative.cal +177 -0
- bifacial_radiance/data/gencumsky/cumulative.rad +14 -0
- bifacial_radiance/data/gencumsky/cumulativesky_rotated.rad +2 -0
- bifacial_radiance/data/gencumsky/gencumulativesky +0 -0
- bifacial_radiance/data/gencumsky/gencumulativesky.cpp +269 -0
- bifacial_radiance/data/gencumsky/make_gencumskyexe.py +107 -0
- bifacial_radiance/data/gencumsky/paths.h +62 -0
- bifacial_radiance/data/gencumulativesky +0 -0
- bifacial_radiance/data/gencumulativesky.exe +0 -0
- bifacial_radiance/data/ground.rad +83 -0
- bifacial_radiance/data/module.json +103 -0
- bifacial_radiance/gui.py +1696 -0
- bifacial_radiance/images/fig1_fixed_small.gif +0 -0
- bifacial_radiance/images/fig2_tracked_small.gif +0 -0
- bifacial_radiance/load.py +1156 -0
- bifacial_radiance/main.py +5673 -0
- bifacial_radiance/mismatch.py +461 -0
- bifacial_radiance/modelchain.py +299 -0
- bifacial_radiance/module.py +1427 -0
- bifacial_radiance/performance.py +466 -0
- bifacial_radiance/spectral_utils.py +555 -0
- bifacial_radiance-0.5.1.dist-info/METADATA +129 -0
- bifacial_radiance-0.5.1.dist-info/RECORD +63 -0
- bifacial_radiance-0.5.1.dist-info/WHEEL +6 -0
- bifacial_radiance-0.5.1.dist-info/licenses/LICENSE +30 -0
- bifacial_radiance-0.5.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Tue Mar 26 20:16:47 2019
|
|
4
|
+
|
|
5
|
+
@author: sayala
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from deprecated import deprecated
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _sensorupsampletocellsbyInterpolation(df, cellsy):
|
|
13
|
+
'''
|
|
14
|
+
|
|
15
|
+
Function for when sensorsy in the results are less than cellsy desired.
|
|
16
|
+
Interpolates the dataframe.
|
|
17
|
+
|
|
18
|
+
#2DO: improve interpolation with pandas. right onw it's row by row.
|
|
19
|
+
|
|
20
|
+
_sensorupsampletocellsbyInterpolation(df, cellsy)
|
|
21
|
+
'''
|
|
22
|
+
|
|
23
|
+
import pandas as pd
|
|
24
|
+
import numpy as np
|
|
25
|
+
|
|
26
|
+
sensorsy = len(df)
|
|
27
|
+
|
|
28
|
+
#2DO: Update this section to match bifacialvf
|
|
29
|
+
cellCenterPVM=[]
|
|
30
|
+
for i in range (0, cellsy):
|
|
31
|
+
cellCenterPVM.append((i*sensorsy/cellsy+(i+1)*sensorsy/cellsy)/2)
|
|
32
|
+
|
|
33
|
+
df2 = pd.DataFrame()
|
|
34
|
+
for j in range (0, len(df.keys())):
|
|
35
|
+
A = list(df[df.keys()[j]])
|
|
36
|
+
B= np.interp(cellCenterPVM, list(range(0,sensorsy)), A)
|
|
37
|
+
df2[df.keys()[j]]=B
|
|
38
|
+
|
|
39
|
+
return df2
|
|
40
|
+
|
|
41
|
+
def _sensorsdownsampletocellsbyAverage(df, cellsy):
|
|
42
|
+
'''
|
|
43
|
+
df = dataframe with rows indexed by number (i.e. 0 to sensorsy) where sensorsy > cellsy
|
|
44
|
+
cellsy = int. usually 8 or 12.
|
|
45
|
+
|
|
46
|
+
example:
|
|
47
|
+
F_centeraverages = _sensorsdownsampletocellsbyAverage(F, cellsy)
|
|
48
|
+
'''
|
|
49
|
+
import numpy as np
|
|
50
|
+
import pandas as pd
|
|
51
|
+
|
|
52
|
+
edges=len(df)-np.floor(len(df)/(cellsy))*(cellsy)
|
|
53
|
+
edge1=int(np.floor(edges/2))
|
|
54
|
+
edge2=int(edges-edge1)
|
|
55
|
+
A = list(range(df.index[0]+edge1, df.index[-1]-edge2+2, int(np.floor(len(df)/(cellsy)))))
|
|
56
|
+
B = range(0,len(A)-1,1)
|
|
57
|
+
C = [df.iloc[A[x]:A[x+1]].mean(axis=0) for x in B]
|
|
58
|
+
df_centeraverages=pd.DataFrame(C)
|
|
59
|
+
|
|
60
|
+
return df_centeraverages
|
|
61
|
+
|
|
62
|
+
def _sensorsdownsampletocellbyCenter(df, cellsy):
|
|
63
|
+
'''
|
|
64
|
+
df = dataframe with rows indexed by number (i.e. 0 to sensorsy) where sensorsy > cellsy
|
|
65
|
+
cellsy = int. usually 8 or 12.
|
|
66
|
+
|
|
67
|
+
example:
|
|
68
|
+
F_centervalues = _sensorsdownsampletocellbyCenter(F, cellsy)
|
|
69
|
+
'''
|
|
70
|
+
|
|
71
|
+
import numpy as np
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
edges=len(df)-np.floor(len(df)/(cellsy))*(cellsy)
|
|
75
|
+
edge1=int(np.floor(edges/2))
|
|
76
|
+
edge2=int(edges-edge1)
|
|
77
|
+
A = list(range(df.index[0]+edge1, df.index[-1]-edge2+2, int(np.floor(len(df)/(cellsy)))))
|
|
78
|
+
A = [int(x+(A[1]-A[0])*0.5) for x in A]
|
|
79
|
+
A = A[:-1]
|
|
80
|
+
df_centervalues=df.loc[A]
|
|
81
|
+
df_centervalues=df_centervalues.reset_index(drop=True)
|
|
82
|
+
|
|
83
|
+
return df_centervalues
|
|
84
|
+
|
|
85
|
+
def _setupforPVMismatch(portraitorlandscape, sensorsy, numcells=72):
|
|
86
|
+
r''' Sets values for calling PVMismatch, for ladscape or portrait modes and
|
|
87
|
+
|
|
88
|
+
Example:
|
|
89
|
+
stdpl, cellsx, cellsy = _setupforPVMismatch(portraitorlandscape='portrait', sensorsy=100):
|
|
90
|
+
'''
|
|
91
|
+
|
|
92
|
+
import numpy as np
|
|
93
|
+
|
|
94
|
+
# cell placement for 'portrait'.
|
|
95
|
+
if numcells == 72:
|
|
96
|
+
stdpl=np.array([[0, 23, 24, 47, 48, 71],
|
|
97
|
+
[1, 22, 25, 46, 49, 70],
|
|
98
|
+
[2, 21, 26, 45, 50, 69],
|
|
99
|
+
[3, 20, 27, 44, 51, 68],
|
|
100
|
+
[4, 19, 28, 43, 52, 67],
|
|
101
|
+
[5, 18, 29, 42, 53, 66],
|
|
102
|
+
[6, 17, 30, 41, 54, 65],
|
|
103
|
+
[7, 16, 31, 40, 55, 64],
|
|
104
|
+
[8, 15, 32, 39, 56, 63],
|
|
105
|
+
[9, 14, 33, 38, 57, 62],
|
|
106
|
+
[10, 13, 34, 37, 58, 61],
|
|
107
|
+
[11, 12, 35, 36, 59, 60]])
|
|
108
|
+
|
|
109
|
+
elif numcells == 96:
|
|
110
|
+
stdpl=np.array([[0, 23, 24, 47, 48, 71, 72, 95],
|
|
111
|
+
[1, 22, 25, 46, 49, 70, 73, 94],
|
|
112
|
+
[2, 21, 26, 45, 50, 69, 74, 93],
|
|
113
|
+
[3, 20, 27, 44, 51, 68, 75, 92],
|
|
114
|
+
[4, 19, 28, 43, 52, 67, 76, 91],
|
|
115
|
+
[5, 18, 29, 42, 53, 66, 77, 90],
|
|
116
|
+
[6, 17, 30, 41, 54, 65, 78, 89],
|
|
117
|
+
[7, 16, 31, 40, 55, 64, 79, 88],
|
|
118
|
+
[8, 15, 32, 39, 56, 63, 80, 87],
|
|
119
|
+
[9, 14, 33, 38, 57, 62, 81, 86],
|
|
120
|
+
[10, 13, 34, 37, 58, 61, 82, 85],
|
|
121
|
+
[11, 12, 35, 36, 59, 60, 83, 84]])
|
|
122
|
+
else:
|
|
123
|
+
print("Error. Only 72 and 96 cells modules supported at the moment. Change numcells to either of this options!")
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
if portraitorlandscape == 'landscape':
|
|
127
|
+
stdpl = stdpl.transpose()
|
|
128
|
+
elif portraitorlandscape != 'portrait':
|
|
129
|
+
print("Error. portraitorlandscape variable must either be 'landscape' or 'portrait'")
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
cellsx = len(stdpl[1]); cellsy = len(stdpl)
|
|
133
|
+
|
|
134
|
+
return stdpl, cellsx, cellsy
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def calculatePVMismatch(pvsys, stdpl, cellsx, cellsy, Gpoat):
|
|
138
|
+
r''' calls PVMismatch with all the pre-generated values on bifacial_radiance
|
|
139
|
+
|
|
140
|
+
Example:
|
|
141
|
+
PowerAveraged, PowerDetailed = def calculatePVMismatch(pvsys, stdpl, cellsx, cellsy, Gpoat)
|
|
142
|
+
|
|
143
|
+
'''
|
|
144
|
+
|
|
145
|
+
import numpy as np
|
|
146
|
+
|
|
147
|
+
if np.mean(Gpoat) < 0.001:
|
|
148
|
+
PowerAveraged = 0
|
|
149
|
+
PowerDetailed = 0
|
|
150
|
+
else:
|
|
151
|
+
# makes the system # 1 module, in portrait mode.
|
|
152
|
+
G=np.array([Gpoat]).transpose()
|
|
153
|
+
H = np.ones([1,cellsx])
|
|
154
|
+
array_det = np.dot(G,H)
|
|
155
|
+
array_avg = np.ones([cellsy,cellsx])*np.mean(Gpoat)
|
|
156
|
+
|
|
157
|
+
# ACtually do calculations
|
|
158
|
+
pvsys.setSuns({0: {0: [array_avg, stdpl]}})
|
|
159
|
+
PowerAveraged=pvsys.Pmp
|
|
160
|
+
|
|
161
|
+
pvsys.setSuns({0: {0: [array_det, stdpl]}})
|
|
162
|
+
PowerDetailed=pvsys.Pmp
|
|
163
|
+
|
|
164
|
+
return PowerAveraged, PowerDetailed
|
|
165
|
+
|
|
166
|
+
def mismatch_fit3(data):
|
|
167
|
+
'''
|
|
168
|
+
Electrical mismatch calculation following Progress in PV paper
|
|
169
|
+
Estimating and parameterizing mismatch power loss in bifacial photovoltaic systems
|
|
170
|
+
Chris Deline, Silvana Ayala Pelaez,Sara MacAlpine,Carlos Olalla
|
|
171
|
+
https://doi.org/10.1002/pip.3259
|
|
172
|
+
|
|
173
|
+
.. deprecated:: 0.4.3
|
|
174
|
+
This fitted model is deprecated in favor of :func:`mismatch_fit2` which has
|
|
175
|
+
better agreement with the experimental data.
|
|
176
|
+
|
|
177
|
+
Parameters
|
|
178
|
+
----------
|
|
179
|
+
data : np.ndarray, pd.Series, pd.DataFrame
|
|
180
|
+
Gtotal irradiance measurements. Each column is the irradiance for a module
|
|
181
|
+
at a specific time.
|
|
182
|
+
|
|
183
|
+
Returns
|
|
184
|
+
-------
|
|
185
|
+
fit3 : Float or pd.Series
|
|
186
|
+
Returns mismatch values for each module in percentage [%].
|
|
187
|
+
|
|
188
|
+
Equation: 1/(n^2*Gavg)*Sum Sum (abs(G_i - G_j))
|
|
189
|
+
## Note: starting with Pandas 1.0.0 this function will not work on Series objects.
|
|
190
|
+
'''
|
|
191
|
+
import numpy as np
|
|
192
|
+
import pandas as pd
|
|
193
|
+
|
|
194
|
+
if type(data) == np.ndarray:
|
|
195
|
+
data = pd.DataFrame(data)
|
|
196
|
+
|
|
197
|
+
datac = data[~np.isnan(data)]
|
|
198
|
+
mad = mad_fn(datac) # (percentage)
|
|
199
|
+
mad2 = mad**2
|
|
200
|
+
|
|
201
|
+
fit3 = 0.054*mad + 0.068*mad2
|
|
202
|
+
|
|
203
|
+
if fit3.__len__() == 1:
|
|
204
|
+
if isinstance(fit3, pd.Series):
|
|
205
|
+
fit3 = float(fit3.iloc[0])
|
|
206
|
+
else:
|
|
207
|
+
fit3 = float(fit3)
|
|
208
|
+
|
|
209
|
+
return fit3
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def mismatch_fit2(data):
|
|
213
|
+
'''
|
|
214
|
+
Electrical mismatch calculation following Progress in PV paper
|
|
215
|
+
Estimating and parameterizing mismatch power loss in bifacial photovoltaic systems
|
|
216
|
+
Chris Deline, Silvana Ayala Pelaez,Sara MacAlpine,Carlos Olalla
|
|
217
|
+
https://doi.org/10.1002/pip.3259
|
|
218
|
+
|
|
219
|
+
Parameters
|
|
220
|
+
----------
|
|
221
|
+
data : np.ndarray, pd.Series, pd.DataFrame
|
|
222
|
+
Gtotal irradiance measurements. Each column is the irradiance for a module
|
|
223
|
+
at a specific time.
|
|
224
|
+
|
|
225
|
+
Returns
|
|
226
|
+
-------
|
|
227
|
+
fit2 : Float or pd.Series
|
|
228
|
+
Returns mismatch values for each module in percentage [%].
|
|
229
|
+
|
|
230
|
+
Equation: 1/(n^2*Gavg)*Sum Sum (abs(G_i - G_j))
|
|
231
|
+
## Note: starting with Pandas 1.0.0 this function will not work on Series objects.
|
|
232
|
+
'''
|
|
233
|
+
import numpy as np
|
|
234
|
+
import pandas as pd
|
|
235
|
+
|
|
236
|
+
if type(data) == np.ndarray:
|
|
237
|
+
data = pd.DataFrame(data)
|
|
238
|
+
|
|
239
|
+
datac = data[~np.isnan(data)]
|
|
240
|
+
mad = mad_fn(datac) # (percentage)
|
|
241
|
+
mad2 = mad**2
|
|
242
|
+
|
|
243
|
+
fit2 = 0.142*mad + 0.032*mad2
|
|
244
|
+
|
|
245
|
+
if fit2.__len__() == 1:
|
|
246
|
+
if isinstance(fit2, pd.Series):
|
|
247
|
+
fit2 = float(fit2.iloc[0])
|
|
248
|
+
else:
|
|
249
|
+
fit2 = float(fit2)
|
|
250
|
+
|
|
251
|
+
return fit2
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def mad_fn(data, axis='index'):
|
|
255
|
+
'''
|
|
256
|
+
Mean average deviation calculation for mismatch purposes.
|
|
257
|
+
|
|
258
|
+
Parameters
|
|
259
|
+
----------
|
|
260
|
+
data : np.ndarray or pd.Series or pd.DataFrame
|
|
261
|
+
Gtotal irradiance measurements. If data is a pandas.DataFrame, one
|
|
262
|
+
MAD/Average is returned for each index, based on values across columns.
|
|
263
|
+
|
|
264
|
+
axis : {0 or 'index', 1 or 'columns'}, default 'index'
|
|
265
|
+
Calculate mean average deviation across rows (default) or columns for 2D data
|
|
266
|
+
|
|
267
|
+
* 0, or 'index' : MAD calculated across rows.
|
|
268
|
+
* 1, or 'columns' : MAD calculated across columns.
|
|
269
|
+
Returns
|
|
270
|
+
-------
|
|
271
|
+
scalar or pd.Series: return MAD / Average [%]. Scalar for a 1D array, Series for 2D.
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
Equation: 1/(n^2*Gavg)*Sum Sum (abs(G_i - G_j)) * 100[%]
|
|
275
|
+
|
|
276
|
+
'''
|
|
277
|
+
import numpy as np
|
|
278
|
+
import pandas as pd
|
|
279
|
+
def _mad_1D(data): #1D calculation of MAD
|
|
280
|
+
return (np.abs(np.subtract.outer(data,data)).sum()/float(data.__len__())**2 / np.mean(data))*100
|
|
281
|
+
if type(axis) == str:
|
|
282
|
+
try:
|
|
283
|
+
axis = {"index": 0, "rows": 0, 'columns':1}[axis]
|
|
284
|
+
except KeyError:
|
|
285
|
+
raise Exception('Incorrect index string in mad_fn. options: index, rows, columns.')
|
|
286
|
+
|
|
287
|
+
ndim = data.ndim
|
|
288
|
+
if ndim == 2 and axis==0:
|
|
289
|
+
data = data.T
|
|
290
|
+
# Pandas returns a notimplemented error if this is a DataFrame.
|
|
291
|
+
if (type(data) == pd.Series):
|
|
292
|
+
data = data.to_numpy()
|
|
293
|
+
|
|
294
|
+
if type(data) == pd.DataFrame:
|
|
295
|
+
temp = data.apply(pd.Series.to_numpy, axis=1)
|
|
296
|
+
return(temp.apply(_mad_1D))
|
|
297
|
+
elif ndim ==2: #2D array
|
|
298
|
+
return [_mad_1D(i) for i in data]
|
|
299
|
+
else:
|
|
300
|
+
return _mad_1D(data)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
@deprecated(reason='This analysis script will be moved to its own tutorial' +\
|
|
304
|
+
' file in a future release.', version='0.5.0')
|
|
305
|
+
def analysisIrradianceandPowerMismatch(testfolder, writefiletitle, portraitorlandscape, bififactor, numcells=72, downsamplingmethod='byCenter'):
|
|
306
|
+
r'''
|
|
307
|
+
Use this when sensorsy calculated with bifacial_radiance > cellsy
|
|
308
|
+
|
|
309
|
+
Reads and calculates power output and mismatch for each file in the
|
|
310
|
+
testfolder where all the bifacial_radiance irradiance results .csv are saved.
|
|
311
|
+
First load each file, cleans it and resamples it to the numsensors set in this function,
|
|
312
|
+
and then calculates irradiance mismatch and PVMismatch power output for averaged, minimum,
|
|
313
|
+
or detailed irradiances on each cell for the cases of A) only 12 or 8 downsmaples values are
|
|
314
|
+
considered (at the center of each cell), and B) 12 or 8 values are obtained from averaging
|
|
315
|
+
all the irradiances falling in the area of the cell (No edges or inter-cell spacing are considered
|
|
316
|
+
at this moment). Then it saves all the A and B irradiances, as well as the cleaned/resampled
|
|
317
|
+
front and rear irradiances.
|
|
318
|
+
|
|
319
|
+
Ideally sensorsy in the read data is >> 12 to give results for the irradiance mismatch in the cell.
|
|
320
|
+
|
|
321
|
+
Also ideally n
|
|
322
|
+
|
|
323
|
+
Parameters
|
|
324
|
+
----------
|
|
325
|
+
testfolder: folder containing output .csv files for bifacial_radiance
|
|
326
|
+
writefiletitle: .csv title where the output results will be saved.
|
|
327
|
+
portraitorlandscape: 'portrait' or 'landscape', for PVMismatch input
|
|
328
|
+
which defines the electrical interconnects inside the module.
|
|
329
|
+
bififactor: bifaciality factor of the module. Max 1.0. ALL Rear irradiance values saved include the bifi-factor.
|
|
330
|
+
downsampling method: 1 - 'byCenter' - 2 - 'byAverage'
|
|
331
|
+
|
|
332
|
+
Example:
|
|
333
|
+
|
|
334
|
+
# User information.
|
|
335
|
+
import bifacial_radiance
|
|
336
|
+
testfolder=r'C:\Users\sayala\Documents\HPC_Scratch\EUPVSEC\HPC Tracking Results\RICHMOND\Bifacial_Radiance Results\PVPMC_0\results'
|
|
337
|
+
writefiletitle= r'C:\Users\sayala\Documents\HPC_Scratch\EUPVSEC\HPC Tracking Results\RICHMOND\Bifacial_Radiance Results\PVPMC_0\test_df.csv'
|
|
338
|
+
sensorsy=100
|
|
339
|
+
portraitorlandscape = 'portrait'
|
|
340
|
+
analysis.analysisIrradianceandPowerMismatch(testfolder, writefiletitle, portraitorlandscape, bififactor=1.0, numcells=72)
|
|
341
|
+
|
|
342
|
+
'''
|
|
343
|
+
from bifacial_radiance import load
|
|
344
|
+
import os, glob
|
|
345
|
+
import pandas as pd
|
|
346
|
+
|
|
347
|
+
# Default variables
|
|
348
|
+
numpanels=1 # 1 at the moment, necessary for the cleaning routine.
|
|
349
|
+
automatic=True
|
|
350
|
+
|
|
351
|
+
#loadandclean
|
|
352
|
+
# testfolder = r'C:\Users\sayala\Documents\HPC_Scratch\EUPVSEC\PinPV_Bifacial_Radiance_Runs\HPCResults\df4_FixedTilt\FixedTilt_Cairo_C_0.15\results'
|
|
353
|
+
filelist = sorted(os.listdir(testfolder))
|
|
354
|
+
#filelist = sorted(glob.glob(os.path.join('testfolder','*.csv')))
|
|
355
|
+
print('{} files in the directory'.format(filelist.__len__()))
|
|
356
|
+
|
|
357
|
+
# Check number of sensors on data.
|
|
358
|
+
temp = load.read1Result(os.path.join(testfolder,filelist[0]))
|
|
359
|
+
sensorsy = len(temp)
|
|
360
|
+
|
|
361
|
+
# Setup PVMismatch parameters
|
|
362
|
+
stdpl, cellsx, cellsy = _setupforPVMismatch(portraitorlandscape=portraitorlandscape, sensorsy=sensorsy, numcells=numcells)
|
|
363
|
+
|
|
364
|
+
F=pd.DataFrame()
|
|
365
|
+
B=pd.DataFrame()
|
|
366
|
+
for z in range(0, filelist.__len__()):
|
|
367
|
+
data=load.read1Result(os.path.join(testfolder,filelist[z]))
|
|
368
|
+
[frontres, backres] = load.deepcleanResult(data, sensorsy=sensorsy, numpanels=numpanels, automatic=automatic)
|
|
369
|
+
F[filelist[z]]=frontres
|
|
370
|
+
B[filelist[z]]=backres
|
|
371
|
+
|
|
372
|
+
B = B*bififactor
|
|
373
|
+
# Downsample routines:
|
|
374
|
+
if sensorsy > cellsy:
|
|
375
|
+
if downsamplingmethod == 'byCenter':
|
|
376
|
+
print("Sensors y > cellsy; Downsampling data by finding CellCenter method")
|
|
377
|
+
F = _sensorsdownsampletocellbyCenter(F, cellsy)
|
|
378
|
+
B = _sensorsdownsampletocellbyCenter(B, cellsy)
|
|
379
|
+
elif downsamplingmethod == 'byAverage':
|
|
380
|
+
print("Sensors y > cellsy; Downsampling data by Averaging data into Cells method")
|
|
381
|
+
F = _sensorsdownsampletocellsbyAverage(F, cellsy)
|
|
382
|
+
B = _sensorsdownsampletocellsbyAverage(B, cellsy)
|
|
383
|
+
else:
|
|
384
|
+
print ("Sensors y > cellsy for your module. Select a proper downsampling method ('byCenter', or 'byAverage')")
|
|
385
|
+
return
|
|
386
|
+
elif sensorsy < cellsy:
|
|
387
|
+
print("Sensors y < cellsy; Upsampling data by Interpolation")
|
|
388
|
+
F = _sensorupsampletocellsbyInterpolation(F, cellsy)
|
|
389
|
+
B = _sensorupsampletocellsbyInterpolation(B, cellsy)
|
|
390
|
+
elif sensorsy == cellsy:
|
|
391
|
+
print ("Same number of sensorsy and cellsy for your module.")
|
|
392
|
+
F = F
|
|
393
|
+
B = B
|
|
394
|
+
|
|
395
|
+
# Calculate POATs
|
|
396
|
+
Poat = F+B
|
|
397
|
+
|
|
398
|
+
# Define arrays to fill in:
|
|
399
|
+
Pavg_all=[]; Pdet_all=[]
|
|
400
|
+
Pavg_front_all=[]; Pdet_front_all=[]
|
|
401
|
+
colkeys = F.keys()
|
|
402
|
+
|
|
403
|
+
import pvmismatch
|
|
404
|
+
|
|
405
|
+
if cellsx*cellsy == 72:
|
|
406
|
+
cell_pos = pvmismatch.pvmismatch_lib.pvmodule.STD72
|
|
407
|
+
elif cellsx*cellsy == 96:
|
|
408
|
+
cell_pos = pvmismatch.pvmismatch_lib.pvmodule.STD96
|
|
409
|
+
else:
|
|
410
|
+
print("Error. Only 72 and 96 cells modules supported at the moment. Change numcells to either of this options!")
|
|
411
|
+
return
|
|
412
|
+
|
|
413
|
+
pvmod=pvmismatch.pvmismatch_lib.pvmodule.PVmodule(cell_pos=cell_pos)
|
|
414
|
+
pvsys = pvmismatch.pvsystem.PVsystem(numberStrs=1, numberMods=1, pvmods=pvmod)
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
# Calculate powers for each hour:
|
|
418
|
+
for i in range(0,len(colkeys)):
|
|
419
|
+
Pavg, Pdet = calculatePVMismatch(pvsys = pvsys, stdpl=stdpl, cellsx=cellsx, cellsy=cellsy, Gpoat=list(Poat[colkeys[i]]/1000))
|
|
420
|
+
Pavg_front, Pdet_front = calculatePVMismatch(pvsys = pvsys, stdpl = stdpl, cellsx = cellsx, cellsy = cellsy, Gpoat= list(F[colkeys[i]]/1000))
|
|
421
|
+
Pavg_all.append(Pavg)
|
|
422
|
+
Pdet_all.append(Pdet)
|
|
423
|
+
Pavg_front_all.append(Pavg_front)
|
|
424
|
+
Pdet_front_all.append(Pdet_front)
|
|
425
|
+
|
|
426
|
+
## Rename Rows and save dataframe and outputs.
|
|
427
|
+
F.index='FrontIrradiance_cell_'+F.index.astype(str)
|
|
428
|
+
B.index='BackIrradiance_cell_'+B.index.astype(str)
|
|
429
|
+
Poat.index='POAT_Irradiance_cell_'+Poat.index.astype(str)
|
|
430
|
+
|
|
431
|
+
# Statistics Calculatoins
|
|
432
|
+
dfst=pd.DataFrame()
|
|
433
|
+
dfst['MAD/G_Total'] = mad_fn(Poat)
|
|
434
|
+
dfst['Front_MAD/G_Total'] = mad_fn(F)
|
|
435
|
+
dfst['MAD/G_Total**2'] = dfst['MAD/G_Total']**2
|
|
436
|
+
dfst['Front_MAD/G_Total**2'] = dfst['Front_MAD/G_Total']**2
|
|
437
|
+
dfst['poat'] = Poat.mean()
|
|
438
|
+
dfst['gfront'] = F.mean()
|
|
439
|
+
dfst['grear'] = B.mean()
|
|
440
|
+
dfst['bifi_ratio'] = dfst['grear']/dfst['gfront']
|
|
441
|
+
dfst['stdev'] = Poat.std()/ dfst['poat']
|
|
442
|
+
dfst.index=Poat.columns.astype(str)
|
|
443
|
+
|
|
444
|
+
# Power Calculations/Saving
|
|
445
|
+
Pout=pd.DataFrame()
|
|
446
|
+
Pout['Pavg']=Pavg_all
|
|
447
|
+
Pout['Pdet']=Pdet_all
|
|
448
|
+
Pout['Front_Pavg']=Pavg_front_all
|
|
449
|
+
Pout['Front_Pdet']=Pdet_front_all
|
|
450
|
+
Pout['Mismatch_rel'] = 100-(Pout['Pdet']*100/Pout['Pavg'])
|
|
451
|
+
Pout['Front_Mismatch_rel'] = 100-(Pout['Front_Pdet']*100/Pout['Front_Pavg'])
|
|
452
|
+
Pout.index=Poat.columns.astype(str)
|
|
453
|
+
|
|
454
|
+
## Save CSV as one long row
|
|
455
|
+
df_all = pd.concat([Pout, dfst, Poat.T, F.T, B.T], axis=1)
|
|
456
|
+
df_all.to_csv(writefiletitle)
|
|
457
|
+
print("Saved Results to ", writefiletitle)
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
|