# HG changeset patch # User Michiel Broek # Date 1660739433 -7200 # Node ID 7212b980a527b240461b75cb0f1d02cc27064560 # Parent f41d02c129e5535b43ca4629ea502adfcb746936 Added Bitterness Unit to Real Extract unit calculation and display. In product use final values if possible for the BU:GU and BU:RE calculations depending on the product stage. diff -r f41d02c129e5 -r 7212b980a527 src/EditProduct.cpp --- a/src/EditProduct.cpp Thu Aug 11 10:50:18 2022 +0200 +++ b/src/EditProduct.cpp Wed Aug 17 14:30:33 2022 +0200 @@ -339,6 +339,11 @@ ui->est_carbShow->setMarkerTextIsValue(true); ui->est_carbShow->setRange(product->st_carb_min, product->st_carb_max); ui->est_carbShow->setValue(product->est_carb); + calcStyle(); + ui->est_buguShow->setPrecision(2); + ui->est_buguShow->setMarkerTextIsValue(true); + ui->est_bufguShow->setPrecision(2); + ui->est_bufguShow->setMarkerTextIsValue(true); // Tab equipment. initEquipment(); diff -r f41d02c129e5 -r 7212b980a527 src/EditProduct.h --- a/src/EditProduct.h Thu Aug 11 10:50:18 2022 +0200 +++ b/src/EditProduct.h Wed Aug 17 14:30:33 2022 +0200 @@ -301,6 +301,8 @@ void calcFermentables(); void calcFermentablesFromOG(double og); void calcIBUs(); + void calcStyle(); + void calcBU(); void adjustHops(double factor); void adjustMiscs(double factor); double ZAlkalinity(double pHZ); diff -r f41d02c129e5 -r 7212b980a527 src/EditProductTab1.cpp --- a/src/EditProductTab1.cpp Thu Aug 11 10:50:18 2022 +0200 +++ b/src/EditProductTab1.cpp Wed Aug 17 14:30:33 2022 +0200 @@ -18,6 +18,37 @@ */ +void EditProduct::calcStyle() +{ + /* + * https://www.homebrewersassociation.org/forum/index.php?topic=10548.0 + * + * Calculate the ideal BU:GU and BU:RE ranges. These values + * will be used in the RangedSliders. + */ + double bugu_min = product->st_ibu_min / ((product->st_og_min - 1) * 1000); + double bugu_max = product->st_ibu_max / ((product->st_og_max - 1) * 1000); + ui->est_buguShow->setRange(bugu_min, bugu_max); + + double fg_min = product->st_fg_min; + if (fg_min < 1.002) /* Use 1.002 fg as lowest minimal value */ + fg_min = 1.002; + + /* + * Real Extract (RE) + */ + double re = ((0.1808 * ((Utils::sg_to_plato(product->st_og_min) + Utils::sg_to_plato(product->st_og_max)) / 2)) + + (0.8192 * ((Utils::sg_to_plato(fg_min) + Utils::sg_to_plato(product->st_fg_max)) / 2))); + + /* BU:RE */ + double bure_min = product->st_ibu_min / re; + double bure_max = product->st_ibu_max / re; + ui->est_bufguShow->setRange(bure_min, bure_max); + + qDebug() << "BU:RE" << bure_min << bure_max; +} + + void EditProduct::code_changed(QString code) { product->code = code; @@ -88,6 +119,7 @@ ui->est_carbShow->setRange(query.value(15).toDouble(), query.value(16).toDouble()); ui->est_abvShow->setRange(query.value(17).toDouble(), query.value(18).toDouble()); + calcStyle(); is_changed(); } diff -r f41d02c129e5 -r 7212b980a527 src/EditProductTab6.cpp --- a/src/EditProductTab6.cpp Thu Aug 11 10:50:18 2022 +0200 +++ b/src/EditProductTab6.cpp Wed Aug 17 14:30:33 2022 +0200 @@ -311,6 +311,7 @@ } else { ui->starterTable->hide(); } + calcBU(); } diff -r f41d02c129e5 -r 7212b980a527 src/EditProductTab8.cpp --- a/src/EditProductTab8.cpp Thu Aug 11 10:50:18 2022 +0200 +++ b/src/EditProductTab8.cpp Wed Aug 17 14:30:33 2022 +0200 @@ -187,6 +187,49 @@ } +void EditProduct::calcBU() +{ + if (product->stage < PROD_STAGE_WAIT) + return; + + double BUGU = GetBUGU(); + ui->buguEdit->setValue(BUGU); + ui->est_buguEdit->setValue(BUGU); + ui->est_buguShow->setValue(BUGU); + if (BUGU < 0.32) + ui->buguResult->setText(tr("Very malty and sweet")); + else if (BUGU < 0.43) + ui->buguResult->setText(tr("Malty, sweet")); + else if (BUGU < 0.52) + ui->buguResult->setText(tr("Balanced")); + else if (BUGU < 0.63) + ui->buguResult->setText(tr("Hoppy, bitter")); + else + ui->buguResult->setText(tr("Very hoppy, very bitter")); + + double og = product->est_og; + double fg = product->est_fg; + double ibu = product->est_ibu; + + if (product->stage > PROD_STAGE_BREW) { + og = product->brew_fermenter_sg; + ibu = product->brew_fermenter_ibu; + } + if (product->stage > PROD_STAGE_TERTIARY) { + fg = product->fg; + } + + if (fg < 1.002) /* Can't be too low for this */ + fg = 1.002; + + double bure = ibu / ((0.1808 * Utils::sg_to_plato(og)) + (0.8192 * Utils::sg_to_plato(fg))); + qDebug() << "BU:RE" << bure << product->est_fg << product->fg << product->est_ibu << product->brew_fermenter_ibu; + ui->est_bufguEdit->setValue(bure); + ui->est_bufguShow->setValue(bure); + +} + + void EditProduct::calcWater() { double liters = 0; @@ -383,18 +426,7 @@ chloride = wg_chloride + RA; } - double BUGU = GetBUGU(); - ui->buguEdit->setValue(BUGU); - if (BUGU < 0.32) - ui->buguResult->setText(tr("Very malty and sweet")); - else if (BUGU < 0.43) - ui->buguResult->setText(tr("Malty, sweet")); - else if (BUGU < 0.52) - ui->buguResult->setText(tr("Balanced")); - else if (BUGU < 0.63) - ui->buguResult->setText(tr("Hoppy, bitter")); - else - ui->buguResult->setText(tr("Very hoppy, very bitter")); + calcBU(); double OptSO4Clratio = GetOptSO4Clratio(); ui->so4clEdit->setValue(OptSO4Clratio); @@ -774,9 +806,17 @@ double EditProduct::GetBUGU() { - double gu = (product->est_og - 1) * 1000; + double og = product->est_og; + double ibu = product->est_ibu; + + if (product->stage > PROD_STAGE_BREW) { + og = product->brew_fermenter_sg; + ibu = product->brew_fermenter_ibu; + } + + double gu = (og - 1) * 1000; if (gu > 0) - return product->est_ibu / gu; + return ibu / gu; return 0.5; } diff -r f41d02c129e5 -r 7212b980a527 src/EditRecipe.cpp --- a/src/EditRecipe.cpp Thu Aug 11 10:50:18 2022 +0200 +++ b/src/EditRecipe.cpp Wed Aug 17 14:30:33 2022 +0200 @@ -219,6 +219,11 @@ ui->est_carbShow->setMarkerTextIsValue(true); ui->est_carbShow->setRange(recipe->st_carb_min, recipe->st_carb_max); ui->est_carbShow->setValue(recipe->est_carb); + calcStyle(); + ui->est_buguShow->setPrecision(2); + ui->est_buguShow->setMarkerTextIsValue(true); + ui->est_bufguShow->setPrecision(2); + ui->est_bufguShow->setMarkerTextIsValue(true); // Tab fermentables. ui->est_og2Edit->setValue(recipe->est_og); diff -r f41d02c129e5 -r 7212b980a527 src/EditRecipe.h --- a/src/EditRecipe.h Thu Aug 11 10:50:18 2022 +0200 +++ b/src/EditRecipe.h Wed Aug 17 14:30:33 2022 +0200 @@ -170,6 +170,8 @@ void calcFermentables(); void calcFermentablesFromOG(double og); void calcIBUs(); + void calcStyle(); + void calcBU(); void adjustHops(double factor); void adjustMiscs(double factor); double ZAlkalinity(double pHZ); diff -r f41d02c129e5 -r 7212b980a527 src/EditRecipeTab1.cpp --- a/src/EditRecipeTab1.cpp Thu Aug 11 10:50:18 2022 +0200 +++ b/src/EditRecipeTab1.cpp Wed Aug 17 14:30:33 2022 +0200 @@ -18,6 +18,36 @@ */ +void EditRecipe::calcStyle() +{ + /* + * https://www.homebrewersassociation.org/forum/index.php?topic=10548.0 + * + * Calculate the ideal BU:GU and BU:RE ranges. These values + * will be used in the RangedSliders. + */ + double bugu_min = recipe->st_ibu_min / ((recipe->st_og_min - 1) * 1000); + double bugu_max = recipe->st_ibu_max / ((recipe->st_og_max - 1) * 1000); + ui->est_buguShow->setRange(bugu_min, bugu_max); + + double fg_min = recipe->st_fg_min; + if (fg_min < 1.002) /* Use 1.002 fg as lowest minimal value */ + fg_min = 1.002; + + /* + * Real Extract (RE) + */ + double re = ((0.1808 * ((Utils::sg_to_plato(recipe->st_og_min) + Utils::sg_to_plato(recipe->st_og_max)) / 2)) + + (0.8192 * ((Utils::sg_to_plato(fg_min) + Utils::sg_to_plato(recipe->st_fg_max)) / 2))); + + /* BU:RE */ + double bure_min = recipe->st_ibu_min / re; + double bure_max = recipe->st_ibu_max / re; + ui->est_bufguShow->setRange(bure_min, bure_max); + + qDebug() << "BU:RE" << bure_min << bure_max; +} + void EditRecipe::name_changed(QString name) { @@ -82,6 +112,7 @@ ui->est_carbShow->setRange(query.value(15).toDouble(), query.value(16).toDouble()); ui->est_abvShow->setRange(query.value(17).toDouble(), query.value(18).toDouble()); + calcStyle(); is_changed(); } diff -r f41d02c129e5 -r 7212b980a527 src/EditRecipeTab5.cpp --- a/src/EditRecipeTab5.cpp Thu Aug 11 10:50:18 2022 +0200 +++ b/src/EditRecipeTab5.cpp Wed Aug 17 14:30:33 2022 +0200 @@ -203,6 +203,7 @@ break; } } + calcBU(); } diff -r f41d02c129e5 -r 7212b980a527 src/EditRecipeTab7.cpp --- a/src/EditRecipeTab7.cpp Thu Aug 11 10:50:18 2022 +0200 +++ b/src/EditRecipeTab7.cpp Wed Aug 17 14:30:33 2022 +0200 @@ -187,6 +187,38 @@ } +void EditRecipe::calcBU() +{ + double BUGU = GetBUGU(); + ui->buguEdit->setValue(BUGU); + ui->est_buguEdit->setValue(BUGU); + ui->est_buguShow->setValue(BUGU); + if (BUGU < 0.32) + ui->buguResult->setText(tr("Very malty and sweet")); + else if (BUGU < 0.43) + ui->buguResult->setText(tr("Malty, sweet")); + else if (BUGU < 0.52) + ui->buguResult->setText(tr("Balanced")); + else if (BUGU < 0.63) + ui->buguResult->setText(tr("Hoppy, bitter")); + else + ui->buguResult->setText(tr("Very hoppy, very bitter")); + + double og = recipe->est_og; + double fg = recipe->est_fg; + double ibu = recipe->est_ibu; + + if (fg < 1.002) /* Can't be too low for this */ + fg = 1.002; + + double bure = ibu / ((0.1808 * Utils::sg_to_plato(og)) + (0.8192 * Utils::sg_to_plato(fg))); + qDebug() << "BU:RE" << bure << recipe->est_fg << recipe->est_ibu; + ui->est_bufguEdit->setValue(bure); + ui->est_bufguShow->setValue(bure); + +} + + void EditRecipe::calcWater() { double liters = 0; @@ -383,18 +415,7 @@ chloride = wg_chloride + RA; } - double BUGU = GetBUGU(); - ui->buguEdit->setValue(BUGU); - if (BUGU < 0.32) - ui->buguResult->setText(tr("Very malty and sweet")); - else if (BUGU < 0.43) - ui->buguResult->setText(tr("Malty, sweet")); - else if (BUGU < 0.52) - ui->buguResult->setText(tr("Balanced")); - else if (BUGU < 0.63) - ui->buguResult->setText(tr("Hoppy, bitter")); - else - ui->buguResult->setText(tr("Very hoppy, very bitter")); + calcBU(); double OptSO4Clratio = GetOptSO4Clratio(); ui->so4clEdit->setValue(OptSO4Clratio); diff -r f41d02c129e5 -r 7212b980a527 ui/EditProduct.ui --- a/ui/EditProduct.ui Thu Aug 11 10:50:18 2022 +0200 +++ b/ui/EditProduct.ui Wed Aug 17 14:30:33 2022 +0200 @@ -407,9 +407,9 @@ 10 - 340 + 310 1101 - 121 + 151 @@ -880,6 +880,132 @@ 0.100000000000000 + + + + 10 + 110 + 111 + 20 + + + + BU:GU ratio: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 380 + 110 + 111 + 20 + + + + BU:RE ratio: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 130 + 110 + 71 + 24 + + + + The obsolete Bitterness Unit to Gravity Unit ratio + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + QAbstractSpinBox::NoButtons + + + false + + + 2 + + + 0.000000000000000 + + + 400.000000000000000 + + + 1.000000000000000 + + + + + + 500 + 110 + 71 + 24 + + + + Bitterness Unit to Real Extract ratio + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + QAbstractSpinBox::NoButtons + + + false + + + 2 + + + 0.000000000000000 + + + 400.000000000000000 + + + 1.000000000000000 + + + + + + 210 + 110 + 148 + 24 + + + + + + + 580 + 110 + 148 + 24 + + + @@ -887,7 +1013,7 @@ 10 210 1101 - 121 + 91 @@ -896,9 +1022,9 @@ - 130 + 720 20 - 211 + 16 23 @@ -907,7 +1033,7 @@ 870 - 50 + 20 101 23 @@ -923,7 +1049,7 @@ 130 - 50 + 20 211 23 @@ -939,7 +1065,7 @@ 10 - 50 + 20 111 20 @@ -954,9 +1080,9 @@ - 720 - 50 - 141 + 740 + 20 + 121 20 @@ -967,27 +1093,11 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - 10 - 20 - 111 - 20 - - - - Select style: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - 10 - 80 + 50 111 20 @@ -1003,7 +1113,7 @@ 130 - 80 + 50 211 23 @@ -1019,7 +1129,7 @@ 360 - 80 + 50 131 20 @@ -1035,7 +1145,7 @@ 870 - 80 + 50 71 23 @@ -1051,7 +1161,7 @@ 720 - 80 + 50 141 20 @@ -1067,7 +1177,7 @@ 500 - 80 + 50 211 23 @@ -1083,7 +1193,7 @@ 500 - 50 + 20 211 23 @@ -1099,7 +1209,7 @@ 380 - 50 + 20 111 20 diff -r f41d02c129e5 -r 7212b980a527 ui/EditRecipe.ui --- a/ui/EditRecipe.ui Thu Aug 11 10:50:18 2022 +0200 +++ b/ui/EditRecipe.ui Wed Aug 17 14:30:33 2022 +0200 @@ -404,9 +404,9 @@ 10 - 340 + 310 1101 - 121 + 151 @@ -874,6 +874,132 @@ 0.100000000000000 + + + + 10 + 110 + 111 + 20 + + + + BU:GU ratio: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 130 + 110 + 71 + 24 + + + + The obsolete Bitterness Unit to Gravity Unit ratio + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + QAbstractSpinBox::NoButtons + + + false + + + 2 + + + 0.000000000000000 + + + 400.000000000000000 + + + 1.000000000000000 + + + + + + 580 + 110 + 148 + 24 + + + + + + + 210 + 110 + 148 + 24 + + + + + + + 500 + 110 + 71 + 24 + + + + Bitterness Unit to Real Extract ratio + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + QAbstractSpinBox::NoButtons + + + false + + + 2 + + + 0.000000000000000 + + + 400.000000000000000 + + + 1.000000000000000 + + + + + + 380 + 110 + 111 + 20 + + + + BU:RE ratio: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + @@ -881,7 +1007,7 @@ 10 210 1101 - 121 + 91 @@ -890,9 +1016,9 @@ - 500 + 730 20 - 226 + 16 23 @@ -901,7 +1027,7 @@ 870 - 50 + 20 101 23 @@ -914,7 +1040,7 @@ 500 - 50 + 20 226 23 @@ -927,7 +1053,7 @@ 130 - 50 + 20 226 23 @@ -940,7 +1066,7 @@ 10 - 50 + 20 111 20 @@ -955,9 +1081,9 @@ - 730 - 50 - 131 + 750 + 20 + 111 20 @@ -972,7 +1098,7 @@ 360 - 50 + 20 131 20 @@ -984,27 +1110,11 @@ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - 360 - 20 - 131 - 20 - - - - Select style: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - 10 - 80 + 50 111 20 @@ -1020,7 +1130,7 @@ 130 - 80 + 50 226 23 @@ -1033,7 +1143,7 @@ 360 - 80 + 50 131 20 @@ -1049,7 +1159,7 @@ 870 - 80 + 50 71 23 @@ -1062,7 +1172,7 @@ 730 - 80 + 50 131 20 @@ -1078,7 +1188,7 @@ 500 - 80 + 50 226 23