# Path: brew/constants.py
# GAL_PER_LITER = 1.0 / LITER_PER_GAL
# 
# Path: brew/constants.py
# IMPERIAL_TYPES = {
#     u"volume": u"gallon",
#     u"weight_large": u"lbs",
#     u"weight_small": u"oz",
#     u"temperature": u"degF",
# }
# 
# Path: brew/constants.py
# IMPERIAL_UNITS = u"imperial"
# 
# Path: brew/constants.py
# LITER_PER_GAL = 3.78541
# 
# Path: brew/constants.py
# OZ_PER_G = 1.0 / G_PER_OZ
# 
# Path: brew/constants.py
# SI_TYPES = {
#     u"volume": u"liter",
#     u"weight_large": u"kg",
#     u"weight_small": u"mg",
#     u"temperature": u"degC",
# }
# 
# Path: brew/constants.py
# SI_UNITS = u"metric"
# 
# Path: brew/exceptions.py
# class YeastException(BrewdayException):
#     pass
# 
# Path: brew/validators.py
# def validate_units(units):
#     """
#     Validate units
# 
#     :param str units: Unit type
#     :return: units
#     :rtype: str
#     :raises ValidatorException: If units is unknown
#     """
#     if units in [IMPERIAL_UNITS, SI_UNITS]:
#         return units
#     raise ValidatorException(
#         u"Unkown units '{}', must use {} or {}".format(units, IMPERIAL_UNITS, SI_UNITS)
#     )
# 
# Path: brew/utilities/sugar.py
# def plato_to_sg(deg_plato):
#     """
#     Degrees Plato to Specific Gravity
# 
#     :param float deg_plato: Degrees Plato
#     :return: Specific Gravity
#     :rtype: float
# 
#     The simple formula for S.G. is:
# 
#     :math:`\\text{SG} = 1 + 0.004 \\times \\text{Plato}`
# 
#     The more precise calculation of SG is:
# 
#     :math:`\\text{SG} = \\frac{Plato}{258.6 - \\big(\\frac{Plato}{258.2} \\times 227.1\\big)} + 1`
# 
#     Source:
# 
#     * http://www.learntobrew.com/page/1mdhe/Shopping/Beer_Calculations.html
#     """  # noqa
#     return (deg_plato / (258.6 - ((deg_plato / 258.2) * 227.1))) + 1.0
# 
# Path: brew/utilities/sugar.py
# def sg_to_gu(sg):
#     """
#     Specific Gravity to Gravity Units
# 
#     :param float sg: Specific Gravity
#     :return: Gravity Units
#     :rtype: float
#     """
#     return (sg - 1) * 1000.0
# 
# Path: brew/utilities/sugar.py
# def sg_to_plato(sg):
#     """
#     Specific Gravity to Degrees Plato
# 
#     :param float sg: Specific Gravity
#     :return: Degrees Plato
#     :rtype: float
# 
#     :math:`\\text{Plato} = \\frac{\\big(\\text{SG} - 1\\big) \\times 1000}{4}`
# 
#     The more precise calculation of Plato is:
# 
#     :math:`\\text{Plato} = -616.868 + 1111.14 \\times sg - 630.272 \\times sg^2 + 135.997 \\times sg^3`
# 
#     Source:
# 
#     * http://www.brewersfriend.com/2012/10/31/on-the-relationship-between-plato-and-specific-gravity/
#     """  # noqa
#     # return (sg - 1.0) * 1000 / 4
#     return ((135.997 * sg - 630.272) * sg + 1111.14) * sg - 616.868


