Source code for ladybug.climatezone

# coding=utf-8
"""Functions for computing climate classifications/zones from weather data."""
from __future__ import division

from .datacollection import HourlyContinuousCollection


[docs]def ashrae_climate_zone(dry_bulb_temperature, annual_precipitation=None): """Estimate the ASHRAE climate zone from a single year of dry bulb temperature. Note: [1] American Society of Heating Refrigerating and Air-Conditioning Engineers. 2010. ASHRAE 90.1-2010, Table B-4 International Climate Zone Definitions. Args: dry_bulb_temperature: A HourlyContinuousCollection of air temperature data, typically coming from an EPW. annual_precipitation: A number for the total annual liquid precipitation depth in millimeters. This is used to determine whether the resulting climate has the "dry" classification. If None, the climate will always be assumed to be humid (type "A"), which tends to be more common than the dry classification (type "B"). Returns: Text for the ASHRAE climate zone classification (eg. "4A"). """ # check the input dry_bulb_temperature dbt = dry_bulb_temperature assert isinstance(dbt, HourlyContinuousCollection), \ 'Expected HourlyContinuousCollection for ashrae_climate_zone ' \ 'dry_bulb_temperature. Got {}.'.format(type(dbt)) aper = dbt.header.analysis_period assert aper.is_annual, 'ashrae_climate_zone dry_bulb_temperature must be annual.' assert aper.timestep == 1, \ 'ashrae_climate_zone dry_bulb_temperature must have a timestep of 1.' if dbt.header.unit != 'C': dbt = dbt.to_unit('C') # compute the number of heating and cooling degree days cooling_deg_days, heating_deg_days = 0, 0 for t in dbt.values: cdd = (t - 10) / 24 if t > 10 else 0 cooling_deg_days += cdd hdd = (18 - t) / 24 if t < 18 else 0 heating_deg_days += hdd # get the climate zone number from analysis of the degree days potential_c, no_letter = False, False if cooling_deg_days > 5000: cz_number = '1' elif cooling_deg_days > 3500: cz_number = '2' elif cooling_deg_days > 2500: cz_number = '3' elif cooling_deg_days <= 2500 and heating_deg_days <= 2000: cz_number, potential_c = '3', True elif cooling_deg_days <= 2500 and heating_deg_days <= 3000: cz_number = '4' elif heating_deg_days <= 3000: cz_number, potential_c = '4', True elif heating_deg_days <= 4000: cz_number, potential_c = '5', True elif heating_deg_days <= 5000: cz_number = '6' elif heating_deg_days <= 7000: cz_number, no_letter = '7', True else: cz_number, no_letter = '8', True # determine the letter of the climate zone and return the result if no_letter: return cz_number if potential_c: month_temps = dry_bulb_temperature.average_monthly() if -3 < month_temps.min < 18 and month_temps.max < 22: if len([mon for mon in month_temps if mon > 10]) >= 4: return '{}C'.format(cz_number) if annual_precipitation is not None: precipitation_limit = 20 * (dry_bulb_temperature.average + 7) if annual_precipitation < precipitation_limit: return '{}B'.format(cz_number) return '{}A'.format(cz_number)