Skip to content

custom h5 file exceptions#577

Open
jph6366 wants to merge 1 commit into
NatLabRockies:mainfrom
jph6366:reverr_collection
Open

custom h5 file exceptions#577
jph6366 wants to merge 1 commit into
NatLabRockies:mainfrom
jph6366:reverr_collection

Conversation

@jph6366

@jph6366 jph6366 commented Apr 16, 2026

Copy link
Copy Markdown
Collaborator

custom reV errors/exceptions

<2026-04-10 Fri>

story

implement custom rev exceptions to replace base exceptions

Unused exceptions

  • SlurmWarning
  • SAMExecutionWarning
  • ExtrapolationWarning
  • NearestNeighborError
  • JSONError
Hide/Show Documented Exceptions

SAM

/SAM.py/

  • SAMExecutionError

    • _get_base_handler - get base SAM resource handler
      • raises error if module not found
    • execute - call PySAM execute method
      • raises error if execution fails for some reason
    • collect_outputs - collect SAM output_request -> convert time-series outputs to UTC -> save outputs to self.outputs
      • raises error if bad request from PySAM object
  • SAMInputWarning

    • _make_res_kwargs - make Resource.preloadSam args and kwargs
      • raise warning if downscaling is request for any resource handler that is not NSRDB
    • assign_inputs - assign a flat dict of inputs to the PySAM object
      • raise warning for inputs that are not set because they are not found in PySAM object
  • SAMInputError

    • set_item - set a PySAM input data attribute
      • raises error if attribute not found
      • catches error from setattr(getattr(self.pysam, group), key, value)
  • ResourceError

    • ensure_res_len - ensure time_index has a constant time-step and only covers 365 days (no leap days)
      • raises error if time_index does not have a consistent time-step

/econ.py/

  • SAMExecutionError
    • parse_sys_cap - find the system capacity variable in either inputs or dataframe
      • raises error uf system capacity or turbine capacity is not included in the site-specific inputs in order to calculate annual energy yield for LCOE
  • KeyError
    • _get_cf_profiles - get the multi-site capacity factor time series profiles
      • raises error if cf_profile values are not found
    • _parse_lcoe_inputs - parse for non-site-specific LCOE inputs
      • raises error if cf_mean values are not found for LCOE calculation
        /windbos.py/
  • SAMInputError
    /defaults.py/
  • NotImplementedError
    /generation.py/
  • InputError
    • multiple vals for temperature for site
    • "" potential_MW ""
    • found nan vals for site {} in vars {}
  • SAMExecutionError
  • NotImplementedError
  • ValueError
    • lat/lon exception
      /version_checker.py/
  • PySAMVersionError
  • PySAMVersionWarning

bespoke

/bespoke.py/

  • ValueError
    • Unknown dataset name
  • TypeError
    • min_spacing must be numeric
  • KeyError
    • user requested "lcoe_fcr" but did not input "fixed_charge_rate" in SAM system config
    • could not find LCOE kwargs in outputs; plant_optimizer, original_sam_sys_inputs, or meta
  • ModuleNotFoundError
  • RuntimeError
    • failed while running SAM windpower timeseries analysis
    • failed while running turbine placement optimizer
    • SC gid xxx failed
  • FileNotFoundError
    • exclusions file not found
  • FileInputError
    • techmap dataset not found in exclusions file
  • OSError
    /pack_turbs.py/
  • WhileLoopPackingError
    /place_turbines.py/
  • ValueError
    • will not eval string which contains xxx
  • WhileLoopPackingError

config

/base_config.py/

  • ConfigError
    • init_config - initialize and load config from file
      • raises error if config file does not exist or cannot be parsed
  • IOError
    • init_config - initialize and load config from file
      • raises error when config file path cannot be read

/project_points.py/

  • ConfigError
    • parse - parse project points from file or object
      • raises error when project points file type is not recognized
    • from_range - create project points from a range of gids
      • raises error if sites argument has invalid form
  • ValueError
    • parse_tech - parse the technology from the project points config
      • raises error if more than one unique technology is found in project points
  • TypeError
    • parse - parse project points from file or object
      • raises error when project points input type is not recognized
  • KeyError
    • sam_config_obj - get the SAM config object for a given gid
      • raises error if gid not found in SAM config mapping
  • RuntimeError
    • split - split project points into sub-chunks
      • raises error when project points cannot be split into the requested number of chunks

