Create DFR3 and Mapping Objects#

Analyses use DFR3 mapping sets from IN-CORE service to associate each element of a given set with one or more elements of a second set of DFR3 curves. In IN-CORE and pyIncore specifically, a building inventory (given set) is mapped to a (second) set of fragility curves.

This tutorial shows examples of how to create DFR3 and mapping objects for fragility, restoration and repair curves as well as how to use them in pyIncore.

A user can upload a DFR3 or mapping set to the DFR3 services or use it locally. This tutorial covers both options.

alt text

Please note that in this notebook we use term function in programming context as a class function and curve as a function in mathematical context (lognormal curve).

from pyincore import FragilityService, IncoreClient
from pyincore import Mapping, MappingSet, FragilityCurveSet
# IN-CORE client
client = IncoreClient()

# Initiate fragility service
fragility_services = FragilityService(client)
Connection successful to IN-CORE services. pyIncore version detected: 1.2.0

Fragility set object#

In this section we are going to explore the creation of fragility sets and curves used by the pyIncore library in hazard analyses. We provide examples of getting the curves into your project as well as basic use of pyIncore’s functions to print and visualize various attributes and variables.

Below is an example of a fragility set with three curves and metadata defined as JSON object with key/value pairs.

fragility_data = {
    "description": "< 5000 ft^2",
    "authors": [
        "Federal Emergency Management Agency (FEMA)"
    ],
    "resultType": "Limit State",
    "hazardType": "tsunami",
    "inventoryType": "building",
    "creator": "incore",
    "spaces": [
        "coe"
    ],
    "demandTypes": [
        "Mmax"
    ],
    "demandUnits": [
        "ft^3/s^2"
    ],
    "fragilityCurves": [
        {
            "description": "legacy - StandardFragilityCurve - Immediate Occupancy",
            "rules": [
                {
                    "condition": [
                        "momentumFlux > 0"
                    ],
                    "expression": "scipy.stats.norm.cdf((math.log(momentumFlux) - math.log(247.0))/(0.74))"
                }
            ],
            "returnType": {
                "type": "Limit State",
                "unit": "",
                "description": "LS_0"
            },
        },
        {
            "description": "legacy - StandardFragilityCurve - Life Safety",
            "rules": [
                {
                    "condition": [
                        "momentumFlux > 0"
                    ],
                    "expression": "scipy.stats.norm.cdf((math.log(momentumFlux) - math.log(247.0))/(0.74))"
                }
            ],
            "returnType": {
                "type": "Limit State",
                "unit": "",
                "description": "LS_1"
            },
        },
        {
            "description": "legacy - StandardFragilityCurve - Collapse Prevention",
            "rules": [
                {
                    "condition": [
                        "momentumFlux > 0"
                    ],
                    "expression": "scipy.stats.norm.cdf((math.log(momentumFlux) - math.log(247.0))/(0.74))"
                }
            ],
            "returnType": {
                "type": "Limit State",
                "unit": "",
                "description": "LS_2"
            },
        }
    ],
    "curveParameters": [
        {
            "name": "momentumFlux",
            "unit": "ft^3/s^2",
            "description": "momentumFlux value from hazard service",
            "fullName": "momentumFlux",
        }
    ]
}

