toji 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/example/koji_making.ipynb +7 -7
  3. data/example/koji_making.rb +5 -5
  4. data/example/koji_recipe.rb +1 -1
  5. data/example/moromi.ipynb +55 -21
  6. data/example/moromi.rb +5 -5
  7. data/example/rice_recipe.rb +2 -2
  8. data/example/shubo.ipynb +6 -6
  9. data/example/shubo.rb +5 -5
  10. data/example/three_step_mashing_recipe.rb +2 -2
  11. data/lib/toji/brew/base.rb +88 -0
  12. data/lib/toji/brew/builder.rb +27 -0
  13. data/lib/toji/brew/graph/ab.rb +85 -0
  14. data/lib/toji/brew/graph/bmd.rb +58 -0
  15. data/lib/toji/brew/graph/progress.rb +142 -0
  16. data/lib/toji/brew/graph.rb +10 -0
  17. data/lib/toji/{product/koji_making.rb → brew/koji.rb} +35 -43
  18. data/lib/toji/{product → brew}/moromi.rb +105 -96
  19. data/lib/toji/brew/shubo.rb +122 -0
  20. data/lib/toji/brew/state.rb +117 -0
  21. data/lib/toji/{product/job_accessor.rb → brew/state_accessor.rb} +4 -4
  22. data/lib/toji/brew/state_record.rb +82 -0
  23. data/lib/toji/brew.rb +21 -0
  24. data/lib/toji/recipe/ingredient/koji/actual.rb +23 -0
  25. data/lib/toji/recipe/ingredient/koji/actual_fermentable.rb +17 -0
  26. data/lib/toji/recipe/ingredient/koji/base.rb +28 -0
  27. data/lib/toji/recipe/ingredient/koji/expected.rb +53 -0
  28. data/lib/toji/recipe/ingredient/koji/expected_fermentable.rb +17 -0
  29. data/lib/toji/recipe/ingredient/koji.rb +21 -0
  30. data/lib/toji/recipe/ingredient/lactic_acid.rb +21 -0
  31. data/lib/toji/recipe/ingredient/rice/actual.rb +20 -0
  32. data/lib/toji/recipe/ingredient/rice/actual_steamable.rb +29 -0
  33. data/lib/toji/recipe/ingredient/rice/base.rb +42 -0
  34. data/lib/toji/recipe/ingredient/rice/expected.rb +48 -0
  35. data/lib/toji/recipe/ingredient/rice/expected_steamable.rb +31 -0
  36. data/lib/toji/recipe/ingredient/rice.rb +21 -0
  37. data/lib/toji/recipe/ingredient/yeast.rb +21 -0
  38. data/lib/toji/recipe/ingredient.rb +11 -0
  39. data/lib/toji/recipe/lactic_acid_rate.rb +17 -0
  40. data/lib/toji/recipe/three_step_mashing.rb +4 -2
  41. data/lib/toji/recipe/yeast_rate.rb +41 -0
  42. data/lib/toji/recipe.rb +3 -0
  43. data/lib/toji/version.rb +1 -1
  44. data/lib/toji.rb +1 -3
  45. metadata +32 -29
  46. data/lib/toji/graph/ab.rb +0 -79
  47. data/lib/toji/graph/bmd.rb +0 -56
  48. data/lib/toji/graph/progress.rb +0 -87
  49. data/lib/toji/graph.rb +0 -8
  50. data/lib/toji/ingredient/koji/actual.rb +0 -21
  51. data/lib/toji/ingredient/koji/actual_fermentable.rb +0 -15
  52. data/lib/toji/ingredient/koji/base.rb +0 -26
  53. data/lib/toji/ingredient/koji/expected.rb +0 -51
  54. data/lib/toji/ingredient/koji/expected_fermentable.rb +0 -15
  55. data/lib/toji/ingredient/koji.rb +0 -19
  56. data/lib/toji/ingredient/rice/actual.rb +0 -18
  57. data/lib/toji/ingredient/rice/actual_steamable.rb +0 -27
  58. data/lib/toji/ingredient/rice/base.rb +0 -40
  59. data/lib/toji/ingredient/rice/expected.rb +0 -46
  60. data/lib/toji/ingredient/rice/expected_steamable.rb +0 -29
  61. data/lib/toji/ingredient/rice.rb +0 -19
  62. data/lib/toji/ingredient/yeast/base.rb +0 -21
  63. data/lib/toji/ingredient/yeast/red_star.rb +0 -30
  64. data/lib/toji/ingredient/yeast.rb +0 -9
  65. data/lib/toji/ingredient.rb +0 -8
  66. data/lib/toji/product/base.rb +0 -74
  67. data/lib/toji/product/job.rb +0 -176
  68. data/lib/toji/product/shubo.rb +0 -130
  69. data/lib/toji/product.rb +0 -11
