# Computing titration curves

**URL:** <https://discourse.julialang.org/t/computing-titration-curves/81415>\
**Category:** Chemistry\
**Created:** [May 21, 2022, 1:15pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415 "2022-05-21T13:15:32Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [May 21, 2022, 1:15pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/1 "2022-05-21T13:15:32Z")

</div>

Is there a Julia package for computing titration curves?

I’ll like to simulate a titration experiment where a weak acid with several pKa values is titrated by a strong base. Something similar to figure 17.3.5 here: [17.3: Acid-Base Titrations - Chemistry LibreTexts](https://chem.libretexts.org/Courses/University_of_Missouri/MU%3A__1330H_(Keller)/17%3A_Additional_Aspects_of_Aqueous_Equilibria/17.3%3A_Acid-Base_Titrations)

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [May 21, 2022, 2:17pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/2 "2022-05-21T14:17:06Z")

</div>

I did seemingly find exactly what you want just not in Julia, rather in R language:

> **[GitHub - naikymen/titration: Numerical and analytical routines for simulation...](https://github.com/naikymen/titration)**
>
> Numerical and analytical routines for simulation of acid-base titration curves. - GitHub - naikymen/titration: Numerical and analytical routines for simulation of acid-base titration curves.

Note, you can use it as-is with RCall.jl, if you just need something to practically work (even without translating the code).

It’s not a whole lot of code if you want to translate (all or maybe you only need) part of it to Julia. Note, the GPL license, so it’s free to use or translate, keeping the same copyleft license. Your whole program will fall under GPL 3.0, not a problem for using, possibly for distributing. GPL 3.0 is not compatible with all licences, but that’s only a problem for distributing code, you can always legally use privately, and that also means legally within your company.

I did look up code in other languages, C, C++, MATLAB, Rust and Python. The good thing about Python code would be you can also call it, still needs its runtime, but PythonCall.jl takes care of installation of dependencies (and Python itself). I’ve seen a wrapper made for R code (Alpaca.jl), which used RCall.jl, but as with PyCall.jl you need to take care of installation of dependencies, and R.

I did also find two packages in Python, both missing a ~~license~~ file [EDIT: at least one of, the package chosen, is BSD-licenced] (both have all code in one file):

> **[pHcalc](https://pypi.org/project/pHcalc/)**
>
> Systematic pH calculation package for Python

> **[GitHub - Sthakur27/Acid-Base-Titration: Titration curve for an acid base...](https://github.com/Sthakur27/Acid-Base-Titration)**
>
> Titration curve for an acid base titration. Contribute to Sthakur27/Acid-Base-Titration development by creating an account on GitHub.

Maybe useful to you: [Titration | kinsaurralde](https://kinsaurralde.com/pages/titration.html)

> The titration calculator website […] The titration calculator is written in c++ and runs on aws lambda. The code for the calculator is located at:  
> [GitHub - kinsaurralde/titration](https://github.com/kinsaurralde/titration)

Again a license file is missing.

I did not see such code for Julia, you could look at this (likely incomplete) list:

> <https://github.com/svaksha/Julia.jl/blob/master/Chemistry.md>

> **[pvr570.pdf](https://modeleau.fsg.ulaval.ca/fileadmin/modeleau/documents/Publications/pvr570.pdf)**
>
> 313.08 KB

There’s no R-to-Julia translator available, that I know of (nor even to C++, but info on how is still helpful):  
[https://adv-r.hadley.nz/rcpp.html](https://adv-r.hadley.nz/rcpp.html)

There’s a (partial) MATLAB-to-Julia translator available. I’ve used it, and those languages are most closely related, so might be best to find MATLAB code for this. There’s also a Python-to-Julia (py2many) but I haven’t tried it.

[https://adv-r.hadley.nz/translation.html](https://adv-r.hadley.nz/translation.html)

See also: [https://cran.r-project.org/web/packages/titrationCurves/vignettes/titrationCurves.pdf](https://cran.r-project.org/web/packages/titrationCurves/vignettes/titrationCurves.pdf)

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [May 21, 2022, 3:13pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/3 "2022-05-21T15:13:25Z")

</div>

Thank you very much @Palli !  
That is a lot of material you found for me 🙂

The pHcalc Python package looks quite general, yet simple, and it generates nice curves:

![billede](https://global.discourse-cdn.com/julialang/original/3X/9/f/9f1e65eaaab16cabd02b0270fe67b1b65e0c88eb.png)

If nobody comes along with a better solution, I think I’ll try to port that to Julia 😉

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [May 21, 2022, 3:38pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/4 "2022-05-21T15:38:27Z")

</div>

Note, since there’s no license file there, you’re not on solid legal grounds. Since it’s on github you would think it’s meant to be used… I would file an issue there, ask for MIT licence file to me added first.

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [May 21, 2022, 3:49pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/5 "2022-05-21T15:49:25Z")

</div>

> since there’s no license file there, you’re not on solid legal grounds.

I would expect that porting a computational method to a different programming language would be enough to give “fresh” copyright. But perhaps it depends on how closely I follow the original?

Anyway, it says it’s BSD licensed in the setup.py file. So I guess that is ok?

> <https://github.com/rnelsonchem/pHcalc/blob/0deb203b08881266fcf9326cb656d8e36f61410e/setup.py#L17>

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [May 21, 2022, 3:57pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/6 "2022-05-21T15:57:22Z")

</div>

> [@tp2750](#):
>
> I would expect that porting a computational method to a different programming language would be enough to give “fresh” copyright.

You would be wrong, still “derived work”. That’s also why some people avoid GPL for porting, even avoid looking at the code, or get others to look at the code, for “cleanroom implementation”.

But `license = "BSD"` should be good enough, it at least conveys intent (there’s no legal requirement that I know of for a main top-level license file, just makes more helpful, what I’m used to so overlooked what you found). BSD is free software, but not it comes in several forms, unclear (to me) which meant, not all GPL compatible:

[https://www.gnu.org/licenses/license-list.html#OriginalBSD](https://www.gnu.org/licenses/license-list.html#OriginalBSD)

So maybe you still want to get it clarified.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [May 21, 2022, 4:04pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/7 "2022-05-21T16:04:30Z")

</div>

> [@tp2750](#):
>
> I think I’ll try to port that to Julia

Great, just know you can also use PythonCall.jl (or PyCall.jl, by now I recommend the former for the features, even with the latter having faster startup, hoping that PythonCall will get optimized to start as fast), for using or helping while porting, to compare and ensure no bugs in conversion.

Is the code slow, is that an argument for porting? In general I’m a great believer in using languages together, not needing to port.

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [May 21, 2022, 4:06pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/8 "2022-05-21T16:06:09Z")

</div>

Thank you for the clarification @Palli . I learn a lot of new things today 🙂

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [May 21, 2022, 4:09pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/9 "2022-05-21T16:09:42Z")

</div>

> Is the code slow, is that an argument for porting?

It does not feel very slow, and you have a point about re-using code.

I’m not super happy about the interface, but it might be faster to wrap that rather than porting the code.  
On the other hand, I’ll probably learn from it 😄

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [May 21, 2022, 4:11pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/10 "2022-05-21T16:11:21Z")

</div>

“BSD” without context doesn’t tell me if it’s e.g. the more problematic “4-clause BSD license” or some of the other variant, down to 0-clause, but since has context, is there in metadata, maybe there’s an official meant for definition in that context. I just don’t know, but would like to know. I think people are (often) more precise in Julia-land.

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [May 21, 2022, 4:15pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/11 "2022-05-21T16:15:41Z")

</div>

> “BSD” without context doesn’t tell me if it’s e.g. the more problematic “4-clause BSD license”

I missed it at first, but a bit further down it says:

```julia
'License :: OSI Approved :: BSD License',

```

However, OSI has 5 BSD licenses 😄[Licenses – Open Source Initiative](https://opensource.org/licenses/alphabetical), so you are right, not very precise.

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [June 6, 2022, 7:52pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/12 "2022-06-06T19:52:31Z")

</div>

It took a bit of time, but I finally got around to implementing a Julia version of the [pHcalc python library](https://github.com/rnelsonchem/pHcalc). It can be found here: [GitHub - tp2750/pHcalc.jl](https://github.com/tp2750/pHcalc.jl)  
Comments are very welcome.

---

<div class="post-metadata">

**Author:** ![tp2750](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tp2750/32/207806_2.png) [@tp2750](https://discourse.julialang.org/u/tp2750)\
**Post date:** [December 11, 2022, 1:35pm UTC](https://discourse.julialang.org/t/computing-titration-curves/81415/13 "2022-12-11T13:35:17Z")

</div>

Turns out there is now also a version in the registry: [GitHub - egonik-unlp/PHcalc.jl: Implementation of the pHcalc library by Ryan Nelson at https://github.com/rnelsonchem/pHcalc](https://github.com/egonik-unlp/PHcalc.jl)