created_fragility = fragility_services.create_dfr3_set(fragility_data)
created_fragility
{'id': '62014b17f8564f226303fa96',
 'description': '< 5000 ft^2',
 'authors': ['Federal Emergency Management Agency (FEMA)'],
 'paperReference': None,
 'resultUnit': None,
 'resultType': 'Limit State',
 'hazardType': 'tsunami',
 'inventoryType': 'building',
 'creator': 'cwang138',
 'curveParameters': [{'name': 'momentumFlux',
   'unit': 'ft^3/s^2',
   'description': 'momentumFlux value from hazard service',
   'fullName': 'momentumFlux',
   'expression': None}],
 'spaces': ['cwang138'],
 'demandTypes': ['Mmax'],
 'demandUnits': ['ft^3/s^2'],
 'fragilityCurves': [{'description': 'legacy - StandardFragilityCurve - Immediate Occupancy',
   'rules': [{'condition': ['momentumFlux > 0'],
     'expression': 'scipy.stats.norm.cdf((math.log(momentumFlux) - math.log(247.0))/(0.74))'}],
   'returnType': {'type': 'Limit State', 'unit': '', 'description': 'LS_0'},
   'curveParameters': None},
  {'description': 'legacy - StandardFragilityCurve - Life Safety',
   'rules': [{'condition': ['momentumFlux > 0'],
     'expression': 'scipy.stats.norm.cdf((math.log(momentumFlux) - math.log(247.0))/(0.74))'}],
   'returnType': {'type': 'Limit State', 'unit': '', 'description': 'LS_1'},
   'curveParameters': None},
  {'description': 'legacy - StandardFragilityCurve - Collapse Prevention',
   'rules': [{'condition': ['momentumFlux > 0'],
     'expression': 'scipy.stats.norm.cdf((math.log(momentumFlux) - math.log(247.0))/(0.74))'}],
   'returnType': {'type': 'Limit State', 'unit': '', 'description': 'LS_2'},
   'curveParameters': None}]}

1. Using IDs from IN-CORE DFR3 services#

In the first example we use IN-CORE’s DFR3 service to get fragility curves and to set a local DFR3 object. We need an ID number of a set in the service. A user can look up the fragility IDs in the DFR3 viewer.

# Set fragility set id from the service
fragility_set_id = "5b47b2d7337d4a36187c61ce"

# Get local fragility curve set
fragility_curve_set = FragilityCurveSet(fragility_services.get_dfr3_set(fragility_set_id))

fragility_curve_set
<pyincore.models.fragilitycurveset.FragilityCurveSet at 0x7faed84e4110>

2. Writing JSON definition#

In the second example we define a fragility set as a text string with JSON type key/value pairs which will then be converted to a JSON object. Note It is necessary to use the specified types of quotes to create the string.

fragility_set_json_str = '''{
    "id": "5b47b2d7337d4a36187c61ce",
    "description": "Mid-Rise Steel Moment Frame",
    "authors": [
        "Elnashai and Jeong"
    ],
    "paperReference": null,
    "resultUnit": null,
    "resultType": "Limit State",
    "hazardType": "earthquake",
    "inventoryType": "building",
    "creator": "incore",
    "spaces": [
        "coe"
    ],
    "demandTypes": [
        "PGA"
    ],
    "demandUnits": [
        "g"
    ],
    "fragilityCurves": [
        {
            "description": "legacy - PeriodStandardFragilityCurve - Moderate",
            "rules": [
                {
                    "condition": [
                        "PGA > 0"
                    ],
                    "expression": "scipy.stats.norm.cdf((math.log(PGA) - (-0.571))/(0.665))"
                }
            ],
            "returnType": {
                "type": "Limit State",
                "unit": "",
                "description": "LS_0"
            },
            "fragilityCurveParameters": null
        },
        {
            "description": "legacy - PeriodStandardFragilityCurve - Extensive",
            "rules": [
                {
                    "condition": [
                        "PGA > 0"
                    ],
                    "expression": "scipy.stats.norm.cdf((math.log(PGA) - (0.352))/(0.675))"
                }
            ],
            "returnType": {
                "type": "Limit State",
                "unit": "",
                "description": "LS_1"
            },
            "fragilityCurveParameters": null
        },
        {
            "description": "legacy - PeriodStandardFragilityCurve - Complete",
            "rules": [
                {
                    "condition": [
                        "PGA > 0"
                    ],
                    "expression": "scipy.stats.norm.cdf((math.log(PGA) - (1.341))/(0.746))"
                }
            ],
            "returnType": {
                "type": "Limit State",
                "unit": "",
                "description": "LS_2"
            },
            "fragilityCurveParameters": null
        }
    ],
    "curveParameters": [
        {
            "name": "PGA",
            "unit": "g",
            "description": "PGA value from hazard service",
            "fullName": "PGA",
            "expression": null
        },
        {
            "name": "num_stories",
            "unit": "",
            "description": "number of stories in building inventory",
            "fullName": null,
            "expression": "1"
        },
        {
            "name": "period",
            "unit": "",
            "description": "default building period",
            "fullName": null,
            "expression": "1.08"
        }
    ]
}
'''
fragility_curve_set = FragilityCurveSet.from_json_str(fragility_set_json_str)
fragility_curve_set
<pyincore.models.fragilitycurveset.FragilityCurveSet at 0x7faed851e690>

