NREL-erad 0.0.0a0__py3-none-any.whl → 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. erad/__init__.py +1 -0
  2. erad/constants.py +20 -20
  3. erad/cypher_queries/load_data_v1.cypher +211 -211
  4. erad/data/World_Earthquakes_1960_2016.csv +23410 -23410
  5. erad/db/assets/critical_infras.py +170 -170
  6. erad/db/assets/distribution_lines.py +101 -101
  7. erad/db/credential_model.py +20 -20
  8. erad/db/disaster_input_model.py +23 -23
  9. erad/db/inject_earthquake.py +52 -52
  10. erad/db/inject_flooding.py +53 -53
  11. erad/db/neo4j_.py +162 -162
  12. erad/db/utils.py +13 -13
  13. erad/exceptions.py +68 -68
  14. erad/metrics/check_microgrid.py +208 -208
  15. erad/metrics/metric.py +178 -178
  16. erad/programs/backup.py +61 -61
  17. erad/programs/microgrid.py +44 -44
  18. erad/scenarios/abstract_scenario.py +102 -102
  19. erad/scenarios/common.py +92 -92
  20. erad/scenarios/earthquake_scenario.py +161 -161
  21. erad/scenarios/fire_scenario.py +160 -160
  22. erad/scenarios/flood_scenario.py +493 -493
  23. erad/scenarios/flows.csv +671 -0
  24. erad/scenarios/utilities.py +75 -75
  25. erad/scenarios/wind_scenario.py +89 -89
  26. erad/utils/ditto_utils.py +252 -252
  27. erad/utils/hifld_utils.py +147 -147
  28. erad/utils/opendss_utils.py +357 -357
  29. erad/utils/overpass.py +76 -76
  30. erad/utils/util.py +178 -178
  31. erad/visualization/plot_graph.py +218 -218
  32. {NREL_erad-0.0.0a0.dist-info → nrel_erad-1.0.0.dist-info}/METADATA +65 -61
  33. nrel_erad-1.0.0.dist-info/RECORD +42 -0
  34. {NREL_erad-0.0.0a0.dist-info → nrel_erad-1.0.0.dist-info}/WHEEL +1 -2
  35. {NREL_erad-0.0.0a0.dist-info → nrel_erad-1.0.0.dist-info/licenses}/LICENSE.txt +28 -28
  36. NREL_erad-0.0.0a0.dist-info/RECORD +0 -42
  37. NREL_erad-0.0.0a0.dist-info/top_level.txt +0 -1
