def test_fout(year): """Gen PV CF profiles with write to disk and compare against rev1.""" cf_file = os.path.join(TESTDATADIR, 'gen_out/gen_ri_pv_{}_x000.h5'.format(year)) sam_files = os.path.join(TESTDATADIR, 'SAM/i_lcoe_naris_pv_1axis_inv13.json') r1f = os.path.join(TESTDATADIR, 'ri_pv/scalar_outputs/project_outputs.h5') dirout = os.path.join(TESTDATADIR, 'lcoe_out') fout = 'lcoe_out_{}.h5'.format(year) fpath = os.path.join(dirout, fout) points = slice(0, 100) Econ.reV_run(points=points, sam_files=sam_files, cf_file=cf_file, year=year, output_request='lcoe_fcr', max_workers=1, sites_per_worker=25, points_range=None, fout=fout, dirout=dirout) with Outputs(fpath) as f: lcoe = f['lcoe_fcr'] with h5py.File(r1f, mode='r') as f: year_rows = {'2012': 0, '2013': 1} r1_lcoe = f['pv']['lcoefcr'][year_rows[str(year)], 0:100] * 1000 result = np.allclose(lcoe, r1_lcoe, rtol=RTOL, atol=ATOL) if PURGE_OUT: os.remove(fpath) assert result
def test_rev_run_gen_econ(points=slice(0, 10), year=2012, max_workers=1): """Test full reV2 gen->econ pipeline with windbos inputs and benchmark against baseline results.""" # get full file paths. sam_files = os.path.join(TESTDATADIR, 'SAM/i_singleowner_windbos.json') res_file = os.path.join(TESTDATADIR, 'wtk/ri_100_wtk_{}.h5'.format(year)) fn_gen = 'windbos_gen_{}.h5'.format(year) cf_file = os.path.join(OUT_DIR, fn_gen) # run reV 2.0 generation Gen.reV_run('windpower', points, sam_files, res_file, output_request=('cf_mean', 'cf_profile'), max_workers=max_workers, sites_per_worker=3, fout=fn_gen, dirout=OUT_DIR) econ_outs = ('lcoe_nom', 'lcoe_real', 'flip_actual_irr', 'project_return_aftertax_npv', 'total_installed_cost', 'turbine_cost', 'sales_tax_cost', 'bos_cost') e = Econ.reV_run(points=points, sam_files=sam_files, cf_file=cf_file, cf_year=year, site_data=None, output_request=econ_outs, max_workers=max_workers, sites_per_worker=3, fout=None) for k in econ_outs: msg = 'Failed for {}'.format(k) assert np.allclose(e.out[k], BASELINE[k], atol=ATOL, rtol=RTOL), msg if PURGE_OUT: for fn in os.listdir(OUT_DIR): os.remove(os.path.join(OUT_DIR, fn)) return e
def test_lcoe(year, max_workers, spw): """Gen PV CF profiles with write to disk and compare against rev1.""" cf_file = os.path.join(TESTDATADIR, 'gen_out/gen_ri_pv_{}_x000.h5'.format(year)) sam_files = os.path.join(TESTDATADIR, 'SAM/i_lcoe_naris_pv_1axis_inv13.json') r1f = os.path.join(TESTDATADIR, 'ri_pv/scalar_outputs/project_outputs.h5') points = slice(0, 100) obj = Econ.reV_run(points=points, sam_files=sam_files, cf_file=cf_file, cf_year=year, output_request='lcoe_fcr', max_workers=max_workers, sites_per_worker=25, points_range=None, fout=None) lcoe = list(obj.out['lcoe_fcr']) with h5py.File(r1f, mode='r') as f: year_rows = {'2012': 0, '2013': 1} r1_lcoe = f['pv']['lcoefcr'][year_rows[str(year)], 0:100] * 1000 result = np.allclose(lcoe, r1_lcoe, rtol=RTOL, atol=ATOL) assert result
def test_rev_run_bos(points=slice(0, 5), max_workers=1): """Test full reV2 gen->econ pipeline with windbos inputs and benchmark against baseline results.""" # get full file paths. sam_files = TESTDATADIR + '/SAM/i_singleowner_windbos.json' site_data = pd.DataFrame({'gid': range(5), 'sales_tax_basis': range(5)}) econ_outs = ('total_installed_cost', 'turbine_cost', 'sales_tax_cost', 'bos_cost') e = Econ.reV_run(points=points, sam_files=sam_files, cf_file=None, year=None, site_data=site_data, output_request=econ_outs, max_workers=max_workers, sites_per_worker=3, fout=None) for k in econ_outs: check = np.allclose(e.out[k], BASELINE_SITE_BOS[k], atol=ATOL, rtol=RTOL) msg = 'Failed for {}'.format(k) assert check, msg return e
def test_append_data(year): """Gen PV CF profiles with write to disk and compare against rev1.""" original_file = os.path.join(TESTDATADIR, 'gen_out/gen_ri_pv_{}_x000.h5'.format(year)) cf_file = os.path.join(TESTDATADIR, 'gen_out/copy_gen_ri_pv_{}_x000.h5'.format(year)) shutil.copy(original_file, cf_file) sam_files = os.path.join(TESTDATADIR, 'SAM/i_lcoe_naris_pv_1axis_inv13.json') r1f = os.path.join(TESTDATADIR, 'ri_pv/scalar_outputs/project_outputs.h5') points = slice(0, 100) Econ.reV_run(points=points, sam_files=sam_files, cf_file=cf_file, cf_year=year, output_request='lcoe_fcr', max_workers=1, sites_per_worker=25, points_range=None, append=True) with Outputs(cf_file) as f: new_dsets = f.dsets cf_profile = f['cf_profile'] lcoe = f['lcoe_fcr'] meta = f.meta ti = f.time_index with Outputs(original_file) as f: og_dsets = f.dsets og_profiles = f['cf_profile'] og_meta = f.meta og_ti = f.time_index with h5py.File(r1f, mode='r') as f: year_rows = {'2012': 0, '2013': 1} r1_lcoe = f['pv']['lcoefcr'][year_rows[str(year)], 0:100] * 1000 if PURGE_OUT: os.remove(cf_file) assert np.allclose(lcoe, r1_lcoe, rtol=RTOL, atol=ATOL) assert np.allclose(cf_profile, og_profiles) assert_frame_equal(meta, og_meta) assert all(ti == og_ti) assert all([d in new_dsets for d in og_dsets])
def test_append_multi_node(node): """Test econ multi node with append flag ON using a real reV run from 8/17/2020""" original_file = os.path.join( TESTDATADIR, 'gen_out/pv_atb20_gen_1998_node0{}.h5'.format(node)) cf_file = os.path.join( TESTDATADIR, 'gen_out/copy_pv_atb20_gen_1998_node0{}.h5'.format(node)) shutil.copy(original_file, cf_file) sam_files = {'default': os.path.join( TESTDATADIR, 'SAM/pv_tracking_atb2020.json')} year = 1998 points = os.path.join( TESTDATADIR, 'config/nsrdb_projpoints_atb2020_capcostmults_subset.csv') site_data = os.path.join( TESTDATADIR, 'config/nsrdb_sitedata_atb2020_capcostmults_subset.csv') econ = Econ.reV_run(points=points, sam_files=sam_files, cf_file=cf_file, year=year, output_request=('lcoe_fcr', 'capital_cost'), max_workers=1, sites_per_worker=25, points_range=None, append=True, site_data=site_data) with Outputs(original_file) as out: data_baseline = out['lcoe_fcr'] with Outputs(cf_file) as out: meta = out.meta data_test = out['lcoe_fcr'] test_cap_cost = out['capital_cost'] if PURGE_OUT: os.remove(cf_file) assert np.allclose(data_baseline, data_test) site_data = pd.read_csv(site_data) sd_cap_cost = site_data.loc[site_data.gid.isin(meta.gid), 'capital_cost'] assert np.allclose(test_cap_cost, sd_cap_cost) assert np.allclose(econ.out['capital_cost'], sd_cap_cost)
def test_single_owner(): """Gen PV CF profiles with write to disk and compare against rev1.""" cf_file = os.path.join(TESTDATADIR, 'gen_out/wind_2012_x000.h5') sam_files = os.path.join(TESTDATADIR, 'SAM/wind_single_owner.json') output_request = ('ppa_price', 'project_return_aftertax_npv', 'lcoe_nom', 'lcoe_real', 'size_of_equity', 'wacc') obj = Econ.reV_run(points=slice(0, 10), sam_files=sam_files, cf_file=cf_file, cf_year=2012, output_request=output_request, max_workers=1, sites_per_worker=10, points_range=None, fout=None) for k, v in obj.out.items(): msg = 'Array for "{}" is bad!'.format(k) result = np.allclose(v, OUT_BASELINE[k], rtol=RTOL, atol=ATOL) assert result, msg return obj.out
def local(ctx, max_workers, timeout, points_range, verbose): """Run econ on local worker(s).""" name = ctx.obj['NAME'] points = ctx.obj['POINTS'] sam_files = ctx.obj['SAM_FILES'] cf_file = ctx.obj['CF_FILE'] cf_year = ctx.obj['CF_YEAR'] site_data = ctx.obj['SITE_DATA'] sites_per_worker = ctx.obj['SITES_PER_WORKER'] fout = ctx.obj['FOUT'] dirout = ctx.obj['DIROUT'] logdir = ctx.obj['LOGDIR'] output_request = ctx.obj['OUTPUT_REQUEST'] append = ctx.obj['APPEND'] verbose = any([verbose, ctx.obj['VERBOSE']]) if append: fout = os.path.basename(cf_file) dirout = os.path.dirname(cf_file) # initialize loggers for multiple modules log_modules = [ __name__, 'reV.econ.econ', 'reV.generation', 'reV.config', 'reV.utilities', 'reV.SAM', 'reV.handlers', 'rex.utilities' ] init_mult(name, logdir, modules=log_modules, verbose=verbose, node=True) for key, val in ctx.obj.items(): logger.debug('ctx var passed to local method: "{}" : "{}" with type ' '"{}"'.format(key, val, type(val))) logger.info( 'Econ local is being run with with job name "{}" and ' 'generation results file: {}. Target output path is: {}'.format( name, cf_file, os.path.join(dirout, fout))) t0 = time.time() # Execute the Generation module with smart data flushing. Econ.reV_run(points=points, sam_files=sam_files, cf_file=cf_file, cf_year=cf_year, site_data=site_data, output_request=output_request, max_workers=max_workers, timeout=timeout, sites_per_worker=sites_per_worker, points_range=points_range, fout=fout, dirout=dirout, append=append) tmp_str = ' with points range {}'.format(points_range) runtime = (time.time() - t0) / 60 logger.info('Econ compute complete for project points "{0}"{1}. ' 'Time elapsed: {2:.2f} min. Target output dir: {3}'.format( points, tmp_str if points_range else '', runtime, dirout)) # add job to reV status file. status = { 'dirout': dirout, 'fout': fout, 'job_status': 'successful', 'runtime': runtime, 'finput': cf_file } Status.make_job_file(dirout, 'econ', name, status)