Merge branch 'CAselect'
Browse files- CHRIS.py +1 -1
- ChemID.py +2 -0
- color2_module/colors.py +100 -39
- color2_module/templates/chemError.html +24 -0
- color2_module/templates/color2_index.html +14 -17
- color2_module/templates/color2_report.html +60 -7
- color2_module/templates/metalError.html +68 -0
- efficiency_module/static/efficiency_COU.html +10 -10
- exposure2_module/exposure.py +1 -1
CHRIS.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
from flask import Flask, render_template
|
| 2 |
|
| 3 |
app = Flask(__name__)
|
| 4 |
-
app.debug =
|
| 5 |
|
| 6 |
from color_module import blueprint
|
| 7 |
app.register_blueprint(blueprint)
|
|
|
|
| 1 |
from flask import Flask, render_template
|
| 2 |
|
| 3 |
app = Flask(__name__)
|
| 4 |
+
app.debug = True
|
| 5 |
|
| 6 |
from color_module import blueprint
|
| 7 |
app.register_blueprint(blueprint)
|
ChemID.py
CHANGED
|
@@ -1,4 +1,6 @@
|
|
| 1 |
import sys,os,glob,re,string
|
|
|
|
|
|
|
| 2 |
import nltk
|
| 3 |
import pandas as pd
|
| 4 |
import numpy as np
|
|
|
|
| 1 |
import sys,os,glob,re,string
|
| 2 |
+
from collections import Counter
|
| 3 |
+
from operator import itemgetter
|
| 4 |
import nltk
|
| 5 |
import pandas as pd
|
| 6 |
import numpy as np
|
color2_module/colors.py
CHANGED
|
@@ -1,13 +1,28 @@
|
|
| 1 |
from flask import Flask, render_template, request
|
| 2 |
import numpy as np
|
| 3 |
-
from functions import SigFigs, Piringer, WilkeChang, SheetRelease
|
| 4 |
from functions import Piecewise, PowerLaw
|
| 5 |
from . import blueprint
|
| 6 |
from polymers import Polymers, Polymers2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
# flag for testing new polymer categories
|
| 9 |
use_new = True
|
| 10 |
|
|
|
|
|
|
|
|
|
|
| 11 |
# load polymer data including Ap values
|
| 12 |
if not use_new:
|
| 13 |
polymers, Ap = Polymers()
|
|
@@ -15,22 +30,21 @@ else:
|
|
| 15 |
polymers, categories, params = Polymers2()
|
| 16 |
|
| 17 |
# Named color additives, TI values, and Mw
|
| 18 |
-
nCA =
|
| 19 |
-
caData = np.zeros((nCA,), dtype=[('name', 'a75'), ('TI', 'd'), ('MW', 'd')])
|
| 20 |
-
caData[0] = ('Titanium dioxide (CAS#:13463-67-7)', 1.0, 1100.)
|
| 21 |
-
caData[1] = ('Carbon black (CAS#:1333-86-4)', 2.0, 1100.)
|
| 22 |
-
caData[2] = ('Pigment brown 24 (CAS#:68186-90-3)', 0.5, 1100.)
|
| 23 |
-
caData[3] = ('Zinc Oxide (CAS#:1314-13-2)', 0.05, 1100.)
|
| 24 |
-
caData[4] = ('Pigment Red 101 (CAS#: 1309-37-1)', 1.0, 1100.)
|
| 25 |
-
caData[5] = ('Solvent violet 13 (CAS#:81-48-1)', 0.0013, 319.4)
|
| 26 |
-
caData[6] = ('Manganese phthalocyanine (CAS#:14325-24-7)', 0.15, 567.5)
|
| 27 |
-
caData[7] = ('Pigment blue 15 (CAS#:147-14-8)', 0.15, 576.1)
|
| 28 |
-
caData[8] = ('Phthalocyanine green (CAS#:
|
| 29 |
-
caData[9] = ('Ultramarine blue (CAS#:
|
| 30 |
-
caData[10] = ('Pigment Yellow 138 (CAS#:30125-47-4)', 1.0, 693.96)
|
| 31 |
-
caData[11] = ('Other
|
| 32 |
-
caData[12] = ('Other
|
| 33 |
-
caData[13] = ('Other color additive associated compound', 1.0, 1100.0)
|
| 34 |
|
| 35 |
CAs = np.zeros(nCA, dtype='object')
|
| 36 |
caMW = np.zeros(nCA, dtype='object')
|
|
@@ -50,6 +64,7 @@ def colors():
|
|
| 50 |
|
| 51 |
@blueprint.route('/color2', methods=['POST'])
|
| 52 |
def app_post():
|
|
|
|
| 53 |
amount = float(request.form["amount"])
|
| 54 |
mass = float(request.form["mass"])
|
| 55 |
density = float(request.form["density"])
|
|
@@ -63,31 +78,73 @@ def app_post():
|
|
| 63 |
|
| 64 |
TI = caData[caIndex][1]
|
| 65 |
impurity = 1.
|
| 66 |
-
MW = 1100.
|
| 67 |
isCA = True
|
| 68 |
chemName = ''
|
| 69 |
|
| 70 |
-
if caIndex <
|
| 71 |
-
|
| 72 |
-
chemName =
|
| 73 |
impurity = float(request.form["impurity"]) * amount * 1e-2
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
impurity = float(request.form["impurity"]) * amount * 1e-2
|
| 79 |
if caIndex == 12:
|
| 80 |
-
MW = float(request.form["MW"])
|
| 81 |
-
chemName = request.form["chemName"] if "chemName" in request.form else "CHEMICAL NAME NOT PROVIDED"
|
| 82 |
-
chemName = '*' + chemName + '*'
|
| 83 |
-
impurity = float(request.form["impurity"]) * amount * 1e-2
|
| 84 |
-
if caIndex == 13:
|
| 85 |
isCA = False
|
| 86 |
-
MW = float(request.form["MW"])
|
| 87 |
-
chemName = request.form["chemName"] if "chemName" in request.form else "CHEMICAL NAME NOT PROVIDED"
|
| 88 |
-
chemName = '*' + chemName + '*'
|
| 89 |
-
impurity = float(request.form["impurity"]) * amount * 1e-2
|
| 90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
if exposure != "limited":
|
| 92 |
time = 24.
|
| 93 |
else:
|
|
@@ -125,9 +182,13 @@ def app_post():
|
|
| 125 |
iMOS = SigFigs(iMOS, 2)
|
| 126 |
impurity = SigFigs(impurity, 2)
|
| 127 |
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
|
|
|
|
| 1 |
from flask import Flask, render_template, request
|
| 2 |
import numpy as np
|
| 3 |
+
from functions import SigFigs, Piringer, WilkeChang, SheetRelease, SheetRates, RatePlot
|
| 4 |
from functions import Piecewise, PowerLaw
|
| 5 |
from . import blueprint
|
| 6 |
from polymers import Polymers, Polymers2
|
| 7 |
+
from ChemID import ResolveChemical, ImageFromSmiles, Imageto64
|
| 8 |
+
import rdkit
|
| 9 |
+
from rdkit.Chem import AllChem as Chem
|
| 10 |
+
|
| 11 |
+
# get additional physical properties, options are: logp, rho, mp
|
| 12 |
+
#get_properties = [] # don't get any; this breaks ceramics logic
|
| 13 |
+
#get_properties = ['logp','rho','mp'] # get all three
|
| 14 |
+
get_properties = ['mp'] # only get mp
|
| 15 |
+
# show additional physical properties
|
| 16 |
+
show_properties = False
|
| 17 |
+
# output additional info for physical properties
|
| 18 |
+
debug = False
|
| 19 |
|
| 20 |
# flag for testing new polymer categories
|
| 21 |
use_new = True
|
| 22 |
|
| 23 |
+
ORGANIC_ATOM_SET = {5, 6, 7, 8, 9, 15, 16, 17, 35, 53}
|
| 24 |
+
METAL_ATOM_SET = set([3,4,11,12,13] + list(range(19,31+1)) + list(range(37,50+1)) + list(range(55,84+1)) + list(range(87,114+1)) + [116])
|
| 25 |
+
|
| 26 |
# load polymer data including Ap values
|
| 27 |
if not use_new:
|
| 28 |
polymers, Ap = Polymers()
|
|
|
|
| 30 |
polymers, categories, params = Polymers2()
|
| 31 |
|
| 32 |
# Named color additives, TI values, and Mw
|
| 33 |
+
nCA = 13
|
| 34 |
+
caData = np.zeros((nCA,), dtype=[('name', 'a75'), ('TI', 'd'), ('MW', 'd'),('CAS', 'a75')])
|
| 35 |
+
caData[0] = ('Titanium dioxide (CAS#:13463-67-7)', 1.0, 1100., '13463-67-7')
|
| 36 |
+
caData[1] = ('Carbon black (CAS#:1333-86-4)', 2.0, 1100., '1333-86-4')
|
| 37 |
+
caData[2] = ('Pigment brown 24 (CAS#:68186-90-3)', 0.5, 1100., '68186-90-3')
|
| 38 |
+
caData[3] = ('Zinc Oxide (CAS#:1314-13-2)', 0.05, 1100., '1314-13-2')
|
| 39 |
+
caData[4] = ('Pigment Red 101 (CAS#: 1309-37-1)', 1.0, 1100., '1309-37-1')
|
| 40 |
+
caData[5] = ('Solvent violet 13 (CAS#:81-48-1)', 0.0013, 319.4, '81-48-1')
|
| 41 |
+
caData[6] = ('Manganese phthalocyanine (CAS#:14325-24-7)', 0.15, 567.5, '14325-24-7')
|
| 42 |
+
caData[7] = ('Pigment blue 15 (CAS#:147-14-8)', 0.15, 576.1, '147-14-8')
|
| 43 |
+
caData[8] = ('Phthalocyanine green (CAS#:1328-53-6)', 0.15, 1092.8, '1328-53-6')
|
| 44 |
+
caData[9] = ('Ultramarine blue (CAS#:57455-37-5)', 3.3, 1100., '57455-37-5')
|
| 45 |
+
caData[10] = ('Pigment Yellow 138 (CAS#:30125-47-4)', 1.0, 693.96, '30125-47-4')
|
| 46 |
+
caData[11] = ('Other color additive', 1.0, 1100.0, ' ')
|
| 47 |
+
caData[12] = ('Other color additive associated compound', 1.0, 1100.0, ' ')
|
|
|
|
| 48 |
|
| 49 |
CAs = np.zeros(nCA, dtype='object')
|
| 50 |
caMW = np.zeros(nCA, dtype='object')
|
|
|
|
| 64 |
|
| 65 |
@blueprint.route('/color2', methods=['POST'])
|
| 66 |
def app_post():
|
| 67 |
+
|
| 68 |
amount = float(request.form["amount"])
|
| 69 |
mass = float(request.form["mass"])
|
| 70 |
density = float(request.form["density"])
|
|
|
|
| 78 |
|
| 79 |
TI = caData[caIndex][1]
|
| 80 |
impurity = 1.
|
|
|
|
| 81 |
isCA = True
|
| 82 |
chemName = ''
|
| 83 |
|
| 84 |
+
if caIndex <= 10:
|
| 85 |
+
IDtype = 'CAS'
|
| 86 |
+
chemName = caData[caIndex][3].decode('UTF-8')
|
| 87 |
impurity = float(request.form["impurity"]) * amount * 1e-2
|
| 88 |
+
# problems:
|
| 89 |
+
# o C.I. Pigment Brown 24 = 68186-90-3, kludge "works"
|
| 90 |
+
# o Manganese(II) phthalocyanine = 14325-24-7, kludge "works"
|
| 91 |
+
# o Phthalocyanine green = 1326-53-6 -> 1328-53-6, corrected CAS works
|
| 92 |
+
# o Ultramarine blue = 57445-37-5 -> 57455-37-5, corrected CAS works
|
| 93 |
+
if caIndex > 10:
|
| 94 |
+
chemName = request.form["chemName"]
|
| 95 |
+
IDtype = request.form["IDtype"]
|
| 96 |
impurity = float(request.form["impurity"]) * amount * 1e-2
|
| 97 |
if caIndex == 12:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
isCA = False
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
|
| 100 |
+
print(chemName)
|
| 101 |
+
if chemName == '68186-90-3':
|
| 102 |
+
#IDtype = 'SMILES'
|
| 103 |
+
#chemName = 'O=[Ti]=O.O=[Sb]O[Sb](=O)=O.O=[Cr]O[Cr]=O'
|
| 104 |
+
#iupac, cas, smiles, MW, LogP, rho, mp, molImage, error = ResolveChemical(chemName, IDtype, get_properties=get_properties)
|
| 105 |
+
iupac, cas, smiles, MW, LogP, rho, mp, molImage, error = None, chemName, 'O=[Ti]=O.O=[Sb]O[Sb]=O.O=[Cr]O[Cr]=O', 1100, None, None, 1001, None, 0
|
| 106 |
+
im = ImageFromSmiles(smiles)
|
| 107 |
+
im64 = Imageto64(im)
|
| 108 |
+
molImage = im64
|
| 109 |
+
elif chemName == '14325-24-7':
|
| 110 |
+
IDtype = 'SMILES'
|
| 111 |
+
chemName = 'C1=CC=C2C(=C1)C3=NC4=NC(=NC5=C6C=CC=CC6=C([N-]5)N=C7C8=CC=CC=C8C(=N7)N=C2[N-]3)C9=CC=CC=C94.[Mn+2]'
|
| 112 |
+
iupac, cas, smiles, MW, LogP, rho, mp, molImage, error = ResolveChemical(chemName, IDtype, get_properties=get_properties)
|
| 113 |
+
#iupac, cas, smiles, MW, LogP, rho, mp, molImage, error = None, chemName, 'C1=CC=C2C(=C1)C3=NC4=NC(=NC5=C6C=CC=CC6=C([N-]5)N=C7C8=CC=CC=C8C(=N7)N=C2[N-]3)C9=CC=CC=C94.[Mn+2]', 567.5, None, None, 500, None, 0
|
| 114 |
+
#elif chemName == '1326-53-6':
|
| 115 |
+
# IDtype = 'SMILES'
|
| 116 |
+
# chemName = 'C1=C2C(=C(C(=C1Cl)Cl)Cl)C3=NC4=NC(=NC5=NC(=NC6=C7C(=C([N-]6)N=C2[N-]3)C(=C(C(=C7Cl)Cl)Cl)Cl)C8=C5C(=C(C(=C8Cl)Cl)Cl)Cl)C9=C4C(=C(C(=C9Cl)Cl)Cl)Cl.[Cu+2]'
|
| 117 |
+
# iupac, cas, smiles, MW, LogP, rho, mp, molImage, error = ResolveChemical(chemName, IDtype, get_properties=get_properties)
|
| 118 |
+
else:
|
| 119 |
+
iupac, cas, smiles, MW, LogP, rho, mp, molImage, error = ResolveChemical(chemName, IDtype, get_properties=get_properties)
|
| 120 |
+
|
| 121 |
+
if error > 0:
|
| 122 |
+
# TODO output more useful info
|
| 123 |
+
return render_template('chemError.html')
|
| 124 |
+
|
| 125 |
+
# metals/ceramics logic
|
| 126 |
+
mol = Chem.MolFromSmiles(smiles)
|
| 127 |
+
#mol = Chem.AddHs(mol)
|
| 128 |
+
#natoms = mol.GetNumAtoms()
|
| 129 |
+
ceramic = False
|
| 130 |
+
atom_num_list = [a.GetAtomicNum() for a in mol.GetAtoms()]
|
| 131 |
+
is_metal = set(atom_num_list) <= METAL_ATOM_SET
|
| 132 |
+
#is_metal = all(a.GetAtomicNum() in metal_nums for a in mol.GetAtoms())
|
| 133 |
+
#is_organic = set(atom_num_list) <= ORGANIC_ATOM_SET
|
| 134 |
+
num_CC_bonds = sum([1 if b.GetBeginAtom().GetAtomicNum() == 6 and b.GetEndAtom().GetAtomicNum() == 6 else 0 for b in mol.GetBonds()])
|
| 135 |
+
if is_metal:
|
| 136 |
+
# if all atoms are metals -> this is a metal
|
| 137 |
+
return render_template('metalError.html', show_properties=show_properties, chemName=chemName, MW=MW,
|
| 138 |
+
LogP=LogP, rho=rho, mp=mp, iupac=iupac,
|
| 139 |
+
cas=cas, smiles=smiles, molImage=molImage)
|
| 140 |
+
#LogP_origin=LogP_origin, rho_origin=rho_origin, mp_origin=mp_origin)
|
| 141 |
+
else:
|
| 142 |
+
if not num_CC_bonds and (type(mp) is float or type(mp) is int) and mp > 1000.:
|
| 143 |
+
# if not a metal and no carbon-carbon bonds but melting point > 1000, assume ceramic
|
| 144 |
+
MW = 1100.
|
| 145 |
+
ceramic = True
|
| 146 |
+
|
| 147 |
+
# Exposure type
|
| 148 |
if exposure != "limited":
|
| 149 |
time = 24.
|
| 150 |
else:
|
|
|
|
| 182 |
iMOS = SigFigs(iMOS, 2)
|
| 183 |
impurity = SigFigs(impurity, 2)
|
| 184 |
|
| 185 |
+
# Generate the rate plot using matplotlib
|
| 186 |
+
tarray = np.arange(1., 31., 1.)
|
| 187 |
+
rates = SheetRates(amount, vol, area, tarray, diff)
|
| 188 |
+
pngImageB64String = RatePlot(tarray, rates)
|
| 189 |
+
|
| 190 |
+
return render_template('color2_report.html', caIndex=caIndex, TI=TI, isCA=isCA, show_properties=show_properties, polymers=polymers, pIndex=pIndex, release=release,
|
| 191 |
+
assume=assume, area=area, vol=vol, amount=amount, diff=diff, time=time, exposure=exposure, TTC=TTC,
|
| 192 |
+
MOS=MOS, chemName=chemName, image=pngImageB64String, MW=MW, LogP=LogP, rho=rho, mp=mp, iupac=iupac, cas=cas, smiles=smiles, molImage=molImage,
|
| 193 |
+
ceramic=ceramic, impurity=impurity, iMOS=iMOS)
|
| 194 |
|
color2_module/templates/chemError.html
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<title>CHRIS-ChemError</title>
|
| 6 |
+
<link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='styles.css') }}">
|
| 7 |
+
|
| 8 |
+
</head>
|
| 9 |
+
|
| 10 |
+
<img src="{{ url_for('static',filename='images/FDAlogo.png') }}" style="float: left;" height="100"/>
|
| 11 |
+
<img src="{{ url_for('static',filename='images/FDAgraphic.png') }}" style="float: right;" height="100"/>
|
| 12 |
+
<br clear="all" />
|
| 13 |
+
|
| 14 |
+
<body>
|
| 15 |
+
|
| 16 |
+
<div style="font-size:5rem;text-align:center"> 🤦 </div>
|
| 17 |
+
|
| 18 |
+
<p style="font-size:2rem;text-align:center">
|
| 19 |
+
Uh-oh! Something went wrong. We were unable to match your chemical. Please return to the previous page and try a
|
| 20 |
+
different identifier.
|
| 21 |
+
</p>
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
</body>
|
color2_module/templates/color2_index.html
CHANGED
|
@@ -16,7 +16,7 @@
|
|
| 16 |
</header>
|
| 17 |
|
| 18 |
<p> For details on how to use the CHRIS color additive module, please read the <a href="{{url_for('.static', filename='README.html')}}"> instructions</a> and
|
| 19 |
-
<a href="
|
| 20 |
found <a href="{{url_for('.static', filename='FAQ.html')}}"> here</a>. For a history of updates, please see the <a href="{{url_for('.static', filename='Changelog.html')}}"> changelog</a>. </p>
|
| 21 |
|
| 22 |
<body>
|
|
@@ -34,11 +34,14 @@ Identity: <select name="CA" id="CA" onchange="javascript:caCheck();">
|
|
| 34 |
{% endfor %}
|
| 35 |
</select>
|
| 36 |
<span id="otherID" style="display:none">
|
| 37 |
-
⇒
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
</span> <br>
|
| 39 |
|
| 40 |
-
Molecular weight (g/mol): <input name="MW" id="MW" step="any" value="1100" min="0.0" max="1100.0" type="number" disabled required><br>
|
| 41 |
-
|
| 42 |
Amount (mg): <input name="amount" id="amount" value="1.0" step="any" min="0.000001" type="number" required> <br>
|
| 43 |
|
| 44 |
Total impurity concentration (%): <input name="impurity" id="impurity" value="0.1" step="any" min="0.000001" max='100.0' type="number" required> <br>
|
|
@@ -48,25 +51,17 @@ Total impurity concentration (%): <input name="impurity" id="impurity" value="0.
|
|
| 48 |
<script type="text/javascript">
|
| 49 |
|
| 50 |
function caCheck() {
|
| 51 |
-
var caMW = ['{{caMW[0]}}','{{caMW[1]}}','{{caMW[2]}}','{{caMW[3]}}','{{caMW[4]}}','{{caMW[5]}}','{{caMW[6]}}','{{caMW[7]}}','{{caMW[8]}}','{{caMW[9]}}','{{caMW[10]}}','{{caMW[11]}}','{{caMW[12]}}','{{caMW[13]}}'];
|
| 52 |
var iCA = parseInt(document.getElementById("CA").selectedIndex);
|
| 53 |
|
| 54 |
-
|
| 55 |
-
document.getElementById('MW').disabled = true;
|
| 56 |
document.getElementById('impurity').disabled = false;
|
| 57 |
|
| 58 |
-
if (iCA >= 13) {
|
| 59 |
-
// document.getElementById('impurity').disabled = true;
|
| 60 |
-
}
|
| 61 |
-
if (iCA >= 12) {
|
| 62 |
-
document.getElementById('MW').disabled = false;
|
| 63 |
-
}
|
| 64 |
if (iCA >= 11) {
|
| 65 |
document.getElementById('otherID').style.display = "inline";
|
| 66 |
-
document.getElementById('chemName').value = "
|
|
|
|
| 67 |
} else {
|
| 68 |
-
document.getElementById("MW").value = parseFloat(caMW[iCA]);
|
| 69 |
document.getElementById('otherID').style.display = "none";
|
|
|
|
| 70 |
}
|
| 71 |
}
|
| 72 |
|
|
@@ -83,8 +78,10 @@ $(window).on('pageshow', function() { caCheck(); });
|
|
| 83 |
<h4 class="modal-title">Color additive</h4>
|
| 84 |
</div>
|
| 85 |
<div class="modal-body">
|
| 86 |
-
<p><em>Identity</em> - Select the color additive in the component being evaluated via the pull down list.
|
| 87 |
-
|
|
|
|
|
|
|
| 88 |
<p><em>Amount</em> - Enter the total mass of the substance in the component being evaluated expressed in milligrams.</p>
|
| 89 |
<p><em>Total impurity concentration</em> - If you have selected a color additive, please enter the combined concentration of all impurities associated with the color additive as a percentage (% mass/mass).</p>
|
| 90 |
</div>
|
|
|
|
| 16 |
</header>
|
| 17 |
|
| 18 |
<p> For details on how to use the CHRIS color additive module, please read the <a href="{{url_for('.static', filename='README.html')}}"> instructions</a> and
|
| 19 |
+
<a href="{{url_for('.static', filename='COU.html')}}"> Context of Use (CoU)</a>, which includes limitations of use. Answers to frequently asked questions can be
|
| 20 |
found <a href="{{url_for('.static', filename='FAQ.html')}}"> here</a>. For a history of updates, please see the <a href="{{url_for('.static', filename='Changelog.html')}}"> changelog</a>. </p>
|
| 21 |
|
| 22 |
<body>
|
|
|
|
| 34 |
{% endfor %}
|
| 35 |
</select>
|
| 36 |
<span id="otherID" style="display:none">
|
| 37 |
+
⇒ Identifier type: <select name="IDtype">
|
| 38 |
+
<option value="CAS" selected>CAS</option>
|
| 39 |
+
<option value="SMILES" >SMILES</option>
|
| 40 |
+
<option value="common" >Common name</option>
|
| 41 |
+
</select>
|
| 42 |
+
Identifier: <input name="chemName" id="chemName" type="text" value="">
|
| 43 |
</span> <br>
|
| 44 |
|
|
|
|
|
|
|
| 45 |
Amount (mg): <input name="amount" id="amount" value="1.0" step="any" min="0.000001" type="number" required> <br>
|
| 46 |
|
| 47 |
Total impurity concentration (%): <input name="impurity" id="impurity" value="0.1" step="any" min="0.000001" max='100.0' type="number" required> <br>
|
|
|
|
| 51 |
<script type="text/javascript">
|
| 52 |
|
| 53 |
function caCheck() {
|
|
|
|
| 54 |
var iCA = parseInt(document.getElementById("CA").selectedIndex);
|
| 55 |
|
|
|
|
|
|
|
| 56 |
document.getElementById('impurity').disabled = false;
|
| 57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
if (iCA >= 11) {
|
| 59 |
document.getElementById('otherID').style.display = "inline";
|
| 60 |
+
document.getElementById('chemName').value = "";
|
| 61 |
+
document.getElementById('chemName').required = true;
|
| 62 |
} else {
|
|
|
|
| 63 |
document.getElementById('otherID').style.display = "none";
|
| 64 |
+
document.getElementById('chemName').required = false;
|
| 65 |
}
|
| 66 |
}
|
| 67 |
|
|
|
|
| 78 |
<h4 class="modal-title">Color additive</h4>
|
| 79 |
</div>
|
| 80 |
<div class="modal-body">
|
| 81 |
+
<p><em>Identity</em> - Select the color additive in the component being evaluated via the pull down list.
|
| 82 |
+
If the color additive is not explicitly listed, please choose "Other color additive" and ...
|
| 83 |
+
If you are evaluating an additive associated with a color additive please select "Other color additive associated compound" and
|
| 84 |
+
enter the chemical name and molecular weight ...
|
| 85 |
<p><em>Amount</em> - Enter the total mass of the substance in the component being evaluated expressed in milligrams.</p>
|
| 86 |
<p><em>Total impurity concentration</em> - If you have selected a color additive, please enter the combined concentration of all impurities associated with the color additive as a percentage (% mass/mass).</p>
|
| 87 |
</div>
|
color2_module/templates/color2_report.html
CHANGED
|
@@ -8,6 +8,28 @@
|
|
| 8 |
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
| 9 |
<link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='styles.css') }}">
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
</head>
|
| 12 |
|
| 13 |
<header>
|
|
@@ -20,10 +42,34 @@
|
|
| 20 |
<script> document.write(new Date().toLocaleDateString()); </script>.
|
| 21 |
</p>
|
| 22 |
|
| 23 |
-
<
|
| 24 |
-
|
| 25 |
-
<
|
| 26 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
exposure = {{release}} mg. </u>
|
| 28 |
<p>
|
| 29 |
|
|
@@ -52,7 +98,14 @@ where \( \tau= D t A^2 / V^2 \) and \( A \) and \( V \) are the surface area and
|
|
| 52 |
\( t \) = {{time}} h <br>
|
| 53 |
<p>
|
| 54 |
|
| 55 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
|
| 57 |
{% if assume[0] and assume[1] and assume[2] and assume[3] and assume[4] %}
|
| 58 |
|
|
@@ -93,7 +146,7 @@ where \( \tau= D t A^2 / V^2 \) and \( A \) and \( V \) are the surface area and
|
|
| 93 |
|
| 94 |
{% endif %}
|
| 95 |
|
| 96 |
-
<
|
| 97 |
|
| 98 |
{% if caIndex > 10 %}
|
| 99 |
|
|
@@ -164,7 +217,7 @@ of {{MOS}}.
|
|
| 164 |
|
| 165 |
{% endif %}
|
| 166 |
|
| 167 |
-
<
|
| 168 |
|
| 169 |
{% if iMOS >= 1 %}
|
| 170 |
|
|
|
|
| 8 |
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
| 9 |
<link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='styles.css') }}">
|
| 10 |
|
| 11 |
+
<style>
|
| 12 |
+
* {
|
| 13 |
+
box-sizing: border-box;
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
/* Create two equal columns that floats next to each other */
|
| 17 |
+
.column {
|
| 18 |
+
float: left;
|
| 19 |
+
width: 50%;
|
| 20 |
+
padding: 10px;
|
| 21 |
+
vertical-align: top;
|
| 22 |
+
align: center;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
/* Clear floats after the columns */
|
| 26 |
+
.row:after {
|
| 27 |
+
content: "";
|
| 28 |
+
display: table;
|
| 29 |
+
clear: both;
|
| 30 |
+
}
|
| 31 |
+
</style>
|
| 32 |
+
|
| 33 |
</head>
|
| 34 |
|
| 35 |
<header>
|
|
|
|
| 42 |
<script> document.write(new Date().toLocaleDateString()); </script>.
|
| 43 |
</p>
|
| 44 |
|
| 45 |
+
<h2> Compound </h2>
|
| 46 |
+
|
| 47 |
+
<div class="container">
|
| 48 |
+
<div class="row">
|
| 49 |
+
<div class="column">
|
| 50 |
+
Input :: {{chemName}} <br> <br>
|
| 51 |
+
IUPAC Name :: {{iupac}} <br> <br>
|
| 52 |
+
CAS :: {{cas}} <br> <br>
|
| 53 |
+
Molecular weight (g/mol) :: {{'%0.4f'%MW|float}}
|
| 54 |
+
{% if ceramic %} :: ceramic detected, assume maximum Mw {% endif %}
|
| 55 |
+
<br> <br>
|
| 56 |
+
{% if show_properties %}
|
| 57 |
+
LogKow :: {{LogP}}{{LogP_origin}}<br> <br>
|
| 58 |
+
Density (g/cm<sup>3</sup>) :: {{rho}}{{rho_origin}}<br> <br>
|
| 59 |
+
Melting point (°C) :: {{mp}}{{mp_origin}}<br> <br>
|
| 60 |
+
{% endif %}
|
| 61 |
+
SMILES :: {{smiles}}
|
| 62 |
+
</div>
|
| 63 |
+
<div class="column">
|
| 64 |
+
<img src="{{molImage}}"/>
|
| 65 |
+
</div>
|
| 66 |
+
</div>
|
| 67 |
+
</div>
|
| 68 |
+
|
| 69 |
+
<h2>Exposure </h2>
|
| 70 |
+
|
| 71 |
+
<p>
|
| 72 |
+
<u> Diffusion calculation for leaching from {{polymers[pIndex]}} estimates a worst case single day
|
| 73 |
exposure = {{release}} mg. </u>
|
| 74 |
<p>
|
| 75 |
|
|
|
|
| 98 |
\( t \) = {{time}} h <br>
|
| 99 |
<p>
|
| 100 |
|
| 101 |
+
<p>
|
| 102 |
+
In addition to the maximum daily (day 1) release rate, it can be helpful to examine the decay in release rate over time predicted by the model,
|
| 103 |
+
which is illustrated for the first 30 days of exposure in the plot below:
|
| 104 |
+
</p>
|
| 105 |
+
|
| 106 |
+
<img src="{{ image }}"/>
|
| 107 |
+
|
| 108 |
+
<h2> Assumptions </h2>
|
| 109 |
|
| 110 |
{% if assume[0] and assume[1] and assume[2] and assume[3] and assume[4] %}
|
| 111 |
|
|
|
|
| 146 |
|
| 147 |
{% endif %}
|
| 148 |
|
| 149 |
+
<h2> Screening level toxicological risk assessment </h2>
|
| 150 |
|
| 151 |
{% if caIndex > 10 %}
|
| 152 |
|
|
|
|
| 217 |
|
| 218 |
{% endif %}
|
| 219 |
|
| 220 |
+
<h2> Impurities </h2>
|
| 221 |
|
| 222 |
{% if iMOS >= 1 %}
|
| 223 |
|
color2_module/templates/metalError.html
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<title>CHRIS-ChemError</title>
|
| 6 |
+
<link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='styles.css') }}">
|
| 7 |
+
|
| 8 |
+
<style>
|
| 9 |
+
* {
|
| 10 |
+
box-sizing: border-box;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
/* Create two equal columns that floats next to each other */
|
| 14 |
+
.column {
|
| 15 |
+
float: left;
|
| 16 |
+
width: 50%;
|
| 17 |
+
padding: 10px;
|
| 18 |
+
vertical-align: top;
|
| 19 |
+
align: center;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
/* Clear floats after the columns */
|
| 23 |
+
.row:after {
|
| 24 |
+
content: "";
|
| 25 |
+
display: table;
|
| 26 |
+
clear: both;
|
| 27 |
+
}
|
| 28 |
+
</style>
|
| 29 |
+
|
| 30 |
+
</head>
|
| 31 |
+
|
| 32 |
+
<img src="{{ url_for('static',filename='images/FDAlogo.png') }}" style="float: left;" height="100"/>
|
| 33 |
+
<img src="{{ url_for('static',filename='images/FDAgraphic.png') }}" style="float: right;" height="100"/>
|
| 34 |
+
<br clear="all" />
|
| 35 |
+
|
| 36 |
+
<body>
|
| 37 |
+
|
| 38 |
+
<div style="font-size:5rem;text-align:center"> 🤦 </div>
|
| 39 |
+
|
| 40 |
+
<h2> Compound </h2>
|
| 41 |
+
|
| 42 |
+
<div class="container">
|
| 43 |
+
<div class="row">
|
| 44 |
+
<div class="column">
|
| 45 |
+
Input :: {{chemName}} <br> <br>
|
| 46 |
+
IUPAC Name :: {{iupac}} <br> <br>
|
| 47 |
+
CAS :: {{cas}} <br> <br>
|
| 48 |
+
Molecular weight (g/mol) :: {{'%0.4f'%MW|float}} <br> <br>
|
| 49 |
+
{% if show_properties %}
|
| 50 |
+
LogKow :: {{LogP}}{{LogP_origin}} <br> <br>
|
| 51 |
+
Density (g/cm<sup>3</sup>) :: {{rho}}{{rho_origin}} <br> <br>
|
| 52 |
+
Melting point (°C) :: {{mp}}{{mp_origin}} <br> <br>
|
| 53 |
+
{% endif %}
|
| 54 |
+
SMILES :: {{smiles}}
|
| 55 |
+
</div>
|
| 56 |
+
<div class="column">
|
| 57 |
+
<img src="{{molImage}}"/>
|
| 58 |
+
</div>
|
| 59 |
+
</div>
|
| 60 |
+
</div>
|
| 61 |
+
|
| 62 |
+
<p style="font-size:2rem;text-align:center">
|
| 63 |
+
Unfortunately, CHRIS cannot be used for metals. Please return to the previous page to evaluate
|
| 64 |
+
a different chemical.
|
| 65 |
+
</p>
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
</body>
|
efficiency_module/static/efficiency_COU.html
CHANGED
|
@@ -42,20 +42,20 @@ The salient limitations are enumerated below:</p>
|
|
| 42 |
Therefore, the output is only applicable to compounds that are
|
| 43 |
introduced either intentionally or unintentionally during synthesis
|
| 44 |
(e.g., residual monomers and oligomers, catalysts, initiators) or
|
| 45 |
-
compounding (e.g., stabilizers, antioxidants, plasticizers)
|
| 46 |
-
|
| 47 |
-
|
| 48 |
<li>The solvent is “perfectly mixed”. This should be a reasonable
|
| 49 |
-
assumption provided the samples are adequately agitated
|
| 50 |
-
|
| 51 |
-
appropriate if sufficient agitation is not applied and a
|
| 52 |
-
develops that slows the release rate or if the extraction
|
| 53 |
-
under flow conditions.</li>
|
| 54 |
<li>Possible chemical reactions are not considered. Therefore, if the
|
| 55 |
polymer matrix undergoes substantive degradation during the extraction
|
| 56 |
test, the predictions may not be relevant. Further, the model does not
|
| 57 |
-
consider the potential for individual extractable compounds to
|
| 58 |
-
|
| 59 |
<li>The test article is comprised of a single polymer matrix. In
|
| 60 |
practice, complex devices may be comprised of multiple components and/or
|
| 61 |
polymer matrices. In these scenarios, careful consideration of the
|
|
|
|
| 42 |
Therefore, the output is only applicable to compounds that are
|
| 43 |
introduced either intentionally or unintentionally during synthesis
|
| 44 |
(e.g., residual monomers and oligomers, catalysts, initiators) or
|
| 45 |
+
compounding (e.g., stabilizers, antioxidants, plasticizers). The model
|
| 46 |
+
is not appropriate for surface residuals from processing, cleaning, and
|
| 47 |
+
sterilization.</li>
|
| 48 |
<li>The solvent is “perfectly mixed”. This should be a reasonable
|
| 49 |
+
assumption provided the samples are adequately agitated over the
|
| 50 |
+
timeframe of the testing. However, this assumption may not be
|
| 51 |
+
appropriate if sufficient agitation is not applied and a signficant
|
| 52 |
+
boundary layer develops that slows the release rate or if the extraction
|
| 53 |
+
is conducted under flow conditions.</li>
|
| 54 |
<li>Possible chemical reactions are not considered. Therefore, if the
|
| 55 |
polymer matrix undergoes substantive degradation during the extraction
|
| 56 |
test, the predictions may not be relevant. Further, the model does not
|
| 57 |
+
consider the potential for individual extractable compounds to degrade
|
| 58 |
+
over the selected timeframe.</li>
|
| 59 |
<li>The test article is comprised of a single polymer matrix. In
|
| 60 |
practice, complex devices may be comprised of multiple components and/or
|
| 61 |
polymer matrices. In these scenarios, careful consideration of the
|
exposure2_module/exposure.py
CHANGED
|
@@ -71,7 +71,7 @@ def exp_post():
|
|
| 71 |
# metals/ceramics logic
|
| 72 |
mol = Chem.MolFromSmiles(smiles)
|
| 73 |
mol = Chem.AddHs(mol)
|
| 74 |
-
natoms = mol.GetNumAtoms()
|
| 75 |
metal_nums = [3,4,11,12,13] + list(range(19,31+1)) + list(range(37,50+1)) + list(range(55,84+1)) + list(range(87,114+1)) + [116]
|
| 76 |
ceramic = False
|
| 77 |
if all(a.GetAtomicNum() in metal_nums for a in mol.GetAtoms()):
|
|
|
|
| 71 |
# metals/ceramics logic
|
| 72 |
mol = Chem.MolFromSmiles(smiles)
|
| 73 |
mol = Chem.AddHs(mol)
|
| 74 |
+
#natoms = mol.GetNumAtoms()
|
| 75 |
metal_nums = [3,4,11,12,13] + list(range(19,31+1)) + list(range(37,50+1)) + list(range(55,84+1)) + list(range(87,114+1)) + [116]
|
| 76 |
ceramic = False
|
| 77 |
if all(a.GetAtomicNum() in metal_nums for a in mol.GetAtoms()):
|