dmsaylor commited on
Commit
5a1cfb4
Β·
1 Parent(s): 0df3462

New version with front end to allow for additional modules to be added in the future.

Browse files
.gitignore CHANGED
@@ -1,5 +1,5 @@
1
  __pycache__/*
2
  .idea/*
3
  .DS_Store
4
- static/.DS_Store
5
 
 
1
  __pycache__/*
2
  .idea/*
3
  .DS_Store
4
+ color_module/static/.DS_Store
5
 
CHRIS.py CHANGED
@@ -1,123 +1,14 @@
1
- from flask import Flask, render_template, request
2
- import numpy as np
3
- from functions import SigFigs, Piringer, WilkeChang, SheetRelease
4
- from polymers import Polymers
5
-
6
- # load polymer data including Ap values
7
- polymers, Ap = Polymers()
8
-
9
- # Named color additives, TI values, and Mw
10
- nCA = 14
11
- caData = np.zeros((nCA,), dtype=[('name', 'a75'), ('TI', 'd'), ('MW', 'd')])
12
- caData[0] = ('Titanium dioxide (CAS#:13463-67-7)', 1.0, 1100.)
13
- caData[1] = ('Carbon black (CAS#:1333-86-4)', 2.0, 1100.)
14
- caData[2] = ('Pigment brown 24 (CAS#:68186-90-3)', 0.5, 1100.)
15
- caData[3] = ('Zinc Oxide (CAS#:1314-13-2)', 0.05, 1100.)
16
- caData[4] = ('Pigment Red 101 (CAS#: 1309-37-1)', 1.0, 1100.)
17
- caData[5] = ('Solvent violet 13 (CAS#:81-48-1)', 0.0013, 319.4)
18
- caData[6] = ('Manganese phthalocyanine (CAS#:14325-24-7)', 0.15, 567.5)
19
- caData[7] = ('Pigment blue 15 (CAS#:147-14-8)', 0.15, 576.1)
20
- caData[8] = ('Phthalocyanine green (CAS#:1326-53-6)', 0.15, 1092.8)
21
- caData[9] = ('Ultramarine blue (CAS#:57445-37-5)', 3.3, 1100.)
22
- caData[10] = ('Pigment Yellow 138 (CAS#:30125-47-4)', 1.0, 693.96)
23
- caData[11] = ('Other metal oxide color additive', 1.0, 1100.0)
24
- caData[12] = ('Other non-metal oxide color additive', 1.0, 1100.0)
25
- caData[13] = ('Other color additive associated compound', 1.0, 1100.0)
26
-
27
- CAs = np.zeros(nCA, dtype='object')
28
- caMW = np.zeros(nCA, dtype='object')
29
- for i in range(nCA):
30
- CAs[i] = caData[i][0].decode('UTF-8')
31
- for i in range(nCA):
32
- caMW[i] = caData[i][2]
33
 
34
  app = Flask(__name__)
35
- app.debug = False
36
 
 
 
37
 
38
  @app.route('/', methods=['GET'])
39
  def app_init():
40
- return render_template('index.html', polymers=polymers, CAs=CAs, caMW=caMW)
41
-
42
-
43
- @app.route('/', methods=['POST'])
44
- def app_post():
45
- amount = float(request.form["amount"])
46
- mass = float(request.form["mass"])
47
- density = float(request.form["density"])
48
- vol = mass / density
49
- polymer = request.form["polymer"]
50
- pIndex = (np.where(polymers == polymer)[0])[0]
51
- area = float(request.form["area"])
52
- exposure = request.form["exposure"]
53
- CA = request.form["CA"]
54
- caIndex = (np.where(CAs == CA)[0])[0]
55
-
56
- TI = caData[caIndex][1]
57
- impurity = 1.
58
- MW = 1100.
59
- isCA = True
60
- chemName = ''
61
-
62
- if caIndex < 11:
63
- MW = caData[caIndex][2]
64
- chemName = '*' + caData[caIndex][0].decode('UTF-8') + '*'
65
- impurity = float(request.form["impurity"]) * amount * 1e-2
66
- if caIndex == 11:
67
- MW = caData[caIndex][2]
68
- chemName = request.form["chemName"] if "chemName" in request.form else "CHEMICAL NAME NOT PROVIDED"
69
- chemName = '*' + chemName + '*'
70
- impurity = float(request.form["impurity"]) * amount * 1e-2
71
- if caIndex == 12:
72
- MW = float(request.form["MW"])
73
- chemName = request.form["chemName"] if "chemName" in request.form else "CHEMICAL NAME NOT PROVIDED"
74
- chemName = '*' + chemName + '*'
75
- impurity = float(request.form["impurity"]) * amount * 1e-2
76
- if caIndex == 13:
77
- isCA = False
78
- MW = float(request.form["MW"])
79
- chemName = request.form["chemName"] if "chemName" in request.form else "CHEMICAL NAME NOT PROVIDED"
80
- chemName = '*' + chemName + '*'
81
-
82
- if exposure != "limited":
83
- time = 24.
84
- else:
85
- time = float(request.form["exptime"])
86
- if exposure != "long-term":
87
- TTC = 0.12
88
- else:
89
- TTC = 0.0015
90
-
91
- assume = np.array((request.form.get("assume1") is not None, request.form.get("assume2") is not None,
92
- request.form.get("assume3") is not None, request.form.get("assume4") is not None,
93
- request.form.get("assume5") is not None))
94
-
95
- if not np.isnan(Ap[pIndex]):
96
- diff = Piringer(MW, Ap[pIndex])
97
- else:
98
- diff = WilkeChang(MW)
99
-
100
- release = SheetRelease(amount, vol, area, time, diff)
101
-
102
- if caIndex > 10:
103
- MOS = TTC / release
104
- else:
105
- MOS = 50. * TI / release
106
-
107
- iMOS = TTC / impurity
108
-
109
- release = SigFigs(release, 2)
110
- MOS = SigFigs(MOS, 2)
111
- diff = SigFigs(diff, 2)
112
- iMOS = SigFigs(iMOS, 2)
113
- impurity = SigFigs(impurity, 2)
114
-
115
- return render_template('report.html', polymers=polymers, pIndex=pIndex, caIndex=caIndex, release=release,
116
- assume=assume,
117
- area=area, vol=vol, amount=amount, diff=diff, time=time, exposure=exposure, TTC=TTC,
118
- isCA=isCA, TI=TI, MOS=MOS,
119
- chemName=chemName, impurity=impurity, iMOS=iMOS)
120
-
121
 
122
  if __name__ == '__main__':
123
  app.run()
 
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)
8
 
9
  @app.route('/', methods=['GET'])
10
  def app_init():
11
+ return render_template('main.html')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  if __name__ == '__main__':
14
  app.run()
color_module/__init__.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ from flask import Blueprint
2
+
3
+ blueprint = Blueprint('color_module', __name__, template_folder='templates', static_folder='static', static_url_path='/color_module')
4
+
5
+ from . import colors
color_module/colors.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request
2
+ import numpy as np
3
+ from functions import SigFigs, Piringer, WilkeChang, SheetRelease
4
+ from . import blueprint
5
+ from polymers import Polymers
6
+
7
+ # load polymer data including Ap values
8
+ polymers, Ap = Polymers()
9
+
10
+ # Named color additives, TI values, and Mw
11
+ nCA = 14
12
+ caData = np.zeros((nCA,), dtype=[('name', 'a75'), ('TI', 'd'), ('MW', 'd')])
13
+ caData[0] = ('Titanium dioxide (CAS#:13463-67-7)', 1.0, 1100.)
14
+ caData[1] = ('Carbon black (CAS#:1333-86-4)', 2.0, 1100.)
15
+ caData[2] = ('Pigment brown 24 (CAS#:68186-90-3)', 0.5, 1100.)
16
+ caData[3] = ('Zinc Oxide (CAS#:1314-13-2)', 0.05, 1100.)
17
+ caData[4] = ('Pigment Red 101 (CAS#: 1309-37-1)', 1.0, 1100.)
18
+ caData[5] = ('Solvent violet 13 (CAS#:81-48-1)', 0.0013, 319.4)
19
+ caData[6] = ('Manganese phthalocyanine (CAS#:14325-24-7)', 0.15, 567.5)
20
+ caData[7] = ('Pigment blue 15 (CAS#:147-14-8)', 0.15, 576.1)
21
+ caData[8] = ('Phthalocyanine green (CAS#:1326-53-6)', 0.15, 1092.8)
22
+ caData[9] = ('Ultramarine blue (CAS#:57445-37-5)', 3.3, 1100.)
23
+ caData[10] = ('Pigment Yellow 138 (CAS#:30125-47-4)', 1.0, 693.96)
24
+ caData[11] = ('Other metal oxide color additive', 1.0, 1100.0)
25
+ caData[12] = ('Other non-metal oxide color additive', 1.0, 1100.0)
26
+ caData[13] = ('Other color additive associated compound', 1.0, 1100.0)
27
+
28
+ CAs = np.zeros(nCA, dtype='object')
29
+ caMW = np.zeros(nCA, dtype='object')
30
+ for i in range(nCA):
31
+ CAs[i] = caData[i][0].decode('UTF-8')
32
+ for i in range(nCA):
33
+ caMW[i] = caData[i][2]
34
+
35
+ app = Flask(__name__)
36
+ app.debug = False
37
+
38
+
39
+ @blueprint.route('/color', methods=['GET'])
40
+ def colors():
41
+ return render_template('index.html', polymers=polymers, CAs=CAs, caMW=caMW)
42
+
43
+
44
+ @blueprint.route('/color', methods=['POST'])
45
+ def app_post():
46
+ amount = float(request.form["amount"])
47
+ mass = float(request.form["mass"])
48
+ density = float(request.form["density"])
49
+ vol = mass / density
50
+ polymer = request.form["polymer"]
51
+ pIndex = (np.where(polymers == polymer)[0])[0]
52
+ area = float(request.form["area"])
53
+ exposure = request.form["exposure"]
54
+ CA = request.form["CA"]
55
+ caIndex = (np.where(CAs == CA)[0])[0]
56
+
57
+ TI = caData[caIndex][1]
58
+ impurity = 1.
59
+ MW = 1100.
60
+ isCA = True
61
+ chemName = ''
62
+
63
+ if caIndex < 11:
64
+ MW = caData[caIndex][2]
65
+ chemName = '*' + caData[caIndex][0].decode('UTF-8') + '*'
66
+ impurity = float(request.form["impurity"]) * amount * 1e-2
67
+ if caIndex == 11:
68
+ MW = caData[caIndex][2]
69
+ chemName = request.form["chemName"] if "chemName" in request.form else "CHEMICAL NAME NOT PROVIDED"
70
+ chemName = '*' + chemName + '*'
71
+ impurity = float(request.form["impurity"]) * amount * 1e-2
72
+ if caIndex == 12:
73
+ MW = float(request.form["MW"])
74
+ chemName = request.form["chemName"] if "chemName" in request.form else "CHEMICAL NAME NOT PROVIDED"
75
+ chemName = '*' + chemName + '*'
76
+ impurity = float(request.form["impurity"]) * amount * 1e-2
77
+ if caIndex == 13:
78
+ isCA = False
79
+ MW = float(request.form["MW"])
80
+ chemName = request.form["chemName"] if "chemName" in request.form else "CHEMICAL NAME NOT PROVIDED"
81
+ chemName = '*' + chemName + '*'
82
+
83
+ if exposure != "limited":
84
+ time = 24.
85
+ else:
86
+ time = float(request.form["exptime"])
87
+ if exposure != "long-term":
88
+ TTC = 0.12
89
+ else:
90
+ TTC = 0.0015
91
+
92
+ assume = np.array((request.form.get("assume1") is not None, request.form.get("assume2") is not None,
93
+ request.form.get("assume3") is not None, request.form.get("assume4") is not None,
94
+ request.form.get("assume5") is not None))
95
+
96
+ if not np.isnan(Ap[pIndex]):
97
+ diff = Piringer(MW, Ap[pIndex])
98
+ else:
99
+ diff = WilkeChang(MW)
100
+
101
+ release = SheetRelease(amount, vol, area, time, diff)
102
+
103
+ if caIndex > 10:
104
+ MOS = TTC / release
105
+ else:
106
+ MOS = 50. * TI / release
107
+
108
+ iMOS = TTC / impurity
109
+
110
+ release = SigFigs(release, 2)
111
+ MOS = SigFigs(MOS, 2)
112
+ diff = SigFigs(diff, 2)
113
+ iMOS = SigFigs(iMOS, 2)
114
+ impurity = SigFigs(impurity, 2)
115
+
116
+ return render_template('report.html', polymers=polymers, pIndex=pIndex, caIndex=caIndex, release=release,
117
+ assume=assume,
118
+ area=area, vol=vol, amount=amount, diff=diff, time=time, exposure=exposure, TTC=TTC,
119
+ isCA=isCA, TI=TI, MOS=MOS,
120
+ chemName=chemName, impurity=impurity, iMOS=iMOS)
121
+
{static β†’ color_module/static}/COU.html RENAMED
File without changes
{static β†’ color_module/static}/COU.md RENAMED
File without changes
{static β†’ color_module/static}/Changelog.html RENAMED
File without changes
{static β†’ color_module/static}/Changelog.md RENAMED
File without changes
{static β†’ color_module/static}/FAQ.html RENAMED
File without changes
{static β†’ color_module/static}/FAQ.md RENAMED
File without changes
{static β†’ color_module/static}/README.html RENAMED
File without changes
{static β†’ color_module/static}/README.md RENAMED
File without changes
color_module/static/images/FDAgraphic.png ADDED

Git LFS Details

  • SHA256: 309a923bc8a29fa479d28c5421f671274bf5c08667207630467bce622fa635fb
  • Pointer size: 130 Bytes
  • Size of remote file: 90.2 kB
color_module/static/images/FDAlogo.png ADDED

Git LFS Details

  • SHA256: b77c9db36215bee929580dba4ba52fe335ab4d35c750cc60e1d1922d348a4dd3
  • Pointer size: 130 Bytes
  • Size of remote file: 26.2 kB
{static β†’ color_module/static}/md2html.sh RENAMED
File without changes
color_module/static/styles.css ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {font-family: Arial, Helvetica, sans-serif;}
2
+
3
+ /* The Modal (background) */
4
+ .modal {
5
+ display: none; /* Hidden by default */
6
+ position: fixed; /* Stay in place */
7
+ z-index: 1; /* Sit on top */
8
+ padding-top: 100px; /* Location of the box */
9
+ left: 0;
10
+ top: 0;
11
+ width: 100%; /* Full width */
12
+ height: 100%; /* Full height */
13
+ max-height: calc(100vh - 210px);
14
+ overflow: auto; /* Enable scroll if needed */
15
+ background-color: rgb(0,0,0); /* Fallback color */
16
+ background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
17
+ }
18
+
19
+ /* Modal Content */
20
+ .modal-content {
21
+ background-color: #fefefe;
22
+ margin: auto;
23
+ padding: 20px;
24
+ border: 1px solid #888;
25
+ width: 80%;
26
+ }
27
+
28
+ /* The Close Button */
29
+ .close {
30
+ color: #aaaaaa;
31
+ float: right;
32
+ font-size: 28px;
33
+ font-weight: bold;
34
+ }
35
+
36
+ .close:hover,
37
+ .close:focus {
38
+ color: #000;
39
+ text-decoration: none;
40
+ cursor: pointer;
41
+ }
42
+
{templates β†’ color_module/templates}/index.html RENAMED
@@ -12,7 +12,7 @@
12
  </head>