3. Constructing a fragility set from individual curves#

In the third example we define the fragility curves as JSON objects first and then combine them into a set. We define the proper set metadata as well.

# create a fragility curve set with three limit state
fragility_curve_LS_0 = {
    "description": "Moderate",
    "rules": [
        {
            "condition": [
                "PGA > 0"
            ],
            "expression": "scipy.stats.norm.cdf((math.log(PGA) - (-0.571))/(0.665))"
        }
    ],
    "returnType": {
        "type": "Limit State",
        "unit": "",
        "description": "LS_0"
    }
}

fragility_curve_LS_1 = {
    "description": "Extensive",
    "rules": [
        {
            "condition": [
                "PGA > 0"
            ],
            "expression": "scipy.stats.norm.cdf((math.log(PGA) - (0.352))/(0.675))"
        }
    ],
    "returnType": {
        "type": "Limit State",
        "unit": "",
        "description": "LS_1"
    }
}

fragility_curve_LS_2 = {
    "description": "Complete",
    "rules": [
        {
            "condition": [
                "PGA > 0"
            ],
            "expression": "scipy.stats.norm.cdf((math.log(PGA) - (1.341))/(0.746))"
        }
    ],
    "returnType": {
        "type": "Limit State",
        "unit": "",
        "description": "LS_2"
    }
}
# place three curves into a set with extra metadata
metadata = {
    "id":"local_fragility_curve_set",
    "description": "Mid-Rise Steel Moment Frame",
    "demandTypes": ["PGA"],
    "demandUnits": ["g"],
    "resultType":"Limit State",
    "hazardType":"earthquake",
    "inventoryType":"building",
    "fragilityCurves":[
        fragility_curve_LS_0,
        fragility_curve_LS_1,
        fragility_curve_LS_2,
    ],
    "curveParameters": [
        {
            "name": "PGA",
            "unit": "g",
            "description": "PGA value from hazard service",
            "fullName": "PGA",
        },
        {
            "name": "num_stories",
            "unit": "",
            "description": "number of stories in building inventory",
            "expression": "1"
        },
        {
            "name": "period",
            "unit": "",
            "description": "default building period",
            "expression": "1.08"
        }
    ]
}
# construct the fragility curve object to use
fragility_curve_set = FragilityCurveSet(metadata)
fragility_curve_set
<pyincore.models.fragilitycurveset.FragilityCurveSet at 0x7faf00625750>

4. Loading a fragility set from a JSON file#

In the last example we load the fragility curves from a JSON file. This is similar to Example 2 because the file content is read as a text string.

fragility_curve_set2 = FragilityCurveSet.from_json_file("files/periodStandardFragilityCurve.json")

Examples of fragility set and curve use#

Damage probability calculation#

We use the previously defined fragility set to calculate a limit state. We will use the fragility set object from Example 3 in Creation of a fragility curve set object section.

probabilities = fragility_curve_set.calculate_limit_state(hazard_values={"PGA": 10}, period=1)
probabilities
{'LS_0': 0.9999922402, 'LS_1': 0.9980722934, 'LS_2': 0.9012988813}

Curve visualization#

Use pyincore-viz library to visualize fragility curve set

