pvrpm.core package
Subpackages
Submodules
pvrpm.core.case module
- class pvrpm.core.case.SamCase(sam_json_dir: str, config: str, num_realizations: int = 0, results_folder: Optional[str] = None)[source]
Bases:
object
SAM Case loader, verifier, and simulation
- base_case_sim() None [source]
Runs the base case simulation for this case, with no failures and optimal lifetime losses
This also sets base case output parameters of this object
- output(name: str) Union[None, float, dict, list, str] [source]
Get an output variable by string name, without specifying the module the variable resides in.
This will search all of the module’s outputs. If the value is not found in all of the modules, an AttributeError is raised.
- Parameters
name (str) – Name of the output
- Returns
The value of the output variable
- precalculate_tracker_losses()[source]
Precalculate_tracker_losses calculates an array of coefficients (one for every day of the year) that account for the “benefit” of trackers on that particular day. This is used to determine how much power is lost if a tracker fails.
- simulate(verbose: int = 0) None [source]
Executes simulations for all modules in this case.
- Parameters
verbose (int) – 0 for no log messages, 1 for simulation log messages
- value(name: str, value: Optional[Any] = None) Union[None, float, dict, list, str] [source]
Get or set by string name a module value, without specifying the module the variable resides in.
If there is no value provided, the value is returned for the variable name.
This will search the module’s data and update the variable if found. If the value is not found in all of the modules, an AttributeError is raised.
- Parameters
name (str) – Name of the value
value (Any, optional) – Value to set variable to
- Returns
Value or the variable if value is None
Note
Some modules have the same keys, this function will return the first key found in the module order specified in the configuration. Because of the way modules share data in PySAM, setting the value in the first module will propagate it to the other modules.
pvrpm.core.components module
- class pvrpm.core.components.Components(case: pvrpm.core.case.SamCase)[source]
Bases:
object
Data container for each component in the simulation, as well as component and simulation level data
- ac_availability() float [source]
Calculates the availability of AC power due to DC component outages, including inverters, disconnects, transformers, and the grid
- Returns
Decimal percentage of AC modules available
- Return type
float
- static compound_failures(function: str, parameters: dict, num_fails: int)[source]
Compounds the failures using the provided function and it’s parameters to calculate the number of days to reduce the time to detection by
- Possible functions and their parameters are:
- step: Failures follow a step function, each step reducing the detection time by a static amount
threshold (float): fraction 0 <= threshold <= 1 that signifies the amount of modules that must fail before next step is reached. So if this is 0.2, every 0.2 * total_components components that fail will reduce detection time by step
step (int): The amount of days to reduce detection time for every step. So 2 steps reduces detection time by 2 * step
- exponential: Failures compound on an exponential function
base (float): The base for the exponential function > 0
- log: Failures compound on a logorithmic function
base (float): The base for the log function > 0
- linear: Failures compound linearly
slope (float): Slope of the linear function > 0
- constant: Each failure reduces the time to detection by a static fraction constant
constant (float): fraction 0 <= frac <= 1 that specifies how much of the overall time each failure reduces. So if fraction is 0.1, a failure will reduce time to detection by “time_to_detection * 0.1”
- current_degradation() float [source]
Calculates the current module degradation, which is averaged for only operational modules, since the power production hit from degradation of non-operational modules would be double counted
- Returns
Average degradation of operational modules
- Return type
float
- dc_availability() float [source]
Calculates the availability of the DC power due to DC component outages, including modules, strings, and combiners
- Returns
Decimal percentage of available DC modules
- Return type
float
- initialize_components(component_level: str) pandas.core.frame.DataFrame [source]
Initalizes all components for the first time
- Parameters
component_level (str) – The configuration key for this component level
- Returns
A dataframe containing the initalized values for this component level
- Return type
pd.DataFrame
- Note: Individual components have these columns:
state (bool): Operational (True) or failed (False)
defective (bool): Whehter component has a defect. True means the component is also eligible for the defective failure mode
time_to_failure (float): Number of days until component fails
failure_type (str): The name of the failure type time_to_failure represents
time_to_repair (float): Number of days from failure until compoent is repaired
time_to_detection (float): Number of days until the component failure is detected and repairs start
repair_times (float): the total repair time for this repair
monitor_times (float): the total monitoring time before repairs start
time_left_on_warranty (int): Number of days left on warranty (if applicable)
cumulative_failures (int): Total number of failures for that component
cumulative_oow_failures (int): Total number of out of warranty failures (if applicable)
failure_by_type_n (int): Each failure will have its own column with the number of failures of this type
defective (bool): Whether this component is defective or not (for defective failures)
defective_failures (int): Total number of defective failures
avail_downtime (int): How many hours this component was available
degradation_factor (float): 1 - percentage component has degraded at this time (module only)
days_of_degradation (int): Time that the module has been degrading for
- snapshot()[source]
Returns the current state of the simulation including all internal dataframes, arrays, and variables for this object
- Returns
A dictionary containing the simulation snapshot data
- Return type
dict
Note
The returned objects are copies of this components objects to avoid changing data in the simulation unintentionally
- The returned dictionary has these keys and values:
module: DataFrame of simulation data for module level
string: DataFrame of simulation data for string level
combiner: DataFrame of simulation data for combiner level
inverter: DataFrame of simulation data for inverter level
disconnect: DataFrame of simulation data for disconnect level
transformer: DataFrame of simulation data for transformer level
grid: DataFrame of simulation data for grid level
tracker: DataFrame of simulation data for tracker level
misc_data: DataFrame containing costs (for each level), module degradation, dc and ac availability, and tracker loss/availability if tracking is used
- summarize_failures(component_level: str)[source]
Returns the number of failures per day for every failure defined
- Parameters
component_level (str) – The configuration key for this component level
- Returns
Dictionary containing the failure mode mapped to an np array of fails per each day
- Return type
dict
- tracker_power_loss(day: int) Tuple[float, float] [source]
Calculates the current loss factor due to failed trackers
- Parameters
day (int) – Current day in the simulation
- Returns
The fraction of trackers operational and the loss factor for failed trackers
- Return type
Tuple[float, float]
- update_fails(component_level: str, day: int)[source]
Changes state of a component to failed, incrementing failures and checking warranty only for failed components of each failure type
- Parameters
component_level (str) – The component level to check for failures
day (int) – Current day in the simulation
Note
Updates the underlying dataframes in place
- update_indep_monitor(day: int)[source]
If independent monitoring is defined, check it for the current day in simulation
- Parameters
day (int) – Current day in the simulation
- update_labor_rates(new_labor: float)[source]
Update labor rates for a all levels for all types of repairs
- Parameters
new_labor (float) – The new labor rate
- update_monitor(component_level: str, day: int)[source]
Updates time to detection from component level, static, and cross component level monitoring based on number of failures
Monitoring defined for each level is unaffected, only cross level monitoring on levels with no monitoring at that level have times updated based on failures, since monitoring defined at the component level uses the defined monitoring distribution for those components instead of the cross level monitoring
- Parameters
component_level (str) – The component level to check for monitoring
day (int) – Current day in the simulation
Note
Updates the underlying dataframes in place
- update_repairs(component_level: str, day: int)[source]
Changes the state of a component to operational once repairs are complete, only for components where the time to repair is zero
- Parameters
component_level (str) – The component level of this repair
day (int) – Current day in the simulation
Note
Updates the underlying dataframes in place
pvrpm.core.enums module
- class pvrpm.core.enums.ConfigKeys[source]
Bases:
object
- BASE = 'base'
- CAN_FAIL = 'can_fail'
- CAN_MONITOR = 'can_monitor'
- CAN_REPAIR = 'can_repair'
- COMBINER = 'combiner'
- COMBINER_PER_INVERTER = 'num_combiners_per_inverter'
- COMP_FUNC = 'compounding_function'
- COMP_MONITOR = 'component_level_monitoring'
- COMP_PARAM = 'compound_parameters'
- CONF_INTERVAL = 'conf_interval'
- CONST = 'constant'
- COST = 'cost'
- COST_PER_WATT = 'cost_per_watt'
- DAYS = 'days'
- DECAY_FRAC = 'decay_fraction'
- DEGRADE = 'degradation'
- DISCONNECT = 'disconnect'
- DIST = 'distribution'
- EXPON = 'exponential'
- FAILURE = 'failures'
- FAIL_PER_THRESH = 'failure_per_threshold'
- FAIL_THRESH = 'global_threshold'
- FRAC = 'fraction'
- GRID = 'grid'
- INDEP_MONITOR = 'indep_monitoring'
- INFLATION = 'inflation'
- INTERVAL = 'interval'
- INVERTER = 'inverter'
- INVERTER_PER_TRANS = 'num_inverters_per_transformer'
- INVERTER_SIZE = 'inverter_size'
- LABOR = 'labor_time'
- LABOR_RATE = 'present_day_labor_rate'
- LEVELS = 'levels'
- LIFETIME_YRS = 'system_lifetime_yrs'
- LINEAR = 'linear'
- LOG = 'log'
- LOGNORM = 'lognormal'
- MEAN = 'mean'
- MODULE = 'module'
- MODULES_PER_STR = 'num_modules_per_string'
- MODULE_ORDER = 'module_order'
- MONITORING = 'monitoring'
- MULTI_SUBARRAY = 'has_multiple_subarrays'
- NAME = 'name'
- NORMAL = 'normal'
- NUM_COMBINERS = 'num_combiners'
- NUM_COMPONENT = 'count'
- NUM_REALIZATION = 'num_realizations'
- NUM_TRACKERS = 'num_trackers'
- NUM_TRANSFORMERS = 'num_transformers'
- PARAM = 'parameters'
- PARTIAL_FAIL = 'concurrent_failures'
- PARTIAL_REPAIR = 'concurrent_repairs'
- REPAIR = 'repairs'
- RESULTS_FOLDER = 'results_folder'
- SHAPE = 'shape'
- SLOPE = 'slope'
- STD = 'std'
- STEP = 'step'
- STRING = 'string'
- STR_PER_COMBINER = 'num_strings_per_combiner'
- THRESH = 'threshold'
- TRACKER = 'tracker'
- TRACKING = 'is_tracking_system'
- TRANSFORMER = 'transformer'
- UNIFORM = 'uniform'
- WARRANTY = 'warranty'
- WEIBULL = 'weibull'
- WORST_TRACKER = 'use_worst_case_tracker'
- component_keys = ['module', 'string', 'combiner', 'inverter', 'disconnect', 'transformer', 'grid', 'tracker']
- compound_funcs = ['step', 'log', 'linear', 'exponential', 'constant']
- compound_keys = ['distribution', 'parameters']
- compound_levels = ['string', 'combiner', 'inverter', 'disconnect', 'transformer', 'grid']
- dists = ['normal', 'exponential', 'weibull', 'lognormal', 'uniform']
- failure_keys = ['distribution', 'parameters', 'labor_time', 'cost']
- indep_monitor_keys = ['cost', 'levels', 'labor_time']
- losses = ['annual_poa_shading_loss_percent', 'annual_poa_soiling_loss_percent', 'annual_poa_cover_loss_percent', 'annual_dc_module_loss_percent', 'annual_dc_mppt_clip_loss_percent', 'annual_dc_mismatch_loss_percent', 'annual_dc_diodes_loss_percent', 'annual_dc_wiring_loss_percent', 'annual_dc_tracking_loss_percent', 'annual_dc_nameplate_loss_percent', 'annual_dc_optimizer_loss_percent', 'annual_dc_perf_adj_loss_percent', 'annual_ac_inv_clip_loss_percent', 'annual_ac_inv_pso_loss_percent', 'annual_ac_inv_pnt_loss_percent', 'annual_ac_inv_eff_loss_percent', 'ac_loss', 'annual_transmission_loss_percent', 'annual_ac_perf_adj_loss_percent', 'annual_xfmr_loss_percent']
- monitoring_keys = ['distribution', 'parameters']
- needed_keys = ['module_order', 'num_realizations', 'num_combiners', 'num_transformers', 'num_trackers', 'results_folder', 'conf_interval', 'present_day_labor_rate', 'inflation', 'use_worst_case_tracker', 'module', 'string', 'combiner', 'inverter', 'disconnect', 'transformer', 'grid']
- partial_failure_keys = ['distribution', 'parameters', 'labor_time', 'cost']
- partial_repair_keys = ['distribution', 'parameters']
- repair_keys = ['distribution', 'parameters']
pvrpm.core.exceptions module
pvrpm.core.logger module
pvrpm.core.simulation module
- pvrpm.core.simulation.cf_interval(alpha: float, std: float, num_samples: int) float [source]
Calculates the two tails margin of error given the desired input. The margin of error is the value added and subtracted by the sample mean to obtain the confidence interval
Sample sizes less then equal to 30 use t score, greater then 30 use z score
- Parameters
alpha (float) – The significance level for the interval
std (float) – The standard deviation of the data
num_samples (int) – The number of samples in the data
- Returns
The margin of error
- Return type
float
- pvrpm.core.simulation.gen_results(case: pvrpm.core.case.SamCase, results: List[pvrpm.core.components.Components]) List[pandas.core.frame.DataFrame] [source]
Generates results for the given SAM case and list of component objects containing the results of each realization.
- Parameters
case (
SamCase
) – The loaded and verified case to use with the simulationresults (
list(Components)
) – List of component objects that contain the results for each realization
- Returns
List of dataframes containing the results.
- Return type
list(pd.DataFrame)
Note
- The order of the returned dataframes is:
Summary Results
Degradation Results
DC Power
AC Power
Yearly Costs
- pvrpm.core.simulation.graph_results(case: pvrpm.core.case.SamCase, results: List[pvrpm.core.components.Components], save_path: Optional[str] = None) None [source]
Generate graphs from a list of Component objects from each realization
- Parameters
case (
SamCase
) – The loaded and verified case to use with the simulationresults (
list(Components)
) – List of component objects that contain the results for each realizationsave_path (str, Optional) – Path to save graphs to, if provided
- pvrpm.core.simulation.pvrpm_sim(case: pvrpm.core.case.SamCase, save_results: bool = False, save_graphs: bool = False, progress_bar: bool = False, debug: int = 0, threads: int = 1) List[pvrpm.core.components.Components] [source]
Run the PVRPM simulation on a specific case. Results will be saved to the folder specified in the configuration.
- Parameters
case (
SamCase
) – The loaded and verified case to use with the simulationsave_results (bool, Optional) – Whether to save output csv results
save_graphs (bool, Optional) – Whether to save output graphs
progress_bar (bool, Optional) – Whether to display progress bar for each realization
debug (int, Optional) – Whether to save simulation state every debug days (0 to turn off)
threads (int, Optional) – Number of threads to use for paralizing realizations
- Returns
Returns the list of results Component objects for each realization
- Return type
list(Components)
- pvrpm.core.simulation.run_system_realization(case: pvrpm.core.case.SamCase, seed: bool = False, realization_num: int = 0, progress_bar: bool = False, debug: int = 0) pvrpm.core.components.Components [source]
Run a full realization for calculating costs
- Parameters
case (
SamCase
) – The loaded and verified case to use with the simulationseed (bool, Optional) – Whether to seed the random number generator, for multiprocessing
realization_num (int, Optional) – Current realization number, used for multiprocessing
progress_bar (bool, Optional) – Whether to display progress bar during the realization
debug (int, Optional) – Whether to save simulation state every debug days (0 to turn off)
- Returns
The components object which contains all the data for this realization
- Return type
Components
- pvrpm.core.simulation.simulate_day(case: pvrpm.core.case.SamCase, comp: pvrpm.core.components.Components, day: int)[source]
Updates and increments the simulation by a day, performing all neccesary component updates.
- Parameters
case (
SamCase
) – The current Sam Case of the simulationcomp (
Components
) – The components class containing all the outputs for this simulationday (int) – Current day in the simulation
pvrpm.core.utils module
- pvrpm.core.utils.component_degradation(percent_per_day: float, t: int) float [source]
Calculate the degradation of a component given the time since last replacement
- Parameters
percent_per_day (float) – The percent degradation per day of the module
t (int) – Time since the module was last replaced, or if its a new module, installed
- Returns
The performance of the module, between 0 and 1
- Return type
float
Note
This gives the overall module performance based on degradation, so if the module has degraded 2 percent so far, this function returns 0.98
- pvrpm.core.utils.filename_to_module(filename: str) object [source]
Takes the filename of an exported json file from SAM, extracts the module name, and returns a callback to that module that can be used to create an object
- Parameters
filename (str) – Filename of the exported case
- Returns
PySAM object the file represents
- Return type
PySAM
- pvrpm.core.utils.get_higher_components(top_level: str, start_level: str, case, start_level_df: Optional[pandas.core.frame.DataFrame] = None) Tuple[numpy.array, numpy.array, int] [source]
Calculates the indicies of the top level that correspond to the given level df indicies and returns the given level indicies count per top level component and the total number of start_level components per top_level component
- Parameters
top_level (str) – The string name of the component level to calculate indicies for
start_level (str) – The string name of the component level to start at
case (SamCase) – The case object for this simulation
start_level_df (
pd.DataFrame
, Optional) – The dataframe of the component level for which to find the corresponding top level indicies for
- Returns
If start_level_df is given, returns the top level indicies, the number of start_level components in start_level_df per top level index, and the total number of start_level components per top_level component. If start_level_df is None this only returns the total number of start_level components per top_level component.
- Return type
tuple(
np.array
,np.array
, int)
- pvrpm.core.utils.load_pysam_modules()[source]
Loads ALL of PySAM’s modules manually and globalizes them
This is needed because PySAM is a wrapper for the ssc and sdk of SAM, which includes dynamic modules that are not properly defined for pybind, so using pkgutil’s walk_packages function does not work (import error). Since the modules need to be loaded in order for getattr to find it, this must be done once when the program starts
- pvrpm.core.utils.sample(distribution: str, parameters: dict, num_samples: int) numpy.array [source]
Sample data from a distribution. If distribution is a supported distribution, parameters should be a dictionary with keys “mean” and “std”. Otherwise, distribution should be a scipy stats function and parameters be the kwargs for the distribution.
- Supported Distributions (only requires mean and std):
lognormal
normal
uniform (one std around mean)
weibull
exponential
- Parameters
distribution (str) – Name of the distribution function
parameters (
dict
) – Kwargs for the distribution (for a supported distribution should only be the mean and std)num_samples (int) – Number of samples to return from distribution
- Returns
obj:(list): List of floats containing samples from the distribution
- pvrpm.core.utils.summarize_dc_energy(dc_power_output: tuple, split: int) numpy.array [source]
Calculates the DC energy (kWh) based on an input array of timeseries DC power (kW) for the system lifetime (likely the ‘dc_net’ output from SAM)
Can be used to summarize similar hourly, daily data to yearly
- Parameters
dc_power_output (
tuple
) – Tuple output from SAM simulationsplit (int) – The frequency to split the data too, typically this is the number of years the system was simulated for (system_lifetime_yrs)
- Returns
Numpy array of length system_lifetime_yrs containing the yearly energy in kWh
- Return type
np.array