13
 
14
  <header>
15
- <h1 style="text-align:center">CHRIS: <font color="#0070C0">C</font>olor <font color="#0070C0">H</font>azard and <font color="#0070C0">RIS</font>k calculator</h1>
16
  </header>
17
 
18
  <p> For details on how to use CHRIS, please read the <a href="{{url_for('static', filename='README.html')}}"> instructions.</a> and
 
12
  </head>
13
 
14
  <header>
15
+ <h1 style="text-align:center"><font color="#0070C0">CH</font>emical <font color="#0070C0">RIS</font>k calculator (CHRIS) - Color additives </h1>
16
  </header>
17
 
18
  <p> For details on how to use CHRIS, please read the <a href="{{url_for('static', filename='README.html')}}"> instructions.</a> and
{templates β†’ color_module/templates}/report.html RENAMED
@@ -11,7 +11,7 @@
11
  </head>
12
 
13
  <header>
14
- <h1 style="text-align:center"><font color="#0070C0">C</font>olor <font color="#0070C0">H</font>azard and <font color="#0070C0">RIS</font>k calculator (CHRIS) Report </h1>
15
  </header>
16
 
17
  <body>
 
11
  </head>
12
 
13
  <header>
14
+ <h1 style="text-align:center"><font color="#0070C0">CH</font>emical <font color="#0070C0">RIS</font>k calculator (CHRIS) Report - Color additives </h1>
15
  </header>
