Added calcYeast(). Added show svg from calcFermentables() on the yeast tab. Fixed wrong data displayed in the yeast table. Show estimated needed dry yeast or starters.

Mon, 18 Apr 2022 20:00:49 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Mon, 18 Apr 2022 20:00:49 +0200
changeset 142
1caa15a0eefc
parent 141
eea8a9e7e1f6
child 143
8414844c9f8b

Added calcYeast(). Added show svg from calcFermentables() on the yeast tab. Fixed wrong data displayed in the yeast table. Show estimated needed dry yeast or starters.

src/EditRecipe.cpp file | annotate | diff | comparison | revisions
src/EditRecipe.h file | annotate | diff | comparison | revisions
src/EditRecipeTab2.cpp file | annotate | diff | comparison | revisions
src/EditRecipeTab5.cpp file | annotate | diff | comparison | revisions
ui/EditRecipe.ui file | annotate | diff | comparison | revisions
--- a/src/EditRecipe.cpp	Mon Apr 18 10:55:33 2022 +0200
+++ b/src/EditRecipe.cpp	Mon Apr 18 20:00:49 2022 +0200
@@ -713,6 +713,7 @@
     calcIBUs();
     refreshMiscs();
     refreshYeasts();
+    calcYeast();
     refreshMashs();
     refreshWaters();
     calcWater();
--- a/src/EditRecipe.h	Mon Apr 18 10:55:33 2022 +0200
+++ b/src/EditRecipe.h	Mon Apr 18 20:00:49 2022 +0200
@@ -331,8 +331,10 @@
     QStringList h_useat = { tr("Mash"), tr("First wort"), tr("Boil"), tr("Aroma"), tr("Whirlpool"), tr("Dry hop") };
     QStringList m_types = { tr("Spice"), tr("Herb"), tr("Flavor"), tr("Fining"), tr("Water agent"), tr("Yeast nutrient"), tr("Other") };
     QStringList m_uses = { tr("Starter"), tr("Mash"), tr("Boil"), tr("Primary"), tr("Secondary"), tr("Bottling") };
-    QStringList y_types = { tr("Liquid"), tr("Dry"), tr("Slant"), tr("Culture"), tr("Frozen"), tr("Bottle"), tr("Dried") };
+    //QStringList y_types = { tr("Lager"), tr("Ale"), tr("Wheat"), tr("Wine"), tr("Champagne"), tr("Brett"), tr("Kveik"), tr("Hybrid") };
+    QStringList y_forms = { tr("Liquid"), tr("Dry"), tr("Slant"), tr("Culture"), tr("Frozen"), tr("Bottle"), tr("Dried") };
     QStringList y_use = { tr("Primary"), tr("Secondary"), tr("Tertiary"), tr("Bottle") };
+    QStringList starters = { tr("Stirred"), tr("Shaken"), tr("Simple") };
     QString bar_red = "QProgressBar::chunk {background: #FF0000;}";
     QString bar_orange = "QProgressBar::chunk {background: #EB7331;}";
     QString bar_green = "QProgressBar::chunk {background: #008C00;}";
@@ -374,6 +376,7 @@
     void calcWater();
     double GetBUGU();
     double GetOptSO4Clratio();
+    void calcYeast();
 };
 
 #endif
--- a/src/EditRecipeTab2.cpp	Mon Apr 18 10:55:33 2022 +0200
+++ b/src/EditRecipeTab2.cpp	Mon Apr 18 20:00:49 2022 +0200
@@ -313,6 +313,7 @@
     }
     if (svg == 0)
 	svg = 77.0;
+    ui->est_svgEdit->setValue(svg);
 
     double fg;
     if (mashkg > 0 && mashinfuse > 0 && mashtime > 0 && mashtemp > 0)
--- a/src/EditRecipeTab5.cpp	Mon Apr 18 10:55:33 2022 +0200
+++ b/src/EditRecipeTab5.cpp	Mon Apr 18 20:00:49 2022 +0200
@@ -70,7 +70,7 @@
 	ui->yeastsTable->setItem(i, 1, new QTableWidgetItem(recipe->yeasts.at(i).y_laboratory));
 	ui->yeastsTable->setItem(i, 2, new QTableWidgetItem(recipe->yeasts.at(i).y_product_id));
 
