Skip to content

Commit

Permalink
lint: linted JOS3 model code
Browse files Browse the repository at this point in the history
  • Loading branch information
FedericoTartarini committed May 2, 2023
1 parent c847e76 commit ed25119
Show file tree
Hide file tree
Showing 10 changed files with 847 additions and 826 deletions.
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
MIT License

Copyright (c) 2019-2020, Federico Tartarini
Copyright (c) 2019 Federico Tartarini

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
70 changes: 38 additions & 32 deletions examples/calc_jos3.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
model = JOS3(height=1.7, weight=60, age=30)

# Set the first phase
model.to = 28 # Operative temperature [oC]
model.to = 28 # Operative temperature [°C]
model.rh = 40 # Relative humidity [%]
model.v = 0.2 # Air velocity [m/s]
model.par = 1.2 # Physical activity ratio [-]
Expand All @@ -34,7 +34,7 @@
# Show the results
df = pd.DataFrame(model.dict_results()) # Make pandas.DataFrame
df.t_skin_mean.plot() # Plot time series of mean skin temperature.
plt.ylabel("Mean skin temperature [oC]") # Set y-label as 'Mean skin temperature [oC]'
plt.ylabel("Mean skin temperature [°C]") # Set y-label as 'Mean skin temperature [°C]'
plt.xlabel("Time [min]") # Set x-label as 'Time [min]'
plt.savefig(
os.path.join(JOS3_EXAMPLE_DIRECTORY, "jos3_example1_mean_skin_temperature.png")
Expand All @@ -45,8 +45,8 @@
model.to_csv(os.path.join(JOS3_EXAMPLE_DIRECTORY, "jos3_example1 (default output).csv"))

# Print the BMR value using the getter
print('BMR=', model.BMR)
print('Body name list: ', model.bodynames)
print("BMR=", model.BMR)
print("Body name list: ", model.body_names)

# -------------------------------------------
# EXAMPLE 2 (detail simulation)
Expand All @@ -68,10 +68,10 @@
# Set environmental conditions such as air temperature, mean radiant temperature using the setter methods.
# Set the first condition
# Environmental parameters can be input as int, float, list, dict, numpy array format.
model.tdb = 28 # Air temperature [oC]
model.tr = 30 # Mean radiant temperature [oC]
model.tdb = 28 # Air temperature [°C]
model.tr = 30 # Mean radiant temperature [°C]
model.rh = 40 # Relative humidity [%]
model.v = np.array( # Air velocity [m/s]
model.v = np.array( # Air velocity [m/s]
[
0.2, # head
0.4, # neck
Expand All @@ -92,7 +92,9 @@
0.1, # right foot
]
)
model.clo = local_clo_typical_ensembles["briefs, socks, undershirt, work jacket, work pants, safety shoes"]["local_body_part"]
model.clo = local_clo_typical_ensembles[
"briefs, socks, undershirt, work jacket, work pants, safety shoes"
]["local_body_part"]

# par should be input as int, float.
model.par = 1.2 # Physical activity ratio [-], assuming a sitting position
Expand All @@ -108,34 +110,34 @@

# Set the next condition (You only need to change the parameters that you want to change)
model.to = 20 # Change operative temperature
model.v = { # Air velocity [m/s], assuming to use a desk fan
'head' : 0.2,
'neck' : 0.4,
'chest' : 0.4,
'back': 0.1,
'pelvis' : 0.1,
'left_shoulder' : 0.4,
'left_arm' : 0.4,
'left_hand' : 0.4,
'right_shoulder' : 0.4,
'right_arm' : 0.4,
'right_hand' : 0.4,
'left_thigh' : 0.1,
'left_leg' : 0.1,
'left_foot' : 0.1,
'right_thigh' : 0.1,
'right_leg' : 0.1,
'right_foot' : 0.1
}
model.v = { # Air velocity [m/s], assuming to use a desk fan
"head": 0.2,
"neck": 0.4,
"chest": 0.4,
"back": 0.1,
"pelvis": 0.1,
"left_shoulder": 0.4,
"left_arm": 0.4,
"left_hand": 0.4,
"right_shoulder": 0.4,
"right_arm": 0.4,
"right_hand": 0.4,
"left_thigh": 0.1,
"left_leg": 0.1,
"left_foot": 0.1,
"right_thigh": 0.1,
"right_leg": 0.1,
"right_foot": 0.1,
}
# Run JOS-3 model
model.simulate(
times=60, # Number of loops of a simulation
dtime=60, # Time delta [sec]. The default is 60.
) # Additional exposure time = 60 [loops] * 60 [sec] = 60 [min]

# Set the next condition (You only need to change the parameters that you want to change)
model.tdb = 30 # Change air temperature [oC]
model.tr = 35 # Change mean radiant temperature [oC]
model.tdb = 30 # Change air temperature [°C]
model.tr = 35 # Change mean radiant temperature [°C]
# Run JOS-3 model
model.simulate(
times=30, # Number of loops of a simulation
Expand All @@ -144,11 +146,15 @@

# Show the results
df = pd.DataFrame(model.dict_results()) # Make pandas.DataFrame
df[["t_skin_mean", "t_skin_head", "t_skin_chest", "t_skin_left_hand"]].plot() # Plot time series of local skin temperature.
df[
["t_skin_mean", "t_skin_head", "t_skin_chest", "t_skin_left_hand"]
].plot() # Plot time series of local skin temperature.
plt.legend(["Mean", "Head", "Chest", "Left hand"]) # Reset the legends
plt.ylabel("Skin temperature [oC]") # Set y-label as 'Skin temperature [oC]'
plt.ylabel("Skin temperature [°C]") # Set y-label as 'Skin temperature [°C]'
plt.xlabel("Time [min]") # Set x-label as 'Time [min]'
plt.savefig(os.path.join(JOS3_EXAMPLE_DIRECTORY, "jos3_example2_skin_temperatures.png")) # Save plot at the current directory
plt.savefig(
os.path.join(JOS3_EXAMPLE_DIRECTORY, "jos3_example2_skin_temperatures.png")
) # Save plot at the current directory
plt.show() # Show the plot

# Exporting the results as csv
Expand Down
108 changes: 52 additions & 56 deletions src/pythermalcomfort/jos3_functions/construction.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-

"""
This code provides functions for calculating the surface area of different body parts, weight ratio,
basal blood flow ratio, and thermal conductance and thermal capacity.
The values of a NumPy array containing 17 elements correspond to the following order:
"head", "neck", "chest", "back", "pelvis",
"left_shoulder", "left_arm", "left_hand", "right_shoulder", "right_arm", "right_hand",
"left_thigh", "left_leg", "left_hand", "right_thigh", "right_leg" and "right_hand".
"""This code provides functions for calculating the surface area of different
body parts, weight ratio, basal blood flow ratio, and thermal conductance and
thermal capacity.
The values of a NumPy array containing 17 elements correspond to the
following order: "head", "neck", "chest", "back", "pelvis",
"left_shoulder", "left_arm", "left_hand", "right_shoulder", "right_arm",
"right_hand", "left_thigh", "left_leg", "left_hand", "right_thigh",
"right_leg" and "right_hand".
"""

import numpy as np
Expand Down Expand Up @@ -37,9 +38,9 @@
]
)


def _to17array(inp):
"""
Create a NumPy array of shape (17,) with the given input.
"""Create a NumPy array of shape (17,) with the given input.
Parameters
----------
Expand All @@ -66,19 +67,21 @@ def _to17array(inp):
if inp.shape == (17,):
array = inp
else:
ValueError("The input list or ndarray is not of length 17")
raise ValueError("The input list or ndarray is not of length 17")
else:
raise ValueError("Unsupported input type. Supported types: int, float, list, dict, ndarray")
raise ValueError(
"Unsupported input type. Supported types: int, float, list, dict, ndarray"
)

return array.copy()


def bsa_rate(
height=1.72,
weight=74.43,
formula="dubois",
):
"""
Calculate the rate of bsa to standard body.
"""Calculate the rate of bsa to standard body.
Parameters
----------
Expand All @@ -100,19 +103,18 @@ def bsa_rate(
weight=weight,
formula=formula,
)
bsa_rate = bsa_all / _BSAst.sum() # The bsa ratio to the standard body (1.87m2)
return bsa_rate
return bsa_all / _BSAst.sum() # The bsa ratio to the standard body (1.87m2)

def localbsa(

def local_bsa(
height=1.72,
weight=74.43,
formula="dubois",
):
"""
Calculate local body surface area (bsa) [m2].
"""Calculate local body surface area (bsa) [m2].
The local body surface area has been derived from 65MN.
The head have been devided to head and neck based on Smith's model.
The head have been divided to head and neck based on Smith's model.
head = 0.1396*0.1117/0.1414 (65MN_Head * Smith_Head / Smith_Head+neck)
neck = 0.1396*0.0297/0.1414 (65MN_Head * Smith_Neck / Smith_Head+neck)
Expand All @@ -132,7 +134,6 @@ def localbsa(
Local body surface area (bsa) [m2].
bsa_rate : float
The ratio of bsa to the standard body [-].
"""
_bsa_rate = bsa_rate(
height=height,
Expand All @@ -146,8 +147,7 @@ def localbsa(
def weight_rate(
weight=74.43,
):
"""
Calculate the ratio of the body weitht to the standard body (74.43 kg).
"""Calculate the ratio of the body weight to the standard body (74.43 kg).
The standard values of local body weights are as below.
weight_local = np.array([
Expand All @@ -169,8 +169,7 @@ def weight_rate(
The ratio of the body weight to the standard body (74.43 kg).
weight_rate = weight / 74.43
"""
rate = weight / 74.43
return rate
return weight / 74.43


def bfb_rate(
Expand All @@ -180,8 +179,8 @@ def bfb_rate(
age=20,
ci=2.59,
):
"""
Calculate the ratio of basal blood flow (BFB) of the standard body (290 L/h).
"""Calculate the ratio of basal blood flow (BFB) of the standard body (290
L/h).
Parameters
----------
Expand Down Expand Up @@ -216,8 +215,7 @@ def bfb_rate(
ci *= 0.7

bfb_all = ci * bsa_rate(height, weight, equation) * _BSAst.sum() # [L/h]
_bfb_rate = bfb_all / 290
return _bfb_rate
return bfb_all / 290


def conductance(
Expand All @@ -226,8 +224,7 @@ def conductance(
equation="dubois",
fat=15,
):
"""
Calculate thermal conductance between layers [W/K].
"""Calculate thermal conductance between layers [W/K].
Parameters
----------
Expand Down Expand Up @@ -375,7 +372,7 @@ def conductance(
# The shape is a cylinder.
# It is assumed that the inner is vascular radius, 2.5mm and the outer is
# stolwijk's core radius.
# The heat transer coefficient of the core is assumed as the Michel's
# The heat transfer coefficient of the core is assumed as the Michel's
# counter-flow model 0.66816 [W/(m・K)].
cdt_ves_cr = np.array(
[
Expand Down Expand Up @@ -423,7 +420,7 @@ def conductance(

# art to vein (counter-flow) [W/K]
# The data has been derived Mitchell's model.
# THe values = 15.869 [W/(m・K)] * the segment lenght [m]
# THe values = 15.869 [W/(m・K)] * the segment length [m]
cdt_art_vein = np.array(
[
0,
Expand Down Expand Up @@ -468,27 +465,27 @@ def conductance(

cdt_whole = np.zeros((NUM_NODES, NUM_NODES))
for i, bn in enumerate(BODY_NAMES):
# Dictionary of indecies in each body segment
# Dictionary of indices in each body segment
# key = layer name, value = index of matrix
indexof = IDICT[bn]
index_of = IDICT[bn]

# Common
cdt_whole[indexof["artery"], indexof["vein"]] = cdt_art_vein[i] # art to vein
cdt_whole[indexof["artery"], indexof["core"]] = cdt_ves_cr[i] # art to cr
cdt_whole[indexof["vein"], indexof["core"]] = cdt_ves_cr[i] # vein to cr
cdt_whole[index_of["artery"], index_of["vein"]] = cdt_art_vein[i] # art to vein
cdt_whole[index_of["artery"], index_of["core"]] = cdt_ves_cr[i] # art to cr
cdt_whole[index_of["vein"], index_of["core"]] = cdt_ves_cr[i] # vein to cr

# Only limbs
if i >= 5:
cdt_whole[indexof["sfvein"], indexof["skin"]] = cdt_sfv_sk[i] # sfv to sk
cdt_whole[index_of["sfvein"], index_of["skin"]] = cdt_sfv_sk[i] # sfv to sk

# If the segment has a muscle or fat layer
if not indexof["muscle"] is None: # or not indexof["fat"] is None
cdt_whole[indexof["core"], indexof["muscle"]] = cdt_cr_ms[i] # cr to ms
cdt_whole[indexof["muscle"], indexof["fat"]] = cdt_ms_fat[i] # ms to fat
cdt_whole[indexof["fat"], indexof["skin"]] = cdt_fat_sk[i] # fat to sk
if index_of["muscle"] is not None: # or not indexof["fat"] is None
cdt_whole[index_of["core"], index_of["muscle"]] = cdt_cr_ms[i] # cr to ms
cdt_whole[index_of["muscle"], index_of["fat"]] = cdt_ms_fat[i] # ms to fat
cdt_whole[index_of["fat"], index_of["skin"]] = cdt_fat_sk[i] # fat to sk

else:
cdt_whole[indexof["core"], indexof["skin"]] = cdt_cr_sk[i] # cr to sk
cdt_whole[index_of["core"], index_of["skin"]] = cdt_cr_sk[i] # cr to sk

# Creates a symmetrical matrix
cdt_whole = cdt_whole + cdt_whole.T
Expand All @@ -497,8 +494,7 @@ def conductance(


def capacity(height=1.72, weight=74.43, equation="dubois", age=20, ci=2.59):
"""
Calculate the thermal capacity [J/K].
"""Calculate the thermal capacity [J/K].
The values of vascular and central blood capacity have been derived from
Yokoyama's model.
Expand Down Expand Up @@ -704,24 +700,24 @@ def capacity(height=1.72, weight=74.43, equation="dubois", age=20, ci=2.59):
cap_whole[0] = cap_cb

for i, bn in enumerate(BODY_NAMES):
# Dictionary of indecies in each body segment
# Dictionary of indices in each body segment
# key = layer name, value = index of matrix
indexof = IDICT[bn]
index_of = IDICT[bn]

# Common
cap_whole[indexof["artery"]] = cap_art[i]
cap_whole[indexof["vein"]] = cap_vein[i]
cap_whole[indexof["core"]] = cap_cr[i]
cap_whole[indexof["skin"]] = cap_sk[i]
cap_whole[index_of["artery"]] = cap_art[i]
cap_whole[index_of["vein"]] = cap_vein[i]
cap_whole[index_of["core"]] = cap_cr[i]
cap_whole[index_of["skin"]] = cap_sk[i]

# Only limbs
if i >= 5:
cap_whole[indexof["sfvein"]] = cap_sfv[i]
cap_whole[index_of["sfvein"]] = cap_sfv[i]

# If the segment has a muscle or fat layer
if not indexof["muscle"] is None: # or not indexof["fat"] is None
cap_whole[indexof["muscle"]] = cap_ms[i]
cap_whole[indexof["fat"]] = cap_fat[i]
if index_of["muscle"] is not None: # or not indexof["fat"] is None
cap_whole[index_of["muscle"]] = cap_ms[i]
cap_whole[index_of["fat"]] = cap_fat[i]

cap_whole *= 3600 # Changes unit [Wh/K] to [J/K]
return cap_whole

0 comments on commit ed25119

Please sign in to comment.