16
 
17
  <body>
templates/main.html ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>CHRIS</title>
6
+
7
+ </head>
8
+
9
+ <img src="{{ url_for('static',filename='images/FDAlogo.png') }}" style="float: left;" height="100"/>
10
+ <img src="{{ url_for('static',filename='images/FDAgraphic.png') }}" style="float: right;" height="100"/>
11
+ <br clear="all" />
12
+
13
+ <header>
14
+ <h1 style="text-align:center">CHRIS: <font color="#0070C0">CH</font>emical <font color="#0070C0">RIS</font>k calculator</h1>
15
+ </header>
16
+
17
+ <body>
18
+
19
+ <p>
20
+ The CHemical RISk calculator (CHRIS) is a collection of MDDT-qualified modules to facilitate the use of physics-based models to estimate exposure
21
+ as part of toxicological risk assessment (TRA) of medical device polymers.
22
+ </p>
23
+
24
+ <p>
25
+ Currently, there is only one MDDT-qualified module available. However, there is a development version that includes additional modules
26
+ and functionality available here.
27
+ </p>
28
+
29
+ <h2>Modules</h2>
30
+
31
+ 1. <a href="/color"> Color additives </a>
32
+
33
+ <p>
34
+ A tool to conduct screening level risk assessments to aid in the biocompatibility evaluation of polymeric medical device components
35
+ that contain color additives (CAs). These assessments can assist device manufacturers by providing instantaneous feedback on whether
36
+ the presence of CAs or other additives and impurities associated with CAs in a device would require additional justification and/or
37
+ testing to demonstrate acceptable biological risk.
38
+ </p>
39
+
40
+
41
+ </body>