Skip to content

Commit e157096

Browse files
committed
Add spectrum integration function, updated weather file handling
1 parent e92a29a commit e157096

2 files changed

Lines changed: 122 additions & 13 deletions

File tree

bifacial_radiance/main.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,7 @@ def readWeatherFile(self, weatherFile=None, starttime=None,
987987
coerce_year=coerce_year, label=label,
988988
tz_convert_val=tz_convert_val)
989989

990-
return self.metdata
990+
return self.metdata, metadata
991991

992992

993993
def readWeatherData(self, metadata, metdata, starttime=None,
@@ -3244,10 +3244,41 @@ def generate_spectral_tmys(self, wavelengths, weather_file, location_name, spect
32443244
output_folder = os.path.join('data','spectral_tmys')
32453245
if not os.path.exists(output_folder):
32463246
os.makedirs(output_folder, exist_ok=True)
3247+
3248+
metdata, metadata = self.readWeatherFile(weatherFile=weather_file)
32473249

32483250
su.generate_spectral_tmys(wavelengths=wavelengths, spectra_folder=spectra_folder,
3249-
weather_file=weather_file, location_name=location_name,
3251+
metdata=self.metdata, location_name=location_name,
32503252
output_folder=output_folder)
3253+
3254+
def integrated_spectrum(self,weather_file, spectra_folder):
3255+
"""
3256+
Generate integrated sum of spectrum from SMARTS generated spectra for use in normalization equations
3257+
3258+
Paramters:
3259+
----------
3260+
weather_file: (path or str)
3261+
File path or path-like string pointing to the weather file used for spectra generation.
3262+
The structure of this file, and it's meta-data, will be copied into the new files.
3263+
spectra_folder: (path or str)
3264+
File path or path-like string pointing to the folder contained the SMARTS generated spectra
3265+
3266+
Returns:
3267+
--------
3268+
spectrum: dict
3269+
Dictionary with the integrated spectrum sums for DNI, DHI, DNI-albedo product, and DHI-albedo-product
3270+
"""
3271+
from bifacial_radiance import spectral_utils as su
3272+
3273+
if spectra_folder is None:
3274+
spectra_folder = 'spectra'
3275+
3276+
metdata, metadata = self.readWeatherFile(weatherFile=weather_file)
3277+
3278+
spectrum = su.integrated_spectrum(spectra_folder=spectra_folder,
3279+
metdata=self.metdata)
3280+
return spectrum
3281+
32513282

32523283
# End RadianceObj definition
32533284

bifacial_radiance/spectral_utils.py

Lines changed: 89 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from scipy import integrate
66
from tqdm import tqdm
77
from pvlib import iotools
8+
from bifacial_radiance import main as main
89

910

1011
class spectral_property(object):
@@ -244,8 +245,8 @@ def generate_spectra(metdata, simulation_path, ground_material='Gravel', spectra
244245
Parameters
245246
----------
246247
metdata : bifacial_radiance MetObj
247-
DESCRIPTION.
248-
simulation_path: bifacial_radiance MetObj
248+
MetObj containing weather data, with a datetime index.
249+
simulation_path: string or path
249250
path of simulation directory
250251
ground_material : string, optional
251252
type of ground material for spectral simulation. Options include:
@@ -389,7 +390,7 @@ def generate_spectra(metdata, simulation_path, ground_material='Gravel', spectra
389390

390391
return (spectral_alb, spectral_dni, spectral_dhi, None)
391392

392-
def generate_spectral_tmys(wavelengths, spectra_folder, weather_file, location_name, output_folder):
393+
def generate_spectral_tmys(wavelengths, spectra_folder, metdata, location_name, output_folder):
393394
"""
394395
Generate a series of TMY-like files with per-wavelength irradiance. There will be one file per
395396
wavelength. These are necessary to run a spectral simulation with gencumsky
@@ -400,8 +401,8 @@ def generate_spectral_tmys(wavelengths, spectra_folder, weather_file, location_n
400401
array or list of integer wavelengths to simulate, in units [nm]. example: [300,325,350]
401402
spectra_folder: (path or str)
402403
File path or path-like string pointing to the folder contained the SMARTS generated spectra
403-
weather_file: (path or str)
404-
File path or path-like string pointing to the weather file used for spectra generation
404+
metdata: pandas DataFrame
405+
DataFrame containing the weather data, with a datetime index.
405406
location_name:
406407
_description_
407408
output_folder:
@@ -413,8 +414,10 @@ def generate_spectral_tmys(wavelengths, spectra_folder, weather_file, location_n
413414
spectra_files.sort()
414415

415416
# -- read in the weather file and format
416-
(tmydata, metdata) = iotools.read_tmy3(weather_file, coerce_year=2021)
417-
tmydata.index = tmydata.index+pd.Timedelta(hours=1)
417+
#(tmydata, metdata) = main.RadianceObj.readWeatherFile(weatherFile=weather_file, coerce_year=2021)
418+
#(tmydata, metdata) = iotools.read_tmy3(weather_file, coerce_year=2021)
419+
tmydata = metdata.tmydata.copy()
420+
#tmydata.index = tmydata.index+pd.Timedelta(hours=1)
418421
tmydata.rename(columns={'dni':'DNI',
419422
'dhi':'DHI',
420423
'temp_air':'DryBulb',
@@ -426,8 +429,9 @@ def generate_spectral_tmys(wavelengths, spectra_folder, weather_file, location_n
426429
dtindex = tmydata.index
427430

428431
# -- grab the weather file header to reproduce location meta-data
429-
with open(weather_file, 'r') as wf:
430-
header = wf.readline()
432+
# with open(weather_file, 'r') as wf:
433+
# header = wf.readline()
434+
header = metdata.metadata.copy()
431435

432436
# -- read in a spectra file to copy wavelength-index
433437
temp = pd.read_csv(os.path.join(spectra_folder,spectra_files[0]), header=1, index_col = 0)
@@ -476,8 +480,82 @@ def generate_spectral_tmys(wavelengths, spectra_folder, weather_file, location_n
476480
wave_df.loc[col[0],col[1]] = spectra_df[col].loc[wave]
477481

478482
with open(fileName, 'w', newline='') as ict:
479-
for line in header:
480-
ict.write(line)
483+
# for line in header:
484+
# ict.write(line)
481485
wave_df.to_csv(ict, index=False)
482486

487+
488+
def integrated_spectrum(spectra_folder, metdata ):
489+
"""
490+
Generate integrated sums across the full spectra
491+
492+
Paramters:
493+
----------
494+
spectra_folder: (path or str)
495+
File path or path-like string pointing to the folder contained the SMARTS generated spectra
496+
metdata: pandas DataFrame
497+
DataFrame containing the weather data, with a datetime index.
498+
499+
500+
Returns:
501+
-------
502+
integrated_sums: (list)
503+
list of integrated sums for DNI, DHI, DNI*ALB, DHI*ALB
504+
"""
505+
506+
# -- read in the spectra files
507+
spectra_files = next(os.walk(spectra_folder))[2]
508+
spectra_files.sort()
509+
510+
# -- read in the weather file and format
511+
#(tmydata, metdata) = main.RadianceObj.readWeatherFile(weatherFile=weather_file, coerce_year=2021)
512+
#(tmydata, metdata) = iotools.read_tmy3(weather_file, coerce_year=2021)
513+
tmydata = metdata.tmydata.copy()
514+
#tmydata.index = tmydata.index+pd.Timedelta(hours=1)
515+
tmydata.rename(columns={'dni':'DNI',
516+
'dhi':'DHI',
517+
'temp_air':'DryBulb',
518+
'wind_speed':'Wspd',
519+
'ghi':'GHI',
520+
'relative_humidity':'RH',
521+
'albedo':'Alb'
522+
}, inplace=True)
523+
dtindex = tmydata.index
524+
525+
# -- grab the weather file header to reproduce location meta-data
526+
# with open(weather_file, 'r') as wf:
527+
# header = wf.readline()
528+
header = metdata.metadata.copy()
529+
530+
# -- read in a spectra file to copy wavelength-index
531+
temp = pd.read_csv(os.path.join(spectra_folder,spectra_files[0]), header=1, index_col = 0)
532+
533+
# -- copy and reproduce the datetime index
534+
dates = []
535+
for file in spectra_files:
536+
take = file[4:-4]
537+
if take not in dates:
538+
dates.append(take)
539+
dates = pd.to_datetime(dates,format='%y_%m_%d_%H').tz_localize(dtindex.tz)
540+
541+
# -- create a multi-index of columns [timeindex:alb,dni,dhi,ghi]
542+
iterables = [dates,['ALB','DHI','DNI','GHI']]
543+
multi_index = pd.MultiIndex.from_product(iterables, names=['time_index','irr_type'])
544+
545+
# -- create empty dataframe
546+
spectra_df = pd.DataFrame(index=temp.index,columns=multi_index)
547+
# -- fill with irradiance data
548+
for file in spectra_files:
549+
a = pd.to_datetime(file[4:-4],format='%y_%m_%d_%H').tz_localize(dtindex.tz)
550+
b = file[:3].upper()
551+
spectra_df[a,b] = pd.read_csv(os.path.join(spectra_folder,file),header=1, index_col=0)
552+
integrated_sums = pd.DataFrame(index=dates, columns=['Sum_DNI', 'Sum_DHI', 'Sum_DNI_ALB', 'Sum_DHI_ALB'])
553+
for col in spectra_df.columns:
554+
integrated_sums.loc[col[0], 'Sum_DNI'] = integrate.trapezoid(spectra_df[col[0], 'DNI'], spectra_df.index)
555+
integrated_sums.loc[col[0], 'Sum_DHI'] = integrate.trapezoid(spectra_df[col[0], 'DHI'], spectra_df.index)
556+
integrated_sums.loc[col[0], 'Sum_DNI_ALB'] = integrate.trapezoid(spectra_df[col[0], 'DNI'] * spectra_df[col[0], 'ALB'], spectra_df.index)
557+
integrated_sums.loc[col[0], 'Sum_DHI_ALB'] = integrate.trapezoid(spectra_df[col[0], 'DHI'] * spectra_df[col[0], 'ALB'], spectra_df.index)
558+
559+
return integrated_sums
560+
483561

0 commit comments

Comments
 (0)