-	item = new QTableWidgetItem(y_types[recipe->yeasts.at(i).y_type]);
+	item = new QTableWidgetItem(y_forms[recipe->yeasts.at(i).y_form]);
         item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
         ui->yeastsTable->setItem(i, 3, item);
 
@@ -94,9 +94,9 @@
         item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
         ui->yeastsTable->setItem(i, 8, item);
 
-	if (recipe->yeasts.at(i).y_type == 0)
-            item = new QTableWidgetItem(QString("%1 pack").arg(recipe->yeasts.at(i).y_amount * 1000.0, 3, 'f', 2, '0'));
-	else if (recipe->yeasts.at(i).y_type == 1)
+	if (recipe->yeasts.at(i).y_form == 0)
+            item = new QTableWidgetItem(QString("%1 pack").arg(recipe->yeasts.at(i).y_amount, 1, 'f', 0, '0'));
+	else if (recipe->yeasts.at(i).y_form == 1)
 	    item = new QTableWidgetItem(QString("%1 gr").arg(recipe->yeasts.at(i).y_amount * 1000.0, 3, 'f', 2, '0'));
 	else
 	    item = new QTableWidgetItem(QString("%1 ml").arg(recipe->yeasts.at(i).y_amount * 1000.0, 3, 'f', 2, '0'));
@@ -130,6 +130,90 @@
 }
 
 
