207 double needed = 0; |
207 double needed = 0; |
208 double initcells = 0; |
208 double initcells = 0; |
209 bool maybe_starter = false; |
209 bool maybe_starter = false; |
210 |
210 |
211 qDebug() << "calcYeast()"; |
211 qDebug() << "calcYeast()"; |
212 qDebug() << " " << product->prop_volume[0] << product->prop_volume[1] << product->prop_volume[2] << product->prop_volume[3]; |
|
213 ui->yeastProcedure->setCurrentIndex(0); |
212 ui->yeastProcedure->setCurrentIndex(0); |
214 |
213 |
215 if (sg <= 1.0001 && product->fg > 1.000) |
214 if (sg <= 1.0001 && product->fg > 1.000) |
216 sg = product->fg; |
215 sg = product->fg; |
217 else if (sg <= 1.0001) |
216 else if (sg <= 1.0001) |
228 |
227 |
229 if (product->yeasts.size() == 0) |
228 if (product->yeasts.size() == 0) |
230 return; // No yeast in product. |
229 return; // No yeast in product. |
231 |
230 |
232 calcViability(); |
231 calcViability(); |
|
232 double dry_amount = 0; |
|
233 for (int i = 0; i < product->yeasts.size(); i++) { |
|
234 if (product->yeasts.at(i).use == YEAST_USE_PRIMARY && product->yeasts.at(i).form == YEAST_FORMS_DRY) { |
|
235 dry_amount += product->yeasts.at(i).amount; |
|
236 } |
|
237 } |
233 |
238 |
234 for (int i = 0; i < product->yeasts.size(); i++) { |
239 for (int i = 0; i < product->yeasts.size(); i++) { |
235 if (product->yeasts.at(i).use == YEAST_USE_PRIMARY) { // Primary |
240 if (product->yeasts.at(i).use == YEAST_USE_PRIMARY) { // Primary |
236 if (product->yeasts.at(i).form == YEAST_FORMS_DRY) { |
241 if (product->yeasts.at(i).form == YEAST_FORMS_DRY) { |
237 /* |
242 /* |
248 double f2 = round(f1 / 5 * 1000000.0) / 1000000.0; |
253 double f2 = round(f1 / 5 * 1000000.0) / 1000000.0; |
249 double multiplier = (sg <= og) ? f1 : (f1 + f2 * (sg - og) / 0.008); |
254 double multiplier = (sg <= og) ? f1 : (f1 + f2 * (sg - og) / 0.008); |
250 qDebug() << " sg:" << sg << "og:" << og << "f1:" << f1 << "f2:" << f2 << "multiplier:" << multiplier; |
255 qDebug() << " sg:" << sg << "og:" << og << "f1:" << f1 << "f2:" << f2 << "multiplier:" << multiplier; |
251 double yeast_grams = round(volume * multiplier * 100.0) / product->starter_viability; |
256 double yeast_grams = round(volume * multiplier * 100.0) / product->starter_viability; |
252 double yeast_gr_hl = round((yeast_grams / (volume * 0.01)) * 100.0) / 100.0; |
257 double yeast_gr_hl = round((yeast_grams / (volume * 0.01)) * 100.0) / 100.0; |
253 double pitch_gr_hl = round(((product->yeasts.at(i).amount * 1000.0) / (volume * 0.01)) * 100.0) / 100.0; |
258 double pitch_gr_hl = round(((dry_amount * 1000.0) / (volume * 0.01)) * 100.0) / 100.0; |
254 ui->dry_needShow->setValue(yeast_grams); |
259 ui->dry_needShow->setValue(yeast_grams); |
255 ui->dry_pitchrateShow->setValue(yeast_gr_hl); |
260 ui->dry_pitchrateShow->setValue(yeast_gr_hl); |
256 ui->pitch_grShow->setValue(pitch_gr_hl); |
261 ui->pitch_grShow->setValue(pitch_gr_hl); |
257 ui->pitch_grShow->setStyleSheet((pitch_gr_hl < yeast_gr_hl) ? "background-color: red":""); |
262 ui->pitch_grShow->setStyleSheet((pitch_gr_hl < yeast_gr_hl) ? "background-color: red":""); |
258 |
263 |
259 #ifdef DEBUG_YEAST |
264 #ifdef DEBUG_YEAST |
260 qDebug() << " need" << yeast_grams << "grams, gr/hl:" << yeast_gr_hl << "pitch:" << pitch_gr_hl; |
265 qDebug() << " Need" << yeast_grams << "grams, gr/hl:" << yeast_gr_hl << "pitch:" << pitch_gr_hl; |
261 #endif |
266 #endif |
|
267 calcBU(); |
262 return; |
268 return; |
263 } else { |
269 } else { |
264 /* |
270 /* |
265 * Liquid, slant, culture etc. |
271 * Liquid, slant, culture etc. |
266 * pitchrate see https://www.brewersfriend.com/yeast-pitch-rate-and-starter-calculator/ |
272 * pitchrate see https://www.brewersfriend.com/yeast-pitch-rate-and-starter-calculator/ |
282 if (sg > 1.060) |
288 if (sg > 1.060) |
283 product->yeast_pitchrate = 1.0; |
289 product->yeast_pitchrate = 1.0; |
284 } |
290 } |
285 is_changed(); |
291 is_changed(); |
286 ui->pitchrateEdit->setValue(product->yeast_pitchrate); |
292 ui->pitchrateEdit->setValue(product->yeast_pitchrate); |
|
293 #ifdef DEBUG_YEAST |
|
294 qDebug() << " Guessed pitchrate" << product->yeast_pitchrate; |
|
295 #endif |
287 } |
296 } |
288 |
297 |
289 initcells = (product->yeasts.at(i).cells / 1000000) * product->yeasts.at(i).amount * (product->starter_viability / 100.0); |
298 initcells = (product->yeasts.at(i).cells / 1000000) * product->yeasts.at(i).amount * (product->starter_viability / 100.0); |
290 if (product->yeasts.at(i).form == YEAST_FORMS_LIQUID) |
299 if (product->yeasts.at(i).form == YEAST_FORMS_LIQUID) |
291 initcells = (product->yeasts.at(i).cells / 1000000000) * product->yeasts.at(i).amount * (product->starter_viability / 100.0); |
300 initcells = (product->yeasts.at(i).cells / 1000000000) * product->yeasts.at(i).amount * (product->starter_viability / 100.0); |
386 res.irate = irate; |
395 res.irate = irate; |
387 res.ncells = ncells; |
396 res.ncells = ncells; |
388 res.totcells = totcells; |
397 res.totcells = totcells; |
389 res.growf = round((ncells / start) * 100.0) / 100.0; |
398 res.growf = round((ncells / start) * 100.0) / 100.0; |
390 #ifdef DEBUG_YEAST |
399 #ifdef DEBUG_YEAST |
391 qDebug() << " calcStep(" << svol << "," << stype << "," << start << ") irate" << irate |
400 qDebug() << " calcStep(" << svol << "," << stype << "," << start << ") irate" << irate |
392 << "ncells" << res.ncells << "totcells" << res.totcells << "growf" << res.growf; |
401 << "ncells" << res.ncells << "totcells" << res.totcells << "growf" << res.growf; |
393 #endif |
402 #endif |
394 return res; |
403 return res; |
395 } |
404 } |
396 |
405 |
429 |
438 |
430 if (start > needed) |
439 if (start > needed) |
431 return; |
440 return; |
432 |
441 |
433 for (step = 1; step < 5; step++) { |
442 for (step = 1; step < 5; step++) { |
434 qDebug() << " step" << step; |
|
435 |
|
436 for (i = lasti; i <= mvols; i++) { |
443 for (i = lasti; i <= mvols; i++) { |
437 lasti = i; |
444 lasti = i; |
438 svol = uvols[lasti]; |
445 svol = uvols[lasti]; |
439 result = calcStep(svol, stype, tcells); |
446 result = calcStep(svol, stype, tcells); |
440 if (result.irate < 25) { |
447 if (result.irate < 25) { |
585 if (product->yeasts.at(i).use == YEAST_USE_PRIMARY) { |
592 if (product->yeasts.at(i).use == YEAST_USE_PRIMARY) { |
586 if (product->yeasts.at(i).form == YEAST_FORMS_LIQUID) { |
593 if (product->yeasts.at(i).form == YEAST_FORMS_LIQUID) { |
587 vpm = 0.80; |
594 vpm = 0.80; |
588 max = 97; |
595 max = 97; |
589 if (product->yeasts.at(i).laboratory == "White Labs") { // PurePitch |
596 if (product->yeasts.at(i).laboratory == "White Labs") { // PurePitch |
590 vpm = 0.95; |
597 /* |
|
598 * Purepitch 6th month viability point 80,8%. |
|
599 * Purepitch Next Generation 6th month viability point 94,9%. |
|
600 */ |
|
601 vpm = 0.9648; // Purepitch |
|
602 //vpm = 0.9914; // Purepitch Next Generation |
591 max = 100; |
603 max = 100; |
592 } |
604 } |
593 } else if (product->yeasts.at(i).form == YEAST_FORMS_DRY) { |
605 } else if (product->yeasts.at(i).form == YEAST_FORMS_DRY) { |
594 vpm = 0.998; |
606 vpm = 0.998; |
595 max = 100; |
607 max = 100; |
620 for (int i = 0; i < timeDiff; i++) { |
632 for (int i = 0; i < timeDiff; i++) { |
621 base = base * degrade; |
633 base = base * degrade; |
622 } |
634 } |
623 if (base > max) |
635 if (base > max) |
624 base = max; |
636 base = max; |
625 base = round(base); |
637 product->starter_viability = round(base * 10) / 10; |
626 product->starter_viability = base; |
|
627 ui->conditionShow->setValue(product->starter_viability); |
638 ui->conditionShow->setValue(product->starter_viability); |
628 #ifdef DEBUG_YEAST |
639 #ifdef DEBUG_YEAST |
629 qDebug() << "age" << timeDiff << "degrade" << degrade << "base" << base ; |
640 qDebug() << "age" << timeDiff << "degrade" << degrade << "viability" << product->starter_viability; |
630 #endif |
641 #endif |
631 } |
642 } |
632 |
643 |
633 |
644 |
634 void EditProduct::yeast_prod_date_changed(QDate val) |
645 void EditProduct::yeast_prod_date_changed(QDate val) |
897 QMessageBox::Yes | QMessageBox::No, QMessageBox::No); |
908 QMessageBox::Yes | QMessageBox::No, QMessageBox::No); |
898 if (rc == QMessageBox::No) |
909 if (rc == QMessageBox::No) |
899 return; |
910 return; |
900 |
911 |
901 product->yeasts.removeAt(row); |
912 product->yeasts.removeAt(row); |
902 bool primary = false; |
913 bool primary = false; /* Check if any primary yeast is left */ |
903 for (int i = 0; i < product->yeasts.size(); i++) { |
914 for (int i = 0; i < product->yeasts.size(); i++) { |
904 if (product->yeasts.at(i).use == YEAST_USE_PRIMARY) |
915 if (product->yeasts.at(i).use == YEAST_USE_PRIMARY) |
905 primary = true; |
916 primary = true; |
906 } |
917 } |
907 if (! primary) { |
918 if (! primary) { |
934 } else { |
945 } else { |
935 product->yeasts[product->yeasts_row].amount = val / 1000.0; |
946 product->yeasts[product->yeasts_row].amount = val / 1000.0; |
936 item = new QTableWidgetItem(QString("%1 ml").arg(val, 3, 'f', 2, '0')); |
947 item = new QTableWidgetItem(QString("%1 ml").arg(val, 3, 'f', 2, '0')); |
937 } |
948 } |
938 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
949 item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter); |
939 ui->yeastsTable->setItem(product->yeasts_row, 9, item); |
950 ui->yeastsTable->setItem(product->yeasts_row, 10, item); |
940 |
951 |
941 calcYeast(); |
952 calcYeast(); |
942 is_changed(); |
953 is_changed(); |
943 } |
954 } |
944 |
955 |
1017 product->yeasts[product->yeasts_row].amount = 1; |
1028 product->yeasts[product->yeasts_row].amount = 1; |
1018 yamountEdit->setValue(product->yeasts[product->yeasts_row].amount); |
1029 yamountEdit->setValue(product->yeasts[product->yeasts_row].amount); |
1019 yamountEdit->setDecimals(0); |
1030 yamountEdit->setDecimals(0); |
1020 yamountEdit->setSingleStep(1.0); |
1031 yamountEdit->setSingleStep(1.0); |
1021 yamountLabel->setText(tr("Total packs:")); |
1032 yamountLabel->setText(tr("Total packs:")); |
|
1033 product->yeast_pitchrate = 0; |
1022 } else if ((product->yeasts.at(product->yeasts_row).form == YEAST_FORMS_DRY) || (product->yeasts.at(product->yeasts_row).form == YEAST_FORMS_DRIED)) { |
1034 } else if ((product->yeasts.at(product->yeasts_row).form == YEAST_FORMS_DRY) || (product->yeasts.at(product->yeasts_row).form == YEAST_FORMS_DRIED)) { |
1023 if (oldform == YEAST_FORMS_LIQUID) |
1035 if (oldform == YEAST_FORMS_LIQUID) |
1024 product->yeasts[product->yeasts_row].amount = 0.01; |
1036 product->yeasts[product->yeasts_row].amount = 0.01; |
1025 yamountEdit->setValue(product->yeasts[product->yeasts_row].amount * 1000.0); |
1037 yamountEdit->setValue(product->yeasts[product->yeasts_row].amount * 1000.0); |
1026 yamountEdit->setDecimals(1); |
1038 yamountEdit->setDecimals(1); |
1031 product->yeasts[product->yeasts_row].amount = 0.01; |
1043 product->yeasts[product->yeasts_row].amount = 0.01; |
1032 yamountEdit->setValue(product->yeasts[product->yeasts_row].amount * 1000.0); |
1044 yamountEdit->setValue(product->yeasts[product->yeasts_row].amount * 1000.0); |
1033 yamountEdit->setDecimals(1); |
1045 yamountEdit->setDecimals(1); |
1034 yamountEdit->setSingleStep(0.5); |
1046 yamountEdit->setSingleStep(0.5); |
1035 yamountLabel->setText(tr("Amount in ml:")); |
1047 yamountLabel->setText(tr("Amount in ml:")); |
|
1048 product->yeast_pitchrate = 0; |
1036 } |
1049 } |
1037 |
1050 |
1038 ui->yeastsTable->setItem(product->yeasts_row, 0, new QTableWidgetItem(product->yeasts.at(product->yeasts_row).name)); |
1051 ui->yeastsTable->setItem(product->yeasts_row, 0, new QTableWidgetItem(product->yeasts.at(product->yeasts_row).name)); |
1039 ui->yeastsTable->setItem(product->yeasts_row, 1, new QTableWidgetItem(product->yeasts.at(product->yeasts_row).laboratory)); |
1052 ui->yeastsTable->setItem(product->yeasts_row, 1, new QTableWidgetItem(product->yeasts.at(product->yeasts_row).laboratory)); |
1040 ui->yeastsTable->setItem(product->yeasts_row, 2, new QTableWidgetItem(product->yeasts.at(product->yeasts_row).product_id)); |
1053 ui->yeastsTable->setItem(product->yeasts_row, 2, new QTableWidgetItem(product->yeasts.at(product->yeasts_row).product_id)); |
1137 #endif |
1149 #endif |
1138 |
1150 |
1139 product->yeasts[product->yeasts_row].use = val; |
1151 product->yeasts[product->yeasts_row].use = val; |
1140 QTableWidgetItem *item = new QTableWidgetItem(QCoreApplication::translate("YeastUse", g_yeast_use[val])); |
1152 QTableWidgetItem *item = new QTableWidgetItem(QCoreApplication::translate("YeastUse", g_yeast_use[val])); |
1141 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); |
1153 item->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter); |
1142 ui->yeastsTable->setItem(product->yeasts_row, 5, item); |
1154 ui->yeastsTable->setItem(product->yeasts_row, 4, item); |
1143 is_changed(); |
1155 is_changed(); |
1144 emit refreshAll(); |
|
1145 } |
1156 } |
1146 |
1157 |
1147 |
1158 |
1148 void EditProduct::editYeastRow_clicked() |
1159 void EditProduct::editYeastRow_clicked() |
1149 { |
1160 { |