Skip to content

Commit

Permalink
Stoichiometry Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
reynavrb committed Dec 12, 2023
1 parent e0408b7 commit 12f2577
Show file tree
Hide file tree
Showing 8 changed files with 376 additions and 37 deletions.
20 changes: 20 additions & 0 deletions materials/elements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# elements.py
import json

element_dict = {
"H": 1, "He": 2, "Li": 3, "Be": 4, "B": 5, "C": 6, "N": 7, "O": 8, "F": 9, "Ne": 10,
"Na": 11, "Mg": 12, "Al": 13, "Si": 14, "P": 15, "S": 16, "Cl": 17, "Ar": 18, "K": 19, "Ca": 20,
"Sc": 21, "Ti": 22, "V": 23, "Cr": 24, "Mn": 25, "Fe": 26, "Ni": 27, "Co": 28, "Cu": 29, "Zn": 30,
"Ga": 31, "Ge": 32, "As": 33, "Se": 34, "Br": 35, "Kr": 36, "Rb": 37, "Sr": 38, "Y": 39, "Zr": 40,
"Nb": 41, "Mo": 42, "Tc": 43, "Ru": 44, "Rh": 45, "Pd": 46, "Ag": 47, "Cd": 48, "In": 49, "Sn": 50,
"Sb": 51, "Te": 52, "I": 53, "Xe": 54, "Cs": 55, "Ba": 56, "La": 57, "Ce": 58, "Pr": 59, "Nd": 60,
"Pm": 61, "Sm": 62, "Eu": 63, "Gd": 64, "Tb": 65, "Dy": 66, "Ho": 67, "Er": 68, "Tm": 69, "Yb": 70,
"Lu": 71, "Hf": 72, "Ta": 73, "W": 74, "Re": 75, "Os": 76, "Ir": 77, "Pt": 78, "Au": 79, "Hg": 80,
"Tl": 81, "Pb": 82, "Bi": 83, "Po": 84, "At": 85, "Rn": 86, "Fr": 87, "Ra": 88, "Ac": 89, "Th": 90,
"Pa": 91, "U": 92, "Np": 93, "Pu": 94, "Am": 95, "Cm": 96, "Bk": 97, "Cf": 98, "Es": 99, "Fm": 100,
"Md": 101, "No": 102, "Lr": 103,
"Rf": 104, "Db": 105, "Sg": 106, "Bh": 107, "Hs": 108, "Mt": 109, "Ds": 110, "Rg": 111, "Cn": 112, "Nh": 113,
"Fl": 114, "Mc": 115, "Lv": 116, "Ts": 117, "Og": 118
}

elements_json = json.dumps(element_dict)
11 changes: 11 additions & 0 deletions materials/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@ class AddSystemForm(forms.Form):
widget=forms.TextInput(attrs={'class': 'form-control'}),
max_length=100,
help_text='Enter n value for the dimensionality of this system if it applies')

from .models import System_Stoichiometry, Stoichiometry_Elements
class SystemStoichiometryForm(forms.ModelForm):
class Meta:
model = System_Stoichiometry
fields = ['system', 'stored_formula']

class StoichiometryElementsForm(forms.ModelForm):
class Meta:
model = Stoichiometry_Elements
fields = ['system_stoichiometry', 'element', 'string_value', 'float_value']