+/*
+ * The results are not stored line in EditProduct. This is just a hint.
+ */
+void EditRecipe::calcYeast()
+{
+    double sg = recipe->est_og;
+    double plato = Utils::sg_to_plato(sg);
+    double volume = recipe->batch_size * 0.9;	// Volume min trub chiller loss.
+    bool maybe_starter = false;
+    double pitchrate = 0.75;
+    double initcells = 0;
+
+    qDebug() << "calcYeast()";
+    ui->yeastProcedure->setCurrentIndex(0);
+
+    if (recipe->yeasts.size() == 0)
+	return;		// No yeast in recipe.
+
+    for (int i = 0; i < recipe->yeasts.size(); i++) {
+	if (recipe->yeasts.at(i).y_use == 0) {		// Primary
+	    if (recipe->yeasts.at(i).y_form == 1) {
+		/*
+		 * Dry yeast, build the formule with the yeast parameters.
+		 * Based on https://www.lallemandbrewing.com/en/canada/brewers-corner/brewing-tools/pitching-rate-calculator/
+		 */
+		ui->yeastProcedure->setCurrentIndex(2);
+		ui->lo_gr_hlEdit->setValue(recipe->yeasts.at(i).y_gr_hl_lo);
+		ui->hi_gr_hlEdit->setValue(recipe->yeasts.at(i).y_gr_hl_hi);
+		ui->lo_sgEdit->setValue(recipe->yeasts.at(i).y_sg_lo);
+		ui->hi_sgEdit->setValue(recipe->yeasts.at(i).y_sg_hi);
+		double og = recipe->yeasts.at(i).y_sg_lo;
+		double f1 = recipe->yeasts.at(i).y_gr_hl_lo / 100.0;
+		double f2 = round(f1 / 5 * 1000000.0) / 1000000.0;
+     		double multiplier = (sg <= og) ? f1 : (f1 + f2 * (sg - og) / 0.008);
+		qDebug() << "  sg:" << sg << "og:" << og << "f1:" << f1 << "f2:" << f2 << "multiplier:" << multiplier;
+     		double yeast_grams = round(volume * multiplier * 100.0) / 100.0; // * (100 / dataRecord.starter_viability), 2);
+     		double yeast_gr_hl = round((yeast_grams / (volume * 0.01)) * 100.0) / 100.0;
+		ui->need_grEdit->setValue(yeast_grams);
+		ui->pitch_grEdit->setValue(yeast_gr_hl);
+     		qDebug() << "  need" << yeast_grams << "grams, gr/hl:" << yeast_gr_hl;
+		return;
+	    } else {
+		/*
+		 * Liquid, slant, culture etc.
+		 * pitchrate see https://www.brewersfriend.com/yeast-pitch-rate-and-starter-calculator/
+		 * and http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/
+		 */
+		ui->yeastProcedure->setCurrentIndex(1);
+		if (recipe->yeasts.at(i).y_type == 0) {		// Lager yeast
+		    pitchrate = 1.5;
+		    if (sg > 1.060)
+			pitchrate = 2.0;
+		} else if (recipe->yeasts.at(i).y_type == 6) {	// Real Kveik
+		    pitchrate = 0.075;
+		} else {
+		    pitchrate = 0.75;
+		    if (sg > 1.060)
+			pitchrate = 1.0;
+		}
+		if (recipe->yeasts.at(i).y_form == 0)
+		    initcells = (recipe->yeasts.at(i).y_cells / 1000000000) * recipe->yeasts.at(i).y_amount * 0.97;	// 97% viability assumed.
+		else
+		    initcells = (recipe->yeasts.at(i).y_cells / 1000000) * recipe->yeasts.at(i).y_amount * 0.97;
+
+		double needed = round(pitchrate * volume * plato * 10.0) / 10.0;
+		double starter = 0;
+		if (needed > initcells) {
+		    maybe_starter = true;
+		    starter = round(needed / 2.0) / 100.0;	// A very rough starter size estimate.
+		}
+
+		ui->pitchrateEdit->setValue(pitchrate);
+		ui->initcellsEdit->setValue(initcells);
+		ui->targetcellsEdit->setValue(needed);
+		ui->starterEdit->setValue(starter);
+
+		qDebug() << "  pitchrate:" << pitchrate << "needed:" << needed << "initcells:" << initcells << "starter" << maybe_starter << "size" << starter;
+	    }
+	    break;
+	}
+    }
+}
+
+
 void EditRecipe::addYeastRow_clicked()
 {
 
--- a/ui/EditRecipe.ui	Mon Apr 18 10:55:33 2022 +0200
+++ b/ui/EditRecipe.ui	Mon Apr 18 20:00:49 2022 +0200
@@ -95,7 +95,7 @@
        <enum>QTabWidget::Rounded</enum>
       </property>
       <property name="currentIndex">
-       <number>3</number>
+       <number>4</number>
       </property>
       <property name="elideMode">
        <enum>Qt::ElideNone</enum>
@@ -1771,7 +1771,7 @@
          <double>0.000000000000000</double>
         </property>
         <property name="maximum">
-         <double>80.000000000000000</double>
+         <double>120.000000000000000</double>
         </property>
         <property name="singleStep">
          <double>0.100000000000000</double>
@@ -1797,21 +1797,207 @@
          </rect>
         </property>
         <property name="currentIndex">
-         <number>0</number>
+         <number>1</number>
         </property>
         <widget class="QWidget" name="yeastNot"/>
         <widget class="QWidget" name="yeastLiquid">
          <widget class="QLabel" name="label">
           <property name="geometry">
            <rect>
-            <x>15</x>
-            <y>0</y>
-            <width>81</width>
+            <x>200</x>
+            <y>20</y>
+            <width>341</width>
+            <height>20</height>
+           </rect>
+          </property>
+          <property name="font">
+           <font>
+            <pointsize>11</pointsize>
+            <weight>75</weight>
+            <bold>true</bold>
+           </font>
+          </property>
+          <property name="text">
+           <string>Liquid yeast advice</string>
+          </property>
+         </widget>
+         <widget class="QDoubleSpinBox" name="pitchrateEdit">
+          <property name="geometry">
+           <rect>
+            <x>200</x>
+            <y>60</y>
+            <width>91</width>
+            <height>24</height>
+           </rect>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+          <property name="buttonSymbols">
+           <enum>QAbstractSpinBox::NoButtons</enum>
+          </property>
+          <property name="accelerated">
+           <bool>false</bool>
+          </property>
+          <property name="decimals">
+           <number>3</number>
+          </property>
+          <property name="maximum">
+           <double>1000.000000000000000</double>
+          </property>
+         </widget>
+         <widget class="QLabel" name="pitchrateLabel">
+          <property name="geometry">
+           <rect>
+            <x>10</x>
+            <y>60</y>
+            <width>181</width>
+            <height>20</height>
+           </rect>
+          </property>
+          <property name="text">
+           <string>Pitchrate million cells/ml/°P:</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+         </widget>
+         <widget class="QLabel" name="initcellsLabel">
+          <property name="geometry">
+           <rect>
+            <x>10</x>
+            <y>90</y>
+            <width>181</width>
+            <height>20</height>
+           </rect>
+          </property>
+          <property name="text">
+           <string>Initial billion cells:</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+         </widget>
+         <widget class="QLabel" name="targetcellsLabel">
+          <property name="geometry">
+           <rect>
+            <x>10</x>
+            <y>120</y>
+            <width>181</width>
             <height>20</height>
            </rect>
           </property>
           <property name="text">
-           <string>Liquid Yeast</string>
+           <string>Target billion cells:</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+         </widget>
+         <widget class="QDoubleSpinBox" name="initcellsEdit">
+          <property name="geometry">
+           <rect>
+            <x>200</x>
+            <y>90</y>
+            <width>91</width>
+            <height>24</height>
+           </rect>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+          <property name="buttonSymbols">
+           <enum>QAbstractSpinBox::NoButtons</enum>
+          </property>
+          <property name="accelerated">
+           <bool>false</bool>
+          </property>
+          <property name="decimals">
+           <number>0</number>
+          </property>
+          <property name="maximum">
+           <double>100000.000000000000000</double>
+          </property>
+         </widget>
+         <widget class="QDoubleSpinBox" name="targetcellsEdit">
+          <property name="geometry">
+           <rect>
+            <x>200</x>
+            <y>120</y>
+            <width>91</width>
+            <height>24</height>
+           </rect>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+          <property name="buttonSymbols">
+           <enum>QAbstractSpinBox::NoButtons</enum>
+          </property>
+          <property name="accelerated">
+           <bool>false</bool>
+          </property>
+          <property name="decimals">
+           <number>0</number>
+          </property>
+          <property name="maximum">
+           <double>100000.000000000000000</double>
+          </property>
+         </widget>
+         <widget class="QLabel" name="starterLabel">
+          <property name="geometry">
+           <rect>
+            <x>10</x>
+            <y>150</y>
+            <width>181</width>
+            <height>20</height>
+           </rect>
+          </property>
+          <property name="text">
+           <string>Starter volume L:</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+         </widget>
+         <widget class="QDoubleSpinBox" name="starterEdit">
+          <property name="geometry">
+           <rect>
+            <x>200</x>
+            <y>150</y>
+            <width>91</width>
+            <height>24</height>
+           </rect>
+          </property>
+          <property name="toolTip">
+           <string>A very rough starter volume estimate.</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+          <property name="buttonSymbols">
+           <enum>QAbstractSpinBox::NoButtons</enum>
+          </property>
+          <property name="accelerated">
+           <bool>false</bool>
+          </property>
+          <property name="decimals">
+           <number>3</number>
+          </property>
+          <property name="maximum">
+           <double>100000.000000000000000</double>
           </property>
          </widget>
         </widget>
@@ -1819,14 +2005,276 @@
          <widget class="QLabel" name="label_2">
           <property name="geometry">
            <rect>
-            <x>15</x>
-            <y>0</y>
-            <width>71</width>
+            <x>170</x>
+            <y>10</y>
+            <width>261</width>
+            <height>20</height>
+           </rect>
+          </property>
+          <property name="font">
+           <font>
+            <pointsize>11</pointsize>
+            <weight>75</weight>
+            <bold>true</bold>
+           </font>
+          </property>
+          <property name="text">
+           <string>Dry yeast advice</string>
+          </property>
+         </widget>
+         <widget class="QLabel" name="lo_gr_hlLabel">
+          <property name="geometry">
+           <rect>
+            <x>50</x>
+            <y>60</y>
+            <width>111</width>
+            <height>20</height>
+           </rect>
+          </property>
+          <property name="text">
+           <string>Low grams/hl:</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+         </widget>
+         <widget class="QLabel" name="hi_gr_hlLabel">
+          <property name="geometry">
+           <rect>
+            <x>50</x>
+            <y>90</y>
+            <width>111</width>
+            <height>20</height>
+           </rect>
+          </property>
+          <property name="text">
+           <string>High grams/hl:</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+         </widget>
+         <widget class="QSpinBox" name="lo_gr_hlEdit">
+          <property name="geometry">
+           <rect>
+            <x>170</x>
+            <y>60</y>
+            <width>61</width>
+            <height>24</height>
+           </rect>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+          <property name="buttonSymbols">
+           <enum>QAbstractSpinBox::NoButtons</enum>
+          </property>
+          <property name="maximum">
+           <number>500</number>
+          </property>
+         </widget>
+         <widget class="QSpinBox" name="hi_gr_hlEdit">
+          <property name="geometry">
+           <rect>
+            <x>170</x>
+            <y>90</y>
+            <width>61</width>
+            <height>24</height>
+           </rect>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+          <property name="buttonSymbols">
+           <enum>QAbstractSpinBox::NoButtons</enum>
+          </property>
+          <property name="maximum">
+           <number>1000</number>
+          </property>
+         </widget>
+         <widget class="QLabel" name="lo_atLabel">
+          <property name="geometry">
+           <rect>
+            <x>240</x>
+            <y>60</y>
+            <width>31</width>
+            <height>20</height>
+           </rect>
+          </property>
+          <property name="text">
+           <string>at</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignCenter</set>
+          </property>
+         </widget>
+         <widget class="QLabel" name="hi_atLabel">
+          <property name="geometry">
+           <rect>
+            <x>240</x>
+            <y>90</y>
+            <width>31</width>
             <height>20</height>
            </rect>
           </property>
           <property name="text">
-           <string>Dry Yeast</string>
+           <string>at</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignCenter</set>
+          </property>
+         </widget>
+         <widget class="QDoubleSpinBox" name="lo_sgEdit">
+          <property name="geometry">
+           <rect>
+            <x>280</x>
+            <y>60</y>
+            <width>71</width>
+            <height>24</height>
+           </rect>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+          <property name="buttonSymbols">
+           <enum>QAbstractSpinBox::NoButtons</enum>
+          </property>
+          <property name="accelerated">
+           <bool>false</bool>
+          </property>
+          <property name="decimals">
+           <number>3</number>
+          </property>
+          <property name="maximum">
+           <double>2.000000000000000</double>
+          </property>
+          <property name="value">
+           <double>0.000000000000000</double>
+          </property>
+         </widget>
+         <widget class="QDoubleSpinBox" name="hi_sgEdit">
+          <property name="geometry">
+           <rect>
+            <x>280</x>
+            <y>90</y>
+            <width>71</width>
+            <height>24</height>
+           </rect>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+          <property name="buttonSymbols">
+           <enum>QAbstractSpinBox::NoButtons</enum>
+          </property>
+          <property name="accelerated">
+           <bool>false</bool>
+          </property>
+          <property name="decimals">
+           <number>3</number>
+          </property>
+          <property name="maximum">
+           <double>2.000000000000000</double>
+          </property>
+         </widget>
+         <widget class="QLabel" name="need_grLabel">
+          <property name="geometry">
+           <rect>
+            <x>50</x>
+            <y>120</y>
+            <width>111</width>
+            <height>20</height>
+           </rect>
+          </property>
+          <property name="text">
+           <string>Pitch grams:</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+         </widget>
+         <widget class="QDoubleSpinBox" name="need_grEdit">
+          <property name="geometry">
+           <rect>
+            <x>170</x>
+            <y>120</y>
+            <width>61</width>
+            <height>24</height>
+           </rect>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+          <property name="buttonSymbols">
+           <enum>QAbstractSpinBox::NoButtons</enum>
+          </property>
+          <property name="accelerated">
+           <bool>false</bool>
+          </property>
+          <property name="decimals">
+           <number>1</number>
+          </property>
+          <property name="maximum">
+           <double>1000.000000000000000</double>
+          </property>
+         </widget>
+         <widget class="QLabel" name="pitch_grLabel">
+          <property name="geometry">
+           <rect>
+            <x>50</x>
+            <y>150</y>
+            <width>111</width>
+            <height>20</height>
+           </rect>
+          </property>
+          <property name="text">
+           <string>Pitch grams/hl:</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+         </widget>
+         <widget class="QDoubleSpinBox" name="pitch_grEdit">
+          <property name="geometry">
+           <rect>
+            <x>170</x>
+            <y>150</y>
+            <width>61</width>
+            <height>24</height>
+           </rect>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+          <property name="buttonSymbols">
+           <enum>QAbstractSpinBox::NoButtons</enum>
+          </property>
+          <property name="accelerated">
+           <bool>false</bool>
+          </property>
+          <property name="decimals">
+           <number>2</number>
+          </property>
+          <property name="maximum">
+           <double>1000.000000000000000</double>
           </property>
          </widget>
         </widget>

mercurial