diff --git a/.gitignore b/.gitignore
index d829c166..9d3c42e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,9 +44,6 @@ rmgweb/media/rmg/tools/*
.pydevproject
.settings/*
-# WSGI
-apache/django.wsgi
-
# VS Code related files
.history/*
diff --git a/environment.yml b/environment.yml
index 8678e419..e59afe9a 100644
--- a/environment.yml
+++ b/environment.yml
@@ -1,19 +1,11 @@
# First, install a conda environment with RMG-Py.
# Then, update the environment using the constraints in this environment file.
-name: rmg_env
+name: rmg_website
channels:
- - rmg
- conda-forge
- - cantera
- - fhvermei
dependencies:
- - docutils
- - django =2.2
- - lxml
- - pip
- - pip:
- - git+https://github.com/bp-kelley/descriptastorus@2.5.0
- - python >=3.7
- - solprop_ml >=1.2
+ - django==4.2
+ - python>=3.9
- xlsxwriter
+ - cantera==2.6.0*
diff --git a/microservices/solprop/Dockerfile b/microservices/solprop/Dockerfile
new file mode 100644
index 00000000..3a306b16
--- /dev/null
+++ b/microservices/solprop/Dockerfile
@@ -0,0 +1,14 @@
+FROM continuumio/miniconda3:latest
+
+WORKDIR /app
+
+RUN conda create -n solprop conda-forge::python=3.7 fhvermei::solprop_ml "conda-forge::scipy<1.11" && \
+ conda install -n solprop rmg::descriptastorus && \
+ conda install -n solprop conda-forge::fastapi conda-forge::uvicorn conda-forge::pydantic conda-forge::requests && \
+ conda clean -a -y
+
+COPY server.py .
+
+EXPOSE 8081
+
+CMD ["conda", "run", "--no-capture-output", "-n", "solprop", "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8081"]
diff --git a/microservices/solprop/README.md b/microservices/solprop/README.md
new file mode 100644
index 00000000..fa0891b0
--- /dev/null
+++ b/microservices/solprop/README.md
@@ -0,0 +1,7 @@
+Wraps the solprop package into a callable microservice.
+
+With docker installed, run `docker build -t solprop_service .` in this directory to build the image.
+After, run `docker run -d -p 8081:8081 --name solprop solprop_service` to start the server.
+You can check the server outputs with `docker logs solprop`.
+
+A prebuilt version of this image is also available on the ReactionMechanismGenerator DockerHub, which you can download and run to avoid building it yourself: https://hub.docker.com/layers/reactionmechanismgenerator/solprop_microservice/1.0.0/images/sha256-ca48dc8d0b0759a9a750c747758c5e095bf0dfcaae8fe0f64912ce8a91c764ff
diff --git a/microservices/solprop/server.py b/microservices/solprop/server.py
new file mode 100644
index 00000000..83da23db
--- /dev/null
+++ b/microservices/solprop/server.py
@@ -0,0 +1,149 @@
+from fastapi import FastAPI
+from pydantic import BaseModel
+import pandas as pd
+import numpy as np
+from typing import Optional
+
+from chemprop_solvation.solvation_estimator import load_DirectML_Gsolv_estimator, load_DirectML_Hsolv_estimator, load_SoluteML_estimator
+from solvation_predictor.solubility.solubility_calculator import SolubilityCalculations
+from solvation_predictor.solubility.solubility_predictions import SolubilityPredictions
+from solvation_predictor.solubility.solubility_data import SolubilityData
+from solvation_predictor.solubility.solubility_models import SolubilityModels
+
+
+class SolubilityDataWrapper:
+ """
+ Class for storing the input data for solubility prediction
+ """
+ def __init__(self, solvent_smiles=None, solute_smiles=None, temp=None, ref_solub=None, ref_solv=None):
+ self.smiles_pairs = [(solvent_smiles, solute_smiles)]
+ self.temperatures = np.array([temp]) if temp is not None else None
+ self.reference_solubility = np.array([ref_solub]) if ref_solub is not None else None
+ self.reference_solvents = np.array([ref_solv]) if ref_solv is not None else None
+
+
+app = FastAPI()
+
+dGsolv_estimator = None
+dHsolv_estimator = None
+SoluteML_estimator = None
+solub_models = None
+
+@app.on_event("startup")
+def load_models():
+ global dGsolv_estimator, dHsolv_estimator, SoluteML_estimator, solub_models
+
+ print("Loading models...")
+
+ dGsolv_estimator = load_DirectML_Gsolv_estimator()
+ dHsolv_estimator = load_DirectML_Hsolv_estimator()
+
+ solub_models = SolubilityModels(
+ load_g=True, load_h=True,
+ reduced_number=False, load_saq=True,
+ load_solute=True, logger=None, verbose=False
+ )
+
+ SoluteML_estimator = load_SoluteML_estimator()
+
+ print("Models loaded.")
+
+class SolubilityRequest(BaseModel):
+ solvent_smiles: Optional[str] = None
+ solute_smiles: Optional[str] = None
+ temperature: Optional[float] = None
+ reference_solvent: Optional[str] = None
+ reference_solubility: Optional[float] = None
+ hsub298: Optional[float] = None
+ cp_gas_298: Optional[float] = None
+ cp_solid_298: Optional[float] = None
+ use_reference: bool = False
+
+@app.post("/dGsolv_estimator")
+def _dGsolv_estimator(req: SolubilityRequest):
+ result = dGsolv_estimator([[req.solvent_smiles, req.solute_smiles]])
+ return {
+ "avg_pred": result[0],
+ "epi_unc": result[1],
+ "valid_indices": result[2]
+ }
+
+@app.post("/dHsolv_estimator")
+def _dHsolv_estimator(req: SolubilityRequest):
+ result = dHsolv_estimator([[req.solvent_smiles, req.solute_smiles]])
+ return {
+ "avg_pred": result[0],
+ "epi_unc": result[1],
+ "valid_indices": result[2]
+ }
+
+@app.post("/SoluteML_estimator")
+def _SoluteML_estimator(req: SolubilityRequest):
+ result = SoluteML_estimator([[req.solute_smiles]])
+ return {
+ "avg_pred": result[0],
+ "epi_unc": result[1],
+ "valid_indices": result[2]
+ }
+
+@app.post("/calc_solubility_no_ref")
+def _calc_solubility_no_ref(req: SolubilityRequest):
+ """
+ Calculate solubility with no reference solvent and reference solubility
+ """
+ hsubl_298 = np.array([req.hsub298]) if req.hsub298 is not None else None
+ Cp_solid = np.array([req.cp_solid_298]) if req.cp_solid_298 is not None else None
+ Cp_gas = np.array([req.cp_gas_298]) if req.cp_gas_298 is not None else None
+
+ solub_data = SolubilityDataWrapper(solvent_smiles=req.solvent_smiles, solute_smiles=req.solute_smiles, temp=req.temperature)
+ predictions = SolubilityPredictions(solub_data, solub_models, predict_aqueous=True,
+ predict_reference_solvents=False, predict_t_dep=True,
+ predict_solute_parameters=True, verbose=False)
+ calculations = SolubilityCalculations(predictions, calculate_aqueous=True,
+ calculate_reference_solvents=False, calculate_t_dep=True,
+ calculate_t_dep_with_t_dep_hdiss=True, verbose=False,
+ hsubl_298=hsubl_298, Cp_solid=Cp_solid, Cp_gas=Cp_gas)
+
+ return {
+ "logsT_method1": calculations.logs_T_with_const_hdiss_from_aq[0],
+ "logsT_method2": calculations.logs_T_with_T_dep_hdiss_from_aq[0],
+ "gsolv_T": calculations.gsolv_T[0],
+ "hsolv_T": calculations.hsolv_T[0],
+ "ssolv_T": calculations.ssolv_T[0],
+ "hsubl_298": calculations.hsubl_298[0],
+ "Cp_gas": calculations.Cp_gas[0],
+ "Cp_solid": calculations.Cp_solid[0],
+ "logs_T_with_T_dep_hdiss_error_message": None if calculations.logs_T_with_T_dep_hdiss_error_message is None else calculations.logs_T_with_T_dep_hdiss_error_message[0],
+ }
+
+
+@app.post("/calc_solubility_with_ref")
+def _calc_solubility_with_ref(req: SolubilityRequest):
+ """
+ Calculate solubility with a reference solvent and reference solubility
+ """
+ hsubl_298 = np.array([req.hsub298]) if req.hsub298 is not None else None
+ Cp_solid = np.array([req.cp_solid_298]) if req.cp_solid_298 is not None else None
+ Cp_gas = np.array([req.cp_gas_298]) if req.cp_gas_298 is not None else None
+
+ solub_data = SolubilityDataWrapper(solvent_smiles=req.solvent_smiles, solute_smiles=req.solute_smiles, temp=req.temperature,
+ ref_solub=req.reference_solubility, ref_solv=req.reference_solvent)
+ predictions = SolubilityPredictions(solub_data, solub_models, predict_aqueous=False,
+ predict_reference_solvents=True, predict_t_dep=True,
+ predict_solute_parameters=True, verbose=False)
+ calculations = SolubilityCalculations(predictions, calculate_aqueous=False,
+ calculate_reference_solvents=True, calculate_t_dep=True,
+ calculate_t_dep_with_t_dep_hdiss=True, verbose=False,
+ hsubl_298=hsubl_298, Cp_solid=Cp_solid, Cp_gas=Cp_gas)
+
+ return {
+ "logsT_method1": calculations.logs_T_with_const_hdiss_from_ref[0],
+ "logsT_method2": calculations.logs_T_with_T_dep_hdiss_from_ref[0],
+ "gsolv_T": calculations.gsolv_T[0],
+ "hsolv_T": calculations.hsolv_T[0],
+ "ssolv_T": calculations.ssolv_T[0],
+ "hsubl_298": calculations.hsubl_298[0],
+ "Cp_gas": calculations.Cp_gas[0],
+ "Cp_solid": calculations.Cp_solid[0],
+ "logs_T_with_T_dep_hdiss_error_message": None if calculations.logs_T_with_T_dep_hdiss_error_message is None else calculations.logs_T_with_T_dep_hdiss_error_message[0],
+ }
diff --git a/microservices/solprop/test.py b/microservices/solprop/test.py
new file mode 100644
index 00000000..b069a74a
--- /dev/null
+++ b/microservices/solprop/test.py
@@ -0,0 +1,134 @@
+import requests
+
+# The base URL where your server is running.
+# Change this if running on a different port or host.
+BASE_URL = "http://localhost:8081"
+
+# ---------------------------------------------------------
+# Test Data Constants
+# ---------------------------------------------------------
+TEST_SOLVENT = "CCO" # Ethanol
+TEST_SOLUTE = "CC(=O)O" # Acetic Acid
+
+# ---------------------------------------------------------
+# Tests for DirectML and SoluteML Estimators
+# ---------------------------------------------------------
+
+def test_dGsolv_estimator_success():
+ payload = {
+ "solvent_smiles": TEST_SOLVENT,
+ "solute_smiles": TEST_SOLUTE
+ }
+
+ response = requests.post(f"{BASE_URL}/dGsolv_estimator", json=payload)
+
+ # Verify the HTTP response
+ assert response.status_code == 200
+
+ # Verify the JSON payload structure
+ data = response.json()
+ assert "avg_pred" in data
+ assert "epi_unc" in data
+ assert "valid_indices" in data
+
+
+def test_dHsolv_estimator_success():
+ payload = {
+ "solvent_smiles": TEST_SOLVENT,
+ "solute_smiles": TEST_SOLUTE
+ }
+
+ response = requests.post(f"{BASE_URL}/dHsolv_estimator", json=payload)
+
+ assert response.status_code == 200
+
+ data = response.json()
+ assert "avg_pred" in data
+ assert "epi_unc" in data
+ assert "valid_indices" in data
+
+
+def test_SoluteML_estimator_success():
+ payload = {
+ "solute_smiles": TEST_SOLUTE
+ }
+
+ response = requests.post(f"{BASE_URL}/SoluteML_estimator", json=payload)
+
+ assert response.status_code == 200
+
+ data = response.json()
+ assert "avg_pred" in data
+ assert "epi_unc" in data
+ assert "valid_indices" in data
+
+
+def test_invalid_payload_fails():
+ # Sending a bad type (like string instead of float for temperature)
+ # should raise a 422 Unprocessable Entity from Pydantic
+ payload = {
+ "temperature": "not_a_number"
+ }
+ response = requests.post(f"{BASE_URL}/dGsolv_estimator", json=payload)
+ assert response.status_code == 422
+
+
+# ---------------------------------------------------------
+# Tests for the Solubility Calculators
+# ---------------------------------------------------------
+
+def test_calc_solubility_no_ref():
+ payload = {
+ "solvent_smiles": TEST_SOLVENT,
+ "solute_smiles": TEST_SOLUTE,
+ "temperature": 298.15
+ }
+
+ response = requests.post(f"{BASE_URL}/calc_solubility_no_ref", json=payload)
+
+ assert response.status_code == 200
+
+ data = response.json()
+
+ # based on the previous version from rmg.mit.edu
+ assert round(data["logsT_method1"], 3) == 1.146
+ assert round(data["logsT_method2"], 3) == 1.146
+ assert round(data["gsolv_T"], 2) == -7.12
+ assert round(data["hsolv_T"], 2) == -12.08
+ assert round(data["ssolv_T"] * 1000, 2) == -16.62
+ assert round(data["hsubl_298"], 2) == 14.86
+ assert round(data["Cp_gas"], 2) == 15.93
+ assert round(data["Cp_solid"], 2) == 22.18
+
+
+def test_calc_solubility_with_ref():
+ payload = {
+ "solvent_smiles": TEST_SOLVENT,
+ "solute_smiles": TEST_SOLUTE,
+ "temperature": 298.15,
+ "reference_solvent": "O", # Water
+ "reference_solubility": -1.5
+ }
+
+ response = requests.post(f"{BASE_URL}/calc_solubility_with_ref", json=payload)
+
+ assert response.status_code == 200
+
+ data = response.json()
+ assert round(data["logsT_method1"], 3) == -1.223
+ assert round(data["logsT_method2"], 3) == -1.223
+ assert round(data["gsolv_T"], 2) == -7.12
+ assert round(data["hsolv_T"], 2) == -12.08
+ assert round(data["ssolv_T"] * 1000, 2) == -16.62
+ assert round(data["hsubl_298"], 2) == 14.86
+ assert round(data["Cp_gas"], 2) == 15.93
+ assert round(data["Cp_solid"], 2) == 22.18
+
+if __name__ == "__main__":
+ test_dGsolv_estimator_success()
+ test_dHsolv_estimator_success()
+ test_SoluteML_estimator_success()
+ test_invalid_payload_fails()
+ test_calc_solubility_no_ref()
+ test_calc_solubility_with_ref()
+ print("All tests passed!")
diff --git a/rmgweb/database/migrations/0014_alter_solubilitysearch_id_alter_solutesearch_id_and_more.py b/rmgweb/database/migrations/0014_alter_solubilitysearch_id_alter_solutesearch_id_and_more.py
new file mode 100644
index 00000000..cc9b4d16
--- /dev/null
+++ b/rmgweb/database/migrations/0014_alter_solubilitysearch_id_alter_solutesearch_id_and_more.py
@@ -0,0 +1,588 @@
+# Generated by Django 4.2.23 on 2025-07-03 15:10
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("database", "0013_solubilitysearch"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="solubilitysearch",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="solutesearch",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="solutesearch",
+ name="solvent",
+ field=models.CharField(
+ blank=True,
+ choices=[
+ ("water", "1. water"),
+ ("1-octanol", "2. 1-octanol"),
+ ("benzene", "3. benzene"),
+ ("cyclohexane", "4. cyclohexane"),
+ ("dibutylether", "5. dibutylether"),
+ ("octane", "6. octane"),
+ ("butanol", "7. butanol"),
+ ("carbontet", "8. carbontet"),
+ ("chloroform", "9. chloroform"),
+ ("decane", "10. decane"),
+ ("1,1-dichloroethane", "11. 1,1-dichloroethane"),
+ ("dimethylformamide", "12. dimethylformamide"),
+ ("dimethylsulfoxide", "13. dimethylsulfoxide"),
+ ("dodecane", "14. dodecane"),
+ ("ethanol", "15. ethanol"),
+ ("heptane", "16. heptane"),
+ ("hexadecane", "17. hexadecane"),
+ ("hexane", "18. hexane"),
+ ("isooctane", "19. isooctane"),
+ ("nonane", "20. nonane"),
+ ("pentane", "21. pentane"),
+ ("toluene", "22. toluene"),
+ ("undecane", "23. undecane"),
+ ("acetonitrile", "24. acetonitrile"),
+ ("ethylacetate", "25. ethylacetate"),
+ ("methanol", "26. methanol"),
+ ("methanol_50_water_50", "27. methanol_50_water_50"),
+ ("acetonitrile_40_water_60", "28. acetonitrile_40_water_60"),
+ ("acetonitrile_60_water_40", "29. acetonitrile_60_water_40"),
+ ("2-methylpyridine", "30. 2-methylpyridine"),
+ ("4-methylpentan-2-one", "31. 4-methylpentan-2-one"),
+ ("acetic acid", "32. acetic acid"),
+ ("1-phenylethanone", "33. 1-phenylethanone"),
+ ("aniline", "34. aniline"),
+ ("anisole", "35. anisole"),
+ ("benzonitrile", "36. benzonitrile"),
+ ("phenylmethanol", "37. phenylmethanol"),
+ ("bromobenzene", "38. bromobenzene"),
+ ("bromoethane", "39. bromoethane"),
+ ("bromoform", "40. bromoform"),
+ ("butan-2-one", "41. butan-2-one"),
+ ("butyl acetate", "42. butyl acetate"),
+ ("butylbenzene", "43. butylbenzene"),
+ ("carbon disulfide", "44. carbon disulfide"),
+ ("chlorobenzene", "45. chlorobenzene"),
+ ("1-chlorohexane", "46. 1-chlorohexane"),
+ ("cyclohexanone", "47. cyclohexanone"),
+ ("decalin", "48. decalin"),
+ ("decan-1-ol", "49. decan-1-ol"),
+ ("1,1-dibromoethane", "50. 1,1-dibromoethane"),
+ ("1,2-dichloroethane", "51. 1,2-dichloroethane"),
+ ("ethoxyethane", "52. ethoxyethane"),
+ ("2-propan-2-yloxypropane", "53. 2-propan-2-yloxypropane"),
+ ("N,N-dimethylacetamide", "54. N,N-dimethylacetamide"),
+ ("ethoxybenzene", "55. ethoxybenzene"),
+ ("ethylbenzene", "56. ethylbenzene"),
+ ("fluorobenzene", "57. fluorobenzene"),
+ ("heptan-1-ol", "58. heptan-1-ol"),
+ ("1-iodohexadecane", "59. 1-iodohexadecane"),
+ ("hexan-1-ol", "60. hexan-1-ol"),
+ ("iodobenzene", "61. iodobenzene"),
+ ("2-methylpropan-1-ol", "62. 2-methylpropan-1-ol"),
+ ("propan-2-ol", "63. propan-2-ol"),
+ ("cumene", "64. cumene"),
+ ("3-methylphenol", "65. 3-methylphenol"),
+ ("2-methoxyethanol", "66. 2-methoxyethanol"),
+ ("dichloromethane", "67. dichloromethane"),
+ ("N-methylformamide", "68. N-methylformamide"),
+ ("nitrobenzene", "69. nitrobenzene"),
+ ("1-nitroethane", "70. 1-nitroethane"),
+ ("nitromethane", "71. nitromethane"),
+ ("nonan-1-ol", "72. nonan-1-ol"),
+ ("1,2-dichlorobenzene", "73. 1,2-dichlorobenzene"),
+ ("pentadecane", "74. pentadecane"),
+ ("pentan-1-ol", "75. pentan-1-ol"),
+ ("hexafluorobenzene", "76. hexafluorobenzene"),
+ ("propan-1-ol", "77. propan-1-ol"),
+ ("pyridine", "78. pyridine"),
+ ("butan-2-ol", "79. butan-2-ol"),
+ ("tert-butylbenzene", "80. tert-butylbenzene"),
+ ("1,1,2,2-tetrachloroethene", "81. 1,1,2,2-tetrachloroethene"),
+ ("c", "82. c"),
+ (
+ "1,2,3,4-tetrahydronaphthalene",
+ "83. 1,2,3,4-tetrahydronaphthalene",
+ ),
+ ("tributyl phosphate", "84. tributyl phosphate"),
+ ("N,N-diethylethanamine", "85. N,N-diethylethanamine"),
+ ("1,2,4-trimethylbenzene", "86. 1,2,4-trimethylbenzene"),
+ ("1,4-xylene", "87. 1,4-xylene"),
+ ("2-methylpropan-2-ol", "88. 2-methylpropan-2-ol"),
+ ("3-methylbutan-1-ol", "89. 3-methylbutan-1-ol"),
+ ("undecan-1-ol", "90. undecan-1-ol"),
+ ("propan-2-one", "91. propan-2-one"),
+ ("methyl acetate", "92. methyl acetate"),
+ ("propyl acetate", "93. propyl acetate"),
+ ("pentyl acetate", "94. pentyl acetate"),
+ ("2-methylbutan-2-ol", "95. 2-methylbutan-2-ol"),
+ ("4-methylpentan-2-ol", "96. 4-methylpentan-2-ol"),
+ ("2-methylpentan-1-ol", "97. 2-methylpentan-1-ol"),
+ ("2-ethylhexan-1-ol", "98. 2-ethylhexan-1-ol"),
+ ("2-methoxy-2-methylpropane", "99. 2-methoxy-2-methylpropane"),
+ ("dodecan-1-ol", "100. dodecan-1-ol"),
+ ("2-butoxyethanol", "101. 2-butoxyethanol"),
+ ("2-ethoxyethanol", "102. 2-ethoxyethanol"),
+ ("1-propoxypropane", "103. 1-propoxypropane"),
+ ("pentan-2-ol", "104. pentan-2-ol"),
+ ("2-methylbutan-1-ol", "105. 2-methylbutan-1-ol"),
+ ("pentan-3-ol", "106. pentan-3-ol"),
+ ("2-propoxyethanol", "107. 2-propoxyethanol"),
+ ("2-propan-2-yloxyethanol", "108. 2-propan-2-yloxyethanol"),
+ ("3-methoxybutan-1-ol", "109. 3-methoxybutan-1-ol"),
+ ("1-tert-butoxy-2-propanol", "110. 1-tert-butoxy-2-propanol"),
+ ("2-methoxy-2-methylbutane", "111. 2-methoxy-2-methylbutane"),
+ ("pentan-2-one", "112. pentan-2-one"),
+ ("ethyl butanoate", "113. ethyl butanoate"),
+ ("heptan-2-one", "114. heptan-2-one"),
+ ("hexyl acetate", "115. hexyl acetate"),
+ ("1-nitro-2-octoxybenzene", "116. 1-nitro-2-octoxybenzene"),
+ ("1-methylpyrrolidin-2-one", "117. 1-methylpyrrolidin-2-one"),
+ ("N-methylacetamide", "118. N-methylacetamide"),
+ ("morpholine-4-carbaldehyde", "119. morpholine-4-carbaldehyde"),
+ ("N,N-dibutylformamide", "120. N,N-dibutylformamide"),
+ ("formamide", "121. formamide"),
+ ("N,N-diethylacetamide", "122. N,N-diethylacetamide"),
+ ("1-methylpiperidin-2-one", "123. 1-methylpiperidin-2-one"),
+ ("N-ethylformamide", "124. N-ethylformamide"),
+ ("N-ethylacetamide", "125. N-ethylacetamide"),
+ ("triolein", "126. triolein"),
+ ("deca-1,9-diene", "127. deca-1,9-diene"),
+ ("hexadec-1-ene", "128. hexadec-1-ene"),
+ ("1,3-xylene", "129. 1,3-xylene"),
+ ("1,2-xylene", "130. 1,2-xylene"),
+ ("1,4-dioxane", "131. 1,4-dioxane"),
+ ("1-chlorobutane", "132. 1-chlorobutane"),
+ ("1,1,2,2-tetrabromoethane", "133. 1,1,2,2-tetrabromoethane"),
+ ("1,1,2,2-tetrachloroethane", "134. 1,1,2,2-tetrachloroethane"),
+ ("propane-1,2-diol", "135. propane-1,2-diol"),
+ (
+ "1,3-dimethylimidazolidin-2-one",
+ "136. 1,3-dimethylimidazolidin-2-one",
+ ),
+ ("propane-1,3-diol", "137. propane-1,3-diol"),
+ ("butane-1,4-diol", "138. butane-1,4-diol"),
+ ("pentane-1,5-diol", "139. pentane-1,5-diol"),
+ ("1-bromonaphthalene", "140. 1-bromonaphthalene"),
+ ("1-chloronaphthalene", "141. 1-chloronaphthalene"),
+ ("dec-1-ene", "142. dec-1-ene"),
+ ("hex-1-ene", "143. hex-1-ene"),
+ ("1-nitropropane", "144. 1-nitropropane"),
+ ("oct-1-ene", "145. oct-1-ene"),
+ ("2-sulfanylethanol", "146. 2-sulfanylethanol"),
+ (
+ "3-methylthiolane 1,1-dioxide",
+ "147. 3-methylthiolane 1,1-dioxide",
+ ),
+ ("hexanedinitrile", "148. hexanedinitrile"),
+ ("benzyl acetate", "149. benzyl acetate"),
+ ("cyclohexylcyclohexane", "150. cyclohexylcyclohexane"),
+ ("butanenitrile", "151. butanenitrile"),
+ ("cis-1,2-dichloroethene", "152. cis-1,2-dichloroethene"),
+ ("cis-decaline", "153. cis-decaline"),
+ ("cyclohexanol", "154. cyclohexanol"),
+ ("cyclohexylbenzene", "155. cyclohexylbenzene"),
+ ("cyclopentanone", "156. cyclopentanone"),
+ ("deuterated water", "157. deuterated water"),
+ (
+ "bis(2-ethylhexyl) hexanedioate",
+ "158. bis(2-ethylhexyl) hexanedioate",
+ ),
+ ("2,2-dichloroacetic acid", "159. 2,2-dichloroacetic acid"),
+ (
+ "diethyl benzene-1,2-dicarboxylate",
+ "160. diethyl benzene-1,2-dicarboxylate",
+ ),
+ ("2-(2-hydroxyethoxy)ethanol", "161. 2-(2-hydroxyethoxy)ethanol"),
+ (
+ "1-ethoxy-2-(2-ethoxyethoxy)ethane",
+ "162. 1-ethoxy-2-(2-ethoxyethoxy)ethane",
+ ),
+ (
+ "1-methoxy-2-(2-methoxyethoxy)ethane",
+ "163. 1-methoxy-2-(2-methoxyethoxy)ethane",
+ ),
+ ("diiodomethane", "164. diiodomethane"),
+ (
+ "dibutyl benzene-1,2-dicarboxylate",
+ "165. dibutyl benzene-1,2-dicarboxylate",
+ ),
+ (
+ "dinonyl benzene-1,2-dicarboxylate",
+ "166. dinonyl benzene-1,2-dicarboxylate",
+ ),
+ ("bis(2-ethylhexyl) phthalate", "167. bis(2-ethylhexyl) phthalate"),
+ (
+ "3-(3-hydroxypropoxy)propan-1-ol",
+ "168. 3-(3-hydroxypropoxy)propan-1-ol",
+ ),
+ ("ethane-1,2-diol", "169. ethane-1,2-diol"),
+ ("furan-2-carbaldehyde", "170. furan-2-carbaldehyde"),
+ ("furan-2-ylmethanol", "171. furan-2-ylmethanol"),
+ ("oxolan-2-one", "172. oxolan-2-one"),
+ ("1H-indene", "173. 1H-indene"),
+ ("2-aminoethanol", "174. 2-aminoethanol"),
+ ("1-ethylpyrrolidin-2-one", "175. 1-ethylpyrrolidin-2-one"),
+ ("tetradecane", "176. tetradecane"),
+ ("tridecane", "177. tridecane"),
+ (
+ "octamethylcyclotetrasiloxane",
+ "178. octamethylcyclotetrasiloxane",
+ ),
+ ("perflexane", "179. perflexane"),
+ ("perfluorooctane", "180. perfluorooctane"),
+ ("2-phenylacetonitrile", "181. 2-phenylacetonitrile"),
+ ("propanenitrile", "182. propanenitrile"),
+ ("4-methyl-1,3-dioxolan-2-one", "183. 4-methyl-1,3-dioxolan-2-one"),
+ ("quinoline", "184. quinoline"),
+ ("2-chlorobutane", "185. 2-chlorobutane"),
+ ("squalane", "186. squalane"),
+ ("tetraethylene glycol", "187. tetraethylene glycol"),
+ ("tetraglyme", "188. tetraglyme"),
+ ("thiodiglycol", "189. thiodiglycol"),
+ ("trans-1,2-dichloroethene", "190. trans-1,2-dichloroethene"),
+ ("trans-decalin", "191. trans-decalin"),
+ ("N,N-dipentylpentan-1-amine", "192. N,N-dipentylpentan-1-amine"),
+ ("tricaprylin", "193. tricaprylin"),
+ ("triethyl phosphate", "194. triethyl phosphate"),
+ ("triethylene glycol", "195. triethylene glycol"),
+ ("triglyme", "196. triglyme"),
+ ("N,N-dibutylbutan-1-amine", "197. N,N-dibutylbutan-1-amine"),
+ ("N,N-dioctyloctan-1-amine", "198. N,N-dioctyloctan-1-amine"),
+ ("hexamethylphosphoramide", "199. hexamethylphosphoramide"),
+ ("dimethyl carbonate", "200. dimethyl carbonate"),
+ ("diethyl carbonate", "201. diethyl carbonate"),
+ (
+ "ethylene carbonate dimethyl carbonate 50:50",
+ "202. ethylene carbonate dimethyl carbonate 50:50",
+ ),
+ ("ethylene carbonate", "203. ethylene carbonate"),
+ ],
+ max_length=200,
+ verbose_name="Solvent (Optional)",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="solvationsearchml",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="solvationsearchtempdep",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="solventselection",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="solventselection",
+ name="solvent",
+ field=models.CharField(
+ blank=True,
+ choices=[
+ ("water", "1. water"),
+ ("1-octanol", "2. 1-octanol"),
+ ("benzene", "3. benzene"),
+ ("cyclohexane", "4. cyclohexane"),
+ ("dibutylether", "5. dibutylether"),
+ ("octane", "6. octane"),
+ ("butanol", "7. butanol"),
+ ("carbontet", "8. carbontet"),
+ ("chloroform", "9. chloroform"),
+ ("decane", "10. decane"),
+ ("1,1-dichloroethane", "11. 1,1-dichloroethane"),
+ ("dimethylformamide", "12. dimethylformamide"),
+ ("dimethylsulfoxide", "13. dimethylsulfoxide"),
+ ("dodecane", "14. dodecane"),
+ ("ethanol", "15. ethanol"),
+ ("heptane", "16. heptane"),
+ ("hexadecane", "17. hexadecane"),
+ ("hexane", "18. hexane"),
+ ("isooctane", "19. isooctane"),
+ ("nonane", "20. nonane"),
+ ("pentane", "21. pentane"),
+ ("toluene", "22. toluene"),
+ ("undecane", "23. undecane"),
+ ("acetonitrile", "24. acetonitrile"),
+ ("ethylacetate", "25. ethylacetate"),
+ ("methanol", "26. methanol"),
+ ("methanol_50_water_50", "27. methanol_50_water_50"),
+ ("acetonitrile_40_water_60", "28. acetonitrile_40_water_60"),
+ ("acetonitrile_60_water_40", "29. acetonitrile_60_water_40"),
+ ("2-methylpyridine", "30. 2-methylpyridine"),
+ ("4-methylpentan-2-one", "31. 4-methylpentan-2-one"),
+ ("acetic acid", "32. acetic acid"),
+ ("1-phenylethanone", "33. 1-phenylethanone"),
+ ("aniline", "34. aniline"),
+ ("anisole", "35. anisole"),
+ ("benzonitrile", "36. benzonitrile"),
+ ("phenylmethanol", "37. phenylmethanol"),
+ ("bromobenzene", "38. bromobenzene"),
+ ("bromoethane", "39. bromoethane"),
+ ("bromoform", "40. bromoform"),
+ ("butan-2-one", "41. butan-2-one"),
+ ("butyl acetate", "42. butyl acetate"),
+ ("butylbenzene", "43. butylbenzene"),
+ ("carbon disulfide", "44. carbon disulfide"),
+ ("chlorobenzene", "45. chlorobenzene"),
+ ("1-chlorohexane", "46. 1-chlorohexane"),
+ ("cyclohexanone", "47. cyclohexanone"),
+ ("decalin", "48. decalin"),
+ ("decan-1-ol", "49. decan-1-ol"),
+ ("1,1-dibromoethane", "50. 1,1-dibromoethane"),
+ ("1,2-dichloroethane", "51. 1,2-dichloroethane"),
+ ("ethoxyethane", "52. ethoxyethane"),
+ ("2-propan-2-yloxypropane", "53. 2-propan-2-yloxypropane"),
+ ("N,N-dimethylacetamide", "54. N,N-dimethylacetamide"),
+ ("ethoxybenzene", "55. ethoxybenzene"),
+ ("ethylbenzene", "56. ethylbenzene"),
+ ("fluorobenzene", "57. fluorobenzene"),
+ ("heptan-1-ol", "58. heptan-1-ol"),
+ ("1-iodohexadecane", "59. 1-iodohexadecane"),
+ ("hexan-1-ol", "60. hexan-1-ol"),
+ ("iodobenzene", "61. iodobenzene"),
+ ("2-methylpropan-1-ol", "62. 2-methylpropan-1-ol"),
+ ("propan-2-ol", "63. propan-2-ol"),
+ ("cumene", "64. cumene"),
+ ("3-methylphenol", "65. 3-methylphenol"),
+ ("2-methoxyethanol", "66. 2-methoxyethanol"),
+ ("dichloromethane", "67. dichloromethane"),
+ ("N-methylformamide", "68. N-methylformamide"),
+ ("nitrobenzene", "69. nitrobenzene"),
+ ("1-nitroethane", "70. 1-nitroethane"),
+ ("nitromethane", "71. nitromethane"),
+ ("nonan-1-ol", "72. nonan-1-ol"),
+ ("1,2-dichlorobenzene", "73. 1,2-dichlorobenzene"),
+ ("pentadecane", "74. pentadecane"),
+ ("pentan-1-ol", "75. pentan-1-ol"),
+ ("hexafluorobenzene", "76. hexafluorobenzene"),
+ ("propan-1-ol", "77. propan-1-ol"),
+ ("pyridine", "78. pyridine"),
+ ("butan-2-ol", "79. butan-2-ol"),
+ ("tert-butylbenzene", "80. tert-butylbenzene"),
+ ("1,1,2,2-tetrachloroethene", "81. 1,1,2,2-tetrachloroethene"),
+ ("c", "82. c"),
+ (
+ "1,2,3,4-tetrahydronaphthalene",
+ "83. 1,2,3,4-tetrahydronaphthalene",
+ ),
+ ("tributyl phosphate", "84. tributyl phosphate"),
+ ("N,N-diethylethanamine", "85. N,N-diethylethanamine"),
+ ("1,2,4-trimethylbenzene", "86. 1,2,4-trimethylbenzene"),
+ ("1,4-xylene", "87. 1,4-xylene"),
+ ("2-methylpropan-2-ol", "88. 2-methylpropan-2-ol"),
+ ("3-methylbutan-1-ol", "89. 3-methylbutan-1-ol"),
+ ("undecan-1-ol", "90. undecan-1-ol"),
+ ("propan-2-one", "91. propan-2-one"),
+ ("methyl acetate", "92. methyl acetate"),
+ ("propyl acetate", "93. propyl acetate"),
+ ("pentyl acetate", "94. pentyl acetate"),
+ ("2-methylbutan-2-ol", "95. 2-methylbutan-2-ol"),
+ ("4-methylpentan-2-ol", "96. 4-methylpentan-2-ol"),
+ ("2-methylpentan-1-ol", "97. 2-methylpentan-1-ol"),
+ ("2-ethylhexan-1-ol", "98. 2-ethylhexan-1-ol"),
+ ("2-methoxy-2-methylpropane", "99. 2-methoxy-2-methylpropane"),
+ ("dodecan-1-ol", "100. dodecan-1-ol"),
+ ("2-butoxyethanol", "101. 2-butoxyethanol"),
+ ("2-ethoxyethanol", "102. 2-ethoxyethanol"),
+ ("1-propoxypropane", "103. 1-propoxypropane"),
+ ("pentan-2-ol", "104. pentan-2-ol"),
+ ("2-methylbutan-1-ol", "105. 2-methylbutan-1-ol"),
+ ("pentan-3-ol", "106. pentan-3-ol"),
+ ("2-propoxyethanol", "107. 2-propoxyethanol"),
+ ("2-propan-2-yloxyethanol", "108. 2-propan-2-yloxyethanol"),
+ ("3-methoxybutan-1-ol", "109. 3-methoxybutan-1-ol"),
+ ("1-tert-butoxy-2-propanol", "110. 1-tert-butoxy-2-propanol"),
+ ("2-methoxy-2-methylbutane", "111. 2-methoxy-2-methylbutane"),
+ ("pentan-2-one", "112. pentan-2-one"),
+ ("ethyl butanoate", "113. ethyl butanoate"),
+ ("heptan-2-one", "114. heptan-2-one"),
+ ("hexyl acetate", "115. hexyl acetate"),
+ ("1-nitro-2-octoxybenzene", "116. 1-nitro-2-octoxybenzene"),
+ ("1-methylpyrrolidin-2-one", "117. 1-methylpyrrolidin-2-one"),
+ ("N-methylacetamide", "118. N-methylacetamide"),
+ ("morpholine-4-carbaldehyde", "119. morpholine-4-carbaldehyde"),
+ ("N,N-dibutylformamide", "120. N,N-dibutylformamide"),
+ ("formamide", "121. formamide"),
+ ("N,N-diethylacetamide", "122. N,N-diethylacetamide"),
+ ("1-methylpiperidin-2-one", "123. 1-methylpiperidin-2-one"),
+ ("N-ethylformamide", "124. N-ethylformamide"),
+ ("N-ethylacetamide", "125. N-ethylacetamide"),
+ ("triolein", "126. triolein"),
+ ("deca-1,9-diene", "127. deca-1,9-diene"),
+ ("hexadec-1-ene", "128. hexadec-1-ene"),
+ ("1,3-xylene", "129. 1,3-xylene"),
+ ("1,2-xylene", "130. 1,2-xylene"),
+ ("1,4-dioxane", "131. 1,4-dioxane"),
+ ("1-chlorobutane", "132. 1-chlorobutane"),
+ ("1,1,2,2-tetrabromoethane", "133. 1,1,2,2-tetrabromoethane"),
+ ("1,1,2,2-tetrachloroethane", "134. 1,1,2,2-tetrachloroethane"),
+ ("propane-1,2-diol", "135. propane-1,2-diol"),
+ (
+ "1,3-dimethylimidazolidin-2-one",
+ "136. 1,3-dimethylimidazolidin-2-one",
+ ),
+ ("propane-1,3-diol", "137. propane-1,3-diol"),
+ ("butane-1,4-diol", "138. butane-1,4-diol"),
+ ("pentane-1,5-diol", "139. pentane-1,5-diol"),
+ ("1-bromonaphthalene", "140. 1-bromonaphthalene"),
+ ("1-chloronaphthalene", "141. 1-chloronaphthalene"),
+ ("dec-1-ene", "142. dec-1-ene"),
+ ("hex-1-ene", "143. hex-1-ene"),
+ ("1-nitropropane", "144. 1-nitropropane"),
+ ("oct-1-ene", "145. oct-1-ene"),
+ ("2-sulfanylethanol", "146. 2-sulfanylethanol"),
+ (
+ "3-methylthiolane 1,1-dioxide",
+ "147. 3-methylthiolane 1,1-dioxide",
+ ),
+ ("hexanedinitrile", "148. hexanedinitrile"),
+ ("benzyl acetate", "149. benzyl acetate"),
+ ("cyclohexylcyclohexane", "150. cyclohexylcyclohexane"),
+ ("butanenitrile", "151. butanenitrile"),
+ ("cis-1,2-dichloroethene", "152. cis-1,2-dichloroethene"),
+ ("cis-decaline", "153. cis-decaline"),
+ ("cyclohexanol", "154. cyclohexanol"),
+ ("cyclohexylbenzene", "155. cyclohexylbenzene"),
+ ("cyclopentanone", "156. cyclopentanone"),
+ ("deuterated water", "157. deuterated water"),
+ (
+ "bis(2-ethylhexyl) hexanedioate",
+ "158. bis(2-ethylhexyl) hexanedioate",
+ ),
+ ("2,2-dichloroacetic acid", "159. 2,2-dichloroacetic acid"),
+ (
+ "diethyl benzene-1,2-dicarboxylate",
+ "160. diethyl benzene-1,2-dicarboxylate",
+ ),
+ ("2-(2-hydroxyethoxy)ethanol", "161. 2-(2-hydroxyethoxy)ethanol"),
+ (
+ "1-ethoxy-2-(2-ethoxyethoxy)ethane",
+ "162. 1-ethoxy-2-(2-ethoxyethoxy)ethane",
+ ),
+ (
+ "1-methoxy-2-(2-methoxyethoxy)ethane",
+ "163. 1-methoxy-2-(2-methoxyethoxy)ethane",
+ ),
+ ("diiodomethane", "164. diiodomethane"),
+ (
+ "dibutyl benzene-1,2-dicarboxylate",
+ "165. dibutyl benzene-1,2-dicarboxylate",
+ ),
+ (
+ "dinonyl benzene-1,2-dicarboxylate",
+ "166. dinonyl benzene-1,2-dicarboxylate",
+ ),
+ ("bis(2-ethylhexyl) phthalate", "167. bis(2-ethylhexyl) phthalate"),
+ (
+ "3-(3-hydroxypropoxy)propan-1-ol",
+ "168. 3-(3-hydroxypropoxy)propan-1-ol",
+ ),
+ ("ethane-1,2-diol", "169. ethane-1,2-diol"),
+ ("furan-2-carbaldehyde", "170. furan-2-carbaldehyde"),
+ ("furan-2-ylmethanol", "171. furan-2-ylmethanol"),
+ ("oxolan-2-one", "172. oxolan-2-one"),
+ ("1H-indene", "173. 1H-indene"),
+ ("2-aminoethanol", "174. 2-aminoethanol"),
+ ("1-ethylpyrrolidin-2-one", "175. 1-ethylpyrrolidin-2-one"),
+ ("tetradecane", "176. tetradecane"),
+ ("tridecane", "177. tridecane"),
+ (
+ "octamethylcyclotetrasiloxane",
+ "178. octamethylcyclotetrasiloxane",
+ ),
+ ("perflexane", "179. perflexane"),
+ ("perfluorooctane", "180. perfluorooctane"),
+ ("2-phenylacetonitrile", "181. 2-phenylacetonitrile"),
+ ("propanenitrile", "182. propanenitrile"),
+ ("4-methyl-1,3-dioxolan-2-one", "183. 4-methyl-1,3-dioxolan-2-one"),
+ ("quinoline", "184. quinoline"),
+ ("2-chlorobutane", "185. 2-chlorobutane"),
+ ("squalane", "186. squalane"),
+ ("tetraethylene glycol", "187. tetraethylene glycol"),
+ ("tetraglyme", "188. tetraglyme"),
+ ("thiodiglycol", "189. thiodiglycol"),
+ ("trans-1,2-dichloroethene", "190. trans-1,2-dichloroethene"),
+ ("trans-decalin", "191. trans-decalin"),
+ ("N,N-dipentylpentan-1-amine", "192. N,N-dipentylpentan-1-amine"),
+ ("tricaprylin", "193. tricaprylin"),
+ ("triethyl phosphate", "194. triethyl phosphate"),
+ ("triethylene glycol", "195. triethylene glycol"),
+ ("triglyme", "196. triglyme"),
+ ("N,N-dibutylbutan-1-amine", "197. N,N-dibutylbutan-1-amine"),
+ ("N,N-dioctyloctan-1-amine", "198. N,N-dioctyloctan-1-amine"),
+ ("hexamethylphosphoramide", "199. hexamethylphosphoramide"),
+ ("dimethyl carbonate", "200. dimethyl carbonate"),
+ ("diethyl carbonate", "201. diethyl carbonate"),
+ (
+ "ethylene carbonate dimethyl carbonate 50:50",
+ "202. ethylene carbonate dimethyl carbonate 50:50",
+ ),
+ ("ethylene carbonate", "203. ethylene carbonate"),
+ ],
+ max_length=200,
+ verbose_name="Solvent (Optional)",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="solventselection",
+ name="solvent_temp",
+ field=models.CharField(
+ blank=True,
+ choices=[
+ ("water", "1. water: ~298 K - 647.09 K"),
+ ("benzene", "3. benzene: ~298 K - 562.01 K"),
+ ("cyclohexane", "4. cyclohexane: ~298 K - 553.59 K"),
+ ("octane", "6. octane: ~298 K - 568.73 K"),
+ ("decane", "10. decane: ~298 K - 617.69 K"),
+ ("dodecane", "14. dodecane: ~298 K - 658.09 K"),
+ ("ethanol", "15. ethanol: ~298 K - 514.70 K"),
+ ("heptane", "16. heptane: ~298 K - 540.12 K"),
+ ("hexane", "18. hexane: ~298 K - 507.81 K"),
+ ("nonane", "20. nonane: ~298 K - 594.54 K"),
+ ("pentane", "21. pentane: ~298 K - 469.69 K"),
+ ("toluene", "22. toluene: ~298 K - 591.74 K"),
+ ("undecane", "23. undecane: ~298 K - 638.79 K"),
+ ("methanol", "26. methanol: ~298 K - 512.49 K"),
+ ("1,2-dichloroethane", "51. 1,2-dichloroethane: ~298 K - 561.59 K"),
+ ("ethoxyethane", "52. ethoxyethane: ~298 K - 466.69 K"),
+ ("ethylbenzene", "56. ethylbenzene: ~298 K - 617.11 K"),
+ ("1,4-xylene", "87. 1,4-xylene: ~298 K - 616.16 K"),
+ ("propan-2-one", "91. propan-2-one: ~298 K - 508.09 K"),
+ ("1,3-xylene", "129. 1,3-xylene: ~298 K - 616.88 K"),
+ ("1,2-xylene", "130. 1,2-xylene: ~298 K - 630.25 K"),
+ (
+ "octamethylcyclotetrasiloxane",
+ "178. octamethylcyclotetrasiloxane: ~298 K - 586.49 K",
+ ),
+ (
+ "dimethyl carbonate",
+ "200. dimethyl carbonate: ~298 K - 556.99 K",
+ ),
+ ],
+ max_length=200,
+ verbose_name="Solvent",
+ ),
+ ),
+ ]
diff --git a/rmgweb/database/templates/kineticsTable.html b/rmgweb/database/templates/kineticsTable.html
index c5a39ad1..8681560a 100644
--- a/rmgweb/database/templates/kineticsTable.html
+++ b/rmgweb/database/templates/kineticsTable.html
@@ -78,11 +78,11 @@
var treeChildren = new Array();
{% for entry in entries %}
- {% ifequal entry.parent None %}
+ {% if entry.parent == None %}
treeParent["{{ entry.index }}"] = "";
{% else %}
treeParent["{{ entry.index }}"] = "{{ entry.parent.index }}";
- {% endifequal %}
+ {% endif %}
treeChildren["{{ entry.index }}"] = [{% for child in entry.children %}"{{ child.index }}"{% if not forloop.last %}, {% endif %}{% endfor %}];
{% endfor %}
diff --git a/rmgweb/database/templates/solvationSolubilitySearch.html b/rmgweb/database/templates/solvationSolubilitySearch.html
index 63ea0699..4ee5a9e2 100644
--- a/rmgweb/database/templates/solvationSolubilitySearch.html
+++ b/rmgweb/database/templates/solvationSolubilitySearch.html
@@ -18,13 +18,28 @@
{% block navbar_items %}
Solvation Tools
-Solid Solubility Prediction
+Solid Solubility Prediction (SolProp ML)
{% endblock %}
{% block page_title %}Solid Solubility Prediction{% endblock %}
{% block page_body %}
+
+
Note
+
+ For non-aqueous solubility prediction (i.e. solubility in organic solvents), we now recommend using fastsolv for solubility prediction.
+
+
+ For more details, see the publication:
+
- Attia, L., Burns, J. W., Doyle, P. S., & Green, W. H.
+ "Data-driven organic solubility prediction at the limit of aleatoric uncertainty." 2022.
+ Nat. Commun. 16(1), 7497.
+ Link
+
+
+
+
Use this form to get temperature-dependent solid solubility (logS in log10(mol/L)) prediction for a
solvent-solute pair of your interest. The logS is in log10 of mol solute per L solution unit.
@@ -35,7 +50,7 @@
Details on the prediction method can be found in the publication shown below. Please cite our work if you wish to use any results.
- Vermeire, F. H.; Chung, Y.; Green, W. H. Predicting Solubility Limits of Organic Solutes for a Wide Range
- of Solvents and Temperatures. 2022. J. Am. Chem. Soc. 2022, 144, 10785-10797. Link
+ of Solvents and Temperatures. 2022. J. Am. Chem. Soc. 144, 10785-10797. Link
diff --git a/rmgweb/database/templates/solvationTools.html b/rmgweb/database/templates/solvationTools.html
index b1ac777f..32b18bfa 100644
--- a/rmgweb/database/templates/solvationTools.html
+++ b/rmgweb/database/templates/solvationTools.html
@@ -41,7 +41,8 @@
Solid Solubility Prediction: get solid
solubility (logS) prediction at any temperature of interest. This tool also provides solvation free energy and
solvation enthalpy prediction at input temperature using transfer-learning machine learning models and
- sublimation enthalpy, solid heat capacity, and gas heat capacity prediction at 298 K for a solute.
+ sublimation enthalpy, solid heat capacity, and gas heat capacity prediction at 298 K for a solute.
+ Note: for non-aqueous solubility prediction, we now recommend using fastsolv (http://fastsolv.mit.edu/).
diff --git a/rmgweb/database/templates/thermoEntry.html b/rmgweb/database/templates/thermoEntry.html
index 83ba0aac..f0c71092 100644
--- a/rmgweb/database/templates/thermoEntry.html
+++ b/rmgweb/database/templates/thermoEntry.html
@@ -89,7 +89,7 @@ Structure
Thermodynamic Data
-{% ifequal thermo.0 'Link' %}
+{% if thermo.0 == 'Link' %}
| Link: |
@@ -98,7 +98,7 @@ Thermodynamic Data
{% else %}
{{ thermo|render_thermo_math:user }}
-{% endifequal %}
+{% endif %}
{% if nasa_string %}
diff --git a/rmgweb/database/tools.py b/rmgweb/database/tools.py
index 648acf07..95a817f6 100644
--- a/rmgweb/database/tools.py
+++ b/rmgweb/database/tools.py
@@ -390,7 +390,6 @@ def generateReactions(database, reactants, products=None, only_families=None, re
reactants, products, only_families=only_families, resonance=resonance)
if len(reactants) == 1:
# if only one reactant, react it with itself bimolecularly, with RMG-py
- # the java version already does this (it includes A+A reactions when you react A)
reactants2 = [reactants[0], reactants[0]]
reaction_list.extend(database.kinetics.generate_reactions(
reactants2, products, only_families=only_families, resonance=resonance))
diff --git a/rmgweb/database/views.py b/rmgweb/database/views.py
index e84dfa36..9bc4fe56 100644
--- a/rmgweb/database/views.py
+++ b/rmgweb/database/views.py
@@ -34,7 +34,6 @@
import math
import os
import re
-import shutil
import subprocess
import urllib
import pandas as pd
@@ -44,11 +43,7 @@
import rdkit.Chem.rdmolops as rdmolops
from CoolProp.CoolProp import PropsSI
from decimal import Decimal
-
-from chemprop_solvation.solvation_estimator import load_DirectML_Gsolv_estimator, load_DirectML_Hsolv_estimator, load_SoluteML_estimator
-from solvation_predictor.solubility.solubility_calculator import SolubilityCalculations
-from solvation_predictor.solubility.solubility_models import SolubilityModels
-from solvation_predictor.solubility.solubility_predictions import SolubilityPredictions
+import requests
import rmgpy
import rmgpy.constants as constants
@@ -57,7 +52,7 @@
TemplateReaction, LibraryReaction
from rmgpy.data.kinetics.depository import DepositoryReaction
from rmgpy.data.reference import Article, Book
-from rmgpy.data.solvation import SoluteData, SolventData, SolvationCorrection
+from rmgpy.data.solvation import SoluteData, SolventData
from rmgpy.data.statmech import GroupFrequencies
from rmgpy.data.thermo import find_cp0_and_cpinf
from rmgpy.data.transport import CriticalPointGroupContribution, TransportData
@@ -74,7 +69,7 @@
from rmgpy.thermo.thermoengine import process_thermo_data
from django.contrib.auth.decorators import login_required
-from django.contrib.staticfiles.templatetags.staticfiles import static
+from django.templatetags.static import static
from django.http import Http404, HttpResponseRedirect, HttpResponse, HttpResponseBadRequest
from django.shortcuts import render
from django.urls import reverse
@@ -86,6 +81,7 @@
from BeautifulSoup import BeautifulSoup
import rmgweb.settings
+from rmgweb.secretsettings import SOLPROP_URL
from rmgweb.database.forms import DivErrorList, EniSearchForm, KineticsEntryEditForm, \
KineticsSearchForm, MoleculeSearchForm, RateEvaluationForm
from rmgweb.database.tools import database, generateReactions, generateSpeciesThermo, reactionHasReactants
@@ -96,15 +92,6 @@
################################################################################
-# Loading these ML estimators takes around 10 seconds.
-# Therefore, instead of loading these each time these estimators are used, let's
-# load them in the beginning only once and use them as needed.
-global dGsolv_estimator, dHsolv_estimator, SoluteML_estimator, solub_models
-dGsolv_estimator = load_DirectML_Gsolv_estimator()
-dHsolv_estimator = load_DirectML_Hsolv_estimator()
-solub_models = SolubilityModels(reduced_number=False, load_g=True, load_h=True, load_saq=True,
- load_solute=True, logger=None, verbose=False)
-SoluteML_estimator = solub_models.solute_models
def load(request):
"""
@@ -113,13 +100,34 @@ def load(request):
database.load()
return HttpResponseRedirect(reverse('database:index'))
-
def index(request):
"""
The RMG database homepage.
"""
return render(request, 'database.html')
+def return_common_entry_data(entries, section, subsection, index, data_type):
+ """
+ A helper function that returns entry data for a species, after the relevant entries are determined.
+ """
+ index = int(index)
+ if index != 0 and index != -1:
+ for entry in entries:
+ if entry.index == index:
+ break
+ else:
+ raise Http404
+ else:
+ if index == 0:
+ index = min(entry.index for entry in entries if entry.index > 0)
+ else:
+ index = max(entry.index for entry in entries if entry.index > 0)
+ return HttpResponseRedirect(reverse(f'database:{data_type}-entry',
+ kwargs={'section': section,
+ 'subsection': subsection,
+ 'index': index,
+ }))
+ return entry
#################################################################################################################################################
@@ -199,23 +207,7 @@ def transportEntry(request, section, subsection, index):
except ValueError:
raise Http404
- index = int(index)
- if index != 0 and index != -1:
- for entry in db.entries.values():
- if entry.index == index:
- break
- else:
- raise Http404
- else:
- if index == 0:
- index = min(entry.index for entry in db.entries.values() if entry.index > 0)
- else:
- index = max(entry.index for entry in db.entries.values() if entry.index > 0)
- return HttpResponseRedirect(reverse('database:transport-entry',
- kwargs={'section': section,
- 'subsection': subsection,
- 'index': index,
- }))
+ entry = return_common_entry_data(db.entries.values(), section, subsection, index, "transport")
# Get the structure of the item we are viewing
structure = getStructureInfo(entry.item)
@@ -412,6 +404,16 @@ def solvationEntry(request, section, subsection, index):
'referenceType': reference_type, 'solvation': solvation})
+def _dGsolv_estimator(pair_smiles):
+ # helper function to call out to the running Docker container
+ result = requests.post(SOLPROP_URL + "/dGsolv_estimator", json={"solvent_smiles": pair_smiles[0][0], "solute_smiles": pair_smiles[0][1]}).json()
+ return result["avg_pred"], result["epi_unc"], result["valid_indices"]
+
+def _dHsolv_estimator(pair_smiles):
+ # helper function to call out to the running Docker container
+ result = requests.post(SOLPROP_URL + "/dHsolv_estimator", json={"solvent_smiles": pair_smiles[0][0], "solute_smiles": pair_smiles[0][1]}).json()
+ return result["avg_pred"], result["epi_unc"], result["valid_indices"]
+
def get_solvation_from_DirectML(pair_smiles, error_msg, dGsolv_required, dHsolv_required, calc_dSsolv, energy_unit):
"""
Calculate solvation free energy, enthalpy, and entropy using the DirectML model. Corresponding
@@ -433,13 +435,13 @@ def get_solvation_from_DirectML(pair_smiles, error_msg, dGsolv_required, dHsolv_
if dGsolv_required:
try:
- avg_pre, epi_unc, valid_indices = dGsolv_estimator(pair_smiles) # default is in kcal/mol
+ avg_pre, epi_unc, valid_indices = _dGsolv_estimator(pair_smiles) # default is in kcal/mol
dGsolv298, dGsolv298_epi_unc = avg_pre[0], epi_unc[0]
except:
error_msg = update_error_msg(error_msg, 'Unable to parse the SMILES', overwrite=True)
if dHsolv_required:
try:
- avg_pre, epi_unc, valid_indices = dHsolv_estimator(pair_smiles) # default is in kcal/mol
+ avg_pre, epi_unc, valid_indices = _dHsolv_estimator(pair_smiles) # default is in kcal/mol
dHsolv298, dHsolv298_epi_unc = avg_pre[0], epi_unc[0]
except:
error_msg = update_error_msg(error_msg, 'Unable to parse the SMILES', overwrite=True)
@@ -499,7 +501,7 @@ def get_solvation_data_ML(solvent_solute_smiles, calc_dGsolv, calc_dHsolv, calc_
logP = 0
else:
try:
- avg_pre, epi_unc, valid_indices = dGsolv_estimator([['O', solute_smiles]])
+ avg_pre, epi_unc, valid_indices = _dGsolv_estimator([['O', solute_smiles]])
dGsolv298_water = convert_energy_unit(avg_pre[0], 'kcal/mol', 'J/mol')
logP = -(dGsolv298 - dGsolv298_water) / (math.log(10) * constants.R * 298)
logP = clean_up_value(logP, deci_place=2, only_big=True)
@@ -670,7 +672,7 @@ def get_temp_dep_logP(solvent_smiles, solute_smiles, temp_SI, solvation_298_resu
solvation_298_results[pair_key_water] = (dGsolv298water, dHsolv298water, dSsolv298water)
if dGsolv298water is not None and dHsolv298water is not None and dSsolv298water is not None:
- dGsolv_water, Kfactor_water = db.get_T_dep_solvation_energy_from_input_298(
+ dGsolv_water, Kfactor_water, henry = db.get_T_dep_solvation_energy_from_input_298(
dGsolv298water, dHsolv298water, dSsolv298water, 'water', temp_SI)
logP = -(dGsolv - dGsolv_water) / (math.log(10) * constants.R * temp_SI)
else:
@@ -975,8 +977,12 @@ def get_solute_data_from_SoluteGC(solute_spc, db, error_msg):
else:
return None, None, error_msg
+def _SoluteML_estimator(solute_smiles):
+ # helper function to call out to the running docker container
+ result = requests.post(SOLPROP_URL + '/SoluteML_estimator', json={'solute_smiles': solute_smiles}).json()
+ return result['avg_pred'], result['epi_unc'], result['valid_indices']
-def get_solute_data_from_SoluteML(smiles, solute_spc, error_msg):
+def get_solute_data_from_SoluteML(solute_smiles, solute_spc, error_msg):
"""
Returns solute data estimated from SoluteML, corresponding comment and error message, and a dictionary
containing the epistemic uncertainty of the SoluteML prediction.
@@ -985,7 +991,7 @@ def get_solute_data_from_SoluteML(smiles, solute_spc, error_msg):
solute_data = SoluteData()
solute_comment = None
try:
- avg_pre, epi_unc, valid_indices = SoluteML_estimator([[smiles]])
+ avg_pre, epi_unc, valid_indices = _SoluteML_estimator(solute_smiles)
[solute_data.E, solute_data.S, solute_data.A, solute_data.B, solute_data.L] = (avg_pre[0][i] for i in range(5))
for i, solute_param in zip(range(5), ['E', 'S', 'A', 'B', 'L']):
solute_epi_unc_dict[f'{solute_param} epi. unc.'] = epi_unc[0][i]
@@ -997,8 +1003,10 @@ def get_solute_data_from_SoluteML(smiles, solute_spc, error_msg):
f'\tpip install git+https://github.com/bp-kelley/descriptastorus\n'
'If "descriptastorus" is already installed, please update "chemprop_solvation" with'
'version 0.0.3 or higher.')
- elif not 'Unable to parse the SMILES' in error_msg:
+ elif 'Unable to parse the SMILES' in error_msg:
error_msg = update_error_msg(error_msg, 'Unable to parse the SMILES', overwrite=False)
+ else:
+ error_msg = update_error_msg(error_msg, 'Unable to get the prediction from the SoluteML method', overwrite=False)
# get V value using RMG
if solute_spc is not None:
try:
@@ -1403,23 +1411,7 @@ def statmechEntry(request, section, subsection, index):
except ValueError:
raise Http404
- index = int(index)
- if index != 0 and index != -1:
- for entry in db.entries.values():
- if entry.index == index:
- break
- else:
- raise Http404
- else:
- if index == 0:
- index = min(entry.index for entry in db.entries.values() if entry.index > 0)
- else:
- index = max(entry.index for entry in db.entries.values() if entry.index > 0)
- return HttpResponseRedirect(reverse('database:statmech-entry',
- kwargs={'section': section,
- 'subsection': subsection,
- 'index': index,
- }))
+ entry = return_common_entry_data(db.entries.values(), section, subsection, index, "statmech")
# Get the structure of the item we are viewing
structure = getStructureInfo(entry.item)
@@ -1548,23 +1540,7 @@ def thermoEntry(request, section, subsection, index):
db = database.get_thermo_database(section, subsection)
except ValueError:
raise Http404
- index = int(index)
- if index != 0 and index != -1:
- for entry in db.entries.values():
- if entry.index == index:
- break
- else:
- raise Http404
- else:
- if index == 0:
- index = min(entry.index for entry in db.entries.values() if entry.index > 0)
- else:
- index = max(entry.index for entry in db.entries.values() if entry.index > 0)
- return HttpResponseRedirect(reverse('database:thermo-entry',
- kwargs={'section': section,
- 'subsection': subsection,
- 'index': index,
- }))
+ entry = return_common_entry_data(db.entries.values(), section, subsection, index, "thermo")
# Get the structure of the item we are viewing
structure = getStructureInfo(entry.item)
@@ -2488,49 +2464,29 @@ def kineticsEntryEdit(request, section, subsection, index):
entry_string = entry_buffer.getvalue()
entry_buffer.close()
- if False:
- # Just return the text.
- return HttpResponse(entry_string, content_type="text/plain")
- if False:
- # Render it as if it were saved.
- return render(request, 'kineticsEntry.html',
- {'section': section,
- 'subsection': subsection,
- 'databaseName': db.name,
- 'entry': new_entry,
- 'reference': entry.reference,
- 'kinetics': entry.data,
- })
- if True:
- # save it
- db.entries[index] = new_entry
- path = os.path.join(rmgweb.settings.DATABASE_PATH, 'kinetics', section, subsection + '.py')
- db.save(path)
- commit_author = "{0.first_name} {0.last_name} <{0.email}>".format(request.user)
- commit_message = "{1}:{2} {3}\n\nChange to kinetics/{0}/{1} entry {2} submitted through RMG website:\n{3}\n{4}".format(section, subsection, index, form.cleaned_data['change'], commit_author)
- commit_result = subprocess.check_output(['git', 'commit', '-m', commit_message, '--author',
- commit_author, path],
- cwd=rmgweb.settings.DATABASE_PATH, stderr=subprocess.STDOUT)
- subprocess.check_output(['git', 'push'], cwd=rmgweb.settings.DATABASE_PATH, stderr=subprocess.STDOUT)
-
- # return HttpResponse(commit_result, content_type="text/plain")
-
- kwargs = {'section': section,
- 'subsection': subsection,
- 'index': index}
- forward_url = reverse('database:kinetics-entry', kwargs=kwargs)
- message = """
- Changes saved succesfully:
- {0}
- See result at {1}.
- """.format(commit_result, forward_url)
- return render(request, 'simple.html',
- {'title': 'Change saved successfully.',
- 'body': message,
- })
+ db.entries[index] = new_entry
+ path = os.path.join(rmgweb.settings.DATABASE_PATH, 'kinetics', section, subsection + '.py')
+ db.save(path)
+ commit_author = "{0.first_name} {0.last_name} <{0.email}>".format(request.user)
+ commit_message = "{1}:{2} {3}\n\nChange to kinetics/{0}/{1} entry {2} submitted through RMG website:\n{3}\n{4}".format(section, subsection, index, form.cleaned_data['change'], commit_author)
+ commit_result = subprocess.check_output(['git', 'commit', '-m', commit_message, '--author',
+ commit_author, path],
+ cwd=rmgweb.settings.DATABASE_PATH, stderr=subprocess.STDOUT)
+ subprocess.check_output(['git', 'push'], cwd=rmgweb.settings.DATABASE_PATH, stderr=subprocess.STDOUT)
- # redirect
- return HttpResponseRedirect(forward_url)
+ kwargs = {'section': section,
+ 'subsection': subsection,
+ 'index': index}
+ forward_url = reverse('database:kinetics-entry', kwargs=kwargs)
+ message = """
+ Changes saved succesfully:
+ {0}
+ See result at {1}.
+ """.format(commit_result, forward_url)
+ return render(request, 'simple.html',
+ {'title': 'Change saved successfully.',
+ 'body': message,
+ })
else: # not POST
# Get the entry as a entry_string
@@ -2615,31 +2571,27 @@ def thermoEntryNew(request, section, subsection, adjlist):
}
forward_url = reverse('database:thermo-entry', kwargs=kwargs)
- if False:
- # Just return the text.
- return HttpResponse(entry_string, content_type="text/plain")
- if True:
- # save it
- db.entries[index] = new_entry
- path = os.path.join(rmgweb.settings.DATABASE_PATH, 'thermo', section, subsection + '.py')
- db.save(path)
- commit_author = '{0.first_name} {0.last_name} <{0.email}>'.format(request.user)
- commit_message = 'New Entry: {section}/{subsection}/{index}\n\n{msg}'.format(section=section,
- subsection=subsection,
- index=new_entry.index,
- msg=msg)
- commit_message += '\n\nSubmitted through the RMG website.'
- commit_result = subprocess.check_output(['git', 'commit', '-m', commit_message,
- '--author', commit_author, path],
- cwd=rmgweb.settings.DATABASE_PATH, stderr=subprocess.STDOUT)
- subprocess.check_output(['git', 'push'], cwd=rmgweb.settings.DATABASE_PATH, stderr=subprocess.STDOUT)
- message = """
- New entry saved succesfully:
- {0}
- See result at {1}.
- """.format(commit_result, forward_url)
- return render(request, 'simple.html',
- {'title': '', 'body': message})
+ # save it
+ db.entries[index] = new_entry
+ path = os.path.join(rmgweb.settings.DATABASE_PATH, 'thermo', section, subsection + '.py')
+ db.save(path)
+ commit_author = '{0.first_name} {0.last_name} <{0.email}>'.format(request.user)
+ commit_message = 'New Entry: {section}/{subsection}/{index}\n\n{msg}'.format(section=section,
+ subsection=subsection,
+ index=new_entry.index,
+ msg=msg)
+ commit_message += '\n\nSubmitted through the RMG website.'
+ commit_result = subprocess.check_output(['git', 'commit', '-m', commit_message,
+ '--author', commit_author, path],
+ cwd=rmgweb.settings.DATABASE_PATH, stderr=subprocess.STDOUT)
+ subprocess.check_output(['git', 'push'], cwd=rmgweb.settings.DATABASE_PATH, stderr=subprocess.STDOUT)
+ message = """
+ New entry saved succesfully:
+ {0}
+ See result at {1}.
+ """.format(commit_result, forward_url)
+ return render(request, 'simple.html',
+ {'title': '', 'body': message})
else: # not POST
entry_string = """
label = "{label}",
@@ -2713,49 +2665,32 @@ def thermoEntryEdit(request, section, subsection, index):
entry_string = entry_buffer.getvalue()
entry_buffer.close()
- if False:
- # Just return the text.
- return HttpResponse(entry_string, content_type="text/plain")
- if False:
- # Render it as if it were saved.
- return render(request, 'thermoEntry.html',
- {'section': section,
- 'subsection': subsection,
- 'databaseName': db.name,
- 'entry': new_entry,
- 'reference': entry.reference,
- 'kinetics': entry.data,
- })
- if True:
- # save it
- db.entries[index] = new_entry
- path = os.path.join(rmgweb.settings.DATABASE_PATH, 'thermo', section, subsection + '.py')
- db.save(path)
- commit_author = "{0.first_name} {0.last_name} <{0.email}>".format(request.user)
- commit_message = "{1}:{2} {3}\n\nChange to thermo/{0}/{1} entry {2} submitted through RMG website:\n{3}\n{4}".format(section, subsection, index, form.cleaned_data['change'], commit_author)
- commit_result = subprocess.check_output(['git', 'commit', '-m', commit_message,
- '--author', commit_author, path],
- cwd=rmgweb.settings.DATABASE_PATH, stderr=subprocess.STDOUT)
- subprocess.check_output(['git', 'push'], cwd=rmgweb.settings.DATABASE_PATH, stderr=subprocess.STDOUT)
-
- # return HttpResponse(commit_result, content_type="text/plain")
+ # save it
+ db.entries[index] = new_entry
+ path = os.path.join(rmgweb.settings.DATABASE_PATH, 'thermo', section, subsection + '.py')
+ db.save(path)
+ commit_author = "{0.first_name} {0.last_name} <{0.email}>".format(request.user)
+ commit_message = "{1}:{2} {3}\n\nChange to thermo/{0}/{1} entry {2} submitted through RMG website:\n{3}\n{4}".format(section, subsection, index, form.cleaned_data['change'], commit_author)
+ commit_result = subprocess.check_output(['git', 'commit', '-m', commit_message,
+ '--author', commit_author, path],
+ cwd=rmgweb.settings.DATABASE_PATH, stderr=subprocess.STDOUT)
+ subprocess.check_output(['git', 'push'], cwd=rmgweb.settings.DATABASE_PATH, stderr=subprocess.STDOUT)
- kwargs = {'section': section,
- 'subsection': subsection,
- 'index': index}
- forward_url = reverse('database:thermo-entry', kwargs=kwargs)
- message = """
- Changes saved succesfully:
- {0}
- See result at {1}.
- """.format(commit_result, forward_url)
- return render(request, 'simple.html',
- {'title': 'Change saved successfully.',
- 'body': message,
- })
+ # return HttpResponse(commit_result, content_type="text/plain")
- # redirect
- return HttpResponseRedirect(forward_url)
+ kwargs = {'section': section,
+ 'subsection': subsection,
+ 'index': index}
+ forward_url = reverse('database:thermo-entry', kwargs=kwargs)
+ message = """
+ Changes saved succesfully:
+ {0}
+ See result at {1}.
+ """.format(commit_result, forward_url)
+ return render(request, 'simple.html',
+ {'title': 'Change saved successfully.',
+ 'body': message,
+ })
else: # not POST
# Get the entry as a entry_string
@@ -2784,8 +2719,7 @@ def thermoEntryEdit(request, section, subsection, index):
'entry': entry,
'form': form,
})
-
-
+
def kineticsEntry(request, section, subsection, index):
"""
A view for showing an entry in a kinetics database.
@@ -2805,23 +2739,7 @@ def kineticsEntry(request, section, subsection, index):
# if the entries are lists
entries = reduce(lambda x, y: x + y, entries)
- index = int(index)
- if index != 0 and index != -1:
- for entry in entries:
- if entry.index == index:
- break
- else:
- raise Http404
- else:
- if index == 0:
- index = min(entry.index for entry in entries if entry.index > 0)
- else:
- index = max(entry.index for entry in entries if entry.index > 0)
- return HttpResponseRedirect(reverse('database:kinetics-entry',
- kwargs={'section': section,
- 'subsection': subsection,
- 'index': index,
- }))
+ entry = return_common_entry_data(entries, section, subsection, index, "kinetics")
reference = entry.reference
reference_type = ''
@@ -3725,6 +3643,17 @@ def solvationSolubilityData(request, solvent_str, solute_str, temp_str, ref_solv
{'html_table': html_table},
)
+def _calc_solubility_with_ref(solvent_smiles=None, solute_smiles=None, temp=None, ref_solvent_smiles=None,
+ ref_solubility298=None, hsub298=None, cp_gas_298=None
+ , cp_solid_298=None):
+ res = requests.post(SOLPROP_URL + "/calc_solubility_with_ref", json={"solvent_smiles": solvent_smiles, "solute_smiles": solute_smiles, "temperature": temp, "reference_solvent": ref_solvent_smiles, "reference_solubility": ref_solubility298, "hsub298": hsub298, "cp_gas_298": cp_gas_298, "cp_solid_298": cp_solid_298}).json()
+ return res["logsT_method1"], res["logsT_method2"], res["gsolv_T"], res["hsolv_T"], res["ssolv_T"], res["hsubl_298"], res["Cp_gas"], res["Cp_solid"], res["logs_T_with_T_dep_hdiss_error_message"]
+
+def _calc_solubility_no_ref(solvent_smiles=None, solute_smiles=None, temp=None, hsub298=None, cp_gas_298=None,
+ cp_solid_298=None):
+ res = requests.post(SOLPROP_URL + "/calc_solubility_no_ref", json={"solvent_smiles": solvent_smiles, "solute_smiles": solute_smiles, "temperature": temp, "hsub298": hsub298, "cp_gas_298": cp_gas_298, "cp_solid_298": cp_solid_298}).json()
+ return res["logsT_method1"], res["logsT_method2"], res["gsolv_T"], res["hsolv_T"], res["ssolv_T"], res["hsubl_298"], res["Cp_gas"], res["Cp_solid"], res["logs_T_with_T_dep_hdiss_error_message"]
+
def get_solubility_pred(solvent_smiles, solute_smiles, temp, ref_solvent_smiles, ref_solubility, ref_temp, hsub298,
cp_gas_298, cp_solid_298):
@@ -3733,107 +3662,47 @@ def get_solubility_pred(solvent_smiles, solute_smiles, temp, ref_solvent_smiles,
"""
# Case 1: reference values are not provided
if ref_solvent_smiles is None:
- calculations = calc_solubility_no_ref(solvent_smiles=solvent_smiles, solute_smiles=solute_smiles, temp=temp,
+ logST_method1, logST_method2, dGsolvT, dHsolvT, dSsolvT, hsubl_298, Cp_gas, Cp_solid, T_dep_hdiss_error_mesg = _calc_solubility_no_ref(solvent_smiles=solvent_smiles, solute_smiles=solute_smiles, temp=temp,
hsub298=hsub298, cp_gas_298=cp_gas_298, cp_solid_298=cp_solid_298)
- # Extract the solubility prediction results using from_aq keys
- logST_method1 = calculations.logs_T_with_const_hdiss_from_aq[0]
- logST_method2 = calculations.logs_T_with_T_dep_hdiss_from_aq[0]
# Case 2: reference values are provided
else:
- calculations_ref = calc_solubility_no_ref(solvent_smiles=ref_solvent_smiles, solute_smiles=solute_smiles,
+ logST_method1, logST_method2, dGsolvT, dHsolvT, dSsolvT, hsubl_298, Cp_gas, Cp_solid, T_dep_hdiss_error_mesg = _calc_solubility_no_ref(solvent_smiles=ref_solvent_smiles, solute_smiles=solute_smiles,
temp=ref_temp, hsub298=hsub298, cp_gas_298=cp_gas_298,
cp_solid_298=cp_solid_298)
- ref_solubility298 = get_ref_solubility298(calculations_ref=calculations_ref, ref_solubility=ref_solubility)
- calculations = calc_solubility_with_ref(solvent_smiles=solvent_smiles, solute_smiles=solute_smiles, temp=temp,
+ ref_solubility298 = get_ref_solubility298(logs_T_with_T_dep_hdiss_from_aq=logST_method2, logs_T_with_const_hdiss_from_aq=logST_method1, logs_298_from_aq=ref_solubility, ref_solubility=ref_solubility)
+ logST_method1, logST_method2, dGsolvT, dHsolvT, dSsolvT, hsubl_298, Cp_gas, Cp_solid, T_dep_hdiss_error_mesg = _calc_solubility_with_ref(solvent_smiles=solvent_smiles, solute_smiles=solute_smiles, temp=temp,
ref_solvent_smiles=ref_solvent_smiles,
ref_solubility298=ref_solubility298,
hsub298=hsub298, cp_gas_298=cp_gas_298, cp_solid_298=cp_solid_298)
- # Extract the solubility prediction results using from_ref keys
- logST_method1 = calculations.logs_T_with_const_hdiss_from_ref[0]
- logST_method2 = calculations.logs_T_with_T_dep_hdiss_from_ref[0]
# Extract other results
- dGsolvT, dHsolvT, dSsolvT = calculations.gsolv_T[0], calculations.hsolv_T[0], calculations.ssolv_T[0] # in kcal/mol
if dSsolvT is not None:
dSsolvT = dSsolvT * 1000 # convert to cal/mol/K
- Hsub298_pred = calculations.hsubl_298[0] if hsub298 is None else None # in kcal/mol
- Cpg298_pred = calculations.Cp_gas[0] if cp_gas_298 is None else None # in cal/mol/K
- Cps298_pred = calculations.Cp_solid[0] if cp_solid_298 is None else None # in cal/mol/K
- T_dep_hdiss_error_mesg = calculations.logs_T_with_T_dep_hdiss_error_message[0]
+ Hsub298_pred = hsubl_298 if hsub298 is None else None # in kcal/mol
+ Cpg298_pred = Cp_gas if cp_gas_298 is None else None # in cal/mol/K
+ Cps298_pred = Cp_solid if cp_solid_298 is None else None # in cal/mol/K
calc_error_msg, warning_msg = format_T_dep_hdiss_error_mesg(T_dep_hdiss_error_mesg)
pred_val_list = [logST_method1, logST_method2, dGsolvT, dHsolvT, dSsolvT, Hsub298_pred, Cpg298_pred, Cps298_pred]
return pred_val_list, calc_error_msg, warning_msg
-def calc_solubility_no_ref(solvent_smiles=None, solute_smiles=None, temp=None, hsub298=None, cp_gas_298=None,
- cp_solid_298=None):
- """
- Calculate solubility with no reference solvent and reference solubility
- """
- hsubl_298 = np.array([hsub298]) if hsub298 is not None else None
- Cp_solid = np.array([cp_solid_298]) if cp_solid_298 is not None else None
- Cp_gas = np.array([cp_gas_298]) if cp_gas_298 is not None else None
-
- solub_data = SolubilityData(solvent_smiles=solvent_smiles, solute_smiles=solute_smiles, temp=temp)
- predictions = SolubilityPredictions(solub_data, solub_models, predict_aqueous=True,
- predict_reference_solvents=False, predict_t_dep=True,
- predict_solute_parameters=True, verbose=False)
- calculations = SolubilityCalculations(predictions, calculate_aqueous=True,
- calculate_reference_solvents=False, calculate_t_dep=True,
- calculate_t_dep_with_t_dep_hdiss=True, verbose=False,
- hsubl_298=hsubl_298, Cp_solid=Cp_solid, Cp_gas=Cp_gas)
- return calculations
-
-
-def calc_solubility_with_ref(solvent_smiles=None, solute_smiles=None, temp=None, ref_solvent_smiles=None,
- ref_solubility298=None, hsub298=None, cp_gas_298=None, cp_solid_298=None):
- """
- Calculate solubility with a reference solvent and reference solubility
- """
- hsubl_298 = np.array([hsub298]) if hsub298 is not None else None
- Cp_solid = np.array([cp_solid_298]) if cp_solid_298 is not None else None
- Cp_gas = np.array([cp_gas_298]) if cp_gas_298 is not None else None
-
- solub_data = SolubilityData(solvent_smiles=solvent_smiles, solute_smiles=solute_smiles, temp=temp,
- ref_solub=ref_solubility298, ref_solv=ref_solvent_smiles)
- predictions = SolubilityPredictions(solub_data, solub_models, predict_aqueous=False,
- predict_reference_solvents=True, predict_t_dep=True,
- predict_solute_parameters=True, verbose=False)
- calculations = SolubilityCalculations(predictions, calculate_aqueous=False,
- calculate_reference_solvents=True, calculate_t_dep=True,
- calculate_t_dep_with_t_dep_hdiss=True, verbose=False,
- hsubl_298=hsubl_298, Cp_solid=Cp_solid, Cp_gas=Cp_gas)
- return calculations
-
-
-def get_ref_solubility298(calculations_ref=None, ref_solubility=None):
+def get_ref_solubility298(logs_T_with_T_dep_hdiss_from_aq, logs_T_with_const_hdiss_from_aq, logs_298_from_aq, ref_solubility=None):
"""
Estimate the reference solubility at 298 K based on the reference solvent calculation results and input
reference solubility value at reference temperature.
"""
# Use the prediction from method 2 if available. If not, use the prediction from method 1 as the ref value
- logST_ref_pred = calculations_ref.logs_T_with_T_dep_hdiss_from_aq[0]
+ logST_ref_pred = logs_T_with_T_dep_hdiss_from_aq
if logST_ref_pred is None:
- logST_ref_pred = calculations_ref.logs_T_with_const_hdiss_from_aq[0]
+ logST_ref_pred = logs_T_with_const_hdiss_from_aq
# Get ref_solubility value at 298 K from ref_solubility at T
- logS298_ref_from_aq = calculations_ref.logs_298_from_aq[0]
+ logS298_ref_from_aq = logs_298_from_aq
logS_diff = logST_ref_pred - logS298_ref_from_aq
ref_solubility298 = ref_solubility - logS_diff
return ref_solubility298
-class SolubilityData:
- """
- Class for storing the input data for solubility prediction
- """
- def __init__(self, solvent_smiles=None, solute_smiles=None, temp=None, ref_solub=None, ref_solv=None):
- self.smiles_pairs = [(solvent_smiles, solute_smiles)]
- self.temperatures = np.array([temp]) if temp is not None else None
- self.reference_solubility = np.array([ref_solub]) if ref_solub is not None else None
- self.reference_solvents = np.array([ref_solv]) if ref_solv is not None else None
-
-
def format_T_dep_hdiss_error_mesg(error_msg):
"""
Turn the error_msg for the T-dep Hdiss prediction into appropriate error and warning messages
@@ -4058,7 +3927,8 @@ def json_to_adjlist(request):
Interprets ChemDoodle JSON and returns an RMG adjacency list.
"""
adjlist = ''
- if request.is_ajax() and request.method == 'POST':
+ is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
+ if is_ajax and request.method == 'POST':
cd_json_str = request.POST.get('data')
cd_json = json.loads(cd_json_str)
diff --git a/rmgweb/main/migrations/0002_alter_userprofile_id.py b/rmgweb/main/migrations/0002_alter_userprofile_id.py
new file mode 100644
index 00000000..59e406c3
--- /dev/null
+++ b/rmgweb/main/migrations/0002_alter_userprofile_id.py
@@ -0,0 +1,20 @@
+# Generated by Django 4.2.23 on 2025-07-03 15:10
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("main", "0001_initial"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="userprofile",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ ]
diff --git a/rmgweb/main/templatetags/render_solvation.py b/rmgweb/main/templatetags/render_solvation.py
index 9e003955..e8a51b80 100644
--- a/rmgweb/main/templatetags/render_solvation.py
+++ b/rmgweb/main/templatetags/render_solvation.py
@@ -37,7 +37,7 @@
from rmgpy.data.base import Entry
from rmgpy.species import Species
from rmgpy.molecule.group import Group
-from rmgpy.data.solvation import *
+from rmgpy.data.solvation import SoluteData, SolventData, SolvationCorrection
# Register this module as a Django template tag library
register = template.Library()
diff --git a/rmgweb/main/views.py b/rmgweb/main/views.py
index 2db81f41..6f5e2398 100644
--- a/rmgweb/main/views.py
+++ b/rmgweb/main/views.py
@@ -44,6 +44,9 @@
from django.urls import reverse
from django.views.decorators.csrf import csrf_exempt
+from rmgpy.molecule.group import Group
+from rmgpy.molecule.adjlist import InvalidAdjacencyListError
+
from rmgpy.molecule.atomtype import allElements as SUPPORTED_ELEMENTS
from rmgweb.main.forms import *
@@ -68,6 +71,10 @@
elif len(element) == 2:
SUPPORTED_ELEMENTS_TWO_LETTERS.append(element)
+# add conda environment bin to PATH. Added on 3 July 2025 to ensure graphviz is added to path, even if bashrc is not sourced.
+bin = os.path.join(os.environ.get("CONDA_PREFIX", ""), "bin")
+if bin and bin not in os.environ["PATH"]:
+ os.environ["PATH"] = bin + os.pathsep + os.environ["PATH"]
def index(request):
"""
@@ -354,30 +361,28 @@ def drawGroup(request, adjlist, format='png'):
Returns an image of the provided adjacency list `adjlist` for a molecular
group. urllib is used to quote/unquote the adjacency list.
"""
- from rmgpy.molecule.group import Group
- from rmgpy.molecule.adjlist import InvalidAdjacencyListError
adjlist = urllib.parse.unquote(adjlist)
- # try:
- # group = Group().from_adjacency_list(adjlist)
- # except (InvalidAdjacencyListError, ValueError):
- # response = HttpResponseRedirect(static('img/invalid_icon.png'))
- # else:
- # if format == 'png':
- # response = HttpResponse(content_type="image/png")
- # response.write(group.draw('png'))
- # elif format == 'svg':
- # response = HttpResponse(content_type="image/svg+xml")
- # svg_data = group.draw('svg')
- # # Remove the scale and rotate transformations applied by pydot
- # svg_data = re.sub(r'scale\(0\.722222 0\.722222\) rotate\(0\) ', '', svg_data)
- # response.write(svg_data)
- # else:
- # response = HttpResponse('Image format not implemented.', status=501)
-
- # return response
- return HttpResponse(content_type="image/png") # TODO: fix root cause. Added 3/31/25 as a stopgap to prevent 'neato not found' errors.
+ try:
+ group = Group().from_adjacency_list(adjlist)
+ except (InvalidAdjacencyListError, ValueError):
+ response = HttpResponseRedirect(static('img/invalid_icon.png'))
+ else:
+ if format == 'png':
+ response = HttpResponse(content_type="image/png")
+ response.write(group.draw('png'))
+ elif format == 'svg':
+ response = HttpResponse(content_type="image/svg+xml")
+ svg_data = group.draw('svg')
+ # Remove the scale and rotate transformations applied by pydot
+ svg_data = re.sub(r'scale\(0\.722222 0\.722222\) rotate\(0\) ', '', svg_data)
+ response.write(svg_data)
+ else:
+ response = HttpResponse('Image format not implemented.', status=501)
+
+ return response
+# return HttpResponse(content_type="image/svg+xml")
@login_required
diff --git a/rmgweb/pdep/models.py b/rmgweb/pdep/models.py
index a95f138c..8b2fb738 100644
--- a/rmgweb/pdep/models.py
+++ b/rmgweb/pdep/models.py
@@ -72,7 +72,8 @@ def getDirname(self):
Return the absolute path of the directory that the Network object uses
to store files.
"""
- return os.path.join(settings.MEDIA_ROOT, 'pdep', 'networks', str(self.pk))
+ pk_str = self.pk.decode() if isinstance(self.pk, bytes) else str(self.pk)
+ return os.path.join(settings.MEDIA_ROOT, 'pdep', 'networks', pk_str)
def getInputFilename(self):
"""
diff --git a/rmgweb/rmg/migrations/0011_delete_adjlistconversion_remove_fluxdiagram_java_and_more.py b/rmgweb/rmg/migrations/0011_delete_adjlistconversion_remove_fluxdiagram_java_and_more.py
new file mode 100644
index 00000000..ccae0c2e
--- /dev/null
+++ b/rmgweb/rmg/migrations/0011_delete_adjlistconversion_remove_fluxdiagram_java_and_more.py
@@ -0,0 +1,603 @@
+# Generated by Django 4.2.23 on 2025-07-03 15:10
+
+from django.db import migrations, models
+import rmgweb.rmg.models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("rmg", "0010_auto_20220208_2307"),
+ ]
+
+ operations = [
+ migrations.DeleteModel(
+ name="AdjlistConversion",
+ ),
+ migrations.RemoveField(
+ model_name="fluxdiagram",
+ name="java",
+ ),
+ migrations.AlterField(
+ model_name="chemkin",
+ name="chem_file",
+ field=models.FileField(
+ blank=True,
+ null=True,
+ upload_to=rmgweb.rmg.models.uploadTo("chemkin/chem.inp"),
+ verbose_name="Chemkin File",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="chemkin",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="diff",
+ name="chem_file1",
+ field=models.FileField(
+ blank=True,
+ null=True,
+ upload_to=rmgweb.rmg.models.uploadTo("chem1.inp"),
+ verbose_name="Model 1: Chemkin File",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="diff",
+ name="chem_file2",
+ field=models.FileField(
+ blank=True,
+ null=True,
+ upload_to=rmgweb.rmg.models.uploadTo("chem2.inp"),
+ verbose_name="Model 2: Chemkin File",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="diff",
+ name="dict_file1",
+ field=models.FileField(
+ blank=True,
+ null=True,
+ upload_to=rmgweb.rmg.models.uploadTo("RMG_Dictionary1.txt"),
+ verbose_name="Model 1: RMG Dictionary",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="diff",
+ name="dict_file2",
+ field=models.FileField(
+ blank=True,
+ null=True,
+ upload_to=rmgweb.rmg.models.uploadTo("RMG_Dictionary2.txt"),
+ verbose_name="Model 2: RMG Dictionary",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="diff",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="fluxdiagram",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="input",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="populatereactions",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="reactionlibrary",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="reactionlibrary",
+ name="reaction_lib",
+ field=models.CharField(
+ blank=True,
+ choices=[
+ ("1989_Stewart_2CH3_to_C2H5_H", "1989_Stewart_2CH3_to_C2H5_H"),
+ ("2-BTP/full", "2-BTP/full"),
+ ("2-BTP/seed", "2-BTP/seed"),
+ (
+ "2001_Tokmakov_H_Toluene_to_CH3_Benzene",
+ "2001_Tokmakov_H_Toluene_to_CH3_Benzene",
+ ),
+ (
+ "2003_Miller_Propargyl_Recomb_High_P",
+ "2003_Miller_Propargyl_Recomb_High_P",
+ ),
+ ("2005_Senosiain_OH_C2H2", "2005_Senosiain_OH_C2H2"),
+ ("2006_Joshi_OH_CO", "2006_Joshi_OH_CO"),
+ ("2009_Sharma_C5H5_CH3_highP", "2009_Sharma_C5H5_CH3_highP"),
+ ("2015_Buras_C2H3_C4H6_highP", "2015_Buras_C2H3_C4H6_highP"),
+ (
+ "Aromatics_high_pressure/C10H10_1",
+ "Aromatics_high_pressure/C10H10_1",
+ ),
+ (
+ "Aromatics_high_pressure/C10H10_2",
+ "Aromatics_high_pressure/C10H10_2",
+ ),
+ (
+ "Aromatics_high_pressure/C10H10_H_abstraction",
+ "Aromatics_high_pressure/C10H10_H_abstraction",
+ ),
+ (
+ "Aromatics_high_pressure/C10H11_1",
+ "Aromatics_high_pressure/C10H11_1",
+ ),
+ (
+ "Aromatics_high_pressure/C10H11_2",
+ "Aromatics_high_pressure/C10H11_2",
+ ),
+ (
+ "Aromatics_high_pressure/C10H11_3",
+ "Aromatics_high_pressure/C10H11_3",
+ ),
+ (
+ "Aromatics_high_pressure/C10H11_4",
+ "Aromatics_high_pressure/C10H11_4",
+ ),
+ ("Aromatics_high_pressure/C10H7", "Aromatics_high_pressure/C10H7"),
+ (
+ "Aromatics_high_pressure/C10H8_H_abstraction_H_recomb",
+ "Aromatics_high_pressure/C10H8_H_abstraction_H_recomb",
+ ),
+ (
+ "Aromatics_high_pressure/C10H9_1",
+ "Aromatics_high_pressure/C10H9_1",
+ ),
+ (
+ "Aromatics_high_pressure/C10H9_2",
+ "Aromatics_high_pressure/C10H9_2",
+ ),
+ (
+ "Aromatics_high_pressure/C10H9_3",
+ "Aromatics_high_pressure/C10H9_3",
+ ),
+ (
+ "Aromatics_high_pressure/C10H9_4",
+ "Aromatics_high_pressure/C10H9_4",
+ ),
+ (
+ "Aromatics_high_pressure/C12H10_1",
+ "Aromatics_high_pressure/C12H10_1",
+ ),
+ (
+ "Aromatics_high_pressure/C12H10_2",
+ "Aromatics_high_pressure/C12H10_2",
+ ),
+ (
+ "Aromatics_high_pressure/C12H10_H_abstraction",
+ "Aromatics_high_pressure/C12H10_H_abstraction",
+ ),
+ (
+ "Aromatics_high_pressure/C12H11",
+ "Aromatics_high_pressure/C12H11",
+ ),
+ (
+ "Aromatics_high_pressure/C12H8_H_abstraction",
+ "Aromatics_high_pressure/C12H8_H_abstraction",
+ ),
+ ("Aromatics_high_pressure/C12H9", "Aromatics_high_pressure/C12H9"),
+ (
+ "Aromatics_high_pressure/C14H10_H_abstraction_H_recomb",
+ "Aromatics_high_pressure/C14H10_H_abstraction_H_recomb",
+ ),
+ (
+ "Aromatics_high_pressure/C14H11_1",
+ "Aromatics_high_pressure/C14H11_1",
+ ),
+ (
+ "Aromatics_high_pressure/C14H11_2",
+ "Aromatics_high_pressure/C14H11_2",
+ ),
+ (
+ "Aromatics_high_pressure/C14H11_3",
+ "Aromatics_high_pressure/C14H11_3",
+ ),
+ (
+ "Aromatics_high_pressure/C14H11_4",
+ "Aromatics_high_pressure/C14H11_4",
+ ),
+ ("Aromatics_high_pressure/C14H9", "Aromatics_high_pressure/C14H9"),
+ (
+ "Aromatics_high_pressure/C16H11",
+ "Aromatics_high_pressure/C16H11",
+ ),
+ ("Aromatics_high_pressure/C7H8", "Aromatics_high_pressure/C7H8"),
+ (
+ "Aromatics_high_pressure/C7H8_H_abstraction",
+ "Aromatics_high_pressure/C7H8_H_abstraction",
+ ),
+ ("Aromatics_high_pressure/C7H9", "Aromatics_high_pressure/C7H9"),
+ (
+ "Aromatics_high_pressure/C8H6_H_abstraction",
+ "Aromatics_high_pressure/C8H6_H_abstraction",
+ ),
+ ("Aromatics_high_pressure/C8H7", "Aromatics_high_pressure/C8H7"),
+ (
+ "Aromatics_high_pressure/C8H8_H_abstraction",
+ "Aromatics_high_pressure/C8H8_H_abstraction",
+ ),
+ ("Aromatics_high_pressure/C8H9", "Aromatics_high_pressure/C8H9"),
+ (
+ "Aromatics_high_pressure/C9H10_H_abstraction",
+ "Aromatics_high_pressure/C9H10_H_abstraction",
+ ),
+ ("Aromatics_high_pressure/C9H11", "Aromatics_high_pressure/C9H11"),
+ ("Aromatics_high_pressure/C9H7", "Aromatics_high_pressure/C9H7"),
+ (
+ "Aromatics_high_pressure/C9H8_1",
+ "Aromatics_high_pressure/C9H8_1",
+ ),
+ (
+ "Aromatics_high_pressure/C9H8_2",
+ "Aromatics_high_pressure/C9H8_2",
+ ),
+ (
+ "Aromatics_high_pressure/C9H8_H_abstraction",
+ "Aromatics_high_pressure/C9H8_H_abstraction",
+ ),
+ (
+ "Aromatics_high_pressure/C9H9_1",
+ "Aromatics_high_pressure/C9H9_1",
+ ),
+ (
+ "Aromatics_high_pressure/C9H9_2",
+ "Aromatics_high_pressure/C9H9_2",
+ ),
+ ("BurkeH2O2inArHe", "BurkeH2O2inArHe"),
+ ("BurkeH2O2inN2", "BurkeH2O2inN2"),
+ ("Butadiene_Dimerization", "Butadiene_Dimerization"),
+ ("C10H11", "C10H11"),
+ ("C12H11_pdep", "C12H11_pdep"),
+ ("C2H2_init", "C2H2_init"),
+ ("C2H4+O_Klipp2017", "C2H4+O_Klipp2017"),
+ ("C3", "C3"),
+ ("C6H5_C4H4_Mebel", "C6H5_C4H4_Mebel"),
+ ("CF2BrCl", "CF2BrCl"),
+ ("CH3Cl", "CH3Cl"),
+ ("Chernov", "Chernov"),
+ ("Chung_solvation_corrections", "Chung_solvation_corrections"),
+ ("CurranPentane", "CurranPentane"),
+ ("DMSOxy", "DMSOxy"),
+ ("DTU_mech_CH3Cl", "DTU_mech_CH3Cl"),
+ ("Dooley/C1", "Dooley/C1"),
+ ("Dooley/methylformate", "Dooley/methylformate"),
+ ("Dooley/methylformate_2", "Dooley/methylformate_2"),
+ (
+ "Dooley/methylformate_all_ARHEbathgas",
+ "Dooley/methylformate_all_ARHEbathgas",
+ ),
+ (
+ "Dooley/methylformate_all_N2bathgas",
+ "Dooley/methylformate_all_N2bathgas",
+ ),
+ ("ERC-FoundationFuelv0.9", "ERC-FoundationFuelv0.9"),
+ ("Ethylamine", "Ethylamine"),
+ ("FFCM1(-)", "FFCM1(-)"),
+ (
+ "First_to_Second_Aromatic_Ring/2005_Ismail_C6H5_C4H6_highP",
+ "First_to_Second_Aromatic_Ring/2005_Ismail_C6H5_C4H6_highP",
+ ),
+ (
+ "First_to_Second_Aromatic_Ring/2012_Matsugi_C3H3_C7H7_highP",
+ "First_to_Second_Aromatic_Ring/2012_Matsugi_C3H3_C7H7_highP",
+ ),
+ (
+ "First_to_Second_Aromatic_Ring/2016_Mebel_C10H9_highP",
+ "First_to_Second_Aromatic_Ring/2016_Mebel_C10H9_highP",
+ ),
+ (
+ "First_to_Second_Aromatic_Ring/2016_Mebel_C9H9_highP",
+ "First_to_Second_Aromatic_Ring/2016_Mebel_C9H9_highP",
+ ),
+ (
+ "First_to_Second_Aromatic_Ring/2016_Mebel_Indene_CH3_highP",
+ "First_to_Second_Aromatic_Ring/2016_Mebel_Indene_CH3_highP",
+ ),
+ (
+ "First_to_Second_Aromatic_Ring/2017_Buras_C6H5_C3H6_highP",
+ "First_to_Second_Aromatic_Ring/2017_Buras_C6H5_C3H6_highP",
+ ),
+ (
+ "First_to_Second_Aromatic_Ring/2017_Mebel_C6H4C2H_C2H2_highP",
+ "First_to_Second_Aromatic_Ring/2017_Mebel_C6H4C2H_C2H2_highP",
+ ),
+ (
+ "First_to_Second_Aromatic_Ring/2017_Mebel_C6H5C2H2_C2H2_highP",
+ "First_to_Second_Aromatic_Ring/2017_Mebel_C6H5C2H2_C2H2_highP",
+ ),
+ (
+ "First_to_Second_Aromatic_Ring/2017_Mebel_C6H5_C2H2_highP",
+ "First_to_Second_Aromatic_Ring/2017_Mebel_C6H5_C2H2_highP",
+ ),
+ (
+ "First_to_Second_Aromatic_Ring/2017_Mebel_C6H5_C4H4_highP",
+ "First_to_Second_Aromatic_Ring/2017_Mebel_C6H5_C4H4_highP",
+ ),
+ (
+ "First_to_Second_Aromatic_Ring/phenyl_diacetylene_effective",
+ "First_to_Second_Aromatic_Ring/phenyl_diacetylene_effective",
+ ),
+ ("Fulvene_H", "Fulvene_H"),
+ ("GRI-HCO", "GRI-HCO"),
+ ("GRI-Mech3.0", "GRI-Mech3.0"),
+ ("GRI-Mech3.0-N", "GRI-Mech3.0-N"),
+ ("Glarborg/C0", "Glarborg/C0"),
+ ("Glarborg/C1", "Glarborg/C1"),
+ ("Glarborg/C2", "Glarborg/C2"),
+ ("Glarborg/C3", "Glarborg/C3"),
+ ("Glarborg/highP", "Glarborg/highP"),
+ ("HydrazinePDep", "HydrazinePDep"),
+ ("Iodine-R_recombination", "Iodine-R_recombination"),
+ ("JetSurF1.0", "JetSurF1.0"),
+ ("JetSurF2.0", "JetSurF2.0"),
+ ("Klippenstein_Glarborg2016", "Klippenstein_Glarborg2016"),
+ ("Lai_Hexylbenzene", "Lai_Hexylbenzene"),
+ ("LithiumAnalogyKinetics", "LithiumAnalogyKinetics"),
+ ("LithiumPrimaryChargedKinetics", "LithiumPrimaryChargedKinetics"),
+ ("LithiumPrimaryKinetics", "LithiumPrimaryKinetics"),
+ ("LithiumPrimaryKinetics2", "LithiumPrimaryKinetics2"),
+ ("LithiumSurface", "LithiumSurface"),
+ ("LithiumSurfaceAnalogy", "LithiumSurfaceAnalogy"),
+ ("Mebel_C6H5_C2H2", "Mebel_C6H5_C2H2"),
+ ("Mebel_Naphthyl", "Mebel_Naphthyl"),
+ ("Methylformate", "Methylformate"),
+ ("N-S_interactions", "N-S_interactions"),
+ ("NIST_Fluorine/CH2F2/full", "NIST_Fluorine/CH2F2/full"),
+ ("NIST_Fluorine/CH2F2/seed", "NIST_Fluorine/CH2F2/seed"),
+ ("NIST_Fluorine/full", "NIST_Fluorine/full"),
+ ("NIST_Fluorine/seed", "NIST_Fluorine/seed"),
+ ("NOx2018", "NOx2018"),
+ ("Narayanaswamy", "Narayanaswamy"),
+ ("Nitrogen_Dean_and_Bozzelli", "Nitrogen_Dean_and_Bozzelli"),
+ (
+ "Nitrogen_Glarborg_Gimenez_et_al",
+ "Nitrogen_Glarborg_Gimenez_et_al",
+ ),
+ (
+ "Nitrogen_Glarborg_Lucassen_et_al",
+ "Nitrogen_Glarborg_Lucassen_et_al",
+ ),
+ ("Nitrogen_Glarborg_Zhang_et_al", "Nitrogen_Glarborg_Zhang_et_al"),
+ ("Sulfur/DMDS", "Sulfur/DMDS"),
+ ("Sulfur/DMS", "Sulfur/DMS"),
+ ("Sulfur/DTBS", "Sulfur/DTBS"),
+ ("Sulfur/GlarborgBozzelli", "Sulfur/GlarborgBozzelli"),
+ ("Sulfur/GlarborgH2S", "Sulfur/GlarborgH2S"),
+ ("Sulfur/GlarborgH2S/alt", "Sulfur/GlarborgH2S/alt"),
+ ("Sulfur/GlarborgMarshall", "Sulfur/GlarborgMarshall"),
+ ("Sulfur/GlarborgNS", "Sulfur/GlarborgNS"),
+ ("Sulfur/HSSH_1bar", "Sulfur/HSSH_1bar"),
+ ("Sulfur/Hexanethial_nr", "Sulfur/Hexanethial_nr"),
+ ("Sulfur/Sendt", "Sulfur/Sendt"),
+ ("Sulfur/TP_Song", "Sulfur/TP_Song"),
+ ("Sulfur/Thial_Hydrolysis", "Sulfur/Thial_Hydrolysis"),
+ ("Surface/Ammonia/Duan_Ni111", "Surface/Ammonia/Duan_Ni111"),
+ ("Surface/Ammonia/Duan_Ni211", "Surface/Ammonia/Duan_Ni211"),
+ (
+ "Surface/Ammonia/Kraehnert_Pt111",
+ "Surface/Ammonia/Kraehnert_Pt111",
+ ),
+ ("Surface/Ammonia/Novell_Pd111", "Surface/Ammonia/Novell_Pd111"),
+ ("Surface/Ammonia/Novell_Pt111", "Surface/Ammonia/Novell_Pt111"),
+ ("Surface/Ammonia/Novell_Rh111", "Surface/Ammonia/Novell_Rh111"),
+ (
+ "Surface/Ammonia/Offermans_Pt111",
+ "Surface/Ammonia/Offermans_Pt111",
+ ),
+ ("Surface/Ammonia/Popa_Rh111", "Surface/Ammonia/Popa_Rh111"),
+ ("Surface/Ammonia/Rebrov_Pt111", "Surface/Ammonia/Rebrov_Pt111"),
+ ("Surface/Ammonia/Roldan_Ru0001", "Surface/Ammonia/Roldan_Ru0001"),
+ ("Surface/Ammonia/Scheuer_Pt", "Surface/Ammonia/Scheuer_Pt"),
+ (
+ "Surface/Ammonia/Schneider_Pd111",
+ "Surface/Ammonia/Schneider_Pd111",
+ ),
+ (
+ "Surface/Ammonia/Schneider_Pd211",
+ "Surface/Ammonia/Schneider_Pd211",
+ ),
+ (
+ "Surface/Ammonia/Schneider_Pt111",
+ "Surface/Ammonia/Schneider_Pt111",
+ ),
+ (
+ "Surface/Ammonia/Schneider_Pt211",
+ "Surface/Ammonia/Schneider_Pt211",
+ ),
+ (
+ "Surface/Ammonia/Schneider_Rh111",
+ "Surface/Ammonia/Schneider_Rh111",
+ ),
+ (
+ "Surface/Ammonia/Schneider_Rh211",
+ "Surface/Ammonia/Schneider_Rh211",
+ ),
+ (
+ "Surface/Ammonia/Vlachos_Ru0001",
+ "Surface/Ammonia/Vlachos_Ru0001",
+ ),
+ (
+ "Surface/CPOX_Pt/Deutschmann2006_adjusted",
+ "Surface/CPOX_Pt/Deutschmann2006_adjusted",
+ ),
+ ("Surface/DOC/Arevalo_Pt111", "Surface/DOC/Arevalo_Pt111"),
+ ("Surface/DOC/Ishikawa_Rh111", "Surface/DOC/Ishikawa_Rh111"),
+ ("Surface/DOC/Mhadeshwar_Pt111", "Surface/DOC/Mhadeshwar_Pt111"),
+ ("Surface/DOC/Nitrogen", "Surface/DOC/Nitrogen"),
+ ("Surface/Example", "Surface/Example"),
+ (
+ "Surface/Hydrazine/Roldan_Cu111",
+ "Surface/Hydrazine/Roldan_Cu111",
+ ),
+ (
+ "Surface/Hydrazine/Roldan_Ir111",
+ "Surface/Hydrazine/Roldan_Ir111",
+ ),
+ (
+ "Surface/Methane/Deutschmann_Ni",
+ "Surface/Methane/Deutschmann_Ni",
+ ),
+ (
+ "Surface/Methane/Deutschmann_Ni_full",
+ "Surface/Methane/Deutschmann_Ni_full",
+ ),
+ (
+ "Surface/Methane/Deutschmann_Pt",
+ "Surface/Methane/Deutschmann_Pt",
+ ),
+ ("Surface/Methane/Vlachos_Pt111", "Surface/Methane/Vlachos_Pt111"),
+ ("Surface/Methane/Vlachos_Rh", "Surface/Methane/Vlachos_Rh"),
+ ("TEOS", "TEOS"),
+ ("Xu_cyclopentadiene", "Xu_cyclopentadiene"),
+ ("YF/full", "YF/full"),
+ ("YF/seed", "YF/seed"),
+ ("biCPD_H_shift", "biCPD_H_shift"),
+ ("c-C5H5_CH3_Sharma", "c-C5H5_CH3_Sharma"),
+ ("combustion_core/version2", "combustion_core/version2"),
+ ("combustion_core/version3", "combustion_core/version3"),
+ ("combustion_core/version4", "combustion_core/version4"),
+ ("combustion_core/version5", "combustion_core/version5"),
+ ("fascella", "fascella"),
+ ("kislovB", "kislovB"),
+ ("naphthalene_H", "naphthalene_H"),
+ ("primaryH2O2", "primaryH2O2"),
+ ("primaryNitrogenLibrary", "primaryNitrogenLibrary"),
+ ("primaryNitrogenLibrary/LowT", "primaryNitrogenLibrary/LowT"),
+ ("primarySulfurLibrary", "primarySulfurLibrary"),
+ ("vinylCPD_H", "vinylCPD_H"),
+ ],
+ max_length=200,
+ ),
+ ),
+ migrations.AlterField(
+ model_name="reactor",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="reactorspecies",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="thermolibrary",
+ name="id",
+ field=models.BigAutoField(
+ auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
+ ),
+ ),
+ migrations.AlterField(
+ model_name="thermolibrary",
+ name="thermo_lib",
+ field=models.CharField(
+ blank=True,
+ choices=[
+ ("2-BTP", "2-BTP"),
+ ("2-BTP_G4", "2-BTP_G4"),
+ ("BurcatNS", "BurcatNS"),
+ ("BurkeH2O2", "BurkeH2O2"),
+ ("Butadiene_Dimerization", "Butadiene_Dimerization"),
+ ("C10H11", "C10H11"),
+ ("C3", "C3"),
+ ("CBS_QB3_1dHR", "CBS_QB3_1dHR"),
+ ("CH", "CH"),
+ ("CHN", "CHN"),
+ ("CHO", "CHO"),
+ ("CHOBr_G4", "CHOBr_G4"),
+ ("CHOClBr_G4", "CHOClBr_G4"),
+ ("CHOCl_G4", "CHOCl_G4"),
+ ("CHOFBr_G4", "CHOFBr_G4"),
+ ("CHOFClBr_G4", "CHOFClBr_G4"),
+ ("CHOFCl_G4", "CHOFCl_G4"),
+ ("CHOF_G4", "CHOF_G4"),
+ ("CHON", "CHON"),
+ ("CHON_G4", "CHON_G4"),
+ ("CN", "CN"),
+ ("Chernov", "Chernov"),
+ ("Chlorinated_Hydrocarbons", "Chlorinated_Hydrocarbons"),
+ ("Chlorination", "Chlorination"),
+ ("CurranPentane", "CurranPentane"),
+ ("DFT_QCI_thermo", "DFT_QCI_thermo"),
+ ("Elliott_OOQOOH", "Elliott_OOQOOH"),
+ ("FFCM1(-)", "FFCM1(-)"),
+ ("Fluorine", "Fluorine"),
+ ("Fulvene_H", "Fulvene_H"),
+ ("GRI-Mech3.0", "GRI-Mech3.0"),
+ ("GRI-Mech3.0-N", "GRI-Mech3.0-N"),
+ ("JetSurF1.0", "JetSurF1.0"),
+ ("JetSurF2.0", "JetSurF2.0"),
+ ("Klippenstein_Glarborg2016", "Klippenstein_Glarborg2016"),
+ ("Lai_Hexylbenzene", "Lai_Hexylbenzene"),
+ ("LithiumAdditionalThermo", "LithiumAdditionalThermo"),
+ ("LithiumPrimaryThermo", "LithiumPrimaryThermo"),
+ ("LithiumPrimaryThermo2", "LithiumPrimaryThermo2"),
+ ("LithiumSurface", "LithiumSurface"),
+ ("NH3", "NH3"),
+ ("NISTThermoLibrary", "NISTThermoLibrary"),
+ ("NOx2018", "NOx2018"),
+ ("Narayanaswamy", "Narayanaswamy"),
+ ("NitrogenCurran", "NitrogenCurran"),
+ ("SABIC_aromatics", "SABIC_aromatics"),
+ ("SABIC_aromatics_1dHR", "SABIC_aromatics_1dHR"),
+ ("SABIC_aromatics_1dHR_extended", "SABIC_aromatics_1dHR_extended"),
+ (
+ "Spiekermann_refining_elementary_reactions",
+ "Spiekermann_refining_elementary_reactions",
+ ),
+ ("SulfurGlarborgBozzelli", "SulfurGlarborgBozzelli"),
+ ("SulfurGlarborgH2S", "SulfurGlarborgH2S"),
+ ("SulfurGlarborgMarshall", "SulfurGlarborgMarshall"),
+ ("SulfurGlarborgNS", "SulfurGlarborgNS"),
+ ("SulfurHaynes", "SulfurHaynes"),
+ ("SulfurLibrary", "SulfurLibrary"),
+ ("USC-Mech-ii", "USC-Mech-ii"),
+ ("bio_oil", "bio_oil"),
+ ("computationalLithiumElectrode", "computationalLithiumElectrode"),
+ ("electrocatLiThermo", "electrocatLiThermo"),
+ ("electrocatThermo", "electrocatThermo"),
+ ("halogens", "halogens"),
+ ("heavy_oil_ccsdtf12_1dHR", "heavy_oil_ccsdtf12_1dHR"),
+ ("iodinated_Hydrocarbons", "iodinated_Hydrocarbons"),
+ ("naphthalene_H", "naphthalene_H"),
+ ("primaryNS", "primaryNS"),
+ ("primaryThermoLibrary", "primaryThermoLibrary"),
+ ("s3_5_7_ane", "s3_5_7_ane"),
+ ("surfaceThermoLi", "surfaceThermoLi"),
+ ("surfaceThermoNi111", "surfaceThermoNi111"),
+ ("surfaceThermoPt111", "surfaceThermoPt111"),
+ ("thermo_DFT_CCSDTF12_BAC", "thermo_DFT_CCSDTF12_BAC"),
+ ("vinylCPD_H", "vinylCPD_H"),
+ ],
+ max_length=200,
+ ),
+ ),
+ ]
diff --git a/rmgweb/rmg/migrations/0012_alter_reactionlibrary_reaction_lib.py b/rmgweb/rmg/migrations/0012_alter_reactionlibrary_reaction_lib.py
new file mode 100644
index 00000000..631197b7
--- /dev/null
+++ b/rmgweb/rmg/migrations/0012_alter_reactionlibrary_reaction_lib.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2 on 2026-03-20 15:29
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('rmg', '0011_delete_adjlistconversion_remove_fluxdiagram_java_and_more'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='reactionlibrary',
+ name='reaction_lib',
+ field=models.CharField(blank=True, choices=[('1989_Stewart_2CH3_to_C2H5_H', '1989_Stewart_2CH3_to_C2H5_H'), ('2-BTP/full', '2-BTP/full'), ('2-BTP/seed', '2-BTP/seed'), ('2001_Tokmakov_H_Toluene_to_CH3_Benzene', '2001_Tokmakov_H_Toluene_to_CH3_Benzene'), ('2003_Miller_Propargyl_Recomb_High_P', '2003_Miller_Propargyl_Recomb_High_P'), ('2005_Senosiain_OH_C2H2', '2005_Senosiain_OH_C2H2'), ('2006_Joshi_OH_CO', '2006_Joshi_OH_CO'), ('2009_Sharma_C5H5_CH3_highP', '2009_Sharma_C5H5_CH3_highP'), ('2015_Buras_C2H3_C4H6_highP', '2015_Buras_C2H3_C4H6_highP'), ('Aromatics_high_pressure/C10H10_1', 'Aromatics_high_pressure/C10H10_1'), ('Aromatics_high_pressure/C10H10_2', 'Aromatics_high_pressure/C10H10_2'), ('Aromatics_high_pressure/C10H10_H_abstraction', 'Aromatics_high_pressure/C10H10_H_abstraction'), ('Aromatics_high_pressure/C10H11_1', 'Aromatics_high_pressure/C10H11_1'), ('Aromatics_high_pressure/C10H11_2', 'Aromatics_high_pressure/C10H11_2'), ('Aromatics_high_pressure/C10H11_3', 'Aromatics_high_pressure/C10H11_3'), ('Aromatics_high_pressure/C10H11_4', 'Aromatics_high_pressure/C10H11_4'), ('Aromatics_high_pressure/C10H7', 'Aromatics_high_pressure/C10H7'), ('Aromatics_high_pressure/C10H8_H_abstraction_H_recomb', 'Aromatics_high_pressure/C10H8_H_abstraction_H_recomb'), ('Aromatics_high_pressure/C10H9_1', 'Aromatics_high_pressure/C10H9_1'), ('Aromatics_high_pressure/C10H9_2', 'Aromatics_high_pressure/C10H9_2'), ('Aromatics_high_pressure/C10H9_3', 'Aromatics_high_pressure/C10H9_3'), ('Aromatics_high_pressure/C10H9_4', 'Aromatics_high_pressure/C10H9_4'), ('Aromatics_high_pressure/C12H10_1', 'Aromatics_high_pressure/C12H10_1'), ('Aromatics_high_pressure/C12H10_2', 'Aromatics_high_pressure/C12H10_2'), ('Aromatics_high_pressure/C12H10_H_abstraction', 'Aromatics_high_pressure/C12H10_H_abstraction'), ('Aromatics_high_pressure/C12H11', 'Aromatics_high_pressure/C12H11'), ('Aromatics_high_pressure/C12H8_H_abstraction', 'Aromatics_high_pressure/C12H8_H_abstraction'), ('Aromatics_high_pressure/C12H9', 'Aromatics_high_pressure/C12H9'), ('Aromatics_high_pressure/C14H10_H_abstraction_H_recomb', 'Aromatics_high_pressure/C14H10_H_abstraction_H_recomb'), ('Aromatics_high_pressure/C14H11_1', 'Aromatics_high_pressure/C14H11_1'), ('Aromatics_high_pressure/C14H11_2', 'Aromatics_high_pressure/C14H11_2'), ('Aromatics_high_pressure/C14H11_3', 'Aromatics_high_pressure/C14H11_3'), ('Aromatics_high_pressure/C14H11_4', 'Aromatics_high_pressure/C14H11_4'), ('Aromatics_high_pressure/C14H9', 'Aromatics_high_pressure/C14H9'), ('Aromatics_high_pressure/C16H11', 'Aromatics_high_pressure/C16H11'), ('Aromatics_high_pressure/C7H8', 'Aromatics_high_pressure/C7H8'), ('Aromatics_high_pressure/C7H8_H_abstraction', 'Aromatics_high_pressure/C7H8_H_abstraction'), ('Aromatics_high_pressure/C7H9', 'Aromatics_high_pressure/C7H9'), ('Aromatics_high_pressure/C8H6_H_abstraction', 'Aromatics_high_pressure/C8H6_H_abstraction'), ('Aromatics_high_pressure/C8H7', 'Aromatics_high_pressure/C8H7'), ('Aromatics_high_pressure/C8H8_H_abstraction', 'Aromatics_high_pressure/C8H8_H_abstraction'), ('Aromatics_high_pressure/C8H9', 'Aromatics_high_pressure/C8H9'), ('Aromatics_high_pressure/C9H10_H_abstraction', 'Aromatics_high_pressure/C9H10_H_abstraction'), ('Aromatics_high_pressure/C9H11', 'Aromatics_high_pressure/C9H11'), ('Aromatics_high_pressure/C9H7', 'Aromatics_high_pressure/C9H7'), ('Aromatics_high_pressure/C9H8_1', 'Aromatics_high_pressure/C9H8_1'), ('Aromatics_high_pressure/C9H8_2', 'Aromatics_high_pressure/C9H8_2'), ('Aromatics_high_pressure/C9H8_H_abstraction', 'Aromatics_high_pressure/C9H8_H_abstraction'), ('Aromatics_high_pressure/C9H9_1', 'Aromatics_high_pressure/C9H9_1'), ('Aromatics_high_pressure/C9H9_2', 'Aromatics_high_pressure/C9H9_2'), ('BurkeH2O2inArHe', 'BurkeH2O2inArHe'), ('BurkeH2O2inN2', 'BurkeH2O2inN2'), ('Butadiene_Dimerization', 'Butadiene_Dimerization'), ('C10H11', 'C10H11'), ('C12H11_pdep', 'C12H11_pdep'), ('C2H2_init', 'C2H2_init'), ('C2H4+O_Klipp2017', 'C2H4+O_Klipp2017'), ('C3', 'C3'), ('C6H5_C4H4_Mebel', 'C6H5_C4H4_Mebel'), ('CF2BrCl', 'CF2BrCl'), ('CH3Cl', 'CH3Cl'), ('Chernov', 'Chernov'), ('Chung_solvation_corrections', 'Chung_solvation_corrections'), ('CurranPentane', 'CurranPentane'), ('DMSOxy', 'DMSOxy'), ('DTU_mech_CH3Cl', 'DTU_mech_CH3Cl'), ('Dooley/C1', 'Dooley/C1'), ('Dooley/methylformate', 'Dooley/methylformate'), ('Dooley/methylformate_2', 'Dooley/methylformate_2'), ('Dooley/methylformate_all_ARHEbathgas', 'Dooley/methylformate_all_ARHEbathgas'), ('Dooley/methylformate_all_N2bathgas', 'Dooley/methylformate_all_N2bathgas'), ('ERC-FoundationFuelv0.9', 'ERC-FoundationFuelv0.9'), ('Ethylamine', 'Ethylamine'), ('FFCM1(-)', 'FFCM1(-)'), ('First_to_Second_Aromatic_Ring/2005_Ismail_C6H5_C4H6_highP', 'First_to_Second_Aromatic_Ring/2005_Ismail_C6H5_C4H6_highP'), ('First_to_Second_Aromatic_Ring/2012_Matsugi_C3H3_C7H7_highP', 'First_to_Second_Aromatic_Ring/2012_Matsugi_C3H3_C7H7_highP'), ('First_to_Second_Aromatic_Ring/2016_Mebel_C10H9_highP', 'First_to_Second_Aromatic_Ring/2016_Mebel_C10H9_highP'), ('First_to_Second_Aromatic_Ring/2016_Mebel_C9H9_highP', 'First_to_Second_Aromatic_Ring/2016_Mebel_C9H9_highP'), ('First_to_Second_Aromatic_Ring/2016_Mebel_Indene_CH3_highP', 'First_to_Second_Aromatic_Ring/2016_Mebel_Indene_CH3_highP'), ('First_to_Second_Aromatic_Ring/2017_Buras_C6H5_C3H6_highP', 'First_to_Second_Aromatic_Ring/2017_Buras_C6H5_C3H6_highP'), ('First_to_Second_Aromatic_Ring/2017_Mebel_C6H4C2H_C2H2_highP', 'First_to_Second_Aromatic_Ring/2017_Mebel_C6H4C2H_C2H2_highP'), ('First_to_Second_Aromatic_Ring/2017_Mebel_C6H5C2H2_C2H2_highP', 'First_to_Second_Aromatic_Ring/2017_Mebel_C6H5C2H2_C2H2_highP'), ('First_to_Second_Aromatic_Ring/2017_Mebel_C6H5_C2H2_highP', 'First_to_Second_Aromatic_Ring/2017_Mebel_C6H5_C2H2_highP'), ('First_to_Second_Aromatic_Ring/2017_Mebel_C6H5_C4H4_highP', 'First_to_Second_Aromatic_Ring/2017_Mebel_C6H5_C4H4_highP'), ('First_to_Second_Aromatic_Ring/phenyl_diacetylene_effective', 'First_to_Second_Aromatic_Ring/phenyl_diacetylene_effective'), ('Fulvene_H', 'Fulvene_H'), ('GRI-HCO', 'GRI-HCO'), ('GRI-Mech3.0', 'GRI-Mech3.0'), ('GRI-Mech3.0-N', 'GRI-Mech3.0-N'), ('Glarborg/C0', 'Glarborg/C0'), ('Glarborg/C1', 'Glarborg/C1'), ('Glarborg/C2', 'Glarborg/C2'), ('Glarborg/C3', 'Glarborg/C3'), ('Glarborg/highP', 'Glarborg/highP'), ('HydrazinePDep', 'HydrazinePDep'), ('Iodine-R_recombination', 'Iodine-R_recombination'), ('JetSurF1.0', 'JetSurF1.0'), ('JetSurF2.0', 'JetSurF2.0'), ('Klippenstein_Glarborg2016', 'Klippenstein_Glarborg2016'), ('Lai_Hexylbenzene', 'Lai_Hexylbenzene'), ('LithiumAnalogyKinetics', 'LithiumAnalogyKinetics'), ('LithiumPrimaryChargedKinetics', 'LithiumPrimaryChargedKinetics'), ('LithiumPrimaryKinetics', 'LithiumPrimaryKinetics'), ('LithiumPrimaryKinetics2', 'LithiumPrimaryKinetics2'), ('LithiumSurface', 'LithiumSurface'), ('LithiumSurfaceAnalogy', 'LithiumSurfaceAnalogy'), ('Mebel_C6H5_C2H2', 'Mebel_C6H5_C2H2'), ('Mebel_Naphthyl', 'Mebel_Naphthyl'), ('Methylformate', 'Methylformate'), ('N-S_interactions', 'N-S_interactions'), ('NIST_Fluorine/CH2F2/full', 'NIST_Fluorine/CH2F2/full'), ('NIST_Fluorine/CH2F2/seed', 'NIST_Fluorine/CH2F2/seed'), ('NIST_Fluorine/full', 'NIST_Fluorine/full'), ('NIST_Fluorine/seed', 'NIST_Fluorine/seed'), ('NOx2018', 'NOx2018'), ('Narayanaswamy', 'Narayanaswamy'), ('Nitrogen_Dean_and_Bozzelli', 'Nitrogen_Dean_and_Bozzelli'), ('Nitrogen_Glarborg_Gimenez_et_al', 'Nitrogen_Glarborg_Gimenez_et_al'), ('Nitrogen_Glarborg_Lucassen_et_al', 'Nitrogen_Glarborg_Lucassen_et_al'), ('Nitrogen_Glarborg_Zhang_et_al', 'Nitrogen_Glarborg_Zhang_et_al'), ('Sulfur/DMDS', 'Sulfur/DMDS'), ('Sulfur/DMS', 'Sulfur/DMS'), ('Sulfur/DTBS', 'Sulfur/DTBS'), ('Sulfur/GlarborgBozzelli', 'Sulfur/GlarborgBozzelli'), ('Sulfur/GlarborgH2S', 'Sulfur/GlarborgH2S'), ('Sulfur/GlarborgH2S/alt', 'Sulfur/GlarborgH2S/alt'), ('Sulfur/GlarborgMarshall', 'Sulfur/GlarborgMarshall'), ('Sulfur/GlarborgNS', 'Sulfur/GlarborgNS'), ('Sulfur/HSSH_1bar', 'Sulfur/HSSH_1bar'), ('Sulfur/Hexanethial_nr', 'Sulfur/Hexanethial_nr'), ('Sulfur/Sendt', 'Sulfur/Sendt'), ('Sulfur/TP_Song', 'Sulfur/TP_Song'), ('Sulfur/Thial_Hydrolysis', 'Sulfur/Thial_Hydrolysis'), ('Surface/Ammonia/Duan_Ni111', 'Surface/Ammonia/Duan_Ni111'), ('Surface/Ammonia/Duan_Ni211', 'Surface/Ammonia/Duan_Ni211'), ('Surface/Ammonia/Kraehnert_Pt111', 'Surface/Ammonia/Kraehnert_Pt111'), ('Surface/Ammonia/Novell_Pd111', 'Surface/Ammonia/Novell_Pd111'), ('Surface/Ammonia/Novell_Pt111', 'Surface/Ammonia/Novell_Pt111'), ('Surface/Ammonia/Novell_Rh111', 'Surface/Ammonia/Novell_Rh111'), ('Surface/Ammonia/Offermans_Pt111', 'Surface/Ammonia/Offermans_Pt111'), ('Surface/Ammonia/Popa_Rh111', 'Surface/Ammonia/Popa_Rh111'), ('Surface/Ammonia/Rebrov_Pt111', 'Surface/Ammonia/Rebrov_Pt111'), ('Surface/Ammonia/Roldan_Ru0001', 'Surface/Ammonia/Roldan_Ru0001'), ('Surface/Ammonia/Scheuer_Pt', 'Surface/Ammonia/Scheuer_Pt'), ('Surface/Ammonia/Schneider_Pd111', 'Surface/Ammonia/Schneider_Pd111'), ('Surface/Ammonia/Schneider_Pd211', 'Surface/Ammonia/Schneider_Pd211'), ('Surface/Ammonia/Schneider_Pt111', 'Surface/Ammonia/Schneider_Pt111'), ('Surface/Ammonia/Schneider_Pt211', 'Surface/Ammonia/Schneider_Pt211'), ('Surface/Ammonia/Schneider_Rh111', 'Surface/Ammonia/Schneider_Rh111'), ('Surface/Ammonia/Schneider_Rh211', 'Surface/Ammonia/Schneider_Rh211'), ('Surface/Ammonia/Vlachos_Ru0001', 'Surface/Ammonia/Vlachos_Ru0001'), ('Surface/CPOX_Pt/Deutschmann2006_adjusted', 'Surface/CPOX_Pt/Deutschmann2006_adjusted'), ('Surface/DOC/Arevalo_Pt111', 'Surface/DOC/Arevalo_Pt111'), ('Surface/DOC/Ishikawa_Rh111', 'Surface/DOC/Ishikawa_Rh111'), ('Surface/DOC/Mhadeshwar_Pt111', 'Surface/DOC/Mhadeshwar_Pt111'), ('Surface/DOC/Nitrogen', 'Surface/DOC/Nitrogen'), ('Surface/Example', 'Surface/Example'), ('Surface/Hydrazine/Roldan_Cu111', 'Surface/Hydrazine/Roldan_Cu111'), ('Surface/Hydrazine/Roldan_Ir111', 'Surface/Hydrazine/Roldan_Ir111'), ('Surface/Methane/Deutschmann_Ni', 'Surface/Methane/Deutschmann_Ni'), ('Surface/Methane/Deutschmann_Ni_full', 'Surface/Methane/Deutschmann_Ni_full'), ('Surface/Methane/Deutschmann_Pt', 'Surface/Methane/Deutschmann_Pt'), ('Surface/Methane/Vlachos_Pt111', 'Surface/Methane/Vlachos_Pt111'), ('Surface/Methane/Vlachos_Rh', 'Surface/Methane/Vlachos_Rh'), ('TEOS', 'TEOS'), ('YF/full', 'YF/full'), ('YF/seed', 'YF/seed'), ('biCPD_H_shift', 'biCPD_H_shift'), ('c-C5H5_CH3_Sharma', 'c-C5H5_CH3_Sharma'), ('combustion_core/version2', 'combustion_core/version2'), ('combustion_core/version3', 'combustion_core/version3'), ('combustion_core/version4', 'combustion_core/version4'), ('combustion_core/version5', 'combustion_core/version5'), ('fascella', 'fascella'), ('kislovB', 'kislovB'), ('naphthalene_H', 'naphthalene_H'), ('primaryH2O2', 'primaryH2O2'), ('primaryNitrogenLibrary', 'primaryNitrogenLibrary'), ('primaryNitrogenLibrary/LowT', 'primaryNitrogenLibrary/LowT'), ('primarySulfurLibrary', 'primarySulfurLibrary'), ('vinylCPD_H', 'vinylCPD_H')], max_length=200),
+ ),
+ ]
diff --git a/rmgweb/rmg/views.py b/rmgweb/rmg/views.py
index 31b0339e..3253f2ce 100644
--- a/rmgweb/rmg/views.py
+++ b/rmgweb/rmg/views.py
@@ -129,8 +129,6 @@ def generateFlux(request):
to generate a flux diagram video.
"""
- from rmgpy.tools.fluxdiagram import create_flux_diagram
-
flux = FluxDiagram()
path = ''
flux.deleteDir()
@@ -144,7 +142,6 @@ def generateFlux(request):
arguments["chem_output"] = ''
if 'chem_output' in request.FILES:
arguments["chem_output"] = os.path.join(flux.path, 'chemkin_output.out')
- arguments['java'] = form.cleaned_data['java']
arguments['max_nodes'] = form.cleaned_data['max_nodes']
arguments['max_edges'] = form.cleaned_data['max_edges']
arguments['time_step'] = form.cleaned_data['time_step']
diff --git a/rmgweb/secretsettings.py.example b/rmgweb/secretsettings.py.example
index bd23e1cf..fbfea838 100644
--- a/rmgweb/secretsettings.py.example
+++ b/rmgweb/secretsettings.py.example
@@ -48,3 +48,6 @@ DATABASES = {
# import random
# ''.join([random.SystemRandom().choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50)])
SECRET_KEY = 'this_is_a_bad_secret_key_and_you_should_replace_it'
+
+# path to the running solprop microservice
+SOLPROP_URL = "http://localhost:8081"
diff --git a/rmgweb/settings.py b/rmgweb/settings.py
index 2cfdcdb8..0ee8e024 100644
--- a/rmgweb/settings.py
+++ b/rmgweb/settings.py
@@ -169,3 +169,7 @@
# Settings relating to user account management
LOGIN_URL = '/login'
LOGIN_REDIRECT_URL = '/'
+
+# Set auto field for auto-created primary key fields
+DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+