Module: Hops

Defined in:
lib/hops.rb

Overview

Various hop calculations

Class Method Summary collapse

Class Method Details

.extract_adjustment(extract) ⇒ Float

Note:

Extract must be measured in specific gravity

Calculate extract adjustment

Examples:

Hops.extract_adjustment 1.065

Parameters:

  • extract (Float)

    specific gravity of wort

Returns:

  • (Float)

    extract adjustment


41
42
43
# File 'lib/hops.rb', line 41

def self.extract_adjustment extract
  (1.65 * 0.000125 ** (extract - 1)).round 2
end

.hopshot_extract_adjustment(extract) ⇒ Float

Note:

Extract must be measured in specific gravity

Calculate extract adjustment for HopShot

Examples:

Hops.hopshot_extract_adjustment 1.065

Parameters:

  • extract (Float)

    specific gravity of wort

Returns:

  • (Float)

    HopShot extract adjustment


128
129
130
131
132
133
134
135
136
137
138
# File 'lib/hops.rb', line 128

def self.hopshot_extract_adjustment extract
  if extract >= 1.08 && extract < 1.1
    0.1
  elsif extract >= 1.1 && extract < 1.15
    0.2
  elsif extract >= 1.15
    0.3
  else
    0
  end
end

.hopshot_required(data) ⇒ Float

Note:

Extract must be measured specific gravity, mass in grams and volume in liters

Calculate milliliters of HopShot required to achieve specific IBUs.

Examples:

Hops.hopshot_required({
  alpha: 13.5,
  extract: 1.05,
  ibus: 25,
  time: 60,
  volume: 20
})

Parameters:

  • data (Hash)

    data required to calculate HopShot required; alpha, extract, ibus, time, volume

Returns:

  • (Float)

    milliliters of HopShot required to achieve specific IBUs


105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/hops.rb', line 105

def self.hopshot_required data
  unadjusted_amount = (data[:ibus] / 10.0) * (data[:volume] / 19.0)

  hopshot_required =  unadjusted_amount +
                     (unadjusted_amount * hopshot_extract_adjustment(data[:extract]))

  if data[:time] >= 90
    hopshot_required = hopshot_required - (unadjusted_amount * 0.1)
  end

  hopshot_required.round 1
end

.ibus(data) ⇒ Fixnum

Note:

Extract must be measured specific gravity, mass in grams and volume in liters

Calculates IBUs for hop addition

Examples:

Hops.ibus({
  alpha: 12.4,
  extract: 1.055,
  mass: 56,
  time: 90,
  volume: 20
})

Parameters:

  • data (Hash)

    data required to calculate IBUs; alpha, extract, mass, time, volume

Returns:

  • (Fixnum)

    IBUs from hop addition


61
62
63
64
65
# File 'lib/hops.rb', line 61

def self.ibus data
  (extract_adjustment(data[:extract]) *
   time_adjustment(data[:time]) * (data[:alpha] / 100) *
   data[:mass] * 1000 / (data[:volume] * 4.15)).round
end

.mass_required(data) ⇒ Float

Note:

Extract must be measured specific gravity, mass in grams and volume in liters

Calculates hop mass required to achieve specific IBUs.

Examples:

Hops.hop_mass_required({
  alpha: 1.05,
  extract: 16,
  ibus: 25,
  time: 60,
  volume: 20
})

Parameters:

  • data (Hash)

    data required to calculate hop mass required; alpha, extract, ibus, time, volume

Returns:

  • (Float)

    hop mass required to achieve specific IBUs


83
84
85
86
87
# File 'lib/hops.rb', line 83

def self.mass_required data
  ((data[:volume] * data[:ibus]) /
   (utilization(data[:time], data[:extract]) *
    data[:alpha] * 10)).round
end

.time_adjustment(time) ⇒ Float

Calculate boil time adjustment

Examples:

Hops.time_adjustment 60

Parameters:

  • time (Fixnum)

    remaining boil time

Returns:

  • (Float)

    boil time adjustment


27
28
29
# File 'lib/hops.rb', line 27

def self.time_adjustment time
  (1 - Math.exp(-0.04 * time)).round 2
end

.utilization(time, extract) ⇒ Float

Note:

Extract must be measured in specific gravity

Calculates hop utilization.

Examples:

Hops.utilization 20, 1.055

Parameters:

  • time (Fixnum)

    remaining boil time

  • extract (Float)

    specific gravity of wort

Returns:

  • (Float)

    hop utilization


15
16
17
18
# File 'lib/hops.rb', line 15

def self.utilization time, extract
  ((extract_adjustment extract) *
  ((time_adjustment time) / 4.15)).round 2
end