from pyincore_viz.plotutil import PlotUtil as plot
plt = plot.get_fragility_plot(fragility_curve_set, start=0, end=50)
../../_images/create_dfr3_object_27_0.png

Computation functions on each individual curve#

In this example we define a fragility curve using a JSON object and then use different functions to print hazard, infrastructure and ground phenomenon variables; a limit state probability and liquefaction.

# use single fragility curve fragility_curve_LS_0 as example
# get limit state probability
probability = fragility_curve_set.fragility_curves[0].solve_curve_expression(
    hazard_values={"PGA":4}, curve_parameters=[
        {
            "name": "PGA",
            "unit": "g",
            "description": "PGA value from hazard service",
            "fullName": "PGA",
        },
        {
            "name": "num_stories",
            "unit": "",
            "description": "number of stories in building inventory",
            "expression": "1"
        },
        {
            "name": "period",
            "unit": "",
            "description": "default building period",
            "expression": "1.08"
        }
    ],
    num_stories=5,
    period=1
)
print("limit state probability is :" , probability, "\n")
limit state probability is : 0.9983763310617616 

DFR3 Mapping Set#

In this section we are going to explore creation of mapping rules used by the pyIncore library in hazard analyses. We again provide three examples of getting the mappings into your project as well as basic use of DFR3 mappings in pyIncore.

Below is an example of a mapping set with three rules and metadata defined as a JSON object with key/value pairs. Fragility curves are defined by ID codes and structural types define units of infrastructure.

mapping_data = {
  "name": "pytest - Tsunami Building Fragility Mapping",
  "hazardType": "tsunami",
  "inventoryType": "building",
  "mappingType": "fragility",
  "mappings": [
      {
          "entry": {
              "Non-Retrofit Inundation Fragility ID Code": "5bbbaedfec2309046c2745c8",
              "Non-Retrofit MomentumFlux Fragility ID Code": "5bbbae19ec2309046c2745c6"
          },
          "rules": [
              [
                 "java.lang.String struct_typ EQUALS W1"
              ]
          ]
      },
      {
          "entry": {
              "Non-Retrofit Inundation Fragility ID Code": "5bbbaf58ec2309046c2745c9",
              "Non-Retrofit MomentumFlux Fragility ID Code": "5bbbae5eec2309046c2745c7"
          },
          "rules": [
              [
                  "java.lang.String struct_typ EQUALS W2"
              ]
          ]
      },
      {
          "entry": {
               "Non-Retrofit Inundation Fragility ID Code": "5bbbafcdec2309046c2745ca",
              "Non-Retrofit MomentumFlux Fragility ID Code": "5bbbba6bec2309046c2745d8"
          },
          "rules": [
              [
                  "java.lang.String struct_typ EQUALS RC"
              ]
          ]
      }
  ]
}
created_mapping = fragility_services.create_mapping(mapping_data)
created_mapping
{'id': '62014b17f8564f226303fa97',
 'name': 'pytest - Tsunami Building Fragility Mapping',
 'hazardType': 'tsunami',
 'inventoryType': 'building',
 'mappings': [{'legacyEntry': {},
   'entry': {'Non-Retrofit Inundation Fragility ID Code': '5bbbaedfec2309046c2745c8',
    'Non-Retrofit MomentumFlux Fragility ID Code': '5bbbae19ec2309046c2745c6'},
   'rules': [['java.lang.String struct_typ EQUALS W1']]},
  {'legacyEntry': {},
   'entry': {'Non-Retrofit Inundation Fragility ID Code': '5bbbaf58ec2309046c2745c9',
    'Non-Retrofit MomentumFlux Fragility ID Code': '5bbbae5eec2309046c2745c7'},
   'rules': [['java.lang.String struct_typ EQUALS W2']]},
  {'legacyEntry': {},
   'entry': {'Non-Retrofit Inundation Fragility ID Code': '5bbbafcdec2309046c2745ca',
    'Non-Retrofit MomentumFlux Fragility ID Code': '5bbbba6bec2309046c2745d8'},
   'rules': [['java.lang.String struct_typ EQUALS RC']]}],
 'creator': 'cwang138',
 'spaces': ['cwang138'],
 'mappingType': 'fragility'}