import math
from ..constants import GAL_PER_LITER
from ..constants import IMPERIAL_TYPES
from ..constants import IMPERIAL_UNITS
from ..constants import LITER_PER_GAL
from ..constants import OZ_PER_G
from ..constants import SI_TYPES
from ..constants import SI_UNITS
from ..exceptions import YeastException
from ..validators import validate_units
from .sugar import plato_to_sg
from .sugar import sg_to_gu
from .sugar import sg_to_plato
        cells = cells_per_pack * num_packs * viability

        if self.units == IMPERIAL_UNITS:
            modifier = sg_to_gu(original_gravity)
        elif self.units == SI_UNITS:
            modifier = sg_to_plato(original_gravity)
        pitch_rate_as_is = cells / final_volume / modifier
        pitch_rate_cells = target_pitch_rate * final_volume * modifier

        if cells <= 0.0:
            required_growth_rate = 0.0
        else:
            required_growth_rate = pitch_rate_cells / cells

        return {
            u"original_gravity": original_gravity,
            u"final_volume": final_volume,
            u"target_pitch_rate": target_pitch_rate,
            u"viability": round(viability, 2),
            u"cells": round(cells, 2),
            u"pitch_rate_as_is": round(pitch_rate_as_is, 2),
            u"pitch_rate_cells": round(pitch_rate_cells, 2),
            u"cells_needed": round(pitch_rate_cells - cells, 2),
            u"required_growth_rate": round(required_growth_rate, 2),
            u"units": self.units,
        }

    def get_starter_volume(
        self,
        available_cells,

# Path: brew/constants.py
# GAL_PER_LITER = 1.0 / LITER_PER_GAL
# 
# Path: brew/constants.py
# IMPERIAL_TYPES = {
#     u"volume": u"gallon",
#     u"weight_large": u"lbs",
#     u"weight_small": u"oz",
#     u"temperature": u"degF",
# }
# 
# Path: brew/constants.py
# IMPERIAL_UNITS = u"imperial"
# 
# Path: brew/constants.py
# LITER_PER_GAL = 3.78541
# 
# Path: brew/constants.py
# OZ_PER_G = 1.0 / G_PER_OZ
# 
# Path: brew/constants.py
# SI_TYPES = {
#     u"volume": u"liter",
#     u"weight_large": u"kg",
#     u"weight_small": u"mg",
#     u"temperature": u"degC",
# }
# 
# Path: brew/constants.py
# SI_UNITS = u"metric"
# 
# Path: brew/exceptions.py
# class YeastException(BrewdayException):
#     pass
# 
# Path: brew/validators.py
# def validate_units(units):
#     """
#     Validate units
# 
#     :param str units: Unit type
#     :return: units
#     :rtype: str
#     :raises ValidatorException: If units is unknown
#     """
#     if units in [IMPERIAL_UNITS, SI_UNITS]:
#         return units
#     raise ValidatorException(
#         u"Unkown units '{}', must use {} or {}".format(units, IMPERIAL_UNITS, SI_UNITS)
#     )
# 
# Path: brew/utilities/sugar.py
# def plato_to_sg(deg_plato):
#     """
#     Degrees Plato to Specific Gravity
# 
#     :param float deg_plato: Degrees Plato
#     :return: Specific Gravity
#     :rtype: float
# 
#     The simple formula for S.G. is:
# 
#     :math:`\\text{SG} = 1 + 0.004 \\times \\text{Plato}`
# 
#     The more precise calculation of SG is:
# 
#     :math:`\\text{SG} = \\frac{Plato}{258.6 - \\big(\\frac{Plato}{258.2} \\times 227.1\\big)} + 1`
# 
#     Source:
# 
#     * http://www.learntobrew.com/page/1mdhe/Shopping/Beer_Calculations.html
#     """  # noqa
#     return (deg_plato / (258.6 - ((deg_plato / 258.2) * 227.1))) + 1.0
# 
# Path: brew/utilities/sugar.py
# def sg_to_gu(sg):
#     """
#     Specific Gravity to Gravity Units
# 
#     :param float sg: Specific Gravity
#     :return: Gravity Units
#     :rtype: float
#     """
#     return (sg - 1) * 1000.0
# 
# Path: brew/utilities/sugar.py
# def sg_to_plato(sg):
#     """
#     Specific Gravity to Degrees Plato
# 
#     :param float sg: Specific Gravity
#     :return: Degrees Plato
#     :rtype: float
# 
#     :math:`\\text{Plato} = \\frac{\\big(\\text{SG} - 1\\big) \\times 1000}{4}`
# 
#     The more precise calculation of Plato is:
# 
#     :math:`\\text{Plato} = -616.868 + 1111.14 \\times sg - 630.272 \\times sg^2 + 135.997 \\times sg^3`
# 
#     Source:
# 
#     * http://www.brewersfriend.com/2012/10/31/on-the-relationship-between-plato-and-specific-gravity/
#     """  # noqa
#     # return (sg - 1.0) * 1000 / 4
#     return ((135.997 * sg - 630.272) * sg + 1111.14) * sg - 616.868


# Path: brew/utilities/yeast.py
import math
from ..constants import GAL_PER_LITER
from ..constants import IMPERIAL_TYPES
from ..constants import IMPERIAL_UNITS
from ..constants import LITER_PER_GAL
from ..constants import OZ_PER_G
from ..constants import SI_TYPES
from ..constants import SI_UNITS
from ..exceptions import YeastException
from ..validators import validate_units
from .sugar import plato_to_sg
from .sugar import sg_to_gu
from .sugar import sg_to_plato

        cells = cells_per_pack * num_packs * viability

        if self.units == IMPERIAL_UNITS:
            modifier = sg_to_gu(original_gravity)
        elif self.units == SI_UNITS:
            modifier = sg_to_plato(original_gravity)
        pitch_rate_as_is = cells / final_volume / modifier
        pitch_rate_cells = target_pitch_rate * final_volume * modifier

        if cells <= 0.0:
            required_growth_rate = 0.0
        else:
            required_growth_rate = pitch_rate_cells / cells

        return {
            u"original_gravity": original_gravity,
            u"final_volume": final_volume,
            u"target_pitch_rate": target_pitch_rate,
            u"viability": round(viability, 2),
            u"cells": round(cells, 2),
            u"pitch_rate_as_is": round(pitch_rate_as_is, 2),
            u"pitch_rate_cells": round(pitch_rate_cells, 2),
            u"cells_needed": round(pitch_rate_cells - cells, 2),
            u"required_growth_rate": round(required_growth_rate, 2),
            u"units": self.units,
        }

    def get_starter_volume(
        self,
        available_cells,

        starter_volume=2.0 * GAL_PER_LITER,