/execution.py/

  • ConfigError
    • parse_execution_control - parse execution control from config
      • raises error if required execution control parameters are missing or invalid

econ

/econ.py/

  • Exception
    • run_single_worker - run a single econ worker for a set of sites
      • raises base exception if econ_fun fails during SAM econ execution
  • ExecutionError
    • parse_output_request - parse and validate user output requests
      • raises error if none of the user output requests are recognized
    • get_data_shape - get the output data shape from SAM config
      • raises error if non-scalar site_data input key is passed as an output_request
  • ValueError
    • parse_output_request - parse and validate user output requests
      • raises error if econ outputs requested span incompatible SAM modules
  • Exception
    • run - run econ analysis for all sites
      • raises base exception if analysis sites from project points are not found in cf file
      • raises base exception if SmartParallelJob execution fails

/cli_econ.py/

  • IOError
    • parse_cf_files - parse capacity factor files for econ
      • raises error if a cf file does not exist on disk
  • ConfigError
    • parse_cf_files - parse capacity factor files for econ
      • raises error if the number of cf files does not match the number of analysis years
      • raises error if a requested analysis year cannot be found in the cf files

/economies_of_scale.py/

  • TypeError
    • preflight - run preflight checks on input data
      • raises error if data input is not a dict or DataFrame
  • KeyError
    • preflight - run preflight checks on input data
      • raises error if variables required for an equation are missing from input data
    • get_prioritized_keys - get keys from input dict by priority order
      • raises error if none of the requested keys are found in the input dict
  • ValueError
    • preflight - run preflight checks on input data
      • raises error if equation string evaluates to an invalid value

generation

/base.py/

  • Exception
    • out.setter - set site output results
      • raises base exception if site results are non-sequential
  • TypeError
    • out.setter - set site output results
      • raises error if output type is unrecognized
    • output_request_type_check - validate the output_request argument type
      • raises error if output_request is not str, list, or tuple
  • ValueError
    • handle_leap_ti - handle leap year time index by dropping Feb 29
      • raises error if time index length is not a multiple of 365
    • site_index - get or set the current site index
      • raises error if output_index is negative (site index already set)
    • patch_wave_gen_pysam_5 - patch wave generation output for PySAM 5
      • raises error if non-zero values are found at the end of the generation array
  • Exception
    • parse_site_data - parse site-specific SAM input data from csv or DataFrame
      • raises base exception if site data input is not a .csv or DataFrame
  • KeyError
    • parse_site_data - parse site-specific SAM input data from csv or DataFrame
      • raises error if gid column is missing from site data
    • get_pc - get the points control object for a given technology
      • raises error if the technology string is not recognized
  • ExecutionError
    • get_data_shape_from_sam_config - get output data shape from SAM config
      • raises error if a non-scalar SAM input key is passed as an output_request
    • get_data_shape_from_pysam - get output data shape from PySAM object
      • raises error if the requested dataset is not found in the PySAM object

/cli_gen.py/

  • ConfigError
    • parse_res_files - parse resource files from generation config
      • raises error if resource_file is not a recognized type
      • raises error if resource file count does not match the number of analysis years

/generation.py/

  • KeyError
    • init - initialize the generation object
      • raises error if the technology string is not in OPTIONS dict
  • ProjectPointsValueError
    • meta - get the resource meta data for analysis sites
      • raises error if the max site gid exceeds the resource meta data length
  • ConfigError
    • handle_lifetime_index - handle lifetime index for multi-year modeling
      • raises error if multiple analysis_periods are found in the config
      • raises error if invalid output arrays are requested alongside lifetime modeling
  • Exception
    • run_single_worker - run a single generation worker for a set of sites
      • raises base exception if cls.OPTIONS[tech].reV_run fails
    • run - run generation for all sites with parallel execution
      • raises base exception if generation execution fails
  • InputError
    • parse_gid_map - parse optional gid map to remap resource gids to supply curve gids
      • raises error if the gid_map file cannot be parsed

handlers

/exclusions.py/

  • TypeError
    • init - initialize exclusions handler
      • raises error if h5_file is not str, list, or tuple
  • MultiFileExclusionError
    • preflight_multi_file - run preflight checks for multi-file exclusions
      • raises error if a layer shape does not match lat/lon shapes
      • raises error if multi-file exclusions do not have matching coordinate profiles
  • HandlerKeyError
    • get_latitude - get latitude array from h5 file
      • raises error if latitude dataset is missing from h5 file
    • get_longitude - get longitude array from h5 file
      • raises error if longitude dataset is missing from h5 file
    • get_layer - get a single exclusion layer from h5 file
      • raises error if requested layer is not in available layers