class AddPropertyForm(forms.Form):
name = forms.CharField(
Expand Down
31 changes: 27 additions & 4 deletions materials/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,35 @@ def __str__(self):

def listAlternateNames(self):
return self.group.replace(',', ' ').split()

#stoichiometry tables
class System_Stoichiometry(models.Model):
system = models.ForeignKey(System, on_delete=models.CASCADE)

@property
def formula(self):
return self.system.formula

stored_formula = models.CharField(max_length=200, blank=True, null=True)
#system_id = models.AutoField(primary_key=True)
def __str__(self):
return self.system.compound_name


class stoichiometry(models.Model):
compound_name = models.CharField(max_length=1000)
class Meta:
verbose_name = "System Stoichiometry"
verbose_name_plural = "System Stoichiometries"


class stoichiometry_values(models.Model):
system_id = models.CharField(max_length=1000)
class Stoichiometry_Elements(models.Model):

system_stoichiometry = models.ForeignKey(System_Stoichiometry, blank=True, null=True, on_delete=models.PROTECT)#, related_name='system_id', default=0)
element = models.CharField(max_length=1000)
string_value = models.CharField(max_length=1000, default = '0')
float_value = models.FloatField(default=0.0)

def __str__(self):
return self.system_stoichiometry

class Dataset(Base):
"""Class for mainly tables and figures.
Expand Down
225 changes: 199 additions & 26 deletions materials/templates/materials/add_data.html
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ <h4>Add Data</h4>
</div>
<div class="form-group col-md-6">
{% input_field system_form.formula %}
<div class="input-group-append">
<button class="btn btn-info" type="button" onclick="extractStoichiometry()">Extract Stoichiometry</button>
{{"Stoichiometry extraction is case sensitive. For example, CsCl will read as Cs:1, Cl:1 as it needs to be distinguishable from CSCl, which will extract as C:1, S:1, Cl:1"|tooltip}}
</div>
<div id="stoichiometry-display"></div>
</div>
<div class="form-group col-md-6">
<label for="stoichiometry">Stoichiometry</label>
<input type="text" class="form-control" id="stoichiometry" name="stoichiometry">
</div>
<div class="form-group col-md-6">
{% input_field system_form.organic %}
Expand Down Expand Up @@ -124,6 +133,37 @@ <h4>Add Data</h4>
</div>
</div>

<!--Confirm Stoichiometry -->
<div class="modal fade" id="stoichiometryModal" tabindex="-1" role="dialog" aria-labelledby="stoichiometryModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="stoichiometryModalLabel">Is this the correct stoichiometry?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p id="stoichiometryOutput"></p>
<div id="newStoichiometrySection" style="display: none;">
<label for="newStoichiometryInput">Enter new stoichiometry in the correct format (ex. C3H6O should be entered as C:3, H:6, O:1)</label>
<input type="text" id="newStoichiometryInput" style="display: none;" placeholder="Enter stoichiometry here">
<button type="button" class="btn btn-primary" onclick="handleNewStoichiometry()">Enter</button>
</div>
<div id="stoichiometryWarning" style="display: none; color: red;">
Warning: Stoichiometry should not contain the letter 'V'.
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclick="handleStoichiometryConfirmation('Yes')">Yes</button>
<button type="button" class="btn btn-secondary" onclick="handleStoichiometryConfirmation('No')">No</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>


<!-- ADD NEW PROPERTY -->
<div id="new-property-card" class="card mt-3 new-entry-card new-entry-card2" hidden="true">
<div class="card-header">
Expand Down Expand Up @@ -244,8 +284,50 @@ <h4>Add Data</h4>
</div>
<div class="form-check form-check-inline">
{% input_field main_form.two_axes %}
</div>
</div>
</div>

<br>
<!-- DATA -->
<div class="card card-item">
<div class="card-header">
Data
</div>
<div class="card-body card-add-data">
<div class="form-inline">
<div class="form-group">
{{ main_form.number_of_subsets.label_tag }}
<span class="ml-2">{{ main_form.number_of_subsets.help_text|tooltip }}</span>
{{ main_form.number_of_subsets }}
</div>
<input type="file" id="import-all-data" class="inputfile">
<label for="import-all-data"><i class="fa fa-upload" aria-hidden="true"></i>
Import all from file...</label>
<i class="fa fa-question-circle tooltip-container ml-2">
<span class="tooltiptext">Select to import all data (all subsets) from a single file. Use the ampersand ("&") as a delimiter between different data subsets.</span>
</i>
</div>
<div id="data-subset"></div>
</div>
</div>

<br>

<!-- Origin of Data -->
<div class="card card-item">
<div class="card-header">
Origin of Data
</div>
<div class="card-body card-add-data">
<div class="form-row">
<div class="form-group col-md-6">
<div class="input-group">
<div class="mt-2 mr-2">
</div>
</div>
</div>
</div>
<hr>
<div class="form-row">
<div class="col-md-6">
{% input_field main_form.origin_of_data %}
Expand Down Expand Up @@ -365,31 +447,6 @@ <h4>Add Data</h4>

<br>

<!-- DATA -->
<div class="card card-item">
<div class="card-header">
Data
</div>
<div class="card-body card-add-data">
<div class="form-inline">
<div class="form-group">
{{ main_form.number_of_subsets.label_tag }}
<span class="ml-2">{{ main_form.number_of_subsets.help_text|tooltip }}</span>
{{ main_form.number_of_subsets }}
</div>
<input type="file" id="import-all-data" class="inputfile">
<label for="import-all-data"><i class="fa fa-upload" aria-hidden="true"></i>
Import all from file...</label>
<i class="fa fa-question-circle tooltip-container ml-2">
<span class="tooltiptext">Select to import all data (all subsets) from a single file. Use the ampersand ("&") as a delimiter between different data subsets.</span>
</i>
</div>
<div id="data-subset"></div>
</div>
</div>

<br>

<!-- ADDITIONAL DATA -->
<div class="card card-item">
<div class="card-header">
Expand Down Expand Up @@ -542,6 +599,12 @@ <h4>Add Data</h4>
</div>
</div>
<!-- end template -->




<div class="card-body card-add-data">
{% input_field main_form.uploaded_files %}
{% endblock %}

{% block script %}
Expand Down Expand Up @@ -600,4 +663,114 @@ <h4>Add Data</h4>
$('#id_phase_transition_value_{{ subset_counter }}').val('{{ value|escapejs }}');
{% endfor %}
</script>
<script>
var elementsData = {{ elements_json|safe }};
</script>
<script>
function extractStoichiometry() {
// Get the formula input value
const formulaInput = document.getElementById('id_formula');

// Check if the formulaInput is found
if (!formulaInput) {
console.error("Formula input not found");
return;
}
const formula = formulaInput.value;
// Check if the formula is retrieved correctly
console.log("Formula:", formula);
console.log(newStoichiometryInput);
// Regular expression to match element and count
const regex = /([A-Z][a-z]*)(\d*)/g;
// Object to store element counts
const elementCounts = {};
// Match elements and counts in the formula
let match;
while ((match = regex.exec(formula)) !== null) {
const element = match[1];
const count = match[2] === '' ? 1 : parseInt(match[2], 10);

// Update or add the element count
if (elementCounts[element]) {
elementCounts[element] += count;
} else {
elementCounts[element] = count;
}
}

// Build the stoichiometry string
let stoichiometryString = '';
for (const element in elementCounts) {
stoichiometryString += `${element}:${elementCounts[element]}, `;
}

// Remove the trailing comma and space
stoichiometryString = stoichiometryString.slice(0, -2);
console.log("Stoichiometry:", stoichiometryString);
// Display the stoichiometry in the modal
document.getElementById('stoichiometryOutput').innerText = `${stoichiometryString}`;
//Show as modal
$('#stoichiometryModal').modal('show');

}
function handleStoichiometryConfirmation(answer){
const stoichiometryTextBox = document.getElementById('stoichiometry');
const newStoichiometrySection = document.getElementById('newStoichiometrySection');

if(answer == 'Yes'){
const stoichiometryOutput = document.getElementById('stoichiometryOutput').innerHTML;


//Validate
if (stoichiometryOutput.includes('V')) {
document.getElementById('stoichiometryWarning').style.display = 'block';
return;
}
if(stoichiometryTextBox){
stoichiometryTextBox.value = stoichiometryOutput;
}
}
else if (answer == 'No') {
showNewStoichiometrySection();
}
document.getElementById('stoichiometryWarning').style.display = 'none';
$('#stoichiometryModal').modal('hide');
}
function showNewStoichiometrySection() {
document.getElementById('newStoichiometrySection').style.display = 'block';
document.getElementById('newStoichiometryInput').style.display = 'block';
document.getElementById('enterButton').style.display = 'block';
document.getElementById('stoichiometryWarning').style.display = 'none'; //Hidden Warning
}

function handleNewStoichiometry() {
const stoichiometryTextBox = document.getElementById('stoichiometry');
const newStoichiometrySection = document.getElementById('newStoichiometrySection');
const newStoichiometryInput = document.getElementById('newStoichiometryInput').value;

// Validate
if (newStoichiometryInput.includes('V')) {
document.getElementById('stoichiometryWarning').style.display = 'block';
return;
}

// Set the value in the main stoichiometry text box
if (stoichiometryTextBox && newStoichiometryInput.trim() !== '') {
stoichiometryTextBox.value = newStoichiometryInput.trim();
}
// Hide the new text box and Enter button
newStoichiometrySection.style.display = 'none';
// Clear the new stoichiometry input
newStoichiometryInput.value = '';
// Hide the stoichiometry confirmation modal
document.getElementById('stoichiometryWarning').style.display = 'none';
$('#stoichiometryModal').modal('hide');
}


</script>




{% endblock %}
Loading

0 comments on commit 12f2577

Please sign in to comment.