toji 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/example/koji_recipe.rb +34 -0
- data/example/make_koji.rb +18 -0
- data/example/rice_recipe.rb +28 -0
- data/example/three_step_mashing_recipe.rb +65 -0
- data/lib/toji.rb +12 -0
- data/lib/toji/graph.rb +6 -0
- data/lib/toji/graph/ab.rb +75 -0
- data/lib/toji/ingredient.rb +8 -0
- data/lib/toji/ingredient/koji.rb +19 -0
- data/lib/toji/ingredient/koji/actual.rb +21 -0
- data/lib/toji/ingredient/koji/actual_fermentable.rb +15 -0
- data/lib/toji/ingredient/koji/base.rb +26 -0
- data/lib/toji/ingredient/koji/expected.rb +51 -0
- data/lib/toji/ingredient/koji/expected_fermentable.rb +15 -0
- data/lib/toji/ingredient/rice.rb +19 -0
- data/lib/toji/ingredient/rice/actual.rb +18 -0
- data/lib/toji/ingredient/rice/actual_steamable.rb +27 -0
- data/lib/toji/ingredient/rice/base.rb +40 -0
- data/lib/toji/ingredient/rice/expected.rb +46 -0
- data/lib/toji/ingredient/rice/expected_steamable.rb +29 -0
- data/lib/toji/ingredient/yeast.rb +9 -0
- data/lib/toji/ingredient/yeast/base.rb +21 -0
- data/lib/toji/ingredient/yeast/red_star.rb +30 -0
- data/lib/toji/progress.rb +11 -0
- data/lib/toji/progress/job.rb +165 -0
- data/lib/toji/progress/job_accessor.rb +13 -0
- data/lib/toji/progress/jobs.rb +142 -0
- data/lib/toji/progress/make_koji.rb +100 -0
- data/lib/toji/progress/moromi.rb +276 -0
- data/lib/toji/progress/shubo.rb +158 -0
- data/lib/toji/recipe.rb +9 -0
- data/lib/toji/recipe/koji_rate.rb +16 -0
- data/lib/toji/recipe/rice_rate.rb +10 -0
- data/lib/toji/recipe/rice_rate/base.rb +21 -0
- data/lib/toji/recipe/rice_rate/cooked.rb +61 -0
- data/lib/toji/recipe/rice_rate/steamed.rb +42 -0
- data/lib/toji/recipe/step.rb +65 -0
- data/lib/toji/recipe/three_step_mashing.rb +87 -0
- data/lib/toji/version.rb +3 -0
- data/toji.gemspec +36 -0
- metadata +178 -0
@@ -0,0 +1,26 @@
|
|
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
|
@@ -0,0 +1,51 @@
|
|
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
|
@@ -0,0 +1,19 @@
|
|
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
|
@@ -0,0 +1,18 @@
|
|
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
|
@@ -0,0 +1,27 @@
|
|
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
|
@@ -0,0 +1,40 @@
|
|
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
|
@@ -0,0 +1,46 @@
|
|
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
|
@@ -0,0 +1,29 @@
|
|
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
|
@@ -0,0 +1,21 @@
|
|
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
|
@@ -0,0 +1,30 @@
|
|
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
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module Toji
|
2
|
+
module Progress
|
3
|
+
class Job
|
4
|
+
HOUR = 60 * 60
|
5
|
+
DAY = 24 * HOUR
|
6
|
+
|
7
|
+
WARM_DAKI = 1
|
8
|
+
WARM_ANKA = 1<<1
|
9
|
+
WARM_MAT = 1<<2
|
10
|
+
|
11
|
+
attr_accessor :jobs
|
12
|
+
|
13
|
+
attr_accessor :time
|
14
|
+
attr_accessor :elapsed_time
|
15
|
+
attr_accessor :id
|
16
|
+
attr_accessor :before_temp
|
17
|
+
attr_accessor :after_temp
|
18
|
+
|
19
|
+
attr_accessor :preset_temp
|
20
|
+
attr_accessor :room_temp
|
21
|
+
attr_accessor :room_psychrometry
|
22
|
+
|
23
|
+
attr_accessor :baume
|
24
|
+
attr_accessor :nihonshudo
|
25
|
+
attr_accessor :acid
|
26
|
+
attr_accessor :amino_acid
|
27
|
+
attr_accessor :alcohol
|
28
|
+
|
29
|
+
attr_accessor :warming
|
30
|
+
attr_accessor :note
|
31
|
+
|
32
|
+
def initialize(
|
33
|
+
time: nil, elapsed_time: nil, id: nil, before_temp: nil, after_temp: nil,
|
34
|
+
preset_temp: nil, room_temp: nil, room_psychrometry: nil,
|
35
|
+
baume: nil, nihonshudo: nil, acid: nil, amino_acid: nil, alcohol: nil,
|
36
|
+
warming: nil, note: nil)
|
37
|
+
@time = time
|
38
|
+
@elapsed_time = elapsed_time
|
39
|
+
@id = id
|
40
|
+
@before_temp = before_temp
|
41
|
+
@after_temp = after_temp
|
42
|
+
|
43
|
+
@preset_temp = preset_temp
|
44
|
+
@room_temp = room_temp
|
45
|
+
@room_psychrometry = room_psychrometry
|
46
|
+
|
47
|
+
@baume = baume
|
48
|
+
@nihonshudo = nihonshudo
|
49
|
+
@acid = acid
|
50
|
+
@amino_acid = amino_acid
|
51
|
+
@alcohol = alcohol
|
52
|
+
|
53
|
+
@warming = warming
|
54
|
+
@note = note
|
55
|
+
end
|
56
|
+
|
57
|
+
def temps
|
58
|
+
result = []
|
59
|
+
|
60
|
+
if @before_temp
|
61
|
+
result << @before_temp
|
62
|
+
end
|
63
|
+
|
64
|
+
if @after_temp
|
65
|
+
result << @after_temp
|
66
|
+
end
|
67
|
+
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
def baume
|
72
|
+
if @baume
|
73
|
+
@baume
|
74
|
+
elsif @nihonshudo
|
75
|
+
@nihonshudo * -0.1
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def nihonshudo
|
80
|
+
if @nihonshudo
|
81
|
+
@nihonshudo
|
82
|
+
elsif @baume
|
83
|
+
@baume * -10
|
84
|
+
else
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def baume_display
|
90
|
+
if @baume || @nihonshudo
|
91
|
+
b = baume
|
92
|
+
if b<3.0
|
93
|
+
nihonshudo
|
94
|
+
else
|
95
|
+
b
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def moromi_time
|
101
|
+
tome = jobs[:tome]
|
102
|
+
if tome
|
103
|
+
time = elapsed_time - tome.elapsed_time
|
104
|
+
if 0<time
|
105
|
+
return time
|
106
|
+
end
|
107
|
+
end
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
|
111
|
+
def moromi_day
|
112
|
+
moromi_t = moromi_time
|
113
|
+
if moromi_t
|
114
|
+
(moromi_t.to_f / Job::DAY).floor + 1
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def bmd
|
119
|
+
_moromi_day = moromi_day
|
120
|
+
_baume = baume
|
121
|
+
|
122
|
+
if _moromi_day && _baume
|
123
|
+
_moromi_day * _baume
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def warmings
|
128
|
+
result = []
|
129
|
+
if @warming & WARM_DAKI
|
130
|
+
result << :daki
|
131
|
+
end
|
132
|
+
if @warming & WARM_ANKA
|
133
|
+
result << :anka
|
134
|
+
end
|
135
|
+
if @warming & WARM_MAT
|
136
|
+
result << :mat
|
137
|
+
end
|
138
|
+
result
|
139
|
+
end
|
140
|
+
|
141
|
+
def to_h
|
142
|
+
{
|
143
|
+
time: time,
|
144
|
+
elapsed_time: elapsed_time,
|
145
|
+
id: id,
|
146
|
+
preset_temp: preset_temp,
|
147
|
+
before_temp: before_temp,
|
148
|
+
after_temp: after_temp,
|
149
|
+
temps: temps,
|
150
|
+
room_temp: room_temp,
|
151
|
+
room_psychrometry: room_psychrometry,
|
152
|
+
baume: baume,
|
153
|
+
nihonshudo: nihonshudo,
|
154
|
+
acid: acid,
|
155
|
+
amino_acid: amino_acid,
|
156
|
+
alcohol: alcohol,
|
157
|
+
warmings: warmings,
|
158
|
+
moromi_day: moromi_day,
|
159
|
+
bmd: bmd,
|
160
|
+
note: note,
|
161
|
+
}
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|