-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reproducing the NEB Tm calculator behavior in pydna #237
Comments
@BjornFJohansson @hiyama341 , it would be great if you could provide:
|
Nearest Neighbor Method explained: https://www.youtube.com/watch?v=jy5h9NwBEgk |
Minimal example extracted from teemi. The results are identical to the web interface.
|
I had settings for Biopython's MeltingTemp to simulate Q5 and Phusion Tm calculations on the NEB website some time ago (at that time, calculations for Q5 and Phusion gave different results), but obviously they changed some settings in their calculator. |
Yes, I get wildly different results right now. I would like to mimic the behaviour of the NEB calculator, the source code is not easy to follow though. |
I had a look at the js code and it's compiled by babel, so I don't think it is possible to extract the source code to reverse-engineer without spending a lot of time. Some possible solutions to consider @BjornFJohansson @hiyama341:
They would both take some thinking, but they seem feasable, so it's a matter of how much is this slowing you down. |
@hiyama341 I went ahead and made a first version using the mentioned approximation (first with the default pydna, then with the one from neb, and it's faster): dev_bjorn...issue_237_optimisation The file example.py compares the two approaches for finding a primer and you can see that the approximation is faster and uses fewer requests. This is what it prints. Let me know what you think. Also, I could not use the teemi functions to make the request with "normal" headers. I was getting 403 response from the server. I had to mimmic a browser request to be able to use the API. Not sure if you encounter these problems. I could not even run their curl example. See the headers here.
|
@manulera and @BjornFJohansson great work! Yeah, two days ago I started getting the 403 response from the server. They must have changed something cause it was working just fine before. And thanks I'm gonna try to add the headers to teemi and see if it works. Regarding the workload, maybe we can discuss on the 5th pydna meeting whether it is worth to reverse-engineer the primer calc function. Personally, I think it would be useful to have something fast and stable when we are calculating/making hundreds of primers but let's discuss next week. |
I agree with @hiyama341 on this one. Localized Tm code would be very useful and I suspect would convince potential users. |
I also agree that ideally we would want the code in the library and not rely on an external API that may cut access like they just did. The issue is that it's not as simple as "translating the javascript code into python". The javascript code we can access from their website is bundled code. This is generated by javascript libraries like Babel, which basically make a single javascript file with all the code for the page, without dependencies on external files or libraries, and maximizing browser compatibility. This means that the source code that people in NEB wrote looks very different (and much more understandable) that what is in that file which is not meant to be read by humans, so reverse-engineering would take a lot of time and knowledge of javascript. |
Why don't you use Biopython's MeltingTemp and find the correct settings to simulate NEB's TM calculator? Isn't Biopython a library that is likely to be used together with PyDNA? |
Hi @MarkusPiotrowski NEB's calculator gives different values depending on the polymerase that will be used, and overall does a more complex calculation from what the others said. When I was doing PCR I was never too concerned with exact Tm calculations but it seems some people trust NEB's calculator over anything else and would exclude tools that use other Tm calculations. |
@manulera I'm the author of Biopython's MeltingTemp. There are several options that are usually applied for calculating Tm's with the nearest neighbor thermodynamic method:
I would wonder if NEB uses a "more sophisticated" method and if their results can't be simulated with Biopython's MeltingTemp. I guess it's a question of finding the right parameters, and there are numerous possibilities for them. And of course they may have different parameters for different enzymes. Their own help page gives some details (if they stick to them and is still up-to-date): https://tmcalculator.neb.com/#!/help |
@MarkusPiotrowski @manulera @hiyama341 Please have a look at this comparison Biopython vs NEB Seems like there is a ~7 degree difference for a large list of primers. I replicated the behaviour as best I could given the sometimes incomplete information given by NEB. |
In this repo they somehow run the NEB Tm Calculator from Python. |
@BjornFJohansson Thanks for the pointers tho these pages. For Taq polymerase I now managed to simulate NEB's Tm calculator with Biopython's MeltingTemp. In NEB's calculator, they obviously do not correct for Mg ions. So the Mg2+ concentrations and dNTPs concentrations are irrelevant for their calculation. Thus, we need to remove them from the call to Tm_NN (when Mg is 0 [default], dNTPs are not considered). Then it fits nicely: import Bio
from Bio.SeqUtils import MeltingTemp as mt
primers = (
'AGCGGATAACAATTTCACACAGGA',
'GTAAAACGACGGCCAGT',
'AGCGGATAAGGGCAATTTCAC',
'GTAAAACGACGGCCA',
)
NEBtms = (58, 54, 57, 50) # from NEB Tm calculator
for temp, primer in zip(NEBtms, primers):
tm = mt.Tm_NN(
primer,
nn_table=mt.DNA_NN3,
Na=0, # mM
K=50, # mM
Tris=10, # mM
# Mg=1.5,
dnac1=200, # nM
dnac2=0, # nM
dNTPs=0.8, # mM
saltcorr=6,
)
print(
f'Primer: {primer}, Tm: NEB: {temp}, Biopython: {round(tm)}'
f' delta: {round(tm - temp, 2)}'
) Result:
The deltas are of course because NEB's calculator already gives rounded values. As I said, one need to find the 'correct' settings. I'll go on to check for Phusion and Q5. |
I can't find the composition of Phusions HF buffer, however, looking on the assay conditions and some assumption, I would suggest the following settings: # For Phusion, use this settings
tm = mt.Tm_NN(
primer,
nn_table=mt.DNA_NN3,
Na=0, # mM
K=50, # mM
Tris=25, # mM
Mg=1.5,
dnac1=200, # nM
dnac2=0, # nM
dNTPs=0.8, # mM
saltcorr=1,
) These give values that derive from the rounded NEB data by about 0.2 °C. As written in their Help page, for Phusion they use a different salt correction method and, obviously, there they include Mg and dNTPs concentrations in their calculation. |
These settings fit for Q5: tm = mt.Tm_NN(
primer,
nn_table=mt.DNA_NN3,
Na=0, # mM
K=50, # mM
Tris=10, # mM
Mg=1.5,
dnac1=200, # nM
dnac2=0, # nM
dNTPs=0.8, # mM
saltcorr=6,
) |
Thank you all for your contributions. Ill look into it asap. |
Let me add a little bit to the discussion: While I could provide settings to simulate quite well the Tm values of NEB's Tm calculator (see above, fine for Taq and Q5, some small deviation with Phusion sometimes), I wonder if this is a goal you want to go for. When I rewrote Biopython's MeltingTemp code some years ago, I also compared the results to other calculators (mostly to check if I do the math correctly), but I focused on established academic tools, at that time this was MELTING and Primer3 or Primer3Plus. Online calculators from companies were hard to compare with because except some general statements ("using nearest neighbor.... according to...."), detailed information about the exact usage of the algorithm (which thermodynamic tables do they use, how do they calculate the initialization, which salt correction algorithm do they use) were sparse. BTW, this source https://github.com/kalekundert/ligrna (mentioned by @BjornFJohansson ) seems to contain the pre-2016 code? (it mentions Breslauer, that is not mentioned in the recent pages). Also, I browsed through the Javascript and while I can find the calculations and published constants, I don't find the actual buffer salt concentrations. |
Hi @MarkusPiotrowski thanks for testing, it is very appreciated. Elaborating a bit more on why we were trying to match NEB's results: As far as I understand it, the reason for wanting to reproduce the NEB's calculations is not so much to achieve the most "thermodynamically correct" results. Instead, from what @hiyama341 was saying, some researchers trust NEB over other calculators because they have been using it for a long time, so it's more an issue of "habit" rather than accuracy. Because of this, they would not trust/use a tool that uses other calculators and this could be an issue for some of the tools built on top of pydna that we are working on, namely teemi and ShareYourCloning. |
@manulera Thank you for the explanation. You know your users better than I, so you can probably be convinced that they prefer NEB's calculator. Some years ago we had a Promega (now Thermo) freezer in the neighboring department, so we got our enzymes usually from them, and at that time I would have preferred to use their calculator. What I would sum up from my testing and also by taking a look at the Javascript code from NEB's calculator: Above you have the settings that work well. Maybe some hints:
So I would suggest, to use a small wrapper around Biopython's Meltingtemp and supply your users with different predefined sets of settings, e.g., NEB_Taq, NEB_Phusion, NEB_Q5 etc. |
@BjornFJohansson There is an error in https://github.com/BjornFJohansson/tm/blob/master/NEB%20Phusion/NEB%20Phusion.ipynb . You gave the dNTPs in µmolar instead of millimolar. Thus free Mg becomes 0 and ist not longer taken into consideration for calculations. |
Thanks, Ill look into it. I am compiling results for the NEB Phusion which worked perfectly. |
By the way @MarkusPiotrowski, we will meet this Thursday 25th of July at 14:00 UK time to discuss some issues of pydna, including this one. If you want to join the discussion, your insight would be appreciated! Below a Teams link for that: |
Dear all, Some updated comparisons between neb calculator and the different combinations of biopython options. Specifically, I made a sum of least squares minimization as suggested using Scipy.minimize for the Q5 polymerase. I get close, but not as close as with some of the others (thanks, @MarkusPiotrowski for the help). There seems to be some creative mixtures of thermodynamic data in the neb tm calculator source code. The ones I could find are extracted to Python in the NEB_website folder. Salt correction seems to be the same as biopython 7 (Owczarzy 2008) and not Owczarzy 2004 as documented. |
Hello, I was working on #250 and I noticed that sometimes longer primers give lower Tms, is this normal? from pydna.tm import tm_default
print(tm_default("agatcgactatctacttatgcatctta")) # 58.90561619071127
print(tm_default("agatcgactatctacttatgcatctt")) # 59.1327553388262 |
Hi all, |
* added new translation function * new orfs method for Seq based on three_frame_orfs function * new orfs_to_features method for Dseqrecord * new extract_from_text functions that also returns the intervening text between sequences * bugfix orfs for Seq and Dsecrecord * added crispr tests * added pairwise for older Python versions * older type hint * Deploying to gh-pages from @ da3e7e9 🚀 * Deploying to gh-pages from @ 5be4f9d 🚀 * Deploying to gh-pages from @ b37a17c 🚀 * Deploying to gh-pages from @ 11aae3c 🚀 * Deploying to gh-pages from @ 0f95223 🚀 * try to build docs locally on gh-pages * try to build gh pages * try to build gh pages * fix * added sphinx ext * Deploying to gh-pages from @ bc08a36 🚀 * try fix docs * build docs * clean * redirect docs badge to action * redirect docs badge to action * fix readme links * fix readme * fix * try to fix test error * fix bug that recognized parts of re enzyme names as other enzymes * added comment with number of enzymes * changed number of expected enzymes to the correct number 621 * more informative error msg * closes #216 (2) * closes #196 * vscode and poetry settings added * fix test * add locations_overlap to utils * Issue 238 (#239) * closes #238 * fix notebook * closes #240 * atomically write default config * optimisation for #237 * fix python 3.8 typing * include neb calculator and its tests * fix design and add tests * example commit for #176 * Documentation notebooks 2 (#272) * Documentation notebooks (#271) * added documentation for dseq.py * fixed docs for Dseq.py * fixed docs for Dseq.py * add hook * fix exclusions and run hook * strip outputs of Dseq.ipynb * update Dseq notebook * placed notebooks in docs * added looped and shifted methods in Dseq docs * added docs for importing files using pydna * added some Dseqrecord docs * added docs+examples for Dseq_Features * added origin spanning feats and removing feats for Dseq_Features * some comments and todos * added restriction page * updated Importing_Seq page * updated Dseq_Feature Page w/examples * added restrict+ligate notebook * added some PCR notes * added examples, prints * added tm and design * fixed tm_default docs * added gibson assembly * some comments on current progress * gibson * fixed comments, added gibson example and CRISPR * added Restriction example * added Gibson example * closes #256 * run pre-commit * alternative example for gibson * gibson updated example * modified crispr * modified crispr * feedback changes for #260 * best practices for qualifiers --------- Co-authored-by: Pei-Lun Xie <[email protected]> Co-authored-by: Pei-Lun Xie <[email protected]> * remove unnecessary file * remove dir exclusions * exclude test notebooks --------- Co-authored-by: Pei-Lun Xie <[email protected]> Co-authored-by: Pei-Lun Xie <[email protected]> * update contribution guidelines (#274) * update CI action to enforce hooks (#277) * update CI action to enforce hooks * update action * update: Added google badge to all notebooks issue #266 (#275) * fourth trt * final file added * update: added installation of pydna * added seguid stamp to Genbank sequence files * fix test sequence file * dependabot monthly * New CRISPR example notebook (#260) (#284) * fourth trt * final file added * update: added installation of pydna * update: added CRIPSR examples in notebooks issue #259 * update: added google badge issue #266 * Polished Example CRISPR notebook --------- Co-authored-by: Manuel Lera-Ramirez <[email protected]> * Updated notebooks (#295) * updated example_restriction (#285) Co-authored-by: Pei-Lun Xie <[email protected]> * small fixes (#294) * allow run all on notebooks that have pip install for google colab --------- Co-authored-by: Pei-Lun Xie <[email protected]> * progress towards #261 * WIP * remove code image from README for #261 * more README updates + make requirements.txt * add requirements file * fix configuration * typing for PrettyTable * typing for codon dicts * typing for Seq * typing for FakeSeq * typing for Genbank * typing for sequence_picker module * typing for common_sub_strings module * typing for Assembly.__init__ and Assembly.__repr__ * Bump pillow from 10.3.0 to 10.4.0 Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.3.0 to 10.4.0. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](python-pillow/Pillow@10.3.0...10.4.0) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> * Bump autopep8 from 2.1.0 to 2.3.1 Bumps [autopep8](https://github.com/hhatto/autopep8) from 2.1.0 to 2.3.1. - [Release notes](https://github.com/hhatto/autopep8/releases) - [Commits](hhatto/autopep8@v2.1.0...v2.3.1) --- updated-dependencies: - dependency-name: autopep8 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> * Bump black from 24.4.2 to 24.8.0 Bumps [black](https://github.com/psf/black) from 24.4.2 to 24.8.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](psf/black@24.4.2...24.8.0) --- updated-dependencies: - dependency-name: black dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> * Bump sphinx-rtd-theme from 2.0.0 to 3.0.0 Bumps [sphinx-rtd-theme](https://github.com/readthedocs/sphinx_rtd_theme) from 2.0.0 to 3.0.0. - [Changelog](https://github.com/readthedocs/sphinx_rtd_theme/blob/master/docs/changelog.rst) - [Commits](readthedocs/sphinx_rtd_theme@2.0.0...3.0.0) --- updated-dependencies: - dependency-name: sphinx-rtd-theme dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> * Bump prettytable from 3.10.0 to 3.11.0 Bumps [prettytable](https://github.com/jazzband/prettytable) from 3.10.0 to 3.11.0. - [Release notes](https://github.com/jazzband/prettytable/releases) - [Changelog](https://github.com/jazzband/prettytable/blob/main/CHANGELOG.md) - [Commits](prettytable/prettytable@3.10.0...3.11.0) --- updated-dependencies: - dependency-name: prettytable dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> * closes #261 (#297) * tests for #281 #279, add type to pcr (#298) * update codecov action for #242 * Issue 270 (#301) * closes #270 * closes #269 by adding an example notebook + extra tests * closes #288, includes the graphics in docs notebook * added example.ipynb to tests folder * removed example.ipynb * deal with Tm = 0 * fix notebook export related to #279 * New docs (#304) * new docs * update action * update action * fix typo in action * update README + closes #305 * improve docs * document how docs work * fix autogen_docs.sh * fix crispr docstring * Fix link in README (#310) * Fix action (#311) * fix action * fix action --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: BjornFJohansson <[email protected]> Co-authored-by: BjornFJohansson <[email protected]> Co-authored-by: Pei-Lun Xie <[email protected]> Co-authored-by: Jerry Xu <[email protected]> Co-authored-by: Pei-Lun Xie <[email protected]> Co-authored-by: Lucas Levassor <[email protected]> Co-authored-by: Kawin <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel García Ruano <[email protected]>
As per the 4th Pydna meeting, it was generally agreed that Pydna and tools that depend on it would benefit from being able to simulate modern commercial Tm calculators offline.
I have compiled data around this here
The NEB.ipynb notebook contain attempts to replicate the NEB Tm calculator simply by selecting parameters in the biopython Tm module. This was successful for the standard Taq polymerase with the buffer composition stated by NEB.
I was not able to guess the result for the Q5 polymerase. A contributing factor is the secrecy of the buffer composition.
The NEB logics seems contained in the file
NEB/NEB_website/NEB Tm Calculator_files/main-3d92a74abb.js
I formatted the code with an online js formatter in the file
main-3d92a74abb_formatted.js
.The variables below seem important, but I was not able to follow the logics.
r.TmCalc.prototype.nnBr
r.TmCalc.prototype.nnSa
r.TmCalc.prototype.nnde
r.TmCalc.prototype.nndhds
r.TmCalc.prototype.nnloop
r.TmCalc.prototype.nnbulge
r.TmCalc.prototype.nntmm
r.TmCalc.prototype.R=1.987,
r.TmCalc.prototype.dSBr
r.TmCalc.prototype.dSSa
r.TmCalc.prototype.dHBr
r.TmCalc.prototype.dHSa
r.TmCalc.prototype.init
r.TmCalc.prototype.saltCorrect
r.TmCalc.prototype.setCt
r.TmCalc.prototype.setMonosalt
r.TmCalc.prototype.setDisalt
r.TmCalc.prototype.setDMSO
r.TmCalc.prototype.buildPairMap
Some other people have worked on similar issues here and here
I think this is worth spending some time, since interestingly, the Thermofisher Tm calculator here gives similar, but not identical results and claims to use similar but not identical thermodynamic data.
The text was updated successfully, but these errors were encountered: