diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..843261c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+__pycache__
+.pyc
+venv
+.idea
diff --git a/isotables/isotopapp/models.py b/isotables/isotopapp/models.py
index 4624681..20a97ab 100644
--- a/isotables/isotopapp/models.py
+++ b/isotables/isotopapp/models.py
@@ -2,12 +2,12 @@ from django.db import models
# Create your models here.
class Isotope(models.Model):
- n_protons = models.IntegerField()
- n_nucleons = models.IntegerField()
- stable = models.BooleanField()
- symbol = models.CharField(max_length=2)
- name = models.CharField(max_length=255)
- spin_quantum_number = models.FloatField()
- gamma = models.FloatField() # MHz/T
- natural_abundance = models.FloatField()
- quadrupole_moment = models.FloatField(null=True)
+ n_protons = models.IntegerField(help_text="Protons in isotope")
+ n_nucleons = models.IntegerField(help_text="Nucleons in isotope")
+ stable = models.BooleanField(help_text="Is isotope stable?")
+ symbol = models.CharField(max_length=2, help_text="Symbol of isotope")
+ name = models.CharField(max_length=255, help_text="Name of isotope")
+ spin_quantum_number = models.FloatField(help_text="Spin quantum number")
+ gamma = models.FloatField(help_text="Gyromagnetic ratio in MHz/T") # MHz/T
+ natural_abundance = models.FloatField(help_text="Natural abundance")
+ quadrupole_moment = models.FloatField(null=True, help_text="Quadrupole moment")
diff --git a/isotables/isotopapp/templates/home.html b/isotables/isotopapp/templates/home.html
index 51a6b2f..5dde4cf 100644
--- a/isotables/isotopapp/templates/home.html
+++ b/isotables/isotopapp/templates/home.html
@@ -1,18 +1,29 @@
-
Basic Calculator
+
NMR Frequency Calculator
diff --git a/isotables/isotopapp/templates/result.html b/isotables/isotopapp/templates/result.html
index df708ca..f599d63 100644
--- a/isotables/isotopapp/templates/result.html
+++ b/isotables/isotopapp/templates/result.html
@@ -1,15 +1,88 @@
+
- The result is:
-
{{ans}}
-
+
+
+ Table downloaded from easyspin.org
+ (2023-07-29 markusro)
+
+
+
+ N |
+ Symbol |
+ Name |
+ f0 in MHz |
+ Spin |
+ Nat. ab. in % |
+ γ in MHz/T |
+
+
+
+
+ {% for attr in ans %}
+
+ {% for i in attr %}
+ {{ i }} |
+ {% endfor %}
+
+ {% endfor %}
+
+
+
Go Back
-
-
+ }
+
+ table {
+ border-collapse: collapse;
+ border: 2px solid rgb(140 140 140);
+ font-family: sans-serif;
+ font-size: 1.2rem;
+ letter-spacing: 1px;
+ }
+
+ caption {
+ caption-side: bottom;
+ padding: 8px;
+ font-weight: normal;
+ font-size: 0.8rem;
+ text-align: center;
+ }
+
+ thead,
+ tfoot {
+ background-color: rgb(228 240 245);
+ }
+
+ th,
+ td {
+ border: 1px solid rgb(160 160 160);
+ padding: 10px 4px;
+ text-align: center;
+ }
+
+ td:last-of-type {
+ text-align: center;
+ }
+
+ tbody > tr:nth-of-type(even) {
+ background-color: rgb(237 238 242);
+ }
+
+ tfoot th {
+ text-align: right;
+ }
+
+ tfoot td {
+ font-weight: bold;
+ }
+
+
diff --git a/isotables/isotopapp/views.py b/isotables/isotopapp/views.py
index 7bd9ab7..6aa6f35 100644
--- a/isotables/isotopapp/views.py
+++ b/isotables/isotopapp/views.py
@@ -1,25 +1,76 @@
-from django.shortcuts import render
+from math import pi
+from django.shortcuts import render
+from django.utils.safestring import mark_safe
+import re
+
+
+from isotopapp.models import Isotope
# Create your views here.
def home(request):
return render(request, 'home.html')
-def result(request):
- num1 = int(request.GET.get('number1'))
- num2 = int(request.GET.get('number2'))
-
-
- if request.GET.get('add') == "":
- ans = num1 + num2
-
- elif request.GET.get('subtract') == "":
- ans = num1 - num2
-
- elif request.GET.get('multiply') == "":
- ans = num1 * num2
+def extract_isotope_parts(isotope_str):
+ """Extracts the number and element from an isotope string (e.g., '23Na')."""
+ print(isotope_str)
+ match = re.match(r"(\d+)([A-Za-z]+)", isotope_str)
+ if not match:
+ raise ValueError("Invalid isotope format")
+ return int(match.group(1)), match.group(2)
+def isotope_info(isotope, field):
+ f_larmor = field*isotope.gamma
+ if isotope.spin_quantum_number.as_integer_ratio()[1]==1:
+ spin = int(isotope.spin_quantum_number)
else:
- ans = num1 / num2
+ spin = mark_safe(f"{isotope.spin_quantum_number.as_integer_ratio()[0]}⁄{isotope.spin_quantum_number.as_integer_ratio()[1]}")
+ return [isotope.n_nucleons,
+ mark_safe(f"{isotope.n_nucleons}{isotope.symbol}"),
+ isotope.name.capitalize(),
+ f"{f_larmor:.3f}",
+ spin,
+ f"{isotope.natural_abundance:.1f}",
+ f"{isotope.gamma*1e6:.5e}"]
+
+def result(request):
+ n1, element1 = extract_isotope_parts(request.GET.get('isotope1'))
+ isotope1 = Isotope.objects.filter(symbol=element1, n_nucleons=n1).get()
+
+
+ freq = float(request.GET.get('freq'))
+
+ field_T = freq / isotope1.gamma
+
+ close_isotopes = []
+
+ if request.GET.get('search') == "":
+ freq_range = float(request.GET.get('freq_range'))
+ Isotope.objects.filter()
+ # calculate the frequency for all isotopes and compile a list of close by isotopes
+ for isotope in Isotope.objects.all():
+ if isotope.gamma == 0: continue
+ if not isotope.stable: continue
+ f_Larmor = field_T*isotope.gamma
+ if abs(f_Larmor - freq) <= freq_range:
+ close_isotopes.append(isotope_info(isotope, field_T))
+ ans = sorted(close_isotopes, key=lambda x: x[3])
+
+ elif request.GET.get('calculate') == "":
+ sample_diameter = 5e-3
+ gradient = float(request.GET.get('gradient'))
+ freq_range = sample_diameter/2 * gradient * isotope1.gamma
+ for isotope in Isotope.objects.all():
+ if isotope.gamma == 0: continue
+ if not isotope.stable: continue
+ f_Larmor = field_T*isotope.gamma
+ if abs(f_Larmor - freq) <= freq_range:
+ close_isotopes.append(isotope_info(isotope, field_T))
+ ans = sorted(close_isotopes, key=lambda x: x[3])
+ elif request.GET.get('transform') == "":
+ n2, element2 = extract_isotope_parts(request.GET.get('isotope2'))
+ isotope2 = Isotope.objects.filter(symbol=element2, n_nucleons=n2).get()
+ #isotope_info(isotope2, field_T)
+ ans = [isotope_info(isotope2, field_T)]
return render(request, 'result.html', {'ans': ans})