/multi_year.py/

  • ConfigError
    • source_files (MultiYearGroup) - get list of source files for multi-year aggregation
      • raises error if source_files is not a list, tuple, or "PIPELINE"
      • raises error if neither source_files nor source_dir+source_prefix are provided
  • CollectionRuntimeError
    • source_files (MultiYearGroup) - get list of source files for multi-year aggregation
      • raises error if source_pattern glob results in non-h5 files
    • parse_source_files_pattern - parse source files from a glob pattern
      • raises error if non-h5 files are found in the pattern results
  • FileNotFoundError
    • source_files (MultiYearGroup) - get list of source files for multi-year aggregation
      • raises error if no source files are found matching the pattern
  • TypeError
    • parse_source_files_pattern - parse source files from a glob pattern
      • raises error if source_files type is not recognized
  • HandlerRuntimeError
    • copy_dset - copy a dataset across source files into multi-year output
      • raises error if meta data lengths differ across source files
    • compute_means - compute multi-year means for a dataset
      • raises error if dataset shapes do not match across source files
    • compute_stdev - compute multi-year standard deviation for a dataset
      • raises error if dataset shapes do not match across source files
  • CollectionValueError
    • is_profile - check if dataset is a time-series profile
      • raises error if requested dataset is not found in the source file
  • CollectionWarning
    • copy_dset - copy a dataset across source files into multi-year output
      • warns if coordinates do not match between collection files
    • my_collect_groups - collect all groups into a single multi-year HDF5 file
      • warns when an existing multi-year output file is found and removed (clobber)

/transmission.py/

  • HandlerKeyError
    • getitem - get feature data by gid
      • raises error if the feature gid is invalid
    • features_from_table - build features dict from a transmission table
      • raises error if feature type is not recognized
    • substation_capacity - get capacity available at a substation
      • raises error if capacities are not found for the substation
  • ValueError
    • features_from_table - build features dict from a transmission table
      • raises error if features dict input is not valid
  • RuntimeError
    • check_feature_dependencies - check that parent features exist for substations
      • raises error if parent features depend on missing transmission lines
    • connect - connect a supply curve point to a transmission feature
      • raises error if needed capacity exceeds available capacity
  • HandlerRuntimeError
    • available_capacity - get available capacity at a transmission feature
      • raises error if available capacity cannot be parsed from the feature data
  • NotImplementedError
    • POIFeatures.cost - compute connection cost for POI features
      • raises error because cost computation is not supported for POI features
    • _POIFeatures.calc_cost - internal cost calculation for POI features
      • raises error because POI cost calculation is not implemented

losses

/power_curve.py/

  • reVLossesValueError
    • _PowerCurve.validate_wind_speed - validate wind speed input array
      • raises error if wind speed contains negative values
    • _PowerCurve.validate_generation - validate generation output array
      • raises error if there are no positive generation values in the power curve
      • raises error if non-zero generation values exist above the cutoff wind speed
    • _PowerCurveLosses.validate_wind_resource - validate wind resource input
      • raises error if wind resource contains negative values
    • _PowerCurveLosses.validate_weights - validate bin weights for wind resource
      • raises error if weights size does not match wind resource size
    • _PowerCurveLossesInput.validate_required_keys_exist - validate required keys in loss spec
      • raises error if required keys are missing from the loss specification
    • _PowerCurveLossesInput.validate_transformation - validate transformation name
      • raises error if transformation name is not in TRANSFORMATIONS dict
    • _PowerCurveLossesInput.validate_percentage - validate loss percentage value
      • raises error if percentage is not in the range [0, 100]
    • PowerCurveWindResource.wind_resource_for_site - get wind resource for a single site
      • raises error if pressure units cannot be determined from dataset
    • _AbstractPowerCurveTransformation.validate_non_zero_generation - validate transformed power curve
      • raises error if the calculated power curve is invalid (all zeros or negative)
    • _AbstractPowerCurveTransformation.validate_same_cutoff - validate cutoff wind speeds match
      • raises error if cutoff wind speeds of original and transformed curves don't match
    • PowerCurveLossesMixin.wind_resource_from_input - get wind resource from user input
      • raises error if wind_resource_model_choice is incompatible with input type
  • NotImplementedError
    • AbstractPowerCurveTransformation.apply - apply the power curve transformation
      • raises error when subclass has not set _transformed_generation

