Home Brew Forums (http://www.homebrewtalk.com/forum.php)
-   Brewing Software (http://www.homebrewtalk.com/f84/)

 doobliebop 01-12-2011 09:36 PM

Script to calculate water salt additions

I wrote this script to calculate the optimal amount of brewing salts to add to your water profile to end up with a target profile. I grabbed most of my numbers from ProMash, and so far this seems to be working well for me.

It is a python script, so you'll need the python interpreter with numpy, and the PyIMSL numerical libraries (freely available here: http://www.imslaps.com/products/imsl/pyimsl/)

Code:

``` from numpy import * from imsl.math.linLsqLinConstraints import linLsqLinConstraints from imsl.math.writeMatrix import writeMatrix from imsl.math.vectorNorm import vectorNorm #Replace the values in base_water with your water profile base_water = [26.0, 3.6, 13.2, 28.0, 12.2, 68] #################Values taken from ProMash################ burton_on_trent = [268., 62., 30., 638., 36., 141.] calistoga_mineral = [11.1, 62., 30., 638., 36., 141.] distilled_water = [0.,0.,0.,0.,0.,0.] dortmund = [260.,23.,69.,240.,206.,270.] dublin = [118., 4., 12., 54., 19., 319.] edinburgh = [140., 36., 92., 231., 60., 270.] london = [90., 4., 24., 58., 18., 123.] marin_county_ca = [12., 10., 15., 17., 13., 74.] munich = [76., 18., 1., 10., 2., 152.] pilsen = [7., 3., 3.2, 5.8, 5., 9.] vienna = [200., 60., 8., 125., 12., 120.] yorkshire = [105., 17., 23., 66., 30., 153.] ########################################################### target = burton_on_trent #Salt contents (PPM / (grams per gallon)) caso4 =  [61.5, 0.0, 0.0, 147.4, 0.0, 0.0] mgso4 =  [0.0, 26.1, 0.0, 103.0, 0.0, 0.0] nacl =  [0.0, 0.0, 103.9, 0.0, 160.3, 0.0] nahco3 = [0.0, 0.0, 72.0, 0.0, 0.0, 189.0] cacl2 =  [72.0, 0.0, 0.0, 0.0, 127.4, 0.0] caco3 =  [105.8, 0.0, 0.0, 0.0, 0.0, 158.4] # The overall goal here is to find x ST: # Ax =~ b # x >= 0 a = transpose([caso4, mgso4, nacl, nahco3, cacl2, caco3]) b = array(target) - array(base_water) xlb = [0.] * 6 xub = [-1.0e30] * 6 c = [] con_type = [] bu = [] bl = [] residual = [] x = linLsqLinConstraints(a, b, c, bl, bu, con_type,  xlb, xub, residual=residual) ion_labels = ['', 'Ca', 'Mg', 'Na', 'SO4', 'Cl', 'HCO3'] salt_labels = ['', 'CaSO4', 'MgSO4', 'NaCl', 'NaHCO3', 'CaCl2', 'CaCO3'] writeMatrix("Salt amounts to add \n(Grams per Gallon)", x, colLabels=salt_labels) writeMatrix("Target Profile \n(PPM)", target, colLabels=ion_labels) writeMatrix("Base Water + Recomended Salt Additions \n(PPM)", dot(a,x) + array(base_water), colLabels=ion_labels) writeMatrix("Residuals \n(PPM)", residual, colLabels=ion_labels) print ("\nNorm of residual = %f" % (vectorNorm(residual)))```
Here's a run calculating additions from my water to Burton on Trent. Plugging these numbers back into ProMash I get these exact totals.
Code:

```ryan@ubuntu-desktop:~/Desktop\$ python water.py                               Salt amounts to add                             (Grams per Gallon)       CaSO4        MgSO4        NaCl      NaHCO3        CaCl2        CaCO3       2.888        1.817        0.106        0.000        0.083        0.489                                 Target Profile                                     (PPM)         Ca          Mg          Na          SO4          Cl        HCO3         268          62          30          638          36          141                     Base Water + Recomended Salt Additions                                     (PPM)         Ca          Mg          Na          SO4          Cl        HCO3       261.3        51.0        24.2        640.8        39.8        145.5                                   Residuals                                     (PPM)         Ca          Mg          Na          SO4          Cl        HCO3       -6.67      -10.98        -5.81        2.78        3.77        4.45 Norm of residual = 15.513117```
Hope somebody finds this useful! :mug:

 htc 09-07-2012 05:29 AM

This is the first calculator I've found that (supposedly) calculates the proper additions to reach a desired water profile, rather than calculating the profile based on my additions. The first problem is that the link above for the python interpreter doesn't work. The second problem is that I have no idea what "python" or "numpy" are. Help please.

 HopSong 09-11-2012 07:11 PM

Got an 500 Error.. Internal Server on the link

 hafmpty 09-16-2012 03:50 AM

I'd love to be able to use this. Unfortunately, like a previous poster, I don't know how exactly. I've used a python script a couple times for something I was doing about a year ago, but I had no idea what I was doing. Could you (would you?) put together a "How-To" of getting the proper software/program and actually running the script? That would make this uber-helpful. Thanks so much.

 htc 09-19-2012 09:33 PM

^^^^=awesome!

 All times are GMT. The time now is 08:35 AM.