@@ -1,103 +1,103 @@
1
- """ Module contains the base class defination for all scenarios.
2
-
3
- Each scenario type will extend the base class to implement a given scenario
4
- """
5
-
6
-
7
- from shapely.geometry import MultiPolygon, Polygon, LineString, Point
8
- from datetime import datetime
9
- from typing import *
10
- import shapely
11
-
12
- from erad.scenarios.common import AssetTypes
13
-
14
- class BaseScenario:
15
-
16
- """Base class for scenario defination.
17
-
18
- Attributes:
19
- geodata (MultiPolygon, Point, LineString): Region of interest
20
- probability_model (dict): Dictionary mapping asset types to probability funcitons
21
- timestamp (datetime): Scenario occurance time
22
- kwargs (dict): Additional parameters relevant for a particular scenario type
23
-
24
- """
25
-
26
- def __init__(self, geodata : Union[MultiPolygon, Point, LineString] , probability_model : dict, timestamp : datetime, **kwargs) -> None:
27
- """Constructor for BaseScenario class.
28
-
29
- Args:
30
- geodata (MultiPolygon, Point, LineString): Region of interest
31
- probability_model (dict): Dictionary mapping asset types to probability funcitons
32
- timestamp (datetime): Scenario occurance time
33
- kwargs (dict): Additional parameters relevant for a particular scenario type
34
- """
35
- if probability_model is None:
36
- probability_model = self.fragility_curves
37
- self.valitate_user_defined_fragility_curves(probability_model)
38
-
39
-
40
- if isinstance(geodata, Polygon):
41
- geodata = MultiPolygon([geodata])
42
-
43
- if isinstance(geodata, MultiPolygon):
44
- print("Is multipolygon")
45
- self.multipolygon = geodata
46
- elif isinstance(geodata, Point):
47
- print("Is point")
48
- self.origin = geodata
49
- elif isinstance(geodata, LineString):
50
- print("Is linestring")
51
- self.front = geodata
52
- else:
53
- print(geodata, Point)
54
- raise Exception(f"Invalid data type {type(geodata)}")
55
-
56
- self.probability_model = probability_model
57
- self.to_projection = f"epsg:{self.identify_stateplane_projection}"
58
- self.timestamp = timestamp
59
- return
60
-
61
- @property
62
- def area(self) -> float:
63
- """Method to calculate area of affected region."""
64
- raise NotImplementedError("Method needs to be defined in derived classes")
65
-
66
- @property
67
- def polygon(self) -> MultiPolygon:
68
- """Method to return polygon for the affected region."""
69
- raise NotImplementedError("Method needs to be defined in derived classes")
70
-
71
- @property
72
- def boundary(self) -> LineString:
73
- """Method to return boundary for the affected region."""
74
- raise NotImplementedError("Method needs to be defined in derived classes")
75
-
76
- @property
77
- def centroid(self) -> Point:
78
- """Method to return the centroid of the affected region."""
79
- raise NotImplementedError("Method needs to be defined in derived classes")
80
-
81
- def increment_time(self) -> dict:
82
- """Method to increment simulation time for time evolviong scenarios."""
83
- raise NotImplementedError("Method needs to be defined in derived classes")
84
-
85
- def calculate_survival_probability(self, assets : dict, timestamp : datetime) -> dict:
86
- """Method to calculate survival probaility of asset types.
87
-
88
- Args:
89
- assets (dict): The dictionary of all assets and their corresponding asset types
90
- """
91
- raise NotImplementedError("Method needs to be defined in derived classes")
92
-
93
- def plot(self):
94
- """Method to plot survival probaility of in the region of interest"""
95
- raise NotImplementedError("Method needs to be defined in derived classes")
96
-
97
- def asset_survial_probability(self, asset_type):
98
- raise NotImplementedError("Method needs to be defined in derived classes")
99
-
100
- def valitate_user_defined_fragility_curves(self, distributions):
101
- for asset_type in distributions:
102
- assert AssetTypes.has_asset(asset_type), f"{asset_type} is not a valid asset type. Valid options are {list(AssetTypes.__members__.keys())}"
1
+ """ Module contains the base class defination for all scenarios.
2
+
3
+ Each scenario type will extend the base class to implement a given scenario
4
+ """
5
+
6
+
7
+ from shapely.geometry import MultiPolygon, Polygon, LineString, Point
8
+ from datetime import datetime
9
+ from typing import *
10
+ import shapely
11
+
12
+ from erad.scenarios.common import AssetTypes
13
+
14
+ class BaseScenario:
15
+
16
+ """Base class for scenario defination.
17
+
18
+ Attributes:
19
+ geodata (MultiPolygon, Point, LineString): Region of interest
20
+ probability_model (dict): Dictionary mapping asset types to probability funcitons
21
+ timestamp (datetime): Scenario occurance time
22
+ kwargs (dict): Additional parameters relevant for a particular scenario type
23
+
24
+ """
25
+
26
+ def __init__(self, geodata : Union[MultiPolygon, Point, LineString] , probability_model : dict, timestamp : datetime, **kwargs) -> None:
27
+ """Constructor for BaseScenario class.
28
+
29
+ Args:
30
+ geodata (MultiPolygon, Point, LineString): Region of interest
31
+ probability_model (dict): Dictionary mapping asset types to probability funcitons
32
+ timestamp (datetime): Scenario occurance time
33
+ kwargs (dict): Additional parameters relevant for a particular scenario type
34
+ """
35
+ if probability_model is None:
36
+ probability_model = self.fragility_curves
37
+ self.valitate_user_defined_fragility_curves(probability_model)
38
+
39
+
40
+ if isinstance(geodata, Polygon):
41
+ geodata = MultiPolygon([geodata])
42
+
43
+ if isinstance(geodata, MultiPolygon):
44
+ print("Is multipolygon")
45
+ self.multipolygon = geodata
46
+ elif isinstance(geodata, Point):
47
+ print("Is point")
48
+ self.origin = geodata
49
+ elif isinstance(geodata, LineString):
50
+ print("Is linestring")
51
+ self.front = geodata
52
+ else:
53
+ print(geodata, Point)
54
+ raise Exception(f"Invalid data type {type(geodata)}")
55
+
56
+ self.probability_model = probability_model
57
+ self.to_projection = f"epsg:{self.identify_stateplane_projection}"
58
+ self.timestamp = timestamp
59
+ return
60
+
61
+ @property
62
+ def area(self) -> float:
63
+ """Method to calculate area of affected region."""
64
+ raise NotImplementedError("Method needs to be defined in derived classes")
65
+
66
+ @property
67
+ def polygon(self) -> MultiPolygon:
68
+ """Method to return polygon for the affected region."""
69
+ raise NotImplementedError("Method needs to be defined in derived classes")
70
+
71
+ @property
72
+ def boundary(self) -> LineString:
73
+ """Method to return boundary for the affected region."""
74
+ raise NotImplementedError("Method needs to be defined in derived classes")
75
+
76
+ @property
77
+ def centroid(self) -> Point:
78
+ """Method to return the centroid of the affected region."""
79
+ raise NotImplementedError("Method needs to be defined in derived classes")
80
+
81
+ def increment_time(self) -> dict:
82
+ """Method to increment simulation time for time evolviong scenarios."""
83
+ raise NotImplementedError("Method needs to be defined in derived classes")
84
+
85
+ def calculate_survival_probability(self, assets : dict, timestamp : datetime) -> dict:
86
+ """Method to calculate survival probaility of asset types.
87
+
88
+ Args:
89
+ assets (dict): The dictionary of all assets and their corresponding asset types
90
+ """
91
+ raise NotImplementedError("Method needs to be defined in derived classes")
92
+
93
+ def plot(self):
94
+ """Method to plot survival probaility of in the region of interest"""
95
+ raise NotImplementedError("Method needs to be defined in derived classes")
96
+
97
+ def asset_survial_probability(self, asset_type):
98
+ raise NotImplementedError("Method needs to be defined in derived classes")
99
+
100
+ def valitate_user_defined_fragility_curves(self, distributions):
101
+ for asset_type in distributions:
102
+ assert AssetTypes.has_asset(asset_type), f"{asset_type} is not a valid asset type. Valid options are {list(AssetTypes.__members__.keys())}"
103
103
  return