/utils.py/

  • reVLossesValueError
    • validate_arrays_not_empty - validate that input data arrays are not empty
      • raises error if an input data array is empty

/scheduled.py/

  • reVLossesValueError
    • _Outage.validate_required_keys_exist - validate required keys in outage spec
      • raises error if required keys are missing from the outage specification
    • _Outage.validate_count - validate outage count value
      • raises error if count is not an integer or is less than 1
    • _Outage.validate_and_convert_to_full_name_months - validate and normalize month names
      • raises error if no recognized month names are provided
    • _Outage.validate_duration - validate outage duration value
      • raises error if duration is not an integer or is outside the valid range
    • _Outage.validate_percentage - validate outage loss percentage
      • raises error if percentage is not in the range (0, 100]

nrwal

/nrwal.py/

  • KeyError
    • parse_site_data - parse and validate site data input
      • raises error if required columns (gid, config) are missing from site_data
  • OffshoreWindInputError
    • preflight_checks - run preflight validation checks
      • raises error if config ids in site_data are missing from the NRWAL config input
      • raises error if site_meta_cols are not found in site_data
    • get_input_data - get input data arrays for NRWAL analysis
      • raises error if required NRWAL input variables are not found in gen outputs or meta
  • DataShapeError
    • get_input_data - get input data arrays for NRWAL analysis
      • raises error if data shape is not 1D or 2D
    • save_nrwal_out - save NRWAL output arrays to the output file
      • raises error if a 1D output is found to be 2D but not all-NaN
      • raises error if NRWAL output shape cannot be understood
  • TypeError
    • value_to_array - convert a NRWAL output value to a numpy array
      • raises error if a NRWAL key returns a value of an unrecognized type

qa_qc

/qa_qc.py/

  • TypeError
    • QaQcModule.init_ - initialize the QA/QC module handler
      • raises error if config input is not a dict
  • PipelineError
    • QaQcModule.fpath - get the file path for the module output
      • raises error if fpath cannot be parsed from previous pipeline jobs

rep_profiles

/rep_profiles.py/

  • FileInputError
    • _RepProfilesBase.parse_rev_summary - parse the reV summary CSV file
      • raises error if the reV summary file cannot be parsed
  • TypeError
    • _RepProfilesBase.parse_rev_summary - parse the reV summary CSV file
      • raises error if rev_summary input is not a valid dtype (str path or DataFrame)
  • KeyError
    • _RepProfilesBase.check_req_cols - check that required columns exist in the summary table
      • raises error if required column labels are not found in the rev_summary table
    • _RepProfilesBase.check_rev_gen - check that the gen file has required datasets
      • raises error if cf_dset is not in the gen file datasets
      • raises error if time_index is not in the gen file datasets
  • DataShapeError
    • _RegionRepProfile.run_rep_methods - run representative profile methods for a region
      • raises error if the weights column length doesn't match the profiles shape
  • ValueError
    • RepProfiles.init_ - initialize representative profiles
      • raises error if reg_cols is None

supply_curves

/aggregation.py/

  • RuntimeError
    • run_serial / run_parallel - run supply curve aggregation
      • raises error if aggregation fails for a supply curve point
  • SupplyCurveInputError
    • check_files - check that required input files exist
      • raises error if required exclusions or resource files are not found
  • FileInputError
    • check_files - check that required input files exist
      • raises error if techmap dataset is not found in the exclusions file
  • FileNotFoundError
    • check_files - check that required input files exist
      • raises error if the exclusions h5 file does not exist
  • EmptySupplyCurvePointError
    • run_single - run aggregation for a single supply curve point
      • raises error if no valid resource pixels are found within the supply curve cell

/sc_aggregation.py/

  • FileInputError
    • check_excl_files - check exclusion file inputs
      • raises error if the techmap dataset is not found in the exclusions file
  • TypeError
    • parse_sc_points - parse supply curve points
      • raises error if sc_points input type is not recognized
  • KeyError
    • parse_cf_dset - parse capacity factor dataset name
      • raises error if cf_dset is not found in the resource file
  • ValueError
    • check_res_file - check resource file is valid
      • raises error if resource file does not contain required datasets
  • EmptySupplyCurvePointError
    • run_single - run aggregation for a single supply curve point
      • raises error if supply curve point has no valid resource data

