def get_node_pc(points, sam_files, nodes): """Get a PointsControl object to be send to HPC nodes. Parameters ---------- points : slice | str | list | tuple Slice/list specifying project points, string pointing to a project points csv. sam_files : dict | str | list SAM input configuration ID(s) and file path(s). Keys are the SAM config ID(s), top level value is the SAM path. Can also be a single config file str. If it's a list, it is mapped to the sorted list of unique configs requested by points csv. nodes : int Number of nodes that the PointsControl object is being split to. Returns ------- pc : reV.config.project_points.PointsControl PointsControl object to be iterated and send to HPC nodes. """ if isinstance(points, (str, slice, list, tuple)): # create points control via points pp = ProjectPoints(points, sam_files, tech=None) sites_per_node = ceil(len(pp) / nodes) pc = PointsControl(pp, sites_per_split=sites_per_node) else: raise TypeError('Econ Points input type is unrecognized: ' '"{}"'.format(type(points))) return pc
def parse_points_control(self): """Get the generation points control object. Returns ------- points_control : reV.config.project_points.PointsControl PointsControl object based on specified project points and execution control option. """ if self._pc is None: # make an instance of project points pp = ProjectPoints(self.project_points, self['sam_files'], tech=self.technology) if (self.execution_control.option == 'peregrine' or self.execution_control.option == 'eagle'): # sites per split on peregrine or eagle is the number of sites # in project points / number of nodes. This is for the initial # division of the project sites between HPC nodes (jobs) sites_per_worker = ceil(len(pp) / self.execution_control.nodes) elif self.execution_control.option == 'local': # sites per split on local is number of sites / # of processes sites_per_worker = ceil( len(pp) / self.execution_control.max_workers) # make an instance of points control and set to protected attribute self._pc = PointsControl(pp, sites_per_split=sites_per_worker) return self._pc
def test_sam_config_kw_replace(): """Test that the SAM config with old keys from pysam v1 gets updated on the fly and gets propogated to downstream splits.""" fpp = os.path.join(TESTDATADIR, 'project_points/pp_offshore.csv') sam_files = {'onshore': os.path.join( TESTDATADIR, 'SAM/wind_gen_standard_losses_0.json'), 'offshore': os.path.join( TESTDATADIR, 'SAM/wind_gen_standard_losses_1.json')} res_file = os.path.join(TESTDATADIR, 'wtk/ri_100_wtk_2012.h5') pp = ProjectPoints(fpp, sam_files, 'windpower') pc = PointsControl(pp, sites_per_split=100) gen = Gen(pc, res_file) config_on = gen.project_points.sam_configs['onshore'] config_of = gen.project_points.sam_configs['offshore'] assert 'turb_generic_loss' in config_on assert 'turb_generic_loss' in config_of pp_split = ProjectPoints.split(0, 10000, gen.project_points) config_on = pp_split.sam_configs['onshore'] config_of = pp_split.sam_configs['offshore'] assert 'turb_generic_loss' in config_on assert 'turb_generic_loss' in config_of pc_split = PointsControl.split(0, 10000, gen.project_points) config_on = pc_split.project_points.sam_configs['onshore'] config_of = pc_split.project_points.sam_configs['offshore'] assert 'turb_generic_loss' in config_on assert 'turb_generic_loss' in config_of for ipc in pc_split: if 'onshore' in ipc.project_points.sam_configs: config = ipc.project_points.sam_configs['onshore'] assert 'turb_generic_loss' in config if 'offshore' in ipc.project_points.sam_configs: config = ipc.project_points.sam_configs['offshore'] assert 'turb_generic_loss' in config
def test_config_mapping(): """Test the mapping of multiple configs in the project points.""" fpp = os.path.join(TESTDATADIR, 'project_points/pp_offshore.csv') sam_files = {'onshore': os.path.join( TESTDATADIR, 'SAM/wind_gen_standard_losses_0.json'), 'offshore': os.path.join( TESTDATADIR, 'SAM/wind_gen_standard_losses_1.json')} df = pd.read_csv(fpp, index_col=0) pp = ProjectPoints(fpp, sam_files, 'windpower') pc = PointsControl(pp, sites_per_split=100) for i, pc_split in enumerate(pc): for site in pc_split.sites: cid = pc_split.project_points[site][0] assert cid == df.loc[site].values[0]
def test_proj_control_iter(start, interval): """Test the iteration of the points control.""" n = 3 res_file = os.path.join(TESTDATADIR, 'wtk/ri_100_wtk_2012.h5') sam_files = os.path.join(TESTDATADIR, 'SAM/wind_gen_standard_losses_0.json') pp = ProjectPoints(slice(start, 100, interval), sam_files, 'windpower', res_file=res_file) pc = PointsControl(pp, sites_per_split=n) for i, pp_split in enumerate(pc): i0_nom = i * n i1_nom = i * n + n split = pp_split.project_points.df target = pp.df.iloc[i0_nom:i1_nom, :] msg = 'PointsControl iterator split did not function correctly!' assert all(split == target), msg
def test_split_iter(): """Test Points_Control on two slices of ProjectPoints""" res_file = os.path.join(TESTDATADIR, 'wtk/ri_100_wtk_2012.h5') sam_files = os.path.join(TESTDATADIR, 'SAM/wind_gen_standard_losses_0.json') pp = ProjectPoints(slice(0, 500, 5), sam_files, 'windpower', res_file=res_file) n = 3 for s, e in [(0, 50), (50, 100)]: pc = PointsControl.split(s, e, pp, sites_per_split=n) for i, pp_split in enumerate(pc): i0_nom = s + i * n i1_nom = s + i * n + n if i1_nom >= e: i1_nom = e split = pp_split.project_points.df target = pp.df.iloc[i0_nom:i1_nom] msg = 'PointsControl iterator split did not function correctly!' assert split.equals(target), msg
def _econ_append_pc(pp, cf_file, sites_per_worker=None): """ Generate ProjectControls for econ append Parameters ---------- pp : reV.config.project_points.ProjectPoints ProjectPoints to adjust gids for cf_file : str reV generation capacity factor output file with path. sites_per_worker : int Number of sites to run in series on a worker. None defaults to the resource file chunk size. Returns ------- pc : reV.config.project_points.PointsControl PointsControl object instance. """ multi_h5_res, hsds = check_res_file(cf_file) if multi_h5_res: res_cls = MultiFileResource res_kwargs = {} else: res_cls = Resource res_kwargs = {'hsds': hsds} with res_cls(cf_file, **res_kwargs) as f: gid0 = f.meta['gid'].values[0] gid1 = f.meta['gid'].values[-1] i0 = pp.index(gid0) i1 = pp.index(gid1) + 1 pc = PointsControl.split(i0, i1, pp, sites_per_split=sites_per_worker) return pc
def _pp_to_pc(points, points_range, sam_files, tech, sites_per_worker=None, res_file=None, curtailment=None): """ Create ProjectControl from ProjectPoints Parameters ---------- points : slice | list | str | reV.config.project_points.PointsControl Slice specifying project points, or string pointing to a project points csv, or a fully instantiated PointsControl object. points_range : list | None Optional two-entry list specifying the index range of the sites to analyze. To be taken from the reV.config.PointsControl.split_range property. sam_files : dict | str | list | SAMConfig SAM input configuration ID(s) and file path(s). Keys are the SAM config ID(s), top level value is the SAM path. Can also be a single config file str. If it's a list, it is mapped to the sorted list of unique configs requested by points csv. Can also be a pre loaded SAMConfig object. tech : str SAM technology to analyze (pvwattsv7, windpower, tcsmoltensalt, solarwaterheat, troughphysicalheat, lineardirectsteam) The string should be lower-cased with spaces and _ removed. sites_per_worker : int Number of sites to run in series on a worker. None defaults to the resource file chunk size. res_file : str Filepath to single resource file, multi-h5 directory, or /h5_dir/prefix*suffix curtailment : NoneType | dict | str | config.curtailment.Curtailment Inputs for curtailment parameters. If not None, curtailment inputs are expected. Can be: - Explicit namespace of curtailment variables (dict) - Pointer to curtailment config json file with path (str) - Instance of curtailment config object (config.curtailment.Curtailment) Returns ------- pc : reV.config.project_points.PointsControl PointsControl object instance. """ if not isinstance(points, ProjectPoints): # make Project Points instance pp = ProjectPoints(points, sam_files, tech=tech, res_file=res_file, curtailment=curtailment) else: pp = ProjectPoints(points.df, sam_files, tech=tech, res_file=res_file, curtailment=curtailment) # make Points Control instance if points_range is not None: # PointsControl is for just a subset of the project points... # this is the case if generation is being initialized on one # of many HPC nodes in a large project pc = PointsControl.split(points_range[0], points_range[1], pp, sites_per_split=sites_per_worker) else: # PointsControl is for all of the project points pc = PointsControl(pp, sites_per_split=sites_per_worker) return pc