data/lib/toji/graph/ab.rb DELETED
@@ -1,79 +0,0 @@
1
- module Toji
2
- module Graph
3
- class Ab
4
- attr_reader :coef
5
-
6
- def initialize(coef=1.5)
7
- @coef = coef
8
- @actuals = []
9
- @expects = []
10
- end
11
-
12
- def actual(moromi, name=:actual)
13
- @actuals << [moromi, name]
14
- self
15
- end
16
-
17
- def expect(alcohol, nihonshudo)
18
- @expects << [alcohol.to_f, nihonshudo.to_f]
19
- self
20
- end
21
-
22
- def data
23
- result = []
24
-
25
- @actuals.each {|moromi, name|
26
- data = moromi.map{|j| [j.time || j.elapsed_time + moromi.day_offset, j.alcohol, j.baume]}.select{|a| a[1] && a[2]}
27
-
28
- xs = data.map{|a| a[1]}
29
- ys = data.map{|a| a[2]}
30
- texts = data.map{|a| "%s<br />alc=%s, be=%s" % a}
31
-
32
- result << {x: xs, y: ys, text: texts, name: name}
33
- }
34
-
35
- @expects.each {|alcohol, nihonshudo|
36
- ys = [0.0, 8.0]
37
- xs = ys.map{|b| alcohol - (b - nihonshudo * -0.1) * @coef}
38
-
39
- name = "%s%s %s" % [nihonshudo<0 ? "" : "+", nihonshudo, alcohol]
40
-
41
- result << {x: xs, y: ys, name: name}
42
- }
43
-
44
- result
45
- end
46
-
47
- def min_baume
48
- data.map{|h| h[:y].min}.min || 0
49
- end
50
-
51
- def max_baume
52
- data.map{|h| h[:y].max}.max || 0
53
- end
54
-
55
- def plot
56
- #_min_baume = [min_baume-1, 0].min
57
- _min_baume = 0
58
-
59
- _max_baume = [max_baume+1, 10].max
60
-
61
- Plotly::Plot.new(
62
- data: data,
63
- layout: {
64
- xaxis: {
65
- title: "Alcohol",
66
- dtick: 2,
67
- range: [0, 20],
68
- },
69
- yaxis: {
70
- title: "Baume",
71
- dtick: 1,
72
- range: [_min_baume, _max_baume],
73
- }
74
- }
75
- )
76
- end
77
- end
78
- end
79
- end
@@ -1,56 +0,0 @@
1
- module Toji
2
- module Graph
3
- class Bmd
4
-
5
- def initialize
6
- @actuals = []
7
- @expects = []
8
- end
9
-
10
- def actual(moromi, name=:actual)
11
- @actuals << [moromi, name]
12
- self
13
- end
14
-
15
- def data
16
- result = []
17
-
18
- @actuals.each {|moromi, name|
19
- jobs = moromi.select{|j| j.moromi_time && j.bmd}
20
-
21
- xs = jobs.map(&:moromi_time)
22
- ys = jobs.map(&:bmd)
23
- texts = jobs.map{|j| "%s<br />moromi day=%d, be=%s, bmd=%s" % [j.time || j.elapsed_time + moromi.day_offset, j.moromi_day, j.baume, j.bmd]}
24
-
25
- result << {x: xs, y: ys, text: texts, name: name}
26
- }
27
-
28
- result
29
- end
30
-
31
- def max_moromi_day
32
- @actuals.map(&:first).map(&:moromi_days).max
33
- end
34
-
35
- def plot
36
- _max_moromi_day = [max_moromi_day, 14].max
37
-
38
- Plotly::Plot.new(
39
- data: data,
40
- layout: {
41
- xaxis: {
42
- title: "Moromi day",
43
- dtick: Product::Job::DAY,
44
- range: [1, _max_moromi_day].map{|d| d*Product::Job::DAY},
45
- tickvals: _max_moromi_day.times.map{|d| d*Product::Job::DAY},
46
- ticktext: _max_moromi_day.times.map(&:succ)
47
- },
48
- yaxis: {
49
- title: "BMD",
50
- }
51
- }
52
- )
53
- end
54
- end
55
- end
56
- end
@@ -1,87 +0,0 @@
1
- module Toji
2
- module Graph
3
- class Progress
4
-
5
- attr_accessor :enable_annotations
6
-
7
- def initialize(product, enable_annotations: true)
8
- @product = product
9
- @enable_annotations = enable_annotations
10
- end
11
-
12
- def data(keys=nil)
13
- data = @product.map(&:to_h).map(&:compact)
14
- if !keys
15
- keys = data.map(&:keys).flatten.uniq
16
- end
17
-
18
- result = []
19
-
20
- keys &= [:temps, :preset_temp, :room_temp, :room_psychrometry, :baume, :acid, :amino_acid, :alcohol]
21
-
22
- keys.each {|key|
23
- xs = []
24
- ys = []
25
- text = []
26
- data.each {|h|
27
- if h[key]
28
- [h[key]].flatten.each_with_index {|v,i|
29
- xs << h[:elapsed_time] + i + @product.day_offset
30
- ys << v
31
- text << h[:display_time]
32
- }
33
- end
34
- }
35
-
36
- line_shape = :linear
37
- if key==:preset_temp
38
- line_shape = :hv
39
- end
40
-
41
- result << {x: xs, y: ys, text: text, name: key, line: {shape: line_shape}}
42
- }
43
-
44
- if 0<@product.day_offset
45
- result = result.map{|h|
46
- h[:x].unshift(0)
47
- h[:y].unshift(nil)
48
- h[:text].unshift(nil)
49
- h
50
- }
51
- end
52
-
53
- result
54
- end
55
-
56
- def annotations
57
- @product.select{|j| j.id}.map {|j|
58
- {
59
- x: j.elapsed_time + @product.day_offset,
60
- y: j.temps.first || 0,
61
- xref: 'x',
62
- yref: 'y',
63
- text: j.id,
64
- showarrow: true,
65
- arrowhead: 1,
66
- ax: 0,
67
- ay: -40
68
- }
69
- }
70
- end
71
-
72
- def plot
73
- Plotly::Plot.new(
74
- data: data,
75
- layout: {
76
- xaxis: {
77
- dtick: Product::Job::DAY,
78
- tickvals: @product.days.times.map{|d| d*Product::Job::DAY},
79
- ticktext: @product.day_labels
80
- },
81
- annotations: @enable_annotations ? annotations : [],
82
- }
83
- )
84
- end
85
- end
86
- end
87
- end
data/lib/toji/graph.rb DELETED
@@ -1,8 +0,0 @@
1
- require 'toji/graph/progress'
2
- require 'toji/graph/bmd'
3
- require 'toji/graph/ab'
4
-
5
- module Toji
6
- module Graph
7
- end
8
- end
@@ -1,21 +0,0 @@
1
- module Toji
2
- module Ingredient
3
- module Koji
4
- class Actual
5
- include Base
6
- include Rice::ActualSteamable
7
- include ActualFermentable
8
-
9
- def initialize(raw, soaked, steaming_water, steamed, cooled, tanekoji, dekoji)
10
- @raw = raw
11
- @soaked = soaked
12
- @steaming_water = steaming_water
13
- @steamed = steamed
14
- @cooled = cooled
15
- @tanekoji = tanekoji
16
- @dekoji = dekoji
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,15 +0,0 @@
1
- module Toji
2
- module Ingredient
3
- module Koji
4
- module ActualFermentable
5
- def tanekoji_rate
6
- tanekoji / raw
7
- end
8
-
9
- def dekoji_rate
10
- (dekoji - raw) / raw
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,26 +0,0 @@
1
- module Toji
2
- module Ingredient
3
- module Koji
4
- module Base
5
- include Rice::Base
6
-
7
- # 種麹
8
- #
9
- # 総破精麹を造るには、種麹の量を麹米100kgあたり種麹100gとする
10
- # 突き破精麹を造るには、種麹の量を麹米100kgあたり種麹80gとする
11
- #
12
- # 出典: 酒造教本 P66
13
- attr_reader :tanekoji_rate
14
- attr_reader :tanekoji
15
-
16
- # 出麹歩合
17
- #
18
- # 出麹歩合17〜19%のものが麹菌の繁殖のほどよい麹である
19
- #
20
- # 出典: 酒造教本 P67
21
- attr_reader :dekoji_rate
22
- attr_reader :dekoji
23
- end
24
- end
25
- end
26
- end
@@ -1,51 +0,0 @@
1
- module Toji
2
- module Ingredient
3
- module Koji
4
- class Expected
5
- include Base
6
- include Rice::ExpectedSteamable
7
- include ExpectedFermentable
8
-
9
- def initialize(raw, rice_rate: Recipe::RiceRate::Cooked::DEFAULT, koji_rate: Recipe::KojiRate::DEFAULT)
10
- @raw = raw.to_f
11
-
12
- @rice_rate = rice_rate
13
- @soaked_rate = rice_rate.soaked_rate
14
- @before_steaming_rate = rice_rate.before_steaming_rate
15
- @steamed_rate = rice_rate.steamed_rate
16
- @cooled_rate = rice_rate.cooled_rate
17
-
18
- @koji_rate = koji_rate
19
- @tanekoji_rate = koji_rate.tanekoji_rate
20
- @dekoji_rate = koji_rate.dekoji_rate
21
- end
22
-
23
- def self.create(x)
24
- if self===x
25
- x
26
- else
27
- new(x)
28
- end
29
- end
30
-
31
- def +(other)
32
- if Base===other
33
- Actual.new(raw + other.raw, soaked + other.soaked, steaming_water + other.steaming_water, steamed + other.steamed, cooled + other.cooled, tanekoji + other.tanekoji, dekoji + other.dekoji)
34
- else
35
- x, y = other.coerce(self)
36
- x + y
37
- end
38
- end
39
-
40
- def *(other)
41
- if Integer===other || Float===other
42
- Expected.new(@raw * other, rice_rate: @rice_rate, koji_rate: @koji_rate)
43
- else
44
- x, y = other.coerce(self)
45
- x * y
46
- end
47
- end
48
- end
49
- end
50
- end
51
- end
@@ -1,15 +0,0 @@
1
- module Toji
2
- module Ingredient
3
- module Koji
4
- module ExpectedFermentable
5
- def tanekoji
6
- @raw * @tanekoji_rate
7
- end
8
-
9
- def dekoji
10
- @raw + @raw * @dekoji_rate
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,19 +0,0 @@
1
- require 'toji/ingredient/koji/base'
2
- require 'toji/ingredient/koji/expected_fermentable'
3
- require 'toji/ingredient/koji/expected'
4
- require 'toji/ingredient/koji/actual_fermentable'
5
- require 'toji/ingredient/koji/actual'
6
-
7
- module Toji
8
- module Ingredient
9
- module Koji
10
- def self.expected(raw, rice_rate: Recipe::RiceRate::Cooked::DEFAULT, koji_rate: Recipe::KojiRate::DEFAULT)
11
- Expected.new(raw, rice_rate: rice_rate, koji_rate: koji_rate)
12
- end
13
-
14
- def self.actual(raw, soaked, steaming_water, steamed, cooled, tanekoji, dekoji)
15
- Actual.new(raw, soaked, steaming_water, steamed, cooled, tanekoji, dekoji)
16
- end
17
- end
18
- end
19
- end
@@ -1,18 +0,0 @@
1
- module Toji
2
- module Ingredient
3
- module Rice
4
- class ActualRice
5
- include Base
6
- include ActualSteamable
7
-
8
- def initialize(raw, soaked, steaming_water, steamed, cooled)
9
- @raw = raw
10
- @soaked = soaked
11
- @steaming_water = steaming_water
12
- @steamed = steamed
13
- @cooled = cooled
14
- end
15
- end
16
- end
17
- end
18
- end
@@ -1,27 +0,0 @@
1
- module Toji
2
- module Ingredient
3
- module Rice
4
- module ActualSteamable
5
- def soaked_rate
6
- soaking_water / raw
7
- end
8
-
9
- def soaking_water
10
- soaked - raw
11
- end
12
-
13
- def before_steaming_rate
14
- # TODO
15
- end
16
-
17
- def steamed_rate
18
- (steamed - raw) / raw
19
- end
20
-
21
- def cooled_rate
22
- (cooled - raw) / raw
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,40 +0,0 @@
1
- module Toji
2
- module Ingredient
3
- module Rice
4
- module Base
5
- # 白米
6
- attr_reader :raw
7
-
8
- # 浸漬米吸水率
9
- #
10
- # 標準的な白米吸水率は掛米で30〜35%、麹米で33%前後で許容範囲はかなり狭い
11
- #
12
- # 出典: 酒造教本 P38
13
- attr_reader :soaked_rate
14
- attr_reader :soaking_water
15
- attr_reader :soaked
16
-
17
- # 蒸米吸水率
18
- #
19
- # 蒸しにより通常甑置き前の浸漬白米の重量よりさらに12〜13%吸水する
20
- # 蒸しにより吸水の増加が13%を超える場合は、蒸米の表面が柔らかくべとつく蒸米になりやすい
21
- # 蒸米吸水率は麹米及び酒母米で41〜43%、掛米は39〜40%で、吟醸造りの場合は数%低い
22
- #
23
- # 出典: 酒造教本 P48
24
- attr_reader :steamed_rate
25
- attr_reader :steaming_water
26
- attr_reader :steamed
27
-
28
- # 放冷
29
- #
30
- # 冷却法で若干異なるが蒸米の冷却により掛米で白米重量の10%、麹米で8%程度の水が失われる
31
- # 出典: 酒造教本 P49
32
- #
33
- # 麹を造るのに適した蒸米は、引込時の吸水率が33%を理想とし、許容幅はプラスマイナス1%である
34
- # 出典: 酒造教本 P59
35
- attr_reader :cooled_rate
36
- attr_reader :cooled
37
- end
38
- end
39
- end
40
- end
@@ -1,46 +0,0 @@
1
- module Toji
2
- module Ingredient
3
- module Rice
4
- class Expected
5
- include Base
6
- include ExpectedSteamable
7
-
8
- def initialize(raw, rice_rate: Recipe::RiceRate::Cooked::DEFAULT)
9
- @raw = raw.to_f
10
-
11
- @rice_rate = rice_rate
12
- @soaked_rate = rice_rate.soaked_rate
13
- @before_steaming_rate = rice_rate.before_steaming_rate
14
- @steamed_rate = rice_rate.steamed_rate
15
- @cooled_rate = rice_rate.cooled_rate
16
- end
17
-
18
- def +(other)
19
- if Base===other
20
- Actual.new(raw + other.raw, soaked + other.soaked, steaming_water + other.steaming_water, steamed + other.steamed, cooled + other.cooled)
21
- else
22
- x, y = other.coerce(self)
23
- x + y
24
- end
25
- end
26
-
27
- def *(other)
28
- if Integer===other || Float===other
29
- self.class.new(@raw * other, rice_rate: @rice_rate)
30
- else
31
- x, y = other.coerce(self)
32
- x * y
33
- end
34
- end
35
-
36
- def self.create(x)
37
- if self===x
38
- x
39
- else
40
- new(x)
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,29 +0,0 @@
1
- module Toji
2
- module Ingredient
3
- module Rice
4
- module ExpectedSteamable
5
- def soaking_water
6
- @raw * @soaked_rate
7
- end
8
-
9
- def soaked
10
- @raw + @raw * @soaked_rate
11
- end
12
-
13
- def steaming_water
14
- if @before_steaming_rate
15
- @raw * (@before_steaming_rate - @soaked_rate)
16
- end
17
- end
18
-
19
- def steamed
20
- @raw + @raw * @steamed_rate
21
- end
22
-
23
- def cooled
24
- @raw + @raw * @cooled_rate
25
- end
26
- end
27
- end
28
- end
29
- end
@@ -1,19 +0,0 @@
1
- require 'toji/ingredient/rice/base'
2
- require 'toji/ingredient/rice/expected_steamable'
3
- require 'toji/ingredient/rice/expected'
4
- require 'toji/ingredient/rice/actual_steamable'
5
- require 'toji/ingredient/rice/actual'
6
-
7
- module Toji
8
- module Ingredient
9
- module Rice
10
- def self.expected(raw, rice_rate: Recipe::RiceRate::Cooked::DEFAULT)
11
- Expected.new(raw, rice_rate: rice_rate)
12
- end
13
-
14
- def self.actual(raw, soaked, steaming_water, steamed, cooled)
15
- Actual.new(raw, soaked, steaming_water, steamed, cooled)
16
- end
17
- end
18
- end
19
- end
@@ -1,21 +0,0 @@
1
- module Toji
2
- module Ingredient
3
- module Yeast
4
- module Base
5
- # 1リットル醸造のために必要な酵母の量
6
- attr_reader :yeast_rate
7
-
8
- # 乾燥酵母を戻すのに必要な水の量
9
- attr_reader :water_rate
10
-
11
- def yeast
12
- @total * yeast_rate / 1000.0
13
- end
14
-
15
- def water
16
- yeast * water_rate
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,30 +0,0 @@
1
- module Toji
2
- module Ingredient
3
- module Yeast
4
- # RedStar酵母
5
- #
6
- # 容量 5g
7
- # 醸造可能量 20〜23L
8
- #
9
- # ドライイーストは、生イーストの保存性を高めるために、その水分を大部分除いたものです。
10
- # 使用時にはイーストの10倍以上の30-35℃の無菌のお湯(ミネラルウオーターや湯冷まし)で20-25分程度なじませてください。
11
- # これにより水分を再吸収させると同 時に発酵力を回復させ、生イーストの状態にもどします。
12
- # このときの温湯の温度が、イーストの発酵力に影響します
13
- class RedStar
14
- include Base
15
-
16
- def initialize(total)
17
- @total = total
18
- end
19
-
20
- def yeast_rate
21
- 5.0 / 20.0
22
- end
23
-
24
- def water_rate
25
- 10.0
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,9 +0,0 @@
1
- require 'toji/ingredient/yeast/base'
2
- require 'toji/ingredient/yeast/red_star'
3
-
4
- module Toji
5
- module Ingredient
6
- module Yeast
7
- end
8
- end
9
- end
@@ -1,8 +0,0 @@
1
- require 'toji/ingredient/rice'
2
- require 'toji/ingredient/koji'
3
- require 'toji/ingredient/yeast'
4
-
5
- module Toji
6
- module Ingredient
7
- end
8
- end