erad/scenarios/common.py CHANGED
@@ -1,93 +1,93 @@
1
- from shapely.geometry import MultiPolygon, Point,Polygon
2
- from random import random,seed
3
- from enum import IntEnum
4
- import numpy as np
5
-
6
- class ScenarioTypes(IntEnum):
7
- flood_m = 0
8
- wind_m_per_s = 1
9
- fire_m = 2
10
- earthquake_pga = 3
11
-
12
- class AssetTypes(IntEnum):
13
- substation = 0
14
- solar_panels = 1
15
- buried_lines = 2
16
- wind_turbines= 3
17
- battery_storage = 4
18
- transmission_poles = 5
19
- distribution_poles = 6
20
- transmission_overhead_lines = 7
21
- distribution_overhead_lines = 8
22
- #substructures
23
- #conduit_burial
24
-
25
- @classmethod
26
- def has_value(cls, value):
27
- return value in cls._value2member_map_
28
-
29
- @classmethod
30
- def has_asset(cls, asset):
31
- print(asset)
32
- return asset in cls.__members__
33
-
34
-
35
- def asset_list(x1=41.255, y1=-117.33, x2=41.255, y2=-117.33, samples=100):
36
-
37
- x = np.linspace(x1, x2, samples)
38
- y = np.linspace(y1, y2, samples)
39
-
40
- seed(3)
41
- asset_probabilities = {
42
- AssetTypes.substation: 1 / 10000.0,
43
- AssetTypes.solar_panels : 1/500,
44
- AssetTypes.buried_lines : 1/10.0,
45
- AssetTypes.wind_turbines : 1/5000,
46
- AssetTypes.battery_storage :1/2000,
47
- AssetTypes.transmission_poles: 1 / 10.0,
48
- AssetTypes.distribution_poles : 1 / 10.0,
49
- AssetTypes.transmission_overhead_lines : 1/10.0,
50
- AssetTypes.distribution_overhead_lines : 1/10.0,
51
- }
52
-
53
- heights_ft = {
54
- AssetTypes.substation.name : 3,
55
- AssetTypes.solar_panels.name : 10,
56
- AssetTypes.buried_lines.name : -3,
57
- AssetTypes.wind_turbines.name : 25,
58
- AssetTypes.battery_storage.name : 4,
59
- AssetTypes.transmission_poles.name : 0,
60
- AssetTypes.distribution_poles.name : 0,
61
- AssetTypes.transmission_overhead_lines.name : 100,
62
- AssetTypes.distribution_overhead_lines.name : 30,
63
- }
64
-
65
- assets = {
66
- AssetTypes.substation.name : {},
67
- AssetTypes.solar_panels.name : {},
68
- AssetTypes.buried_lines.name : {},
69
- AssetTypes.wind_turbines.name : {},
70
- AssetTypes.battery_storage.name :{},
71
- AssetTypes.transmission_poles.name : {},
72
- AssetTypes.distribution_poles.name : {},
73
- AssetTypes.transmission_overhead_lines.name : {},
74
- AssetTypes.distribution_overhead_lines.name : {},
75
- }
76
-
77
- for asset_type, probability in asset_probabilities.items():
78
- asset_id = 0
79
- for x1 in x:
80
- for y1 in y:
81
- if random() < probability:
82
- assets[asset_type.name][f"{asset_type.name} {asset_id}"] = {"coordinates" : (x1, y1), "heights_ft": heights_ft[asset_type.name]}
83
- asset_id += 1
84
-
85
- p1 = Point(x.min(), y.min())
86
- p2 = Point(x.max(), y.min())
87
- p3 = Point(x.max(), y.max())
88
- p4 = Point(x.min(), y.max())
89
- pointList = [p1, p2, p3, p4, p1]
90
- poly = Polygon(pointList)
91
- mypoly = MultiPolygon([poly])
92
-
1
+ from shapely.geometry import MultiPolygon, Point,Polygon
2
+ from random import random,seed
3
+ from enum import IntEnum
4
+ import numpy as np
5
+
6
+ class ScenarioTypes(IntEnum):
7
+ flood_m = 0
8
+ wind_m_per_s = 1
9
+ fire_m = 2
10
+ earthquake_pga = 3
11
+
12
+ class AssetTypes(IntEnum):
13
+ substation = 0
14
+ solar_panels = 1
15
+ buried_lines = 2
16
+ wind_turbines= 3
17
+ battery_storage = 4
18
+ transmission_poles = 5
19
+ distribution_poles = 6
20
+ transmission_overhead_lines = 7
21
+ distribution_overhead_lines = 8
22
+ #substructures
23
+ #conduit_burial
24
+
25
+ @classmethod
26
+ def has_value(cls, value):
27
+ return value in cls._value2member_map_
28
+
29
+ @classmethod
30
+ def has_asset(cls, asset):
31
+ print(asset)
32
+ return asset in cls.__members__
33
+
34
+
35
+ def asset_list(x1=41.255, y1=-117.33, x2=41.255, y2=-117.33, samples=100):
36
+
37
+ x = np.linspace(x1, x2, samples)
38
+ y = np.linspace(y1, y2, samples)
39
+
40
+ seed(3)
41
+ asset_probabilities = {
42
+ AssetTypes.substation: 1 / 10000.0,
43
+ AssetTypes.solar_panels : 1/500,
44
+ AssetTypes.buried_lines : 1/10.0,
45
+ AssetTypes.wind_turbines : 1/5000,
46
+ AssetTypes.battery_storage :1/2000,
47
+ AssetTypes.transmission_poles: 1 / 10.0,
48
+ AssetTypes.distribution_poles : 1 / 10.0,
49
+ AssetTypes.transmission_overhead_lines : 1/10.0,
50
+ AssetTypes.distribution_overhead_lines : 1/10.0,
51
+ }
52
+
53
+ heights_ft = {
54
+ AssetTypes.substation.name : 3,
55
+ AssetTypes.solar_panels.name : 10,
56
+ AssetTypes.buried_lines.name : -3,
57
+ AssetTypes.wind_turbines.name : 25,
58
+ AssetTypes.battery_storage.name : 4,
59
+ AssetTypes.transmission_poles.name : 0,
60
+ AssetTypes.distribution_poles.name : 0,
61
+ AssetTypes.transmission_overhead_lines.name : 100,
62
+ AssetTypes.distribution_overhead_lines.name : 30,
63
+ }
64
+
65
+ assets = {
66
+ AssetTypes.substation.name : {},
67
+ AssetTypes.solar_panels.name : {},
68
+ AssetTypes.buried_lines.name : {},
69
+ AssetTypes.wind_turbines.name : {},
70
+ AssetTypes.battery_storage.name :{},
71
+ AssetTypes.transmission_poles.name : {},
72
+ AssetTypes.distribution_poles.name : {},
73
+ AssetTypes.transmission_overhead_lines.name : {},
74
+ AssetTypes.distribution_overhead_lines.name : {},
75
+ }
76
+
77
+ for asset_type, probability in asset_probabilities.items():
78
+ asset_id = 0
79
+ for x1 in x:
80
+ for y1 in y:
81
+ if random() < probability:
82
+ assets[asset_type.name][f"{asset_type.name} {asset_id}"] = {"coordinates" : (x1, y1), "heights_ft": heights_ft[asset_type.name]}
83
+ asset_id += 1
84
+
85
+ p1 = Point(x.min(), y.min())
86
+ p2 = Point(x.max(), y.min())
87
+ p3 = Point(x.max(), y.max())
88
+ p4 = Point(x.min(), y.max())
89
+ pointList = [p1, p2, p3, p4, p1]
90
+ poly = Polygon(pointList)
91
+ mypoly = MultiPolygon([poly])
92
+
93
93
  return assets, mypoly