1. Using mapping IDs from IN-CORE DFR3 services#

In the first example we use IN-CORE’s DFR3 service to get mappings and to set a local mapping set object. We need an ID number of the mapping set in the service. A user can look up the fragility mapping IDs in the DFR3 viewer.

mapping_id = "5b8ec84fec2309047299581f"
fragility_service = FragilityService(client)
mapping_set = MappingSet(fragility_service.get_mapping(mapping_id))
mapping_set
<pyincore.models.mappingset.MappingSet at 0x7faef05a54d0>

2. Writing a mapping definition file#

In the second example we define a mapping set as a text string with JSON type key/value pairs which then will be converted into a JSON object. Note It is necessary to use the specified types of quotes to create the string.

mapping_set_json_str = '''
{
    "id": "5b8ec84fec2309047299581f",
    "name": "Shelby Water Network MMSA",
    "hazardType": "earthquake",
    "inventoryType": "water_facility",
    "mappings": [
        {
            "legacyEntry": {},
            "entry": {
                "pga": "5b7d81ffec230904683d5073"
            },
            "rules": [
                [
                    "java.lang.String data_type EQUALS 'tank'"
                ]
            ]
        },
        {
            "legacyEntry": {},
            "entry": {
                "pga": "5b7d8284ec230904683d5074"
            },
            "rules": [
                [
                    "java.lang.String data_type EQUALS 'pump'",
                    "java.lang.String subtype EQUALS 'booster_pump'"
                ]
            ]
        },
        {
            "legacyEntry": {},
            "entry": {
                "pga": "5b7d8284ec230904683d5074"
            },
            "rules": [
                [
                    "java.lang.String data_type EQUALS 'pump'",
                    "java.lang.String subtype EQUALS 'pump_0'"
                ]
            ]
        },
        {
            "legacyEntry": {},
            "entry": {
                "pga": "5b7d829aec230904683d5075"
            },
            "rules": [
                [
                    "java.lang.String data_type EQUALS 'pump'",
                    "java.lang.String subtype EQUALS 'pump_1'"
                ]
            ]
        },
        {
            "legacyEntry": {},
            "entry": {
                "pga": "5b7d82a6ec230904683d5076"
            },
            "rules": [
                [
                    "java.lang.String data_type EQUALS 'pump'",
                    "java.lang.String subtype EQUALS 'pump_2'"
                ]
            ]
        },
        {
            "legacyEntry": {},
            "entry": {
                "pga": "5b7d82b3ec230904683d5077"
            },
            "rules": [
                [
                    "java.lang.String data_type EQUALS 'pump'",
                    "java.lang.String subtype EQUALS 'pump_3'"
                ]
            ]
        }
    ],
    "mappingType": "fragility"
}
'''

mapping_set = MappingSet.from_json_str(mapping_set_json_str)
mapping_set
<pyincore.models.mappingset.MappingSet at 0x7faef069c190>

3. Constructing a mapping set from individual components#

In the last example we provide a full set of instructions for

Creating a fragility object with curves required for mapping. You may either:

  1. use curve objects (similar to example 3 in Fragility section)

  2. or load a fragility JSON file (example 4)

  3. creating a mapping set object by putting fragility sets into the mappings

  4. adding metadata to the mapping object

  1. Create a fragility set from curve objects (example 3 above).

fragility_set = {
    "id":"local_fragility_curve_set_1",
    "demandTypes": ["PGA"],
    "demandUnits": ["g"],
    "resultType":"Limit State",
    "hazardType":"earthquake",
    "inventoryType":"building",
    "fragilityCurves":[
        fragility_curve_LS_0,
        fragility_curve_LS_1,
        fragility_curve_LS_2,
    ],
    "curveParameters": [
        {
            "name": "PGA",
            "unit": "g",
            "description": "PGA value from hazard service",
            "fullName": "PGA",
        },
        {
            "name": "num_stories",
            "unit": "",
            "description": "number of stories in building inventory",
            "expression": "1"
        },
        {
            "name": "period",
            "unit": "",
            "description": "default building period",
            "expression": "1.08"
        }
    ]
}
fragility_set_1 = FragilityCurveSet(fragility_set)
  1. Create a fragility set object directly from a JSON file (example 4 above).

