Skip to content

Commit

Permalink
Rename Social Vulnerability to Social Vulnerability Score (#572)
Browse files Browse the repository at this point in the history
* Rename Social Vulnerability to Social Vulnerability Score

* readd old files

* update requirements

* updated copyright

* fixed wrong caption

* renamded output name

* renamded output name in the code

* fixed typo in result name

* revert back to previous result name

* Changed copyright year

* modified copyright year
  • Loading branch information
ywkim312 authored May 22, 2024
1 parent 8b88128 commit 9e27a3f
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 150 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
- Permission error in clearing cache process [#563](https://github.com/IN-CORE/pyincore/issues/563)

## [Unreleased]

### Changed
- Rename Social Vulnerability Analysis to Social Vulnerability Index Analysis [#556](https://github.com/IN-CORE/pyincore/issues/556)

## [1.18.1] - 2024-04-30

### Changed
Expand Down
7 changes: 7 additions & 0 deletions docs/source/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,13 @@ analyses/socialvulnerability
============================
.. autoclass:: socialvulnerability.socialvulnerability.SocialVulnerability
:members:
.. deprecated:: 1.19.0
This class will be deprecated soon. Use :class:`socialvulnerabilityscore.SocialVulnerabilityScore` instead.

analyses/socialvulnerabilityscore
============================
.. autoclass:: socialvulnerabilityscore.socialvulnerabilityscore.SocialVulnerabilityScore
:members:

analyses/tornadoepndamage
=========================
Expand Down
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ dependencies:
- rtree>=1.1.0
- scipy>=1.11.3
- shapely>=2.0.2
- deprecated>=1.2.14
158 changes: 8 additions & 150 deletions pyincore/analyses/socialvulnerability/socialvulnerability.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,160 +4,18 @@
# terms of the Mozilla Public License v2.0 which accompanies this distribution,
# and is available at https://www.mozilla.org/en-US/MPL/2.0/

import pandas as pd
from pyincore import BaseAnalysis
from deprecated.sphinx import deprecated

from pyincore.analyses.socialvulnerabilityscore import SocialVulnerabilityScore

class SocialVulnerability(BaseAnalysis):
"""This analysis computes a social vulnerability score for per associated zone in census data.
The computation extracts zoning and a social vulnerability score obtained by computing demographic features of
interest against national average values.
The output of the computation is a dataset CSV format.
Contributors
| Science: Elaina Sutley, Amin Enderami
| Implementation: Amin Enderami, Santiago Núñez-Corrales, and NCSA IN-CORE Dev Team
Related publications
Args:
incore_client (IncoreClient): Service authentication.
"""

@deprecated(version='1.19.0', reason="This class will be deprecated soon. Use SocialVulnerabilityScore instead.")
class SocialVulnerability():
def __init__(self, incore_client):
super(SocialVulnerability, self).__init__(incore_client)

def run(self):
"""Execute the social vulnerability analysis using known parameters."""
df_navs = pd.DataFrame(self.get_input_dataset('national_vulnerability_feature_averages').get_csv_reader())

df_dem = pd.DataFrame(self.get_input_dataset('social_vulnerability_demographic_factors').get_csv_reader())

# Make sure data types match
df_dem["factor_white_nonHispanic"] = df_dem["factor_white_nonHispanic"].astype(float)
df_dem["factor_owner_occupied"] = df_dem["factor_owner_occupied"].astype(float)
df_dem["factor_earning_higher_than_national_poverty_rate"] =\
df_dem["factor_earning_higher_than_national_poverty_rate"].astype(float)
df_dem["factor_over_25_with_high_school_diploma_or_higher"] =\
df_dem["factor_over_25_with_high_school_diploma_or_higher"].astype(float)
df_dem["factor_without_disability_age_18_to_65"] =\
df_dem["factor_without_disability_age_18_to_65"].astype(float)

self.social_vulnerability_model(df_navs, df_dem)

def social_vulnerability_model(self, df_navs, df_dem):
"""
Args:
df_navs (pd.DataFrame): dataframe containing the national average values for vulnerability factors
df_dem (pd.DataFrame): dataframe containing demographic factors required for the vulnerability score
Returns:
"""

# Compute the social vulnerability index
df_sv = self.compute_svs(df_dem, df_navs)

# Save into a CSV file
result_name = self.get_parameter("result_name")
self.set_result_csv_data("sv_result", df_sv,
name=result_name,
source="dataframe")

@staticmethod
def compute_svs(df, df_navs):
""" Computation of the social vulnerability score and corresponding zoning
self._delegate = SocialVulnerabilityScore(incore_client)

Args:
df (pd.DataFrame): dataframe for the census geographic unit of interest
df_navs (pd.DataFrame): dataframe containing national average values
Returns:
pd.DataFrame: Social vulnerability score and corresponding zoning data
def __getattr__(self, name):
"""
navs = df_navs['average'].astype(float).array

df['R1'] = df['factor_white_nonHispanic'] / navs[0]
df['R2'] = df['factor_owner_occupied'] / navs[1]
df['R3'] = df['factor_earning_higher_than_national_poverty_rate'] / navs[2]
df['R4'] = df['factor_over_25_with_high_school_diploma_or_higher'] / navs[3]
df['R5'] = df['factor_without_disability_age_18_to_65'] / navs[4]
df['SVS'] = df.apply(lambda row: (row['R1'] + row['R2'] + row['R3'] + row['R4'] + row['R5']) / 5, axis=1)

maximum_nav = 1/navs
std = abs(1 - (sum(maximum_nav) / len(maximum_nav))) / 3

lb_2 = 1 - 1.5*std
lb_1 = 1 - 0.5*std
ub_1 = 1 + 0.5*std
ub_2 = 1 + 1.5*std

zones = []

for svs in df['SVS'].tolist():
if svs < lb_2:
new_zone = 'High Vulnerable (zone5)'
elif svs < lb_1:
new_zone = 'Medium to High Vulnerable (zone4)'
elif svs < ub_1:
new_zone = 'Medium Vulnerable (zone3)'
elif svs < ub_2:
new_zone = 'Medium to Low Vulnerable (zone2)'
elif svs > ub_2:
new_zone = 'Low Vulnerable (zone1)'
else:
new_zone = 'No Data'
zones.append(new_zone)

df['zone'] = zones
df = df.sort_values(by="GEO_ID")

return df

def get_spec(self):
"""Get specifications of the housing serial recovery model.
Returns:
obj: A JSON object of specifications of the social vulnerability model.
Delegate attribute access to the SocialVulnerabilityScore instance.
"""
return {
'name': 'social-vulnerability',
'description': 'Social vulnerability score model',
'input_parameters': [
{
'id': 'result_name',
'required': True,
'description': 'Result CSV dataset name',
'type': str
},
],
'input_datasets': [
{
'id': 'national_vulnerability_feature_averages',
'required': True,
'description': 'A csv file with national vulnerability feature averages',
'type': ['incore:socialVulnerabilityFeatureAverages']
},
{
'id': 'social_vulnerability_demographic_factors',
'required': True,
'description': 'A csv file with social vulnerability demographic factors for a given geographic '
'type',
'type': ['incore:socialVulnerabilityDemFactors']
}
],
'output_datasets': [
{
'id': 'sv_result',
'parent_type': 'social_vulnerability_score',
'description': 'A csv file with zones containing demographic factors'
'qualified by a social vulnerability score',
'type': 'incore:socialVulnerabilityScore'
}
]
}
return getattr(self._delegate, name)
8 changes: 8 additions & 0 deletions pyincore/analyses/socialvulnerabilityscore/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (c) 2021 University of Illinois and others. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Mozilla Public License v2.0 which accompanies this distribution,
# and is available at https://www.mozilla.org/en-US/MPL/2.0/


from pyincore.analyses.socialvulnerabilityscore.socialvulnerabilityscore import SocialVulnerabilityScore
163 changes: 163 additions & 0 deletions pyincore/analyses/socialvulnerabilityscore/socialvulnerabilityscore.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Copyright (c) 2021 University of Illinois and others. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Mozilla Public License v2.0 which accompanies this distribution,
# and is available at https://www.mozilla.org/en-US/MPL/2.0/

import pandas as pd
from pyincore import BaseAnalysis


class SocialVulnerabilityScore(BaseAnalysis):
"""This analysis computes a social vulnerability score for per associated zone in census data.
The computation extracts zoning and a social vulnerability score obtained by computing demographic features of
interest against national average values.
The output of the computation is a dataset CSV format.
Contributors
| Science: Elaina Sutley, Amin Enderami
| Implementation: Amin Enderami, Santiago Núñez-Corrales, and NCSA IN-CORE Dev Team
Related publications
Args:
incore_client (IncoreClient): Service authentication.
"""

def __init__(self, incore_client):
super(SocialVulnerabilityScore, self).__init__(incore_client)

def run(self):
"""Execute the social vulnerability score analysis using known parameters."""
df_navs = pd.DataFrame(self.get_input_dataset('national_vulnerability_feature_averages').get_csv_reader())

df_dem = pd.DataFrame(self.get_input_dataset('social_vulnerability_demographic_factors').get_csv_reader())

# Make sure data types match
df_dem["factor_white_nonHispanic"] = df_dem["factor_white_nonHispanic"].astype(float)
df_dem["factor_owner_occupied"] = df_dem["factor_owner_occupied"].astype(float)
df_dem["factor_earning_higher_than_national_poverty_rate"] =\
df_dem["factor_earning_higher_than_national_poverty_rate"].astype(float)
df_dem["factor_over_25_with_high_school_diploma_or_higher"] =\
df_dem["factor_over_25_with_high_school_diploma_or_higher"].astype(float)
df_dem["factor_without_disability_age_18_to_65"] =\
df_dem["factor_without_disability_age_18_to_65"].astype(float)

self.social_vulnerability_score_model(df_navs, df_dem)

def social_vulnerability_score_model(self, df_navs, df_dem):
"""
Args:
df_navs (pd.DataFrame): dataframe containing the national average values for vulnerability factors
df_dem (pd.DataFrame): dataframe containing demographic factors required for the vulnerability score
Returns:
"""

# Compute the social vulnerability score index
df_sv = self.compute_svs(df_dem, df_navs)

# Save into a CSV file
result_name = self.get_parameter("result_name")
self.set_result_csv_data("sv_result", df_sv,
name=result_name,
source="dataframe")

@staticmethod
def compute_svs(df, df_navs):
""" Computation of the social vulnerability score and corresponding zoning
Args:
df (pd.DataFrame): dataframe for the census geographic unit of interest
df_navs (pd.DataFrame): dataframe containing national average values
Returns:
pd.DataFrame: Social vulnerability score and corresponding zoning data
"""
navs = df_navs['average'].astype(float).array

df['R1'] = df['factor_white_nonHispanic'] / navs[0]
df['R2'] = df['factor_owner_occupied'] / navs[1]
df['R3'] = df['factor_earning_higher_than_national_poverty_rate'] / navs[2]
df['R4'] = df['factor_over_25_with_high_school_diploma_or_higher'] / navs[3]
df['R5'] = df['factor_without_disability_age_18_to_65'] / navs[4]
df['SVS'] = df.apply(lambda row: (row['R1'] + row['R2'] + row['R3'] + row['R4'] + row['R5']) / 5, axis=1)

maximum_nav = 1/navs
std = abs(1 - (sum(maximum_nav) / len(maximum_nav))) / 3

lb_2 = 1 - 1.5*std
lb_1 = 1 - 0.5*std
ub_1 = 1 + 0.5*std
ub_2 = 1 + 1.5*std

zones = []

for svs in df['SVS'].tolist():
if svs < lb_2:
new_zone = 'High Vulnerable (zone5)'
elif svs < lb_1:
new_zone = 'Medium to High Vulnerable (zone4)'
elif svs < ub_1:
new_zone = 'Medium Vulnerable (zone3)'
elif svs < ub_2:
new_zone = 'Medium to Low Vulnerable (zone2)'
elif svs > ub_2:
new_zone = 'Low Vulnerable (zone1)'
else:
new_zone = 'No Data'
zones.append(new_zone)

df['zone'] = zones
df = df.sort_values(by="GEO_ID")

return df

def get_spec(self):
"""Get specifications of the housing serial recovery model.
Returns:
obj: A JSON object of specifications of the social vulnerability score model.
"""
return {
'name': 'social-vulnerability-score',
'description': 'Social vulnerability score model',
'input_parameters': [
{
'id': 'result_name',
'required': True,
'description': 'Result CSV dataset name',
'type': str
},
],
'input_datasets': [
{
'id': 'national_vulnerability_feature_averages',
'required': True,
'description': 'A csv file with national vulnerability feature averages',
'type': ['incore:socialVulnerabilityFeatureAverages']
},
{
'id': 'social_vulnerability_demographic_factors',
'required': True,
'description': 'A csv file with social vulnerability score demographic factors for a given geographic '
'type',
'type': ['incore:socialVulnerabilityDemFactors']
}
],
'output_datasets': [
{
'id': 'sv_result',
'parent_type': 'social_vulnerability_score',
'description': 'A csv file with zones containing demographic factors'
'qualified by a social vulnerability score',
'type': 'incore:socialVulnerabilityScore'
}
]
}
1 change: 1 addition & 0 deletions requirements.imports
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ shapely
pycodestyle
pytest
python-jose
Deprecated
1 change: 1 addition & 0 deletions requirements.min
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ requests>=2.31.0
rtree>=1.1.0
scipy>=1.11.3
shapely>=2.0.2
Deprecated>=1.2.14
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ requests>=2.31.0
rtree>=1.1.0
scipy>=1.11.3
shapely>=2.0.2
Deprecated>=1.2.14
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
'rtree>=1.1.0',
'scipy>=1.11.3',
'shapely>=2.0.2',
'Deprecated>=1.2.14'
],

extras_require={
Expand Down
Loading

0 comments on commit 9e27a3f

Please sign in to comment.