-
Notifications
You must be signed in to change notification settings - Fork 78
Added biophysical fan use models for rest and occupational contexts #274
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
Added biophysical fan use models for rest and occupational contexts #274
Conversation
…BuiltEnvironment/development Development
…BuiltEnvironment/development Development
…BuiltEnvironment/development docs(changelog): Improve naming and formatting in changelog
…BuiltEnvironment/development development
…BuiltEnvironment/development development
new file: pythermalcomfort/models/bfu_rest.py new file: tests/test_bfu_occupational.py new file: tests/test_bfu_rest.py
WalkthroughThis PR introduces two biophysical fan use (BFU) models for evaluating safe fan operation: a resting model based on Morris2021 and an occupational model based on Foster2021. New input and output dataclasses support these models alongside comprehensive documentation, changelog updates, and test coverage. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Model as BFU Model<br/>(Rest or Occupational)
participant Inputs as Input Dataclass<br/>(Validation)
participant Calc as Calculation Engine<br/>(Physics)
participant Outputs as Output Dataclass
User->>Model: Call with tdb, rh, params
Model->>Inputs: Create inputs (validate)
alt Validation Fails
Inputs-->>User: ValueError
end
Inputs-->>Model: Valid inputs
Model->>Calc: Broadcast & compute heat transfer
Calc->>Calc: Calculate respiratory, evaporative,<br/>storage with/without fan
Calc-->>Model: Computed results
Model->>Outputs: Create result dataclass
Outputs-->>User: Return BFU_rest/BFU_occupational
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Areas requiring attention:
Possibly related PRs
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (52)
AUTHORS.rst(1 hunks)CHANGELOG.rst(1 hunks)docs/documentation/models.rst(1 hunks)docs/documentation/references.rst(1 hunks)pythermalcomfort/classes_input.py(2 hunks)pythermalcomfort/classes_return.py(1 hunks)pythermalcomfort/cli.py(0 hunks)pythermalcomfort/jos3_functions/construction.py(1 hunks)pythermalcomfort/jos3_functions/matrix.py(1 hunks)pythermalcomfort/jos3_functions/parameters.py(1 hunks)pythermalcomfort/jos3_functions/thermoregulation.py(3 hunks)pythermalcomfort/models/__init__.py(2 hunks)pythermalcomfort/models/adaptive_ashrae.py(0 hunks)pythermalcomfort/models/adaptive_en.py(0 hunks)pythermalcomfort/models/ankle_draft.py(1 hunks)pythermalcomfort/models/at.py(1 hunks)pythermalcomfort/models/bfu_occupational.py(1 hunks)pythermalcomfort/models/bfu_rest.py(1 hunks)pythermalcomfort/models/clo_tout.py(1 hunks)pythermalcomfort/models/cooling_effect.py(1 hunks)pythermalcomfort/models/discomfort_index.py(0 hunks)pythermalcomfort/models/esi.py(0 hunks)pythermalcomfort/models/heat_index_lu.py(1 hunks)pythermalcomfort/models/heat_index_rothfusz.py(1 hunks)pythermalcomfort/models/humidex.py(1 hunks)pythermalcomfort/models/jos3.py(3 hunks)pythermalcomfort/models/pet_steady.py(1 hunks)pythermalcomfort/models/phs.py(1 hunks)pythermalcomfort/models/pmv_a.py(1 hunks)pythermalcomfort/models/pmv_athb.py(1 hunks)pythermalcomfort/models/pmv_e.py(1 hunks)pythermalcomfort/models/pmv_ppd_iso.py(0 hunks)pythermalcomfort/models/ridge_regression_predict_t_re_t_sk.py(2 hunks)pythermalcomfort/models/set_tmp.py(0 hunks)pythermalcomfort/models/solar_gain.py(1 hunks)pythermalcomfort/models/thi.py(1 hunks)pythermalcomfort/models/two_nodes_gagge.py(1 hunks)pythermalcomfort/models/two_nodes_gagge_ji.py(1 hunks)pythermalcomfort/models/two_nodes_gagge_sleep.py(1 hunks)pythermalcomfort/models/use_fans_heatwaves.py(1 hunks)pythermalcomfort/models/utci.py(0 hunks)pythermalcomfort/models/vertical_tmp_grad_ppd.py(1 hunks)pythermalcomfort/models/wbgt.py(1 hunks)pythermalcomfort/models/wind_chill_temperature.py(0 hunks)pythermalcomfort/models/work_capacity_dunne.py(0 hunks)pythermalcomfort/models/work_capacity_hothaps.py(0 hunks)pythermalcomfort/models/work_capacity_iso.py(1 hunks)pythermalcomfort/models/work_capacity_niosh.py(1 hunks)pythermalcomfort/utilities.py(3 hunks)pythermalcomfort/utils/scale_wind_speed_log.py(1 hunks)tests/test_bfu_occupational.py(1 hunks)tests/test_bfu_rest.py(1 hunks)
💤 Files with no reviewable changes (11)
- pythermalcomfort/models/utci.py
- pythermalcomfort/models/adaptive_en.py
- pythermalcomfort/models/work_capacity_hothaps.py
- pythermalcomfort/models/discomfort_index.py
- pythermalcomfort/models/pmv_ppd_iso.py
- pythermalcomfort/models/adaptive_ashrae.py
- pythermalcomfort/models/esi.py
- pythermalcomfort/models/wind_chill_temperature.py
- pythermalcomfort/models/work_capacity_dunne.py
- pythermalcomfort/models/set_tmp.py
- pythermalcomfort/cli.py
🧰 Additional context used
📓 Path-based instructions (9)
docs/**/*.rst
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
docs/**/*.rst: Add an '.. autofunction:: pythermalcomfort.models..' entry to the docs for public APIs
Update the appropriate docs reference file that aggregates API docs when adding a public function
Files:
docs/documentation/models.rstdocs/documentation/references.rst
pythermalcomfort/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
pythermalcomfort/**/*.py: Use type hints and NumPy-style docstrings for all library code
Validate inputs in dataclass post_init (call super().post_init() if inheriting BaseInputs)
Convert pandas Series to list/np.array and normalize numeric inputs with np.asarray in post_init
Use validate_type(...) for type checks; raise TypeError for wrong types and ValueError for invalid values
Enforce physical constraints in validation (e.g., non-negativity, z2>z0, z1>z0, z2>z1) with clear error messages
Use numpy operations for numerical work (e.g., np.log, np.asarray) and avoid math.log when arrays are accepted
Validate domains before logs/roots (arguments must be > 0)
Support vectorized behavior; use np.atleast_1d, np.broadcast_to, and check broadcast compatibility
Follow repository patterns: dataclasses, BaseInputs metadata, validate_type, Units/Enums (Postures, WorkIntensity, Sex)
Functions should be small, single-purpose, and include concise, runnable examples in NumPy-style docstrings
Run ruff (lint/format) and docformatter; ensure code is formatted before PR
When accepting arrays, ensure computations are vectorized and avoid per-element Python loops
Files:
pythermalcomfort/utils/scale_wind_speed_log.pypythermalcomfort/models/jos3.pypythermalcomfort/models/at.pypythermalcomfort/jos3_functions/parameters.pypythermalcomfort/jos3_functions/thermoregulation.pypythermalcomfort/utilities.pypythermalcomfort/models/work_capacity_iso.pypythermalcomfort/models/clo_tout.pypythermalcomfort/jos3_functions/matrix.pypythermalcomfort/models/phs.pypythermalcomfort/models/heat_index_lu.pypythermalcomfort/models/pet_steady.pypythermalcomfort/models/bfu_rest.pypythermalcomfort/models/two_nodes_gagge.pypythermalcomfort/models/solar_gain.pypythermalcomfort/models/ridge_regression_predict_t_re_t_sk.pypythermalcomfort/models/use_fans_heatwaves.pypythermalcomfort/models/humidex.pypythermalcomfort/classes_input.pypythermalcomfort/models/thi.pypythermalcomfort/models/work_capacity_niosh.pypythermalcomfort/models/pmv_e.pypythermalcomfort/models/vertical_tmp_grad_ppd.pypythermalcomfort/models/pmv_athb.pypythermalcomfort/models/heat_index_rothfusz.pypythermalcomfort/models/ankle_draft.pypythermalcomfort/models/pmv_a.pypythermalcomfort/models/cooling_effect.pypythermalcomfort/models/__init__.pypythermalcomfort/classes_return.pypythermalcomfort/models/bfu_occupational.pypythermalcomfort/jos3_functions/construction.pypythermalcomfort/models/two_nodes_gagge_ji.pypythermalcomfort/models/two_nodes_gagge_sleep.pypythermalcomfort/models/wbgt.py
pythermalcomfort/models/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
pythermalcomfort/models/*.py: Place new domain model functions in pythermalcomfort/models/.py
Include applicability limits and minimal runnable examples in model function docstrings
Files:
pythermalcomfort/models/jos3.pypythermalcomfort/models/at.pypythermalcomfort/models/work_capacity_iso.pypythermalcomfort/models/clo_tout.pypythermalcomfort/models/phs.pypythermalcomfort/models/heat_index_lu.pypythermalcomfort/models/pet_steady.pypythermalcomfort/models/bfu_rest.pypythermalcomfort/models/two_nodes_gagge.pypythermalcomfort/models/solar_gain.pypythermalcomfort/models/ridge_regression_predict_t_re_t_sk.pypythermalcomfort/models/use_fans_heatwaves.pypythermalcomfort/models/humidex.pypythermalcomfort/models/thi.pypythermalcomfort/models/work_capacity_niosh.pypythermalcomfort/models/pmv_e.pypythermalcomfort/models/vertical_tmp_grad_ppd.pypythermalcomfort/models/pmv_athb.pypythermalcomfort/models/heat_index_rothfusz.pypythermalcomfort/models/ankle_draft.pypythermalcomfort/models/pmv_a.pypythermalcomfort/models/cooling_effect.pypythermalcomfort/models/__init__.pypythermalcomfort/models/bfu_occupational.pypythermalcomfort/models/two_nodes_gagge_ji.pypythermalcomfort/models/two_nodes_gagge_sleep.pypythermalcomfort/models/wbgt.py
AUTHORS.rst
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Optionally add the contributor to AUTHORS.rst
Files:
AUTHORS.rst
pythermalcomfort/utilities.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Place generic helper functions in pythermalcomfort/utilities.py
Files:
pythermalcomfort/utilities.py
pythermalcomfort/{models,utilities}.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Ensure docstring sections include Args (with units), Returns, Raises, Examples, Applicability
Files:
pythermalcomfort/utilities.py
CHANGELOG.*
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Update the CHANGELOG for public API changes
Files:
CHANGELOG.rst
pythermalcomfort/classes_input.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Add or update input dataclasses in pythermalcomfort/classes_input.py (or adjacent to the function when appropriate)
Files:
pythermalcomfort/classes_input.py
tests/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
tests/**/*.py: Write tests covering scalars, arrays, broadcasting, and invalid inputs (TypeError/ValueError)
Use numpy.testing or pytest.approx for numeric assertions
Ensure tests are deterministic, small, and pass locally with pytest before PR
Files:
tests/test_bfu_occupational.pytests/test_bfu_rest.py
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Follow repository patterns: dataclasses, BaseInputs metadata, validate_type, Units/Enums (Postures, WorkIntensity, Sex)
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/models/*.py : Include applicability limits and minimal runnable examples in model function docstrings
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/{models,utilities}.py : Ensure docstring sections include Args (with units), Returns, Raises, Examples, Applicability
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to docs/**/*.rst : Add an '.. autofunction:: pythermalcomfort.models.<module>.<func>' entry to the docs for public APIs
Applied to files:
docs/documentation/models.rstpythermalcomfort/models/at.pypythermalcomfort/jos3_functions/parameters.pypythermalcomfort/jos3_functions/thermoregulation.pypythermalcomfort/utilities.pypythermalcomfort/models/clo_tout.pypythermalcomfort/models/phs.pypythermalcomfort/models/solar_gain.pypythermalcomfort/models/heat_index_rothfusz.pypythermalcomfort/models/cooling_effect.pypythermalcomfort/models/__init__.pypythermalcomfort/jos3_functions/construction.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Follow repository patterns: dataclasses, BaseInputs metadata, validate_type, Units/Enums (Postures, WorkIntensity, Sex)
Applied to files:
docs/documentation/models.rstpythermalcomfort/jos3_functions/thermoregulation.pypythermalcomfort/utilities.pypythermalcomfort/models/work_capacity_iso.pypythermalcomfort/classes_input.pypythermalcomfort/classes_return.pypythermalcomfort/models/bfu_occupational.pytests/test_bfu_occupational.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/utilities.py : Place generic helper functions in pythermalcomfort/utilities.py
Applied to files:
docs/documentation/models.rstpythermalcomfort/jos3_functions/parameters.pypythermalcomfort/jos3_functions/thermoregulation.pypythermalcomfort/utilities.pypythermalcomfort/models/clo_tout.pypythermalcomfort/jos3_functions/matrix.pypythermalcomfort/jos3_functions/construction.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/{models,utilities}.py : Ensure docstring sections include Args (with units), Returns, Raises, Examples, Applicability
Applied to files:
pythermalcomfort/utils/scale_wind_speed_log.pypythermalcomfort/models/jos3.pypythermalcomfort/models/at.pypythermalcomfort/jos3_functions/parameters.pypythermalcomfort/jos3_functions/thermoregulation.pypythermalcomfort/utilities.pypythermalcomfort/models/work_capacity_iso.pypythermalcomfort/models/clo_tout.pypythermalcomfort/models/phs.pypythermalcomfort/models/heat_index_lu.pypythermalcomfort/models/pet_steady.pypythermalcomfort/models/two_nodes_gagge.pypythermalcomfort/models/solar_gain.pypythermalcomfort/models/ridge_regression_predict_t_re_t_sk.pypythermalcomfort/models/use_fans_heatwaves.pypythermalcomfort/models/humidex.pypythermalcomfort/models/thi.pypythermalcomfort/models/work_capacity_niosh.pypythermalcomfort/models/pmv_e.pypythermalcomfort/models/vertical_tmp_grad_ppd.pypythermalcomfort/models/heat_index_rothfusz.pypythermalcomfort/models/ankle_draft.pypythermalcomfort/models/cooling_effect.pypythermalcomfort/jos3_functions/construction.pypythermalcomfort/models/two_nodes_gagge_ji.pypythermalcomfort/models/two_nodes_gagge_sleep.pypythermalcomfort/models/wbgt.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/models/*.py : Include applicability limits and minimal runnable examples in model function docstrings
Applied to files:
pythermalcomfort/utils/scale_wind_speed_log.pypythermalcomfort/models/jos3.pypythermalcomfort/models/at.pypythermalcomfort/jos3_functions/parameters.pypythermalcomfort/jos3_functions/thermoregulation.pypythermalcomfort/utilities.pypythermalcomfort/models/work_capacity_iso.pypythermalcomfort/models/clo_tout.pypythermalcomfort/models/phs.pypythermalcomfort/models/heat_index_lu.pypythermalcomfort/models/two_nodes_gagge.pypythermalcomfort/models/solar_gain.pypythermalcomfort/models/ridge_regression_predict_t_re_t_sk.pypythermalcomfort/models/use_fans_heatwaves.pypythermalcomfort/models/humidex.pypythermalcomfort/models/thi.pypythermalcomfort/models/work_capacity_niosh.pypythermalcomfort/models/pmv_e.pypythermalcomfort/models/vertical_tmp_grad_ppd.pypythermalcomfort/models/pmv_athb.pypythermalcomfort/models/heat_index_rothfusz.pypythermalcomfort/models/ankle_draft.pypythermalcomfort/models/cooling_effect.pypythermalcomfort/jos3_functions/construction.pypythermalcomfort/models/two_nodes_gagge_ji.pypythermalcomfort/models/wbgt.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Functions should be small, single-purpose, and include concise, runnable examples in NumPy-style docstrings
Applied to files:
pythermalcomfort/utils/scale_wind_speed_log.pypythermalcomfort/models/jos3.pypythermalcomfort/models/at.pypythermalcomfort/jos3_functions/parameters.pypythermalcomfort/jos3_functions/thermoregulation.pypythermalcomfort/utilities.pypythermalcomfort/models/work_capacity_iso.pypythermalcomfort/models/clo_tout.pypythermalcomfort/jos3_functions/matrix.pypythermalcomfort/models/phs.pypythermalcomfort/models/heat_index_lu.pypythermalcomfort/models/pet_steady.pypythermalcomfort/models/two_nodes_gagge.pypythermalcomfort/models/solar_gain.pypythermalcomfort/models/ridge_regression_predict_t_re_t_sk.pypythermalcomfort/models/use_fans_heatwaves.pypythermalcomfort/models/humidex.pypythermalcomfort/models/thi.pypythermalcomfort/models/work_capacity_niosh.pypythermalcomfort/models/vertical_tmp_grad_ppd.pypythermalcomfort/models/heat_index_rothfusz.pypythermalcomfort/models/ankle_draft.pypythermalcomfort/models/cooling_effect.pypythermalcomfort/jos3_functions/construction.pypythermalcomfort/models/two_nodes_gagge_ji.pypythermalcomfort/models/wbgt.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Use type hints and NumPy-style docstrings for all library code
Applied to files:
pythermalcomfort/models/at.pypythermalcomfort/jos3_functions/parameters.pypythermalcomfort/jos3_functions/thermoregulation.pypythermalcomfort/utilities.pypythermalcomfort/models/clo_tout.pypythermalcomfort/jos3_functions/matrix.pypythermalcomfort/models/phs.pypythermalcomfort/models/heat_index_lu.pypythermalcomfort/models/solar_gain.pypythermalcomfort/models/use_fans_heatwaves.pypythermalcomfort/models/humidex.pypythermalcomfort/models/thi.pypythermalcomfort/models/work_capacity_niosh.pypythermalcomfort/models/vertical_tmp_grad_ppd.pypythermalcomfort/models/cooling_effect.pypythermalcomfort/jos3_functions/construction.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Support vectorized behavior; use np.atleast_1d, np.broadcast_to, and check broadcast compatibility
Applied to files:
pythermalcomfort/models/at.pypythermalcomfort/utilities.pytests/test_bfu_occupational.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to AUTHORS.rst : Optionally add the contributor to AUTHORS.rst
Applied to files:
AUTHORS.rst
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Run ruff (lint/format) and docformatter; ensure code is formatted before PR
Applied to files:
pythermalcomfort/jos3_functions/thermoregulation.pypythermalcomfort/utilities.pypythermalcomfort/models/thi.pypythermalcomfort/jos3_functions/construction.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Validate inputs in dataclass __post_init__ (call super().__post_init__() if inheriting BaseInputs)
Applied to files:
pythermalcomfort/models/use_fans_heatwaves.pypythermalcomfort/models/humidex.pypythermalcomfort/classes_input.pypythermalcomfort/models/thi.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/classes_input.py : Add or update input dataclasses in pythermalcomfort/classes_input.py (or adjacent to the function when appropriate)
Applied to files:
pythermalcomfort/classes_input.pypythermalcomfort/classes_return.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/models/*.py : Place new domain model functions in pythermalcomfort/models/<name>.py
Applied to files:
pythermalcomfort/models/bfu_occupational.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to tests/**/*.py : Write tests covering scalars, arrays, broadcasting, and invalid inputs (TypeError/ValueError)
Applied to files:
tests/test_bfu_occupational.pytests/test_bfu_rest.py
🧬 Code graph analysis (7)
pythermalcomfort/models/bfu_rest.py (2)
pythermalcomfort/classes_input.py (2)
BFU_rest_Groups(21-26)BFU_rest_Inputs(576-610)pythermalcomfort/classes_return.py (1)
BFU_rest(321-345)
pythermalcomfort/classes_input.py (1)
pythermalcomfort/models/jos3.py (10)
t_skin(1592-1594)t_skin(1597-1598)tdb(1393-1403)tdb(1406-1407)rh(1449-1451)rh(1454-1455)tr(1410-1412)tr(1415-1416)clo(1494-1496)clo(1499-1500)
pythermalcomfort/models/__init__.py (3)
pythermalcomfort/models/bfu_occupational.py (2)
bfu_occupational(9-289)BFU_occupational(292-323)pythermalcomfort/classes_return.py (2)
BFU_occupational(349-388)BFU_rest(321-345)pythermalcomfort/models/bfu_rest.py (1)
BFU_rest(227-240)
pythermalcomfort/classes_return.py (2)
pythermalcomfort/models/bfu_rest.py (1)
BFU_rest(227-240)pythermalcomfort/models/bfu_occupational.py (1)
BFU_occupational(292-323)
pythermalcomfort/models/bfu_occupational.py (2)
pythermalcomfort/classes_input.py (1)
BFU_occupational_Inputs(614-746)pythermalcomfort/classes_return.py (1)
BFU_occupational(349-388)
tests/test_bfu_occupational.py (2)
pythermalcomfort/models/bfu_occupational.py (2)
bfu_occupational(9-289)BFU_occupational(292-323)pythermalcomfort/classes_return.py (1)
BFU_occupational(349-388)
tests/test_bfu_rest.py (2)
pythermalcomfort/classes_return.py (1)
BFU_rest(321-345)pythermalcomfort/models/bfu_rest.py (1)
BFU_rest(227-240)
🔇 Additional comments (47)
AUTHORS.rst (1)
18-18: LGTM! Contributor addition follows existing patterns.The contributor entry and corresponding link anchor are properly formatted and consistent with the repository's attribution structure.
Also applies to: 26-26
pythermalcomfort/models/pmv_e.py (1)
23-29: LGTM! Docstring formatting refinement.This is a cosmetic line-wrapping adjustment with no functional impact. Aligns with the PR's automated linting/formatting pass.
pythermalcomfort/models/at.py (1)
17-22: LGTM! Formatting refinement.Line-wrapping adjustment to the docstring with no functional changes. Consistent with the automated formatting applied across the PR.
pythermalcomfort/models/heat_index_rothfusz.py (1)
16-17: LGTM! Docstring formatting adjustment.Line-wrapping refinement with no functional impact. Consistent with the automated formatting pass.
pythermalcomfort/models/work_capacity_niosh.py (1)
13-14: LGTM! Formatting refinement.Docstring line-wrapping adjustment with no functional changes. Part of the automated formatting applied in this PR.
pythermalcomfort/models/ankle_draft.py (1)
26-27: LGTM! Formatting adjustment.Line-wrapping refinement to the docstring with no functional impact. Consistent with the PR's automated formatting.
pythermalcomfort/models/pmv_a.py (1)
25-29: LGTM! Docstring formatting refinement.Line-wrapping adjustment with no functional changes. Aligns with the automated formatting applied across the PR.
pythermalcomfort/utilities.py (3)
818-819: LGTM – formatting improvement.The docstring reflow is clean and consistent with the repository's style guidelines.
1016-1017: LGTM – formatting improvement.The docstring adjustment improves readability without changing semantics.
1060-1061: LGTM – formatting improvement.The docstring formatting is consistent with the repository's standards.
pythermalcomfort/models/pmv_athb.py (1)
20-26: LGTM – docstring formatting improvement.The reformatted docstring maintains clarity while adhering to the repository's style guidelines. No functional changes detected.
pythermalcomfort/models/cooling_effect.py (1)
25-30: LGTM – docstring formatting improvement.The reformatted docstring is clearer and consistent with the repository's formatting standards. No functional changes.
pythermalcomfort/models/two_nodes_gagge_ji.py (1)
25-26: LGTM – docstring formatting improvement.The docstring reflow is clean and maintains the intended meaning without any functional changes.
pythermalcomfort/models/thi.py (1)
14-15: LGTM – docstring formatting improvement.The reformatted docstring is consistent with the repository's style guidelines. No functional changes.
pythermalcomfort/models/clo_tout.py (1)
16-17: LGTM – docstring formatting improvement.The docstring adjustment is clean and maintains clarity. No functional changes detected.
pythermalcomfort/models/vertical_tmp_grad_ppd.py (1)
21-23: LGTM – docstring formatting improvement.The docstring reflow improves readability while maintaining the original meaning. No functional changes.
pythermalcomfort/models/jos3.py (3)
382-383: LGTM – docstring formatting improvement.The docstring reflow is clean and consistent with the repository's style guidelines. No functional changes.
610-611: LGTM – docstring formatting improvement.The reformatted docstring maintains clarity and adheres to the repository's standards.
1139-1140: LGTM – docstring formatting improvement.The docstring adjustment improves readability without changing semantics. Formatting is consistent with the repository's guidelines.
pythermalcomfort/models/heat_index_lu.py (1)
16-42: Docstring tidy-up looks good.
Reflow aligns with the NumPy-style guidance and keeps the summary crisp—no behavioural risk introduced.pythermalcomfort/models/work_capacity_iso.py (1)
13-44: Docstring reflow approved.
The formatting tweak keeps the prose readable while maintaining reference details—nothing further needed.pythermalcomfort/models/phs.py (1)
32-202: Docstring polish looks solid.
The updated opening paragraph reads cleanly and stays faithful to the ISO references—no issues spotted.pythermalcomfort/jos3_functions/matrix.py (1)
1-168: Docstring refresh acknowledged.
The concise module summary matches our documentation tone and introduces no functional churn.pythermalcomfort/models/wbgt.py (1)
17-69: Docstring formatting change LGTM.
The reshaped intro adheres to our doc formatter style, keeping the WBGT guidance intact.pythermalcomfort/models/humidex.py (1)
16-20: LGTM - Formatting changes only.The docstring reflow improves readability without affecting functionality.
pythermalcomfort/jos3_functions/construction.py (1)
1-6: LGTM - Docstring formatting improvements.Module docstring reflow enhances readability with no functional changes.
pythermalcomfort/models/pet_steady.py (1)
234-236: LGTM - Docstring formatting adjustment.The docstring reflow improves line-length consistency without affecting the implementation.
pythermalcomfort/models/solar_gain.py (1)
24-29: LGTM - Docstring formatting enhancement.Line wrapping adjustment improves readability with no functional impact.
pythermalcomfort/models/use_fans_heatwaves.py (1)
32-32: LGTM - Docstring formatting improvement.The opening sentence consolidation enhances consistency without affecting functionality.
pythermalcomfort/models/two_nodes_gagge_sleep.py (1)
22-23: LGTM - Docstring formatting adjustment.The line reflow improves consistency with no functional changes.
pythermalcomfort/models/ridge_regression_predict_t_re_t_sk.py (2)
3-5: LGTM - Module docstring formatting improvement.The line wrapping adjustment enhances readability without affecting functionality.
206-207: LGTM - Function docstring formatting adjustment.The docstring reflow improves consistency with no functional changes.
pythermalcomfort/models/two_nodes_gagge.py (1)
30-31: LGTM - Docstring formatting enhancement.The line reflow improves readability without affecting the implementation.
pythermalcomfort/models/__init__.py (1)
5-6: LGTM! Public API exports are correctly structured.The new biophysical fan use models are properly imported and exposed following the repository's established patterns. Both imports and
__all__entries maintain alphabetical ordering.Also applies to: 47-48
CHANGELOG.rst (1)
4-8: LGTM! Changelog entry is clear and properly formatted.The version entry accurately documents the addition of the two biophysical fan use models with appropriate reference citations. The RST syntax is correct.
pythermalcomfort/jos3_functions/parameters.py (3)
1-14: LGTM! Formatting improvements only.Module docstring has been reformatted for better readability. No functional changes.
420-420: LGTM! Formatting improvement only.Docstring line rewrapped for better readability. No functional changes.
457-458: LGTM! Formatting improvement only.Docstring line rewrapped for better readability. No functional changes.
pythermalcomfort/utils/scale_wind_speed_log.py (1)
17-18: LGTM! Formatting improvement only.Docstring first line rewrapped for better readability. No functional changes.
pythermalcomfort/jos3_functions/thermoregulation.py (1)
1-1: LGTM! Formatting improvement only.Module docstring reformatted. No functional changes.
docs/documentation/references.rst (1)
45-46: LGTM! Reference entries are properly formatted.Both Morris2021 and Foster2021 references are correctly added with appropriate bibliographic information, matching the citations used in the new models' documentation.
tests/test_bfu_occupational.py (3)
7-26: LGTM! Scalar test validates core functionality.Test properly validates:
- Heat storage reduction with fan use
- Interpretation mapping based on delta_storage thresholds
- Use of
round_output=Falsefor precise assertions
29-64: LGTM! Array test validates vectorization.Test properly validates:
- All output attributes are numpy arrays with correct shapes
- Broadcasting works with per-element position and activity arrays
- Interpretation logic applied element-wise
67-73: LGTM! Error handling validated.Test correctly verifies that an invalid position ("lying") raises a ValueError, ensuring proper input validation.
tests/test_bfu_rest.py (3)
7-11: LGTM! Scalar test validates core functionality.Test properly validates:
- Group identifier propagation to result
- Positive heat_storage indicating fan benefit
14-28: LGTM! Array test validates vectorization.Test properly validates:
- All output attributes are numpy arrays with correct shapes
- Vectorized computation works correctly
- Use of
round_output=Falsefor precise assertions
31-33: LGTM! Error handling validated.Test correctly verifies that an invalid group raises a ValueError, ensuring proper input validation.
|
@nravanelli thank you so much for working on this, could you please review the comments from coderabbit. I will then also provide comments to the code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have left a few comments on the classes_input.py
|
@nravanelli thank you for contributing to the project. I noticed the following issues:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
.pre-commit-config.yaml(1 hunks)CONTRIBUTING.rst(1 hunks)pythermalcomfort/classes_input.py(2 hunks)pythermalcomfort/models/bfu_rest.py(1 hunks)tests/test_bfu_occupational.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
pythermalcomfort/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
pythermalcomfort/**/*.py: Use type hints and NumPy-style docstrings for all library code
Validate inputs in dataclass post_init (call super().post_init() if inheriting BaseInputs)
Convert pandas Series to list/np.array and normalize numeric inputs with np.asarray in post_init
Use validate_type(...) for type checks; raise TypeError for wrong types and ValueError for invalid values
Enforce physical constraints in validation (e.g., non-negativity, z2>z0, z1>z0, z2>z1) with clear error messages
Use numpy operations for numerical work (e.g., np.log, np.asarray) and avoid math.log when arrays are accepted
Validate domains before logs/roots (arguments must be > 0)
Support vectorized behavior; use np.atleast_1d, np.broadcast_to, and check broadcast compatibility
Follow repository patterns: dataclasses, BaseInputs metadata, validate_type, Units/Enums (Postures, WorkIntensity, Sex)
Functions should be small, single-purpose, and include concise, runnable examples in NumPy-style docstrings
Run ruff (lint/format) and docformatter; ensure code is formatted before PR
When accepting arrays, ensure computations are vectorized and avoid per-element Python loops
Files:
pythermalcomfort/classes_input.pypythermalcomfort/models/bfu_rest.py
pythermalcomfort/classes_input.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Add or update input dataclasses in pythermalcomfort/classes_input.py (or adjacent to the function when appropriate)
Files:
pythermalcomfort/classes_input.py
pythermalcomfort/models/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
pythermalcomfort/models/*.py: Place new domain model functions in pythermalcomfort/models/.py
Include applicability limits and minimal runnable examples in model function docstrings
Files:
pythermalcomfort/models/bfu_rest.py
tests/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
tests/**/*.py: Write tests covering scalars, arrays, broadcasting, and invalid inputs (TypeError/ValueError)
Use numpy.testing or pytest.approx for numeric assertions
Ensure tests are deterministic, small, and pass locally with pytest before PR
Files:
tests/test_bfu_occupational.py
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Follow repository patterns: dataclasses, BaseInputs metadata, validate_type, Units/Enums (Postures, WorkIntensity, Sex)
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Follow repository patterns: dataclasses, BaseInputs metadata, validate_type, Units/Enums (Postures, WorkIntensity, Sex)
Applied to files:
pythermalcomfort/classes_input.pyCONTRIBUTING.rsttests/test_bfu_occupational.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/classes_input.py : Add or update input dataclasses in pythermalcomfort/classes_input.py (or adjacent to the function when appropriate)
Applied to files:
pythermalcomfort/classes_input.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Validate inputs in dataclass __post_init__ (call super().__post_init__() if inheriting BaseInputs)
Applied to files:
pythermalcomfort/classes_input.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to tests/**/*.py : Write tests covering scalars, arrays, broadcasting, and invalid inputs (TypeError/ValueError)
Applied to files:
pythermalcomfort/classes_input.pytests/test_bfu_occupational.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Run ruff (lint/format) and docformatter; ensure code is formatted before PR
Applied to files:
CONTRIBUTING.rst
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Add a PR checklist including tests, docstrings, docs, CHANGELOG (if applicable), lint/format, and CI checks
Applied to files:
CONTRIBUTING.rst
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Use type hints and NumPy-style docstrings for all library code
Applied to files:
CONTRIBUTING.rst
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/{models,utilities}.py : Ensure docstring sections include Args (with units), Returns, Raises, Examples, Applicability
Applied to files:
CONTRIBUTING.rst
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Functions should be small, single-purpose, and include concise, runnable examples in NumPy-style docstrings
Applied to files:
CONTRIBUTING.rst
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Support vectorized behavior; use np.atleast_1d, np.broadcast_to, and check broadcast compatibility
Applied to files:
tests/test_bfu_occupational.py
🧬 Code graph analysis (2)
pythermalcomfort/models/bfu_rest.py (2)
pythermalcomfort/classes_input.py (2)
BFU_rest_Groups(21-34)BFU_rest_Inputs(584-618)pythermalcomfort/classes_return.py (1)
BFU_rest(321-345)
tests/test_bfu_occupational.py (2)
pythermalcomfort/models/bfu_occupational.py (2)
bfu_occupational(9-289)BFU_occupational(292-323)pythermalcomfort/classes_return.py (1)
BFU_occupational(349-388)
…i/Feature/biophysical_fan_models # Conflicts: # CHANGELOG.rst # docs/documentation/references.rst # pythermalcomfort/utilities.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
CHANGELOG.rst(1 hunks)docs/documentation/references.rst(1 hunks)pythermalcomfort/classes_return.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
CHANGELOG.*
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Update the CHANGELOG for public API changes
Files:
CHANGELOG.rst
docs/**/*.rst
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
docs/**/*.rst: Add an '.. autofunction:: pythermalcomfort.models..' entry to the docs for public APIs
Update the appropriate docs reference file that aggregates API docs when adding a public function
Files:
docs/documentation/references.rst
pythermalcomfort/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
pythermalcomfort/**/*.py: Use type hints and NumPy-style docstrings for all library code
Validate inputs in dataclass post_init (call super().post_init() if inheriting BaseInputs)
Convert pandas Series to list/np.array and normalize numeric inputs with np.asarray in post_init
Use validate_type(...) for type checks; raise TypeError for wrong types and ValueError for invalid values
Enforce physical constraints in validation (e.g., non-negativity, z2>z0, z1>z0, z2>z1) with clear error messages
Use numpy operations for numerical work (e.g., np.log, np.asarray) and avoid math.log when arrays are accepted
Validate domains before logs/roots (arguments must be > 0)
Support vectorized behavior; use np.atleast_1d, np.broadcast_to, and check broadcast compatibility
Follow repository patterns: dataclasses, BaseInputs metadata, validate_type, Units/Enums (Postures, WorkIntensity, Sex)
Functions should be small, single-purpose, and include concise, runnable examples in NumPy-style docstrings
Run ruff (lint/format) and docformatter; ensure code is formatted before PR
When accepting arrays, ensure computations are vectorized and avoid per-element Python loops
Files:
pythermalcomfort/classes_return.py
🧠 Learnings (2)
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/**/*.py : Follow repository patterns: dataclasses, BaseInputs metadata, validate_type, Units/Enums (Postures, WorkIntensity, Sex)
Applied to files:
pythermalcomfort/classes_return.py
📚 Learning: 2025-09-15T01:23:02.859Z
Learnt from: CR
Repo: CenterForTheBuiltEnvironment/pythermalcomfort PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-15T01:23:02.859Z
Learning: Applies to pythermalcomfort/classes_input.py : Add or update input dataclasses in pythermalcomfort/classes_input.py (or adjacent to the function when appropriate)
Applied to files:
pythermalcomfort/classes_return.py
🧬 Code graph analysis (1)
pythermalcomfort/classes_return.py (2)
pythermalcomfort/models/bfu_rest.py (1)
BFU_rest(225-238)pythermalcomfort/models/bfu_occupational.py (1)
BFU_occupational(292-323)
🔇 Additional comments (2)
CHANGELOG.rst (1)
4-8: CHANGELOG entry is clear and follows repository conventions.The new version entry correctly documents the addition of the two biophysical fan use models with proper references. The brief format is consistent with other entries in the changelog. The date matches the release context, and the reference notation
[Morris2021]_and[Foster2021]_correctly links to the new references added indocs/documentation/references.rst.docs/documentation/references.rst (1)
45-46: Consider adding DOIs for the new references.The reference format is consistent with existing entries, but many recent references in this file include DOI links (e.g., Forbes2025, Ji2022, Yan2025). Both Morris2021 and Foster2021 should have DOIs that would improve traceability.
Based on the PR description mentioning specific DOIs, please verify and add them to the references:
- Morris et al. 2021: DOI: 10.1016/S2542-5196(21)00136-4
- Foster et al. 2021: DOI: 10.1007/s00484-021-02212-y
Apply this diff to add the DOIs:
-.. [Morris2021] Morris N, Chaseling G, English T, Gruss F, Bin Maideen MF, Capon A, Jay O. Electric fan use for cooling during hot weather: a biophysical modelling study. Lancet - Planetary Health. 2021; 5(6): E368-E377. -.. [Foster2021] Foster J, Smallcombe J, Hodder S, Jay O, Flouris A, Havenith G. Quantifying the impact of heat on human physical work capacity; part II: the observed interaction of air velocity with temperature, humidity, sweat rate, and clothing is not captured by most heat stress indices. International Journal of Biometeorology. 2021 Nov;66(3):507-520. +.. [Morris2021] Morris N, Chaseling G, English T, Gruss F, Bin Maideen MF, Capon A, Jay O. Electric fan use for cooling during hot weather: a biophysical modelling study. Lancet - Planetary Health. 2021; 5(6): E368-E377. DOI: 10.1016/S2542-5196(21)00136-4 +.. [Foster2021] Foster J, Smallcombe J, Hodder S, Jay O, Flouris A, Havenith G. Quantifying the impact of heat on human physical work capacity; part II: the observed interaction of air velocity with temperature, humidity, sweat rate, and clothing is not captured by most heat stress indices. International Journal of Biometeorology. 2021 Nov;66(3):507-520. DOI: 10.1007/s00484-021-02212-y
| @dataclass(frozen=True, repr=False) | ||
| class BFU_rest(AutoStrMixin): | ||
| """Dataclass for the fan biophysical model from Morris et al. 2021. | ||
| Attributes | ||
| ---------- | ||
| heat_storage : float or list of floats | ||
| Differential heat storage when using the fan vs. not using the fan, [W/m²]. | ||
| e_req_fan : float or list of floats | ||
| Required evaporative heat loss with the fan, [W/m²]. | ||
| e_max_fan : float or list of floats | ||
| Maximum possible evaporative heat loss with the fan, [W/m²]. | ||
| e_req_no_fan : float or list of floats | ||
| Required evaporative heat loss without the fan, [W/m²]. | ||
| e_max_no_fan : float or list of floats | ||
| Maximum possible evaporative heat loss without the fan, [W/m²]. | ||
| group : str | ||
| Population group identifier used for the calculation (YNG, OLD, MEDS). | ||
| """ | ||
|
|
||
| heat_storage: float | list[float] | ||
| e_req_fan: float | list[float] | ||
| e_max_fan: float | list[float] | ||
| e_req_no_fan: float | list[float] | ||
| e_max_no_fan: float | list[float] | ||
| group: str | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Type hints should include np.ndarray for vectorized support.
The type hints for numeric fields use float | list[float], but the models support vectorized operations via NumPy arrays. For consistency with the coding guidelines ("Support vectorized behavior; use np.atleast_1d, np.broadcast_to") and to accurately reflect the implementation, consider using float | list[float] | np.ndarray or npt.ArrayLike for all numeric fields.
This pattern is already used in some dataclasses (e.g., HI at line 301, ScaleWindSpeedLog at line 1117), though many legacy dataclasses don't include it. For new code, explicitly supporting np.ndarray in type hints improves clarity.
Apply this diff to update the type hints:
@dataclass(frozen=True, repr=False)
class BFU_rest(AutoStrMixin):
"""Dataclass for the fan biophysical model from Morris et al. 2021.
Attributes
----------
- heat_storage : float or list of floats
+ heat_storage : float or list of floats or np.ndarray
Differential heat storage when using the fan vs. not using the fan, [W/m²].
- e_req_fan : float or list of floats
+ e_req_fan : float or list of floats or np.ndarray
Required evaporative heat loss with the fan, [W/m²].
- e_max_fan : float or list of floats
+ e_max_fan : float or list of floats or np.ndarray
Maximum possible evaporative heat loss with the fan, [W/m²].
- e_req_no_fan : float or list of floats
+ e_req_no_fan : float or list of floats or np.ndarray
Required evaporative heat loss without the fan, [W/m²].
- e_max_no_fan : float or list of floats
+ e_max_no_fan : float or list of floats or np.ndarray
Maximum possible evaporative heat loss without the fan, [W/m²].
group : str
Population group identifier used for the calculation (YNG, OLD, MEDS).
"""
- heat_storage: float | list[float]
- e_req_fan: float | list[float]
- e_max_fan: float | list[float]
- e_req_no_fan: float | list[float]
- e_max_no_fan: float | list[float]
+ heat_storage: float | list[float] | np.ndarray
+ e_req_fan: float | list[float] | np.ndarray
+ e_max_fan: float | list[float] | np.ndarray
+ e_req_no_fan: float | list[float] | np.ndarray
+ e_max_no_fan: float | list[float] | np.ndarray
group: str🤖 Prompt for AI Agents
In pythermalcomfort/classes_return.py around lines 321 to 347, the numeric type
hints for BFU_rest use float | list[float] but should include NumPy array types
for vectorized support; update the type annotations for heat_storage, e_req_fan,
e_max_fan, e_req_no_fan, and e_max_no_fan to include np.ndarray or, preferably,
npt.ArrayLike (e.g., float | list[float] | npt.ArrayLike) and add the necessary
import from numpy.typing (import numpy.typing as npt) or import numpy as np if
you opt for np.ndarray, ensuring consistency with other dataclasses that support
vectorized inputs.
| @dataclass(frozen=True, repr=False) | ||
| class BFU_occupational(AutoStrMixin): | ||
| """Dataclass for the occupational fan use model from Foster et al. 2021. | ||
| Attributes | ||
| ---------- | ||
| storage_fan : float or list of floats | ||
| Heat storage rate when the fan is operating, [W/m²]. | ||
| storage_no_fan : float or list of floats | ||
| Heat storage rate without the fan, [W/m²]. | ||
| delta_storage : float or list of floats | ||
| Reduction in heat storage provided by the fan (positive means beneficial), [W/m²]. | ||
| dry_heat_fan : float or list of floats | ||
| Dry heat loss with the fan (radiative + convective), [W/m²]. | ||
| dry_heat_no_fan : float or list of floats | ||
| Dry heat loss without the fan, [W/m²]. | ||
| evaporative_heat_fan : float or list of floats | ||
| Evaporative heat loss via sweating with the fan, [W/m²]. | ||
| evaporative_heat_no_fan : float or list of floats | ||
| Evaporative heat loss via sweating without the fan, [W/m²]. | ||
| respiratory_heat : float or list of floats | ||
| Combined sensible and latent respiratory heat exchange, [W/m²]. | ||
| sweat_efficiency_fan : float or list of floats | ||
| Sweating efficiency (η) with the fan, [-]. | ||
| sweat_efficiency_no_fan : float or list of floats | ||
| Sweating efficiency (η) without the fan, [-]. | ||
| interpretation : int or list of int | ||
| Qualitative interpretation based on Foster et al 2021 (1 = beneficial, 0 = neutral, -1 = harmful). | ||
| """ | ||
|
|
||
| storage_fan: float | list[float] | ||
| storage_no_fan: float | list[float] | ||
| delta_storage: float | list[float] | ||
| dry_heat_fan: float | list[float] | ||
| dry_heat_no_fan: float | list[float] | ||
| evaporative_heat_fan: float | list[float] | ||
| evaporative_heat_no_fan: float | list[float] | ||
| respiratory_heat: float | list[float] | ||
| sweat_efficiency_fan: float | list[float] | ||
| sweat_efficiency_no_fan: float | list[float] | ||
| interpretation: int | list[int] | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Type hints should include np.ndarray for vectorized support.
Similar to BFU_rest, the type hints for numeric and integer fields should include np.ndarray to accurately reflect vectorized operation support. This applies to all fields including interpretation, which should be int | list[int] | np.ndarray.
Apply this diff to update the type hints:
@dataclass(frozen=True, repr=False)
class BFU_occupational(AutoStrMixin):
"""Dataclass for the occupational fan use model from Foster et al. 2021.
Attributes
----------
- storage_fan : float or list of floats
+ storage_fan : float or list of floats or np.ndarray
Heat storage rate when the fan is operating, [W/m²].
- storage_no_fan : float or list of floats
+ storage_no_fan : float or list of floats or np.ndarray
Heat storage rate without the fan, [W/m²].
- delta_storage : float or list of floats
+ delta_storage : float or list of floats or np.ndarray
Reduction in heat storage provided by the fan (positive means beneficial), [W/m²].
- dry_heat_fan : float or list of floats
+ dry_heat_fan : float or list of floats or np.ndarray
Dry heat loss with the fan (radiative + convective), [W/m²].
- dry_heat_no_fan : float or list of floats
+ dry_heat_no_fan : float or list of floats or np.ndarray
Dry heat loss without the fan, [W/m²].
- evaporative_heat_fan : float or list of floats
+ evaporative_heat_fan : float or list of floats or np.ndarray
Evaporative heat loss via sweating with the fan, [W/m²].
- evaporative_heat_no_fan : float or list of floats
+ evaporative_heat_no_fan : float or list of floats or np.ndarray
Evaporative heat loss via sweating without the fan, [W/m²].
- respiratory_heat : float or list of floats
+ respiratory_heat : float or list of floats or np.ndarray
Combined sensible and latent respiratory heat exchange, [W/m²].
- sweat_efficiency_fan : float or list of floats
+ sweat_efficiency_fan : float or list of floats or np.ndarray
Sweating efficiency (η) with the fan, [-].
- sweat_efficiency_no_fan : float or list of floats
+ sweat_efficiency_no_fan : float or list of floats or np.ndarray
Sweating efficiency (η) without the fan, [-].
- interpretation : int or list of int
+ interpretation : int or list of int or np.ndarray
Qualitative interpretation based on Foster et al 2021 (1 = beneficial, 0 = neutral, -1 = harmful).
"""
- storage_fan: float | list[float]
- storage_no_fan: float | list[float]
- delta_storage: float | list[float]
- dry_heat_fan: float | list[float]
- dry_heat_no_fan: float | list[float]
- evaporative_heat_fan: float | list[float]
- evaporative_heat_no_fan: float | list[float]
- respiratory_heat: float | list[float]
- sweat_efficiency_fan: float | list[float]
- sweat_efficiency_no_fan: float | list[float]
- interpretation: int | list[int]
+ storage_fan: float | list[float] | np.ndarray
+ storage_no_fan: float | list[float] | np.ndarray
+ delta_storage: float | list[float] | np.ndarray
+ dry_heat_fan: float | list[float] | np.ndarray
+ dry_heat_no_fan: float | list[float] | np.ndarray
+ evaporative_heat_fan: float | list[float] | np.ndarray
+ evaporative_heat_no_fan: float | list[float] | np.ndarray
+ respiratory_heat: float | list[float] | np.ndarray
+ sweat_efficiency_fan: float | list[float] | np.ndarray
+ sweat_efficiency_no_fan: float | list[float] | np.ndarray
+ interpretation: int | list[int] | np.ndarray🤖 Prompt for AI Agents
In pythermalcomfort/classes_return.py around lines 349 to 390, the dataclass
BFU_occupational's type hints currently list float | list[float] and int |
list[int] but omit np.ndarray support; update every numeric and integer field
annotation (storage_fan, storage_no_fan, delta_storage, dry_heat_fan,
dry_heat_no_fan, evaporative_heat_fan, evaporative_heat_no_fan,
respiratory_heat, sweat_efficiency_fan, sweat_efficiency_no_fan, interpretation)
to include np.ndarray in the union (e.g., float | list[float] | np.ndarray and
int | list[int] | np.ndarray for interpretation), and ensure numpy is imported
as np at the top of the module if it isn’t already.
FedericoTartarini
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you Nick so much for contributing, I left a few important comments for you to review and address. I also merged development in this branch to make sure that the changes in this pull request are only related to the models you are proposing to include. Please let me know if my comments are not clear, happy to have a quick chat if needed.
| :members: | ||
|
|
||
| Biophysical Fan Use Model: Occupational | ||
| ------------------------- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you please describe briefly what these model are and why there are two, occupational and resting? Should not be met an input and should not we combine the two?
|
|
||
| This function is derived from the occupational biophysical fan use model described by Foster et al. 2021 [Foster2021]_ | ||
|
|
||
| .. autofunction:: pythermalcomfort.models.bfu_occupational.BFU_occupational |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all functions names should be lower case
| Biophysical Fan Use Model: Occupational | ||
| ------------------------- | ||
|
|
||
| This function is derived from the occupational biophysical fan use model described by Foster et al. 2021 [Foster2021]_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this text and move it inside the function docstring
| body_surface_area: float | list[float] | np.ndarray = 1.81, | ||
| round_output: bool = True, | ||
| ) -> BFUOccupationalResult: | ||
| """Compute the potential benefit of fans in an occupational context using the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please provide more information about the model and include the reference
| tdb: float | list[float] | np.ndarray, | ||
| rh: float | list[float] | np.ndarray, | ||
| tr: float | list[float] | np.ndarray | None = None, | ||
| clo: float | list[float] | np.ndarray = 0.28, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clo and met should not be default values, the user should enter them manually
|
|
||
|
|
||
| @dataclass(frozen=True, repr=False) | ||
| class BFU_rest(AutoStrMixin): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check name
| e_max_fan: float | list[float] | ||
| e_req_no_fan: float | list[float] | ||
| e_max_no_fan: float | list[float] | ||
| group: str |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure this should be returned since it is an input and it is not modified by the function, I assume
| respiratory_heat: float | list[float] | ||
| sweat_efficiency_fan: float | list[float] | ||
| sweat_efficiency_no_fan: float | list[float] | ||
| interpretation: int | list[int] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use a better variable name?
| delta_storage: float | list[float] | ||
| dry_heat_fan: float | list[float] | ||
| dry_heat_no_fan: float | list[float] | ||
| evaporative_heat_fan: float | list[float] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the var names do not follow the same naming convention in the new two return classes
| assert result.delta_storage < 0 # fan reduces heat storage | ||
| assert result.storage_no_fan > result.storage_fan | ||
|
|
||
| if result.delta_storage < -50: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we will need to add a few more tests if possible
|
@nravanelli please also review the comments from coderabbit and check the code with ruff check and format |
Added 2 biophysical fan use models from Foster et al. 2021 (occupational) and Morris et al. 2021 (rest). Each use a similar concept for determining the net heat storage benefit with fan use relative to still air. The occupational model uses different clothing assumptions and net air velocity (incorporating self generated airflow). I therefore kept them separate and reference both papers independently. The occupational model adopts the interpretation provided of the net difference in heat storage. The models were tested and reproduce the same reference figures/conclusions provided by both peer reviewed papers.
[ X ] New tests added and passing.
[ X ] Docstring updated with examples and applicability limits.
[ X ] Documentation (autofunction) updated if public API changed.
[ X ] CHANGELOG updated (if applicable).
[ X ] Linting and formatting applied.
[ X ] All CI checks pass.
New files added to the repository:
new file: pythermalcomfort/models/bfu_rest.py
new file: pythermalcomfort/models/bfu_occupational.py
new file: tests/test_bfu_occupational.py
new file: tests/test_bfu_rest.py
@FedericoTartarini I think the linting/formatting I ran created small changes in linespacing in my version. Nothing else.
Summary by CodeRabbit
Release Notes – Version 3.9.0
New Features
Documentation
Tests
Chores