fragility_set_2 = FragilityCurveSet.from_json_file('files/periodStandardFragilityCurve.json')
  1. Create mapping objects and put fragility curve sets into the mapping.

entry_1 = {"Non-Retrofit Fragility ID Code": fragility_set_1}
rules_1 = [[ "int no_stories GE 4","int no_stories LE 7"]]
mapping_1 = Mapping(entry_1, rules_1)

entry_2 = {"Non-Retrofit Fragility ID Code": fragility_set_2}
rules_2 = [["int no_stories GE 1", "int no_stories LE 3"]]
mapping_2 = Mapping(entry_2, rules_2)
  1. Add metadata and create the final mapping set object

mapping_set = {
    'id': 'local placeholder',
    'name': 'testing local mapping object creation',
    'hazardType': 'earthquake',
    'inventoryType': 'building',
    'mappings': [
        mapping_1,
        mapping_2,
    ],
    'mappingType': 'fragility'
}
local_building_mapping_set = MappingSet(mapping_set)

Examples of DFR3 mapping use#

from pyincore.analyses.buildingdamage import BuildingDamage

bldg_dmg = BuildingDamage(client)
bldg_dmg.load_remote_input_dataset("buildings", '5a284f0bc7d30d13bc081a28')
bldg_dmg.set_parameter("result_name", 'local_mapping_fragility_memphis_eq_bldg_dmg_result')
Dataset already exists locally. Reading from local cached zip.
Unzipped folder found in the local cache. Reading from it...
True

Method 1: Load mapping from IN-CORE services using set IDs#

fragility_service = FragilityService(client)
mapping_set = MappingSet(fragility_service.get_mapping(mapping_id="5b47b350337d4a3629076f2c"))
bldg_dmg.set_input_dataset('dfr3_mapping_set', mapping_set)
True

Method 2: Load locally created mapping object#

# Local_building_mapping_set is created in the previous section.
bldg_dmg.set_input_dataset("dfr3_mapping_set", local_building_mapping_set)
True
bldg_dmg.set_parameter("hazard_type", 'earthquake')
bldg_dmg.set_parameter("hazard_id", '5b902cb273c3371e1236b36b')
bldg_dmg.set_parameter("num_cpu", 4)

# Run Analysis
bldg_dmg.run_analysis()
True
building_dmg_result = bldg_dmg.get_output_dataset('ds_result')

# Convert dataset to Pandas DataFrame
df_bldg_dmg = building_dmg_result.get_dataframe_from_csv()
# Display top 5 rows of output data
df_bldg_dmg.head()
guid LS_0 LS_1 LS_2 DS_0 DS_1 DS_2 DS_3 haz_expose
0 a41e7dcc-3b82-42f2-9dbd-a2ebdf39d453 0.504540 0.190978 0.046526 0.495460 0.313562 0.144451 0.046526 yes
1 254d1dd8-5d2f-4737-909b-59cc64ca72d4 0.183383 0.012017 0.000379 0.816617 0.171366 0.011638 0.000379 yes
2 b185d5b6-5bc0-43a3-800a-c046017372ab 0.169996 0.010515 0.000321 0.830004 0.159481 0.010194 0.000321 yes
3 7b5dc4f6-ef5e-4178-9836-f044b4b92f0d 0.510562 0.194772 0.047708 0.489438 0.315790 0.147064 0.047708 yes
4 4253802e-b3e5-4ed3-93b0-dda9ef6362b0 NaN NaN NaN NaN NaN NaN NaN NaN