/supply_curve.py/

  • KeyError
    • parse_sc_points - parse supply curve points from input
      • raises error if required columns are missing from the supply curve table
  • RuntimeError
    • run - run supply curve transmission mapping
      • raises error if supply curve execution fails
  • SupplyCurveInputError
    • check_sc_table - validate the supply curve table
      • raises error if required columns are missing or invalid in the supply curve table
  • SupplyCurveError
    • full_sort - sort supply curve by LCOE with transmission costs
      • raises error if supply curve sorting fails unexpectedly

/competitive_wind_farms.py/

  • RuntimeError
    • remove_noncompetitive_wind_farms - remove wind farms that are not cost-competitive
      • raises error if the competitive wind farm removal process fails
  • ValueError
    • parse_wind_dirs - parse wind direction data for competitive analysis
      • raises error if wind direction input is invalid

/points.py/

  • IndexError
    • SupplyCurvePoint.init - initialize a supply curve point
      • raises error if the supply curve gid is out of range
  • SupplyCurveInputError
    • _SupplyCurvePoint.parse_resources - parse resource data for the point
      • raises error if required resource inputs are missing or invalid
  • EmptySupplyCurvePointError
    • _SupplyCurvePoint.check_excl - check exclusion data for the point
      • raises error if no valid (non-excluded) pixels remain in the supply curve cell
  • ValueError
    • _SupplyCurvePoint.parse_lat_lon - parse lat/lon for the supply curve point
      • raises error if latitude or longitude cannot be determined
  • DataShapeError
    • _SupplyCurvePoint.parse_data_shape - parse expected output data shape
      • raises error if resource and exclusion data shapes do not match
  • FileInputError
    • _SupplyCurvePoint.parse_techmap - parse technology mapping from exclusions file
      • raises error if techmap dataset is not found in the exclusions file
  • TypeError
    • _SupplyCurvePoint.parse_input - parse a generic input for the supply curve point
      • raises error if input type is not recognized

/exclusions.py/

  • ValueError
    • _LayerMask.parse_inclusion_weights - parse inclusion weights for a layer
      • raises error if inclusion weight values are invalid
  • ExclusionLayerError
    • LayerMask.init - initialize a layer mask
      • raises error if the layer configuration is invalid
  • KeyError
    • _ExclusionMask.get_layer - get a layer from the exclusions file
      • raises error if a requested layer is not found in the exclusions h5 file
  • SupplyCurveInputError
    • _ExclusionMaskFromDict.parse_layer - parse a single exclusion layer from dict
      • raises error if layer specification dict is invalid

/tech_mapping.py/

  • FileInputError
    • map_to_supply_curve - map resource pixels to supply curve points
      • raises error if techmap dataset is not found in the exclusions file

utilities

/curtailment.py/

  • KeyError
    • _Curtailment.parse - parse curtailment parameters from config
      • raises error if required curtailment parameter keys are missing from the config
Generated-by: Claude:claude-sonnet-4-6 [grep] [glob]

implementation

  1. Browse the different modules and note base exceptions and/or scenarios where an exception may be acceptable and valuable to users downstream
    • identify existing uses of custom exceptions and base exceptions
  2. Replace/Modify exceptions one module at a time.

testing

  • mix .txt or .csv into the glob pattern:
    MultiYear.parse_source_files_pattern("/path/to/data_*.txt")
  • A minimal reV-format h5 with meta and time_index but without the dataset you request.
    MultiYear.is_profile('test_2020.h5', 'cf_profile')
  • two h5 files with the same dataset name but different lat/lon in meta
    with MultiYear('out_my.h5', mode='a') as my:
    my.collect(['year_2020.h5', 'year_2021.h5'], 'cf_mean')
  • create a pre-existing output file at the target path
    my_collect_groups('output_my.h5', groups={...}, clobber=True)

comments

  • “User code can raise built-in exceptions. This can be used to test an exception handler or to report an error condition “just like” the situation in which the interpreter raises the same exception; but beware that there is nothing to prevent user code from raising an inappropriate error.”

  • “ It’s recommended to only subclass one exception type at a time to avoid any possible conflicts between how the bases handle the args attribute, as well as due to possible memory layout incompatibilities.”

  • Allows downstream users of reV to catch reV exceptions explicitly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant