├── Abstract.pdf ├── Instruction Manual.pdf ├── LICENSE ├── README.md ├── dist ├── elixir-0.0.1-py3-none-any.whl ├── elixir-0.0.1.tar.gz ├── elixir-0.0.2-py3-none-any.whl ├── elixir-0.0.2.tar.gz ├── elixir-0.0.3-py3-none-any.whl └── elixir-0.0.3.tar.gz ├── elixir app ├── Media │ └── unnamed.jpg ├── v1.py ├── v1_updated.py ├── v2.py └── v3 ├── elixir.egg-info ├── Na.md ├── PKG-INFO ├── SOURCES.txt ├── dependency_links.txt ├── requires.txt └── top_level.txt ├── elixir ├── __init__.py ├── arterialNetwork.py ├── artery.py ├── cantorProject │ ├── __init__.py │ ├── network.py │ ├── sci_trainer.py │ └── tfp_trainer.py ├── solver.py └── utils.py ├── photo.png ├── pyproject.toml └── setup.py /Abstract.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VANRao-Stack/elixir/6d4c5277c6918d052b6296d531bcd0e0bf523dc3/Abstract.pdf -------------------------------------------------------------------------------- /Instruction Manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VANRao-Stack/elixir/6d4c5277c6918d052b6296d531bcd0e0bf523dc3/Instruction Manual.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 V Abhijith Rao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Elixir 2 | 3 | Modeling blood flow and especially the propagation of the pulse wave in systemic 4 | arteries is a topic that is interesting to the medical society since the shape of the 5 | pressure profiles has diagnostic significance. We build a package that can 6 | simulate blood flow and pressure in large arteries by solving a nonlinear onedimensional 7 | model based on the incompressible Navier-Stokes equations for a 8 | Newtonian fluid in an elastic tube. Our method, however, does not require the 9 | usage of discretized methods for solving differential equations such as the 10 | popular Lax-Wendroff method (LW) but instead uses automatic differentiation to 11 | achieve a similar result. 12 | 13 | Modeling blood flow and pressure in the systemic arteries has been a topic of 14 | interest both to theoretical and clinical investigators. Thus, research in this area 15 | has a vital interdisciplinary aspect. This project aims to develop a package capable 16 | of performing such simulations using the models we develop to treat 17 | cardiovascular diseases better. This is important since most deaths in developed 18 | countries result from cardiovascular diseases, mostly associated with abnormal 19 | flow in the arteries. 20 | 21 | The original project's inspiration arose from previous and present efforts to 22 | develop an anaesthesia simulator based on mathematical models. An important 23 | part of which is having a good model for the cardiovascular system. 24 | However, as stated previously, the traditional focus of such projects generally is 25 | developing a good model. 26 | 27 | The choice of the method to be used to solve the associated equations generally 28 | comes from a standard list of such methods. 29 | 30 | We present a new method that, unlike its predecessors, offers a continuous 31 | solution, along with other benefits such as GPU support, a massive community, 32 | and such like. 33 | 34 | ## Usage 35 | 36 | Please refer to the [instruction manual](https://github.com/VANRao-Stack/elixir/blob/main/Instruction%20Manual.pdf) for instructions on how to set up and use the python package. 37 | 38 | ## Paper 39 | 40 | Please refer to the [abstract](https://github.com/VANRao-Stack/elixir/blob/main/Abstract.pdf) for information regarding the theory and implementational details of the project. 41 | 42 | Watch our video that highlights the fundamental idea of the project. 43 | 44 | [![Project Elixir - Team Disrupt](photo.png)](https://youtu.be/8Q4nvnozVsI "Project Elixir - Team Disrupt") 45 | -------------------------------------------------------------------------------- /dist/elixir-0.0.1-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VANRao-Stack/elixir/6d4c5277c6918d052b6296d531bcd0e0bf523dc3/dist/elixir-0.0.1-py3-none-any.whl -------------------------------------------------------------------------------- /dist/elixir-0.0.1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VANRao-Stack/elixir/6d4c5277c6918d052b6296d531bcd0e0bf523dc3/dist/elixir-0.0.1.tar.gz -------------------------------------------------------------------------------- /dist/elixir-0.0.2-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VANRao-Stack/elixir/6d4c5277c6918d052b6296d531bcd0e0bf523dc3/dist/elixir-0.0.2-py3-none-any.whl -------------------------------------------------------------------------------- /dist/elixir-0.0.2.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VANRao-Stack/elixir/6d4c5277c6918d052b6296d531bcd0e0bf523dc3/dist/elixir-0.0.2.tar.gz -------------------------------------------------------------------------------- /dist/elixir-0.0.3-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VANRao-Stack/elixir/6d4c5277c6918d052b6296d531bcd0e0bf523dc3/dist/elixir-0.0.3-py3-none-any.whl -------------------------------------------------------------------------------- /dist/elixir-0.0.3.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VANRao-Stack/elixir/6d4c5277c6918d052b6296d531bcd0e0bf523dc3/dist/elixir-0.0.3.tar.gz -------------------------------------------------------------------------------- /elixir app/Media/unnamed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VANRao-Stack/elixir/6d4c5277c6918d052b6296d531bcd0e0bf523dc3/elixir app/Media/unnamed.jpg -------------------------------------------------------------------------------- /elixir app/v1.py: -------------------------------------------------------------------------------- 1 | from kivy.app import App 2 | from kivy.uix.widget import Widget 3 | from kivy.uix.boxlayout import BoxLayout 4 | from kivy.graphics import Rectangle 5 | from kivy.core.window import Window 6 | from kivy.uix.button import Button 7 | from kivy.uix.gridlayout import GridLayout 8 | from kivy.uix.textinput import TextInput 9 | from kivy.properties import ObjectProperty 10 | from kivy.uix.screenmanager import Screen,ScreenManager,CardTransition 11 | from kivy.lang import Builder 12 | from kivymd.app import MDApp 13 | from kivymd.uix.textfield import MDTextField 14 | from kivymd.uix.button import MDFillRoundFlatButton,MDIconButton 15 | from kivymd.uix.label import MDIcon 16 | import elixir as ex 17 | import matplotlib.pyplot as plt 18 | import numpy as np 19 | 20 | 21 | Builder.load_string(""" 22 | : 23 | background_color: (1, 1, 1, 1) 24 | canvas.before: 25 | Color: 26 | rgba: root.background_color 27 | Rectangle: 28 | size: self.size 29 | pos: self.pos 30 | : 31 | icon:"home-circle-outline" 32 | theme_text_color:"Custom" 33 | #text_color:(135/255,0,106/255,1) 34 | text_color:(1,1,1,1) 35 | user_font_size: "80sp" 36 | on_release: 37 | app.root.current = "input" 38 | : 39 | icon:"help" 40 | theme_text_color:"Custom" 41 | #text_color :(135/255,0,106/255,1) 42 | text_color:(1,1,1,1) 43 | user_font_size : "80sp" 44 | : 45 | orientation:"vertical" 46 | canvas.before: 47 | Color: 48 | rgba:(0/255,155/255,133/255,1) 49 | Rectangle: 50 | size:self.size 51 | pos:self.pos 52 | Label: 53 | size_hint:(1,0.3) 54 | text:"Elixir" 55 | font_size:"30sp" 56 | HomeButton: 57 | size_hint:(1,.5) 58 | #pos_hint:{"center_x":.5,"center_y":.5} 59 | #icon:"home-variant-outline" 60 | AboutButton: 61 | size_hint:(1,0.5) 62 | BoxLayout: 63 | : 64 | background_color:(0/255,155/255,133/255,1) 65 | color:(1,1,1,1) 66 | : 67 | background_color:(135/255,0,106/255,1) 68 | : 69 | name : "input" 70 | upStr:upStr 71 | downStr:downStr 72 | timePeriod:timePeriod 73 | length:length 74 | BoxLayout: 75 | orientation: "horizontal" 76 | SideBar: 77 | size_hint : 0.3,1 78 | 79 | RelativeLayout: 80 | Image: 81 | source: "./Media/BlueCum.jpg" 82 | allow_stretch: True 83 | keep_ratio: False 84 | #canvas.before: 85 | #Color: 86 | #rgba:(0,2/255,46/255,1) 87 | #rgba:(.5,.5,.5,.5) 88 | #Rectangle: 89 | #pos:root.pos 90 | #size:root.size 91 | 92 | BoxLayout: 93 | pos_hint: {"center_x":.5,"center_y":.5} 94 | size_hint : .6,.65 95 | orientation:"vertical" 96 | canvas.before: 97 | Color: 98 | rgba:(1,1,1,1) 99 | Rectangle: 100 | pos:self.pos 101 | size:self.size 102 | GridLayout: 103 | cols:2 104 | rows:4 105 | spacing:[0,20] 106 | padding:[20,20] 107 | size_hint: (1,.8) 108 | ColorLabel: 109 | text:"Upstream Radius (Ru)" 110 | TextInput: 111 | id:upStr 112 | fill_color:(.5,.5,0,1) 113 | #hint_text: "Up stream Radius" 114 | #hint_text_color: (1,0,0,1) 115 | ColorLabel: 116 | text:"Downstream Radius (Rd) " 117 | TextInput: 118 | id:downStr 119 | ColorLabel: 120 | text:"Time period" 121 | TextInput: 122 | id:timePeriod 123 | ColorLabel: 124 | text:"Length" 125 | TextInput: 126 | id:length 127 | BoxLayout: 128 | orientation:"horizontal" 129 | size_hint:1,0.1 130 | RelativeLayout: 131 | MDFillRoundFlatButton: 132 | text: "Advanced" 133 | #text_size:self.width, None 134 | theme_text_color: "Custom" 135 | text_color: 1, 1, 1, 1 136 | md_bg_color: (0/255,155/255,133/255,1) 137 | size_hint : 0.5,0.7 138 | pos_hint:{'center_x':.5,'center_y':.7} 139 | on_release: 140 | app.root.current = "advancedinput" 141 | RelativeLayout: 142 | MDFillRoundFlatButton: 143 | text: "Submit" 144 | theme_text_color: "Custom" 145 | text_color: 1, 1, 1, 1 146 | md_bg_color: (0/255,155/255,133/255,1) 147 | size_hint : 0.5,0.7 148 | pos_hint:{'center_x':.5,'center_y':.7} 149 | on_release: 150 | root.on_submit() 151 | : 152 | name : "advancedinput" 153 | upStr:upStr 154 | downStr:downStr 155 | timePeriod:timePeriod 156 | length:length 157 | deltab:deltab 158 | reynold:reynold 159 | e:e 160 | h:h 161 | qzer:qzer 162 | activation:activation 163 | numsamp:numsamp 164 | BoxLayout: 165 | orientation: "horizontal" 166 | SideBar: 167 | size_hint : 0.3,1 168 | 169 | RelativeLayout: 170 | Image: 171 | source: "./Media/BlueCum.jpg" 172 | allow_stretch: True 173 | keep_ratio: False 174 | #canvas.before: 175 | #Color: 176 | #rgba:(0,2/255,46/255,1) 177 | #rgba:(.5,.5,.5,.5) 178 | #Rectangle: 179 | #pos:root.pos 180 | #size:root.size 181 | 182 | BoxLayout: 183 | pos_hint: {"center_x":.5,"center_y":.5} 184 | size_hint : .7,.8 185 | orientation:"vertical" 186 | canvas.before: 187 | Color: 188 | rgba:(1,1,1,1) 189 | Rectangle: 190 | pos:self.pos 191 | size:self.size 192 | GridLayout: 193 | cols:2 194 | rows:11 195 | spacing:[0,10] 196 | padding:[20,20] 197 | size_hint: (1,.8) 198 | ColorLabel: 199 | text:"Upstream Radius (Ru)" 200 | TextInput: 201 | id:upStr 202 | fill_color:(.5,.5,0,1) 203 | #hint_text: "Up stream Radius" 204 | #hint_text_color: (1,0,0,1) 205 | 206 | ColorLabel: 207 | text:"Downstream Radius (Rd) " 208 | TextInput: 209 | id:downStr 210 | 211 | ColorLabel: 212 | text:"Time period" 213 | TextInput: 214 | id:timePeriod 215 | 216 | ColorLabel: 217 | text:"Length" 218 | TextInput: 219 | id:length 220 | 221 | ColorLabel: 222 | text:"Delta B" 223 | TextInput: 224 | id:deltab 225 | 226 | ColorLabel: 227 | text:"Reynold's Number" 228 | TextInput: 229 | id:reynold 230 | 231 | ColorLabel: 232 | text:"E" 233 | TextInput: 234 | id:e 235 | 236 | ColorLabel: 237 | text:"H" 238 | TextInput: 239 | id:h 240 | 241 | ColorLabel: 242 | text:"q_0" 243 | TextInput: 244 | id:qzer 245 | 246 | ColorLabel: 247 | text:"Activation" 248 | TextInput: 249 | id:activation 250 | 251 | ColorLabel: 252 | text:"Sample Count" 253 | TextInput: 254 | id:numsamp 255 | 256 | BoxLayout: 257 | orientation:"horizontal" 258 | size_hint:1,0.1 259 | RelativeLayout: 260 | MDFillRoundFlatButton: 261 | text: "Back" 262 | #text_size:self.width, None 263 | theme_text_color: "Custom" 264 | text_color: 1, 1, 1, 1 265 | md_bg_color: (0/255,155/255,133/255,1) 266 | size_hint : 0.5,0.7 267 | pos_hint:{'center_x':.5,'center_y':.7} 268 | on_release: 269 | app.root.current = "input" 270 | RelativeLayout: 271 | MDFillRoundFlatButton: 272 | text: "Submit" 273 | theme_text_color: "Custom" 274 | text_color: 1, 1, 1, 1 275 | md_bg_color: (0/255,155/255,133/255,1) 276 | size_hint : 0.5,0.7 277 | pos_hint:{'center_x':.5,'center_y':.7} 278 | on_release: 279 | root.on_submit() 280 | : 281 | name : "load" 282 | BoxLayout: 283 | orientation: "horizontal" 284 | SideBar: 285 | size_hint : 0.3,1 286 | RelativeLayout: 287 | Image: 288 | source: "./Media/BlueCum.jpg" 289 | allow_stretch: True 290 | keep_ratio: False 291 | Label: 292 | pos_hint: {"center_x":0.5, "center_y":0.5} 293 | size_hint: (1, 0.3) 294 | text: "Loading..." 295 | font_size: "30sp" 296 | : 297 | name : "graphwaitradius" 298 | BoxLayout: 299 | orientation: "horizontal" 300 | SideBar: 301 | size_hint : 0.3,1 302 | RelativeLayout: 303 | Image: 304 | source: "./Media/BlueCum.jpg" 305 | allow_stretch: True 306 | keep_ratio: False 307 | Label: 308 | pos_hint: {"center_x":0.5, "center_y":0.5} 309 | size_hint: (1, 0.3) 310 | text: "Loading..." 311 | font_size: "30sp" 312 | : 313 | name : "graphwaitflow" 314 | BoxLayout: 315 | orientation: "horizontal" 316 | SideBar: 317 | size_hint : 0.3,1 318 | RelativeLayout: 319 | Image: 320 | source: "./Media/BlueCum.jpg" 321 | allow_stretch: True 322 | keep_ratio: False 323 | Label: 324 | pos_hint: {"center_x":0.5, "center_y":0.5} 325 | size_hint: (1, 0.3) 326 | text: "Loading..." 327 | font_size: "30sp" 328 | : 329 | name : "resultoption" 330 | BoxLayout: 331 | orientation: "horizontal" 332 | SideBar: 333 | size_hint : 0.3,1 334 | RelativeLayout: 335 | Image: 336 | source: "./Media/BlueCum.jpg" 337 | allow_stretch: True 338 | keep_ratio: False 339 | #canvas.before: 340 | #Color: 341 | #rgba:(0,2/255,46/255,1) 342 | #rgba:(.5,.5,.5,.5) 343 | #Rectangle: 344 | #pos:root.pos 345 | #size:root.size 346 | BoxLayout: 347 | pos_hint: {"center_x":.5,"center_y":.5} 348 | size_hint : .6,.65 349 | #padding:[20,20] 350 | #spacing:[0,20] 351 | orientation:"vertical" 352 | canvas.before: 353 | Color: 354 | rgba:(1,1,1,1) 355 | Rectangle: 356 | size:self.size 357 | pos:self.pos 358 | RelativeLayout: 359 | MDFillRoundFlatButton: 360 | text: "Predictor" 361 | font_size:"20sp" 362 | theme_text_color: "Custom" 363 | text_color: 1, 1, 1, 1 364 | md_bg_color: (0/255,155/255,133/255,1) 365 | size_hint : 0.7,0.6 366 | pos_hint:{'center_x':.5,'center_y':.5} 367 | on_release: 368 | root.predictor() 369 | RelativeLayout: 370 | MDFillRoundFlatButton: 371 | text: "Flow Graph" 372 | font_size:"20sp" 373 | theme_text_color: "Custom" 374 | text_color: 1, 1, 1, 1 375 | md_bg_color: (0/255,155/255,133/255,1) 376 | size_hint : 0.7,0.6 377 | pos_hint:{'center_x':.5,'center_y':.5} 378 | on_release: 379 | root.flow() 380 | RelativeLayout: 381 | MDFillRoundFlatButton: 382 | text: "Radii Graph" 383 | font_size:"20sp" 384 | theme_text_color: "Custom" 385 | text_color: 1, 1, 1, 1 386 | md_bg_color: (0/255,155/255,133/255,1) 387 | size_hint : 0.7,0.6 388 | pos_hint:{'center_x':.5,'center_y':.5} 389 | on_release: 390 | root.radius() 391 | : 392 | name:"predictor" 393 | z:z 394 | t:t 395 | q:q 396 | r:r 397 | BoxLayout: 398 | orientation: "horizontal" 399 | SideBar: 400 | size_hint : 0.3,1 401 | RelativeLayout: 402 | Image: 403 | source: "./Media/BlueCum.jpg" 404 | allow_stretch: True 405 | keep_ratio: False 406 | #canvas.before: 407 | #Color: 408 | #rgba:(0,2/255,46/255,1) 409 | #rgba:(.5,.5,.5,.5) 410 | #Rectangle: 411 | #pos:root.pos 412 | #size:root.size 413 | BoxLayout: 414 | pos_hint: {"center_x":.5,"center_y":.5} 415 | size_hint : .6,.65 416 | #padding:[20,20] 417 | #spacing:[0,20] 418 | orientation:"vertical" 419 | canvas.before: 420 | Color: 421 | rgba:(1,1,1,1) 422 | Rectangle: 423 | size:self.size 424 | pos:self.pos 425 | GridLayout: 426 | cols:2 427 | rows:4 428 | spacing:[0,20] 429 | padding:[20,20] 430 | size_hint: (1,.8) 431 | ColorLabel: 432 | text:"Location (z)" 433 | TextInput: 434 | id:z 435 | fill_color:(.5,.5,0,1) 436 | #hint_text: "Up stream Radius" 437 | #hint_text_color: (1,0,0,1) 438 | ColorLabel: 439 | text:"Time (t) " 440 | TextInput: 441 | id:t 442 | ColorLabel: 443 | text:"Predicted q" 444 | ColorLabel: 445 | id:q 446 | background_color:(1,1,1,1) 447 | color:(0,0,0,1) 448 | #text:"" 449 | ColorLabel: 450 | text:"Predicted R" 451 | ColorLabel: 452 | id:r 453 | background_color:(1,1,1,1) 454 | color:(0,0,0,1) 455 | #text:"" 456 | BoxLayout: 457 | orientation:"horizontal" 458 | size_hint:(1,.2) 459 | RelativeLayout: 460 | MDFillRoundFlatButton: 461 | text:"Back" 462 | theme_text_color: "Custom" 463 | text_color: 1, 1, 1, 1 464 | md_bg_color: (0/255,155/255,133/255,1) 465 | size_hint : 0.7,0.6 466 | pos_hint:{'center_x':.5,'center_y':.5} 467 | on_release: 468 | #app.root.current = "resultoption" 469 | app.root.current = "input" 470 | RelativeLayout: 471 | 472 | MDFillRoundFlatButton: 473 | text:"Compute" 474 | theme_text_color: "Custom" 475 | text_color: 1, 1, 1, 1 476 | md_bg_color: (0/255,155/255,133/255,1) 477 | size_hint : 0.7,0.6 478 | pos_hint:{'center_x':.5,'center_y':.5} 479 | on_release: 480 | root.predict() 481 | 482 | : 483 | name:"flowinput" 484 | t:t 485 | BoxLayout: 486 | orientation: "horizontal" 487 | SideBar: 488 | size_hint : 0.3,1 489 | RelativeLayout: 490 | Image: 491 | source: "./Media/BlueCum.jpg" 492 | allow_stretch: True 493 | keep_ratio: False 494 | #canvas.before: 495 | #Color: 496 | #rgba:(0,2/255,46/255,1) 497 | #rgba:(.5,.5,.5,.5) 498 | #Rectangle: 499 | #pos:root.pos 500 | #size:root.size 501 | BoxLayout: 502 | pos_hint: {"center_x":.5,"center_y":.5} 503 | size_hint : .7,.4 504 | #padding:[20,20] 505 | #spacing:[0,20] 506 | orientation:"vertical" 507 | canvas.before: 508 | Color: 509 | rgba:(1,1,1,1) 510 | Rectangle: 511 | size:self.size 512 | pos:self.pos 513 | #BoxLayout: 514 | BoxLayout: 515 | orientation:"vertical" 516 | spacing:[0,20] 517 | padding:[20,20] 518 | #size_hint: (1,.8) 519 | BoxLayout: 520 | ColorLabel: 521 | text:"Time Value (t)" 522 | TextInput: 523 | id:t 524 | fill_color:(.5,.5,0,1) 525 | #hint_text: "Up stream Radius" 526 | #hint_text_color: (1,0,0,1) 527 | #BoxLayout: 528 | BoxLayout: 529 | orientation:"horizontal" 530 | #size_hint:(1,.2) 531 | RelativeLayout: 532 | MDFillRoundFlatButton: 533 | text:"Back" 534 | theme_text_color: "Custom" 535 | text_color: 1, 1, 1, 1 536 | md_bg_color: (0/255,155/255,133/255,1) 537 | size_hint : 0.7,0.4 538 | pos_hint:{'center_x':.5,'center_y':.5} 539 | on_release: 540 | app.root.current = "resultoption" 541 | RelativeLayout: 542 | 543 | MDFillRoundFlatButton: 544 | text:"Plot Graph" 545 | theme_text_color: "Custom" 546 | text_color: 1, 1, 1, 1 547 | md_bg_color: (0/255,155/255,133/255,1) 548 | size_hint : 0.7,0.4 549 | pos_hint:{'center_x':.5,'center_y':.5} 550 | on_release: 551 | root.flowgraph() 552 | : 553 | name:"flowoutput" 554 | im:im 555 | BoxLayout: 556 | orientation: "horizontal" 557 | SideBar: 558 | size_hint : 0.3,1 559 | RelativeLayout: 560 | Image: 561 | source: "./Media/BlueCum.jpg" 562 | allow_stretch: True 563 | keep_ratio: False 564 | #canvas.before: 565 | #Color: 566 | #rgba:(0,2/255,46/255,1) 567 | #rgba:(.5,.5,.5,.5) 568 | #Rectangle: 569 | #pos:root.pos 570 | #size:root.size 571 | BoxLayout: 572 | pos_hint: {"center_x":.5,"center_y":.5} 573 | size_hint : .7,.6 574 | #padding:[20,20] 575 | #spacing:[0,20] 576 | orientation:"vertical" 577 | canvas.before: 578 | Color: 579 | rgba:(1,1,1,1) 580 | Rectangle: 581 | size:self.size 582 | pos:self.pos 583 | #BoxLayout: 584 | BoxLayout: 585 | size_hint:1,.7 586 | Image: 587 | id:im 588 | #source: root.graphimage 589 | keep_ratio:False 590 | allow_stretch:True 591 | #BoxLayout: 592 | RelativeLayout: 593 | size_hint:1,.3 594 | MDFillRoundFlatButton: 595 | text:"Back" 596 | theme_text_color: "Custom" 597 | text_color: 1, 1, 1, 1 598 | md_bg_color: (0/255,155/255,133/255,1) 599 | size_hint : 0.7,0.3 600 | pos_hint:{'center_x':.5,'center_y':.5} 601 | on_release: 602 | app.root.current = "resultoption" 603 | 604 | : 605 | name:"radiusoutput" 606 | im:im 607 | BoxLayout: 608 | orientation: "horizontal" 609 | SideBar: 610 | size_hint : 0.3,1 611 | RelativeLayout: 612 | Image: 613 | source: "./Media/BlueCum.jpg" 614 | allow_stretch: True 615 | keep_ratio: False 616 | #canvas.before: 617 | #Color: 618 | #rgba:(0,2/255,46/255,1) 619 | #rgba:(.5,.5,.5,.5) 620 | #Rectangle: 621 | #pos:root.pos 622 | #size:root.size 623 | BoxLayout: 624 | pos_hint: {"center_x":.5,"center_y":.5} 625 | size_hint : .7,.6 626 | #padding:[20,20] 627 | #spacing:[0,20] 628 | orientation:"vertical" 629 | canvas.before: 630 | Color: 631 | rgba:(1,1,1,1) 632 | Rectangle: 633 | size:self.size 634 | pos:self.pos 635 | #BoxLayout: 636 | BoxLayout: 637 | size_hint:1,.7 638 | Image: 639 | id:im 640 | #source: root.graphimage 641 | keep_ratio:False 642 | allow_stretch:True 643 | #BoxLayout: 644 | RelativeLayout: 645 | size_hint:1,.3 646 | MDFillRoundFlatButton: 647 | text:"Back" 648 | theme_text_color: "Custom" 649 | text_color: 1, 1, 1, 1 650 | md_bg_color: (0/255,155/255,133/255,1) 651 | size_hint : 0.7,0.3 652 | pos_hint:{'center_x':.5,'center_y':.5} 653 | on_release: 654 | app.root.current = "resultoption" 655 | 656 | : 657 | name:"radiusinput" 658 | t:t 659 | BoxLayout: 660 | orientation: "horizontal" 661 | SideBar: 662 | size_hint : 0.3,1 663 | RelativeLayout: 664 | Image: 665 | source: "./Media/BlueCum.jpg" 666 | allow_stretch: True 667 | keep_ratio: False 668 | #canvas.before: 669 | #Color: 670 | #rgba:(0,2/255,46/255,1) 671 | #rgba:(.5,.5,.5,.5) 672 | #Rectangle: 673 | #pos:root.pos 674 | #size:root.size 675 | BoxLayout: 676 | pos_hint: {"center_x":.5,"center_y":.5} 677 | size_hint : .7,.4 678 | #padding:[20,20] 679 | #spacing:[0,20] 680 | orientation:"vertical" 681 | canvas.before: 682 | Color: 683 | rgba:(1,1,1,1) 684 | Rectangle: 685 | size:self.size 686 | pos:self.pos 687 | #BoxLayout: 688 | BoxLayout: 689 | orientation:"vertical" 690 | spacing:[0,20] 691 | padding:[20,20] 692 | #size_hint: (1,.8) 693 | BoxLayout: 694 | ColorLabel: 695 | text:"Time Value (t)" 696 | TextInput: 697 | id:t 698 | fill_color:(.5,.5,0,1) 699 | #hint_text: "Up stream Radius" 700 | #hint_text_color: (1,0,0,1) 701 | #BoxLayout: 702 | BoxLayout: 703 | orientation:"horizontal" 704 | #size_hint:(1,.2) 705 | RelativeLayout: 706 | MDFillRoundFlatButton: 707 | text:"Back" 708 | theme_text_color: "Custom" 709 | text_color: 1, 1, 1, 1 710 | md_bg_color: (0/255,155/255,133/255,1) 711 | size_hint : 0.7,0.4 712 | pos_hint:{'center_x':.5,'center_y':.5} 713 | on_release: 714 | app.root.current = "resultoption" 715 | RelativeLayout: 716 | 717 | MDFillRoundFlatButton: 718 | text:"Plot Graph" 719 | theme_text_color: "Custom" 720 | text_color: 1, 1, 1, 1 721 | md_bg_color: (0/255,155/255,133/255,1) 722 | size_hint : 0.7,0.4 723 | pos_hint:{'center_x':.5,'center_y':.5} 724 | on_release: 725 | root.radiusgraph() 726 | """) 727 | 728 | class InputScreen(Screen): 729 | upStr = ObjectProperty(None) 730 | downStr = ObjectProperty(None) 731 | timePeriod = ObjectProperty(None) 732 | length = ObjectProperty(None) 733 | def on_enter(self): 734 | print("Entered input") 735 | 736 | 737 | def on_submit(self): 738 | #create the model object and then pass it to the loading screen 739 | head = ex.artery(Ru=float(self.upStr.text), Rd=float(self.downStr.text), timeperiod=float(self.timePeriod.text)) 740 | LoadingScreen.arteryObj = head 741 | #print(self.upStr.text) 742 | app = App.get_running_app() 743 | app.root.current = "load" 744 | 745 | class AdvancedInputScreen(Screen): 746 | upStr = ObjectProperty(None) 747 | downStr = ObjectProperty(None) 748 | timePeriod = ObjectProperty(None) 749 | length = ObjectProperty(None) 750 | deltab = ObjectProperty(None) 751 | reynold = ObjectProperty(None) 752 | e = ObjectProperty(None) 753 | h = ObjectProperty(None) 754 | qzer = ObjectProperty(None) 755 | activation = ObjectProperty(None) 756 | numsamp = ObjectProperty(None) 757 | def on_submit(self): 758 | if(self.upStr.text == ""): 759 | print("Empty") 760 | head = ex.artery(Ru=float(self.upStr.text), Rd=float(self.downStr.text), timeperiod=float(self.timePeriod.text), L=float(self.length.text), 761 | delta_b=float(self.deltab.text), Reynolds_no=float(self.reynold.text), E=float(self.e.text), h=float(self.h.text), 762 | q_0=float(self.qzer.text), activation=float(self.activation.text), num_train_samples=float(self.numsamp.text)) 763 | LoadingScreen.arteryObj = head 764 | app = App.get_running_app() 765 | app.root.current = "load" 766 | 767 | class LoadingScreen(Screen): 768 | arteryObj = None 769 | def on_enter(self): 770 | ResultOptionScreen.model = self.arteryObj.sci_train() 771 | ResultOptionScreen.arteryObj = self.arteryObj 772 | app = App.get_running_app() 773 | app.root.current = "resultoption" 774 | #def on_enter(self): 775 | #PredictorScreen.arteryObj = self.arteryObj 776 | #app = App.get_running_app() 777 | #app.root.current = "predictor" 778 | 779 | 780 | class ResultOptionScreen(Screen): 781 | arteryObj = None 782 | model = None 783 | def predictor(self): 784 | PredictorScreen.arteryObj = self.arteryObj 785 | app = App.get_running_app() 786 | app.root.current = "predictor" 787 | def flow(self): 788 | FlowInputScreen.arteryObj = self.arteryObj 789 | app = App.get_running_app() 790 | app.root.current = "flowinput" 791 | def radius(self): 792 | RadiusInputScreen.arteryObj = self.arteryObj 793 | app = App.get_running_app() 794 | app.root.current = "radiusinput" 795 | 796 | 797 | class PredictorScreen(Screen): 798 | arteryObj = None 799 | z = ObjectProperty(None) 800 | t = ObjectProperty(None) 801 | r = ObjectProperty(None) 802 | q = ObjectProperty(None) 803 | def predict(self): 804 | #print("predicting") 805 | self.r.text=str(abs(self.arteryObj.q_network.predict([[float(self.z.text), float(self.t.text)]]))) 806 | self.q.text=str(abs(self.arteryObj.R_network.predict([[float(self.z.text), float(self.t.text)]]))) 807 | 808 | class FlowInputScreen(Screen): 809 | arteryObj = None 810 | t = ObjectProperty(None) 811 | def flowgraph(self): 812 | """name = plot(self.arteryObj.R_network, self.arteryObj.L, self.arteryObj.timeperiod, 'Flow') 813 | FlowOutputScreen.graphimage = "./" + name""" 814 | GraphWaitScreenFlow.arteryObj = self.arteryObj 815 | GraphWaitScreenFlow.t = self.t.text 816 | app = App.get_running_app() 817 | app.root.current = "graphwaitflow" 818 | 819 | class GraphWaitScreenFlow(Screen): 820 | arteryObj = None 821 | t = None 822 | def on_enter(self): 823 | name = plot(self.arteryObj.R_network, self.arteryObj.L, float(self.t), 'Flow') 824 | FlowOutputScreen.graphimage = "./" + name 825 | app = App.get_running_app() 826 | app.root.current = "flowoutput" 827 | 828 | 829 | class FlowOutputScreen(Screen): 830 | graphimage= "" 831 | im = ObjectProperty(None) 832 | def on_enter(self): 833 | self.im.source = self.graphimage 834 | print(self.graphimage) 835 | 836 | class RadiusInputScreen(Screen): 837 | arteryObj = None 838 | t = ObjectProperty(None) 839 | def radiusgraph(self): 840 | #name = plot(self.arteryObj.q_network, self.arteryObj.L, self.arteryObj.timeperiod, 'Radii') 841 | #RadiusOutputScreen.graphimage = "./" + name 842 | GraphWaitScreenRadius.arteryObj = self.arteryObj 843 | GraphWaitScreenRadius.t = self.t.text 844 | app = App.get_running_app() 845 | app.root.current = "graphwaitradius" 846 | 847 | class GraphWaitScreenRadius(Screen): 848 | arteryObj = None 849 | t = None 850 | def on_enter(self): 851 | name = plot(self.arteryObj.q_network, self.arteryObj.L, float(self.t), 'Radii') 852 | RadiusOutputScreen.graphimage = "./" + name 853 | app = App.get_running_app() 854 | app.root.current = "radiusoutput" 855 | 856 | 857 | 858 | class RadiusOutputScreen(Screen): 859 | graphimage= "" 860 | im = ObjectProperty(None) 861 | def on_enter(self): 862 | self.im.source = self.graphimage 863 | print(self.graphimage) 864 | 865 | 866 | def plot(network, length, time, plot_type): 867 | plt.style.use('ggplot') 868 | x = np.linspace(0, int(length), int(length)*10) 869 | #print(x.shape) 870 | y = [] 871 | for i in x: 872 | y.append(abs(network.predict([[i, time]]))) 873 | y = np.asarray(y).reshape((int(length)*10, )) 874 | #print(y.shape) 875 | #sns.set_style('darkgrid') 876 | #sns.set(rc={'figure.figsize':(11.7, 8.27)}) 877 | #sns.set(font_scale=1.4) 878 | #d = {'Lenght':x, plot_type:y} 879 | #sns.lineplot(data=d, x='Lenght', y=plot_type, palette=('red',), linewidth=2.5).set_title(plot_type) 880 | plt.plot(x, y, linewidth = 2.0) 881 | plt.xlabel('Position Along Z') 882 | plt.ylabel(plot_type) 883 | value = plot_type + '_t_' + str(time) + '.png' 884 | plt.savefig('./Plots/' + value) 885 | plt.clf() 886 | return 'Plots/' + value 887 | 888 | 889 | class v1App(MDApp): 890 | def build(self): 891 | sm = ScreenManager(transition=CardTransition()) 892 | sm.add_widget(InputScreen()) 893 | sm.add_widget(LoadingScreen()) 894 | sm.add_widget(ResultOptionScreen()) 895 | sm.add_widget(PredictorScreen()) 896 | sm.add_widget(FlowInputScreen()) 897 | sm.add_widget(FlowOutputScreen()) 898 | sm.add_widget(RadiusInputScreen()) 899 | sm.add_widget(RadiusOutputScreen()) 900 | sm.add_widget(AdvancedInputScreen()) 901 | sm.add_widget(GraphWaitScreenRadius()) 902 | sm.add_widget(GraphWaitScreenFlow()) 903 | return sm 904 | 905 | 906 | 907 | if __name__ == "__main__": 908 | v1App().run() 909 | -------------------------------------------------------------------------------- /elixir app/v1_updated.py: -------------------------------------------------------------------------------- 1 | from kivy.app import App 2 | from kivy.uix.widget import Widget 3 | from kivy.uix.boxlayout import BoxLayout 4 | from kivy.graphics import Rectangle 5 | from kivy.core.window import Window 6 | from kivy.uix.button import Button 7 | from kivy.uix.gridlayout import GridLayout 8 | from kivy.uix.textinput import TextInput 9 | from kivy.properties import ObjectProperty 10 | from kivy.uix.screenmanager import Screen,ScreenManager,CardTransition 11 | from kivy.lang import Builder 12 | from kivymd.app import MDApp 13 | from kivymd.uix.textfield import MDTextField 14 | from kivymd.uix.button import MDFillRoundFlatButton,MDIconButton 15 | from kivymd.uix.label import MDIcon 16 | import elixir as ex 17 | 18 | 19 | Builder.load_string(""" 20 | : 21 | background_color: (1, 1, 1, 1) 22 | canvas.before: 23 | Color: 24 | rgba: root.background_color 25 | Rectangle: 26 | size: self.size 27 | pos: self.pos 28 | : 29 | icon:"home-circle-outline" 30 | theme_text_color:"Custom" 31 | #text_color:(135/255,0,106/255,1) 32 | text_color:(1,1,1,1) 33 | user_font_size: "80sp" 34 | on_release: 35 | app.root.current = "input" 36 | : 37 | icon:"help" 38 | theme_text_color:"Custom" 39 | #text_color :(135/255,0,106/255,1) 40 | text_color:(1,1,1,1) 41 | user_font_size : "80sp" 42 | : 43 | orientation:"vertical" 44 | canvas.before: 45 | Color: 46 | rgba:(0/255,155/255,133/255,1) 47 | Rectangle: 48 | size:self.size 49 | pos:self.pos 50 | Label: 51 | size_hint:(1,0.3) 52 | text:"Elixir" 53 | font_size:"30sp" 54 | HomeButton: 55 | size_hint:(1,.5) 56 | #pos_hint:{"center_x":.5,"center_y":.5} 57 | #icon:"home-variant-outline" 58 | AboutButton: 59 | size_hint:(1,0.5) 60 | BoxLayout: 61 | : 62 | background_color:(0/255,155/255,133/255,1) 63 | color:(1,1,1,1) 64 | : 65 | background_color:(135/255,0,106/255,1) 66 | : 67 | name : "input" 68 | upStr:upStr 69 | downStr:downStr 70 | timePeriod:timePeriod 71 | length:length 72 | BoxLayout: 73 | orientation: "horizontal" 74 | SideBar: 75 | size_hint : 0.3,1 76 | 77 | RelativeLayout: 78 | #Image: 79 | #source: "Blue.jpg" 80 | #allow_stretch: True 81 | #keep_ratio: False 82 | canvas.before: 83 | Color: 84 | rgba:(1,1,1,1) 85 | #rgba:(.5,.5,.5,.5) 86 | Rectangle: 87 | pos:root.pos 88 | size:root.size 89 | 90 | BoxLayout: 91 | pos_hint: {"center_x":.5,"center_y":.5} 92 | size_hint : .6,.65 93 | orientation:"vertical" 94 | canvas.before: 95 | Color: 96 | rgba:(1,1,1,1) 97 | Rectangle: 98 | pos:self.pos 99 | size:self.size 100 | GridLayout: 101 | cols:2 102 | rows:4 103 | spacing:[0,20] 104 | padding:[20,20] 105 | size_hint: (1,.8) 106 | ColorLabel: 107 | text:"Upstream Radius (Ru)" 108 | TextInput: 109 | id:upStr 110 | fill_color:(.5,.5,0,1) 111 | #hint_text: "Up stream Radius" 112 | #hint_text_color: (1,0,0,1) 113 | ColorLabel: 114 | text:"Downstream Radius (Rd) " 115 | TextInput: 116 | id:downStr 117 | ColorLabel: 118 | text:"Time period" 119 | TextInput: 120 | id:timePeriod 121 | ColorLabel: 122 | text:"Length" 123 | TextInput: 124 | id:length 125 | BoxLayout: 126 | orientation:"horizontal" 127 | size_hint:1,0.1 128 | RelativeLayout: 129 | MDFillRoundFlatButton: 130 | text: "Advanced" 131 | #text_size:self.width, None 132 | theme_text_color: "Custom" 133 | text_color: 1, 1, 1, 1 134 | md_bg_color: (0/255,155/255,133/255,1) 135 | size_hint : 0.5,0.7 136 | pos_hint:{'center_x':.5,'center_y':.7} 137 | on_release: 138 | app.root.current = "advancedinput" 139 | RelativeLayout: 140 | MDFillRoundFlatButton: 141 | text: "Submit" 142 | theme_text_color: "Custom" 143 | text_color: 1, 1, 1, 1 144 | md_bg_color: (0/255,155/255,133/255,1) 145 | size_hint : 0.5,0.7 146 | pos_hint:{'center_x':.5,'center_y':.7} 147 | on_release: 148 | root.on_submit() 149 | : 150 | name : "advancedinput" 151 | upStr:upStr 152 | downStr:downStr 153 | timePeriod:timePeriod 154 | length:length 155 | deltab:deltab 156 | reynold:reynold 157 | e:e 158 | h:h 159 | qzer:qzer 160 | activation:activation 161 | numsamp:numsamp 162 | BoxLayout: 163 | orientation: "horizontal" 164 | SideBar: 165 | size_hint : 0.3,1 166 | 167 | RelativeLayout: 168 | #Image: 169 | #source: "Blue.jpg" 170 | #allow_stretch: True 171 | #keep_ratio: False 172 | canvas.before: 173 | Color: 174 | rgba:(1,1,1,1) 175 | #rgba:(.5,.5,.5,.5) 176 | Rectangle: 177 | pos:root.pos 178 | size:root.size 179 | 180 | BoxLayout: 181 | pos_hint: {"center_x":.5,"center_y":.5} 182 | size_hint : .7,.8 183 | orientation:"vertical" 184 | canvas.before: 185 | Color: 186 | rgba:(1,1,1,1) 187 | Rectangle: 188 | pos:self.pos 189 | size:self.size 190 | GridLayout: 191 | cols:2 192 | rows:11 193 | spacing:[0,10] 194 | padding:[20,20] 195 | size_hint: (1,.8) 196 | ColorLabel: 197 | text:"Upstream Radius (Ru)" 198 | TextInput: 199 | id:upStr 200 | fill_color:(.5,.5,0,1) 201 | #hint_text: "Up stream Radius" 202 | #hint_text_color: (1,0,0,1) 203 | 204 | ColorLabel: 205 | text:"Downstream Radius (Rd) " 206 | TextInput: 207 | id:downStr 208 | 209 | ColorLabel: 210 | text:"Time period" 211 | TextInput: 212 | id:timePeriod 213 | 214 | ColorLabel: 215 | text:"Length" 216 | TextInput: 217 | id:length 218 | 219 | ColorLabel: 220 | text:"Delta B" 221 | TextInput: 222 | id:deltab 223 | 224 | ColorLabel: 225 | text:"Reynold's Number" 226 | TextInput: 227 | id:reynold 228 | 229 | ColorLabel: 230 | text:"E" 231 | TextInput: 232 | id:e 233 | 234 | ColorLabel: 235 | text:"H" 236 | TextInput: 237 | id:h 238 | 239 | ColorLabel: 240 | text:"q_0" 241 | TextInput: 242 | id:qzer 243 | 244 | ColorLabel: 245 | text:"Activation" 246 | TextInput: 247 | id:activation 248 | 249 | ColorLabel: 250 | text:"Sample Count" 251 | TextInput: 252 | id:numsamp 253 | 254 | BoxLayout: 255 | orientation:"horizontal" 256 | size_hint:1,0.1 257 | RelativeLayout: 258 | MDFillRoundFlatButton: 259 | text: "Back" 260 | #text_size:self.width, None 261 | theme_text_color: "Custom" 262 | text_color: 1, 1, 1, 1 263 | md_bg_color: (0/255,155/255,133/255,1) 264 | size_hint : 0.5,0.7 265 | pos_hint:{'center_x':.5,'center_y':.7} 266 | on_release: 267 | app.root.current = "input" 268 | RelativeLayout: 269 | MDFillRoundFlatButton: 270 | text: "Submit" 271 | theme_text_color: "Custom" 272 | text_color: 1, 1, 1, 1 273 | md_bg_color: (0/255,155/255,133/255,1) 274 | size_hint : 0.5,0.7 275 | pos_hint:{'center_x':.5,'center_y':.7} 276 | on_release: 277 | root.on_submit() 278 | : 279 | name : "load" 280 | BoxLayout: 281 | orientation: "horizontal" 282 | SideBar: 283 | size_hint : 0.3,1 284 | RelativeLayout: 285 | #Image: 286 | #source: "Blue.jpg" 287 | #allow_stretch: True 288 | #keep_ratio: False 289 | canvas.before: 290 | Color: 291 | rgba:(1,1,1,1) 292 | #rgba:(.5,.5,.5,.5) 293 | Rectangle: 294 | pos:root.pos 295 | size:root.size 296 | Label: 297 | pos_hint: {"center_x":0.5, "center_y":0.5} 298 | size_hint: (1, 0.3) 299 | text: "Loading..." 300 | font_size: "30sp" 301 | color: (0/255,155/255,133/255,1) 302 | 303 | 304 | : 305 | name:"predictor" 306 | z:z 307 | t:t 308 | q:q 309 | r:r 310 | BoxLayout: 311 | orientation: "horizontal" 312 | SideBar: 313 | size_hint : 0.3,1 314 | RelativeLayout: 315 | #Image: 316 | #source: "Blue.jpg" 317 | #allow_stretch: True 318 | #keep_ratio: False 319 | canvas.before: 320 | Color: 321 | rgba:(1,1,1,1) 322 | #rgba:(.5,.5,.5,.5) 323 | Rectangle: 324 | pos:root.pos 325 | size:root.size 326 | BoxLayout: 327 | pos_hint: {"center_x":.5,"center_y":.5} 328 | size_hint : .6,.65 329 | #padding:[20,20] 330 | #spacing:[0,20] 331 | orientation:"vertical" 332 | canvas.before: 333 | Color: 334 | rgba:(1,1,1,1) 335 | Rectangle: 336 | size:self.size 337 | pos:self.pos 338 | GridLayout: 339 | cols:2 340 | rows:4 341 | spacing:[0,20] 342 | padding:[20,20] 343 | size_hint: (1,.8) 344 | ColorLabel: 345 | text:"Location (z)" 346 | TextInput: 347 | id:z 348 | fill_color:(.5,.5,0,1) 349 | #hint_text: "Up stream Radius" 350 | #hint_text_color: (1,0,0,1) 351 | ColorLabel: 352 | text:"Time (t) " 353 | TextInput: 354 | id:t 355 | ColorLabel: 356 | text:"Predicted q" 357 | ColorLabel: 358 | id:q 359 | background_color:(1,1,1,1) 360 | color:(0,0,0,1) 361 | #text:"" 362 | ColorLabel: 363 | text:"Predicted R" 364 | ColorLabel: 365 | id:r 366 | background_color:(1,1,1,1) 367 | color:(0,0,0,1) 368 | #text:"" 369 | BoxLayout: 370 | orientation:"horizontal" 371 | size_hint:(1,.2) 372 | RelativeLayout: 373 | MDFillRoundFlatButton: 374 | text:"Back" 375 | theme_text_color: "Custom" 376 | text_color: 1, 1, 1, 1 377 | md_bg_color: (0/255,155/255,133/255,1) 378 | size_hint : 0.7,0.6 379 | pos_hint:{'center_x':.5,'center_y':.5} 380 | on_release: 381 | #app.root.current = "resultoption" 382 | app.root.current = "input" 383 | RelativeLayout: 384 | 385 | MDFillRoundFlatButton: 386 | text:"Compute" 387 | theme_text_color: "Custom" 388 | text_color: 1, 1, 1, 1 389 | md_bg_color: (0/255,155/255,133/255,1) 390 | size_hint : 0.7,0.6 391 | pos_hint:{'center_x':.5,'center_y':.5} 392 | on_release: 393 | root.predict() 394 | 395 | """) 396 | 397 | class InputScreen(Screen): 398 | upStr = ObjectProperty(None) 399 | downStr = ObjectProperty(None) 400 | timePeriod = ObjectProperty(None) 401 | length = ObjectProperty(None) 402 | 403 | def on_enter(self): 404 | print("Entered input") 405 | 406 | def on_submit(self): 407 | #create the model object and then pass it to the loading screen 408 | head = ex.artery(Ru=float(self.upStr.text), Rd=float(self.downStr.text), timeperiod=float(self.timePeriod.text)) 409 | LoadingScreen.arteryObj = head 410 | #print(self.upStr.text) 411 | app = App.get_running_app() 412 | app.root.current = "load" 413 | 414 | class AdvancedInputScreen(Screen): 415 | upStr = ObjectProperty(None) 416 | downStr = ObjectProperty(None) 417 | timePeriod = ObjectProperty(None) 418 | length = ObjectProperty(None) 419 | deltab = ObjectProperty(None) 420 | reynold = ObjectProperty(None) 421 | e = ObjectProperty(None) 422 | h = ObjectProperty(None) 423 | qzer = ObjectProperty(None) 424 | activation = ObjectProperty(None) 425 | numsamp = ObjectProperty(None) 426 | def on_submit(self): 427 | if(self.upStr.text == ""): 428 | print("Empty") 429 | head = ex.artery(Ru=float(self.upStr.text), Rd=float(self.downStr.text), timeperiod=float(self.timePeriod.text), L=float(self.length.text), 430 | delta_b=float(self.deltab.text), Reynolds_no=float(self.reynold.text), E=float(self.e.text), h=float(self.h.text), 431 | q_0=float(self.qzer.text), activation=self.activation.text, num_train_samples=int(self.numsamp.text)) 432 | LoadingScreen.arteryObj = head 433 | app = App.get_running_app() 434 | app.root.current = "load" 435 | 436 | class LoadingScreen(Screen): 437 | arteryObj = None 438 | def on_enter(self): 439 | PredictorScreen.arteryObj = self.arteryObj 440 | PredictorScreen.arteryObj.sci_train() 441 | app = App.get_running_app() 442 | app.root.current = "predictor" 443 | 444 | 445 | class PredictorScreen(Screen): 446 | arteryObj = None 447 | z = ObjectProperty(None) 448 | t = ObjectProperty(None) 449 | r = ObjectProperty(None) 450 | q = ObjectProperty(None) 451 | def predict(self): 452 | #print("predicting") 453 | self.r.text=str(self.arteryObj.q_network.predict([[float(self.z.text), float(self.t.text)]])[0][0]) 454 | self.q.text=str(self.arteryObj.R_network.predict([[float(self.z.text), float(self.t.text)]])[0][0]) 455 | 456 | 457 | class v1App(MDApp): 458 | def build(self): 459 | sm = ScreenManager(transition=CardTransition()) 460 | sm.add_widget(InputScreen()) 461 | sm.add_widget(LoadingScreen()) 462 | sm.add_widget(PredictorScreen()) 463 | sm.add_widget(AdvancedInputScreen()) 464 | return sm 465 | 466 | 467 | 468 | if __name__ == "__main__": 469 | v1App().run() 470 | -------------------------------------------------------------------------------- /elixir app/v2.py: -------------------------------------------------------------------------------- 1 | from kivy.app import App 2 | from kivy.uix.widget import Widget 3 | from kivy.uix.boxlayout import BoxLayout 4 | from kivy.graphics import Rectangle 5 | from kivy.core.window import Window 6 | from kivy.uix.button import Button 7 | from kivy.uix.gridlayout import GridLayout 8 | from kivy.uix.textinput import TextInput 9 | from kivy.properties import ObjectProperty 10 | from kivy.uix.screenmanager import Screen,ScreenManager,CardTransition 11 | from kivy.lang import Builder 12 | from kivymd.app import MDApp 13 | from kivymd.uix.textfield import MDTextField 14 | from kivymd.uix.button import MDFillRoundFlatButton,MDIconButton 15 | from kivymd.uix.label import MDIcon 16 | from kivy_garden.graph import Graph,MeshLinePlot,LinePlot 17 | from math import sin 18 | from kivy.utils import get_color_from_hex as rgb 19 | from kivy.uix.modalview import ModalView 20 | """import elixir as ex 21 | import seaborn as sns 22 | import matplotlib.pyplot as plt 23 | import numpy as np""" 24 | 25 | 26 | Builder.load_string(""" 27 | : 28 | background_color: (1, 1, 1, 1) 29 | canvas.before: 30 | Color: 31 | rgba: root.background_color 32 | Rectangle: 33 | size: self.size 34 | pos: self.pos 35 | : 36 | icon:"home-circle-outline" 37 | theme_text_color:"Custom" 38 | #text_color:(135/255,0,106/255,1) 39 | text_color:(1,1,1,1) 40 | user_font_size: "80sp" 41 | on_release: 42 | app.root.current = "input" 43 | : 44 | icon:"help" 45 | theme_text_color:"Custom" 46 | #text_color :(135/255,0,106/255,1) 47 | text_color:(1,1,1,1) 48 | user_font_size : "80sp" 49 | : 50 | orientation:"vertical" 51 | canvas.before: 52 | Color: 53 | rgba:(0/255,155/255,133/255,1) 54 | Rectangle: 55 | size:self.size 56 | pos:self.pos 57 | Label: 58 | size_hint:(1,0.3) 59 | text:"Elixir" 60 | font_size:"30sp" 61 | HomeButton: 62 | size_hint:(1,.5) 63 | #pos_hint:{"center_x":.5,"center_y":.5} 64 | #icon:"home-variant-outline" 65 | AboutButton: 66 | size_hint:(1,0.5) 67 | BoxLayout: 68 | : 69 | background_color:(0/255,155/255,133/255,1) 70 | color:(1,1,1,1) 71 | : 72 | background_color:(135/255,0,106/255,1) 73 | : 74 | name : "input" 75 | upStr:upStr 76 | downStr:downStr 77 | timePeriod:timePeriod 78 | length:length 79 | BoxLayout: 80 | orientation: "horizontal" 81 | SideBar: 82 | size_hint : 0.3,1 83 | 84 | RelativeLayout: 85 | #Image: 86 | # source: "./Media/BlueCum.jpg" 87 | # allow_stretch: True 88 | # keep_ratio: False 89 | canvas.before: 90 | Color: 91 | rgba:(1,1,1,1) 92 | #rgba:(.5,.5,.5,.5) 93 | Rectangle: 94 | pos:root.pos 95 | size:root.size 96 | BoxLayout: 97 | pos_hint: {"center_x":.5,"center_y":.5} 98 | size_hint : .6,.65 99 | orientation:"vertical" 100 | canvas.before: 101 | Color: 102 | rgba:(1,1,1,1) 103 | Rectangle: 104 | pos:self.pos 105 | size:self.size 106 | GridLayout: 107 | cols:2 108 | rows:4 109 | spacing:[0,20] 110 | padding:[20,20] 111 | size_hint: (1,.8) 112 | ColorLabel: 113 | text:"Upstream Radius (Ru)" 114 | TextInput: 115 | id:upStr 116 | fill_color:(.5,.5,0,1) 117 | #hint_text: "Up stream Radius" 118 | #hint_text_color: (1,0,0,1) 119 | ColorLabel: 120 | text:"Downstream Radius (Rd) " 121 | TextInput: 122 | id:downStr 123 | ColorLabel: 124 | text:"Time period" 125 | TextInput: 126 | id:timePeriod 127 | ColorLabel: 128 | text:"Length" 129 | TextInput: 130 | id:length 131 | BoxLayout: 132 | orientation:"horizontal" 133 | size_hint:1,0.1 134 | RelativeLayout: 135 | MDFillRoundFlatButton: 136 | text: "Advanced" 137 | #text_size:self.width, None 138 | theme_text_color: "Custom" 139 | text_color: 1, 1, 1, 1 140 | md_bg_color: (0/255,155/255,133/255,1) 141 | size_hint : 0.5,0.7 142 | pos_hint:{'center_x':.5,'center_y':.7} 143 | on_release: 144 | app.root.current = "advancedinput" 145 | RelativeLayout: 146 | MDFillRoundFlatButton: 147 | text: "Submit" 148 | theme_text_color: "Custom" 149 | text_color: 1, 1, 1, 1 150 | md_bg_color: (0/255,155/255,133/255,1) 151 | size_hint : 0.5,0.7 152 | pos_hint:{'center_x':.5,'center_y':.7} 153 | on_release: 154 | root.on_submit() 155 | : 156 | name : "advancedinput" 157 | upStr:upStr 158 | downStr:downStr 159 | timePeriod:timePeriod 160 | length:length 161 | deltab:deltab 162 | reynold:reynold 163 | e:e 164 | h:h 165 | qzer:qzer 166 | activation:activation 167 | numsamp:numsamp 168 | BoxLayout: 169 | orientation: "horizontal" 170 | SideBar: 171 | size_hint : 0.3,1 172 | 173 | RelativeLayout: 174 | #Image: 175 | # source: "./Media/BlueCum.jpg" 176 | # allow_stretch: True 177 | # keep_ratio: False 178 | canvas.before: 179 | Color: 180 | rgba:(1,1,1,1) 181 | #rgba:(.5,.5,.5,.5) 182 | Rectangle: 183 | pos:root.pos 184 | size:root.size 185 | 186 | BoxLayout: 187 | pos_hint: {"center_x":.5,"center_y":.5} 188 | size_hint : .7,.8 189 | orientation:"vertical" 190 | canvas.before: 191 | Color: 192 | rgba:(1,1,1,1) 193 | Rectangle: 194 | pos:self.pos 195 | size:self.size 196 | GridLayout: 197 | cols:2 198 | rows:11 199 | spacing:[0,10] 200 | padding:[20,20] 201 | size_hint: (1,.8) 202 | ColorLabel: 203 | text:"Upstream Radius (Ru)" 204 | TextInput: 205 | id:upStr 206 | fill_color:(.5,.5,0,1) 207 | #hint_text: "Up stream Radius" 208 | #hint_text_color: (1,0,0,1) 209 | 210 | ColorLabel: 211 | text:"Downstream Radius (Rd) " 212 | TextInput: 213 | id:downStr 214 | 215 | ColorLabel: 216 | text:"Time period" 217 | TextInput: 218 | id:timePeriod 219 | 220 | ColorLabel: 221 | text:"Length" 222 | TextInput: 223 | id:length 224 | 225 | ColorLabel: 226 | text:"Delta B" 227 | TextInput: 228 | id:deltab 229 | 230 | ColorLabel: 231 | text:"Reynold's Number" 232 | TextInput: 233 | id:reynold 234 | 235 | ColorLabel: 236 | text:"E" 237 | TextInput: 238 | id:e 239 | 240 | ColorLabel: 241 | text:"H" 242 | TextInput: 243 | id:h 244 | 245 | ColorLabel: 246 | text:"q_0" 247 | TextInput: 248 | id:qzer 249 | 250 | ColorLabel: 251 | text:"Activation" 252 | TextInput: 253 | id:activation 254 | 255 | ColorLabel: 256 | text:"Sample Count" 257 | TextInput: 258 | id:numsamp 259 | 260 | BoxLayout: 261 | orientation:"horizontal" 262 | size_hint:1,0.1 263 | RelativeLayout: 264 | MDFillRoundFlatButton: 265 | text: "Back" 266 | #text_size:self.width, None 267 | theme_text_color: "Custom" 268 | text_color: 1, 1, 1, 1 269 | md_bg_color: (0/255,155/255,133/255,1) 270 | size_hint : 0.5,0.7 271 | pos_hint:{'center_x':.5,'center_y':.7} 272 | on_release: 273 | app.root.current = "input" 274 | RelativeLayout: 275 | MDFillRoundFlatButton: 276 | text: "Submit" 277 | theme_text_color: "Custom" 278 | text_color: 1, 1, 1, 1 279 | md_bg_color: (0/255,155/255,133/255,1) 280 | size_hint : 0.5,0.7 281 | pos_hint:{'center_x':.5,'center_y':.7} 282 | on_release: 283 | root.on_submit() 284 | : 285 | name : "load" 286 | BoxLayout: 287 | orientation: "horizontal" 288 | SideBar: 289 | size_hint : 0.3,1 290 | RelativeLayout: 291 | Image: 292 | source: "./Media/BlueCum.jpg" 293 | allow_stretch: True 294 | keep_ratio: False 295 | #canvas.before: 296 | # Color: 297 | # rgba:(1,1,1,1) 298 | # #rgba:(.5,.5,.5,.5) 299 | # Rectangle: 300 | # pos:root.pos 301 | # size:root.size 302 | Label: 303 | pos_hint: {"center_x":0.5, "center_y":0.5} 304 | size_hint: (1, 0.3) 305 | text: "Loading..." 306 | font_size: "30sp" 307 | : 308 | name : "graphwaitradius" 309 | BoxLayout: 310 | orientation: "horizontal" 311 | SideBar: 312 | size_hint : 0.3,1 313 | RelativeLayout: 314 | #Image: 315 | # source: "./Media/BlueCum.jpg" 316 | # allow_stretch: True 317 | # keep_ratio: False 318 | canvas.before: 319 | Color: 320 | rgba:(1,1,1,1) 321 | #rgba:(.5,.5,.5,.5) 322 | Rectangle: 323 | pos:root.pos 324 | size:root.size 325 | Label: 326 | pos_hint: {"center_x":0.5, "center_y":0.5} 327 | size_hint: (1, 0.3) 328 | text: "Loading..." 329 | font_size: "30sp" 330 | : 331 | name : "graphwaitflow" 332 | BoxLayout: 333 | orientation: "horizontal" 334 | SideBar: 335 | size_hint : 0.3,1 336 | RelativeLayout: 337 | #Image: 338 | # source: "./Media/BlueCum.jpg" 339 | # allow_stretch: True 340 | # keep_ratio: False 341 | canvas.before: 342 | Color: 343 | rgba:(1,1,1,1) 344 | #rgba:(.5,.5,.5,.5) 345 | Rectangle: 346 | pos:root.pos 347 | size:root.size 348 | Label: 349 | pos_hint: {"center_x":0.5, "center_y":0.5} 350 | size_hint: (1, 0.3) 351 | text: "Loading..." 352 | font_size: "30sp" 353 | : 354 | name : "resultoption" 355 | BoxLayout: 356 | orientation: "horizontal" 357 | SideBar: 358 | size_hint : 0.3,1 359 | RelativeLayout: 360 | #Image: 361 | # source: "./Media/BlueCum.jpg" 362 | # allow_stretch: True 363 | # keep_ratio: False 364 | canvas.before: 365 | Color: 366 | rgba:(1,1,1,1) 367 | #rgba:(.5,.5,.5,.5) 368 | Rectangle: 369 | pos:root.pos 370 | size:root.size 371 | BoxLayout: 372 | pos_hint: {"center_x":.5,"center_y":.5} 373 | size_hint : .6,.65 374 | #padding:[20,20] 375 | #spacing:[0,20] 376 | orientation:"vertical" 377 | canvas.before: 378 | Color: 379 | rgba:(1,1,1,1) 380 | Rectangle: 381 | size:self.size 382 | pos:self.pos 383 | RelativeLayout: 384 | MDFillRoundFlatButton: 385 | text: "Predictor" 386 | font_size:"20sp" 387 | theme_text_color: "Custom" 388 | text_color: 1, 1, 1, 1 389 | md_bg_color: (0/255,155/255,133/255,1) 390 | size_hint : 0.7,0.6 391 | pos_hint:{'center_x':.5,'center_y':.5} 392 | on_release: 393 | root.predictor() 394 | RelativeLayout: 395 | MDFillRoundFlatButton: 396 | text: "Flow Graph" 397 | font_size:"20sp" 398 | theme_text_color: "Custom" 399 | text_color: 1, 1, 1, 1 400 | md_bg_color: (0/255,155/255,133/255,1) 401 | size_hint : 0.7,0.6 402 | pos_hint:{'center_x':.5,'center_y':.5} 403 | on_release: 404 | root.flow() 405 | RelativeLayout: 406 | MDFillRoundFlatButton: 407 | text: "Radii Graph" 408 | font_size:"20sp" 409 | theme_text_color: "Custom" 410 | text_color: 1, 1, 1, 1 411 | md_bg_color: (0/255,155/255,133/255,1) 412 | size_hint : 0.7,0.6 413 | pos_hint:{'center_x':.5,'center_y':.5} 414 | on_release: 415 | root.radius() 416 | : 417 | name:"predictor" 418 | z:z 419 | t:t 420 | q:q 421 | r:r 422 | BoxLayout: 423 | orientation: "horizontal" 424 | SideBar: 425 | size_hint : 0.3,1 426 | RelativeLayout: 427 | #Image: 428 | # source: "./Media/BlueCum.jpg" 429 | # allow_stretch: True 430 | # keep_ratio: False 431 | canvas.before: 432 | Color: 433 | rgba:(1,1,1,1) 434 | #rgba:(.5,.5,.5,.5) 435 | Rectangle: 436 | pos:root.pos 437 | size:root.size 438 | BoxLayout: 439 | pos_hint: {"center_x":.5,"center_y":.5} 440 | size_hint : .6,.65 441 | #padding:[20,20] 442 | #spacing:[0,20] 443 | orientation:"vertical" 444 | canvas.before: 445 | Color: 446 | rgba:(1,1,1,1) 447 | Rectangle: 448 | size:self.size 449 | pos:self.pos 450 | GridLayout: 451 | cols:2 452 | rows:4 453 | spacing:[0,20] 454 | padding:[20,20] 455 | size_hint: (1,.8) 456 | ColorLabel: 457 | text:"Location (z)" 458 | TextInput: 459 | id:z 460 | fill_color:(.5,.5,0,1) 461 | #hint_text: "Up stream Radius" 462 | #hint_text_color: (1,0,0,1) 463 | ColorLabel: 464 | text:"Time (t) " 465 | TextInput: 466 | id:t 467 | ColorLabel: 468 | text:"Predicted q" 469 | ColorLabel: 470 | id:q 471 | background_color:(1,1,1,1) 472 | color:(0,0,0,1) 473 | #text:"" 474 | ColorLabel: 475 | text:"Predicted R" 476 | ColorLabel: 477 | id:r 478 | background_color:(1,1,1,1) 479 | color:(0,0,0,1) 480 | #text:"" 481 | BoxLayout: 482 | orientation:"horizontal" 483 | size_hint:(1,.2) 484 | RelativeLayout: 485 | MDFillRoundFlatButton: 486 | text:"Back" 487 | theme_text_color: "Custom" 488 | text_color: 1, 1, 1, 1 489 | md_bg_color: (0/255,155/255,133/255,1) 490 | size_hint : 0.7,0.6 491 | pos_hint:{'center_x':.5,'center_y':.5} 492 | on_release: 493 | #app.root.current = "resultoption" 494 | app.root.current = "input" 495 | RelativeLayout: 496 | 497 | MDFillRoundFlatButton: 498 | text:"Compute" 499 | theme_text_color: "Custom" 500 | text_color: 1, 1, 1, 1 501 | md_bg_color: (0/255,155/255,133/255,1) 502 | size_hint : 0.7,0.6 503 | pos_hint:{'center_x':.5,'center_y':.5} 504 | on_release: 505 | root.predict() 506 | 507 | : 508 | name:"flowinput" 509 | t:t 510 | BoxLayout: 511 | orientation: "horizontal" 512 | SideBar: 513 | size_hint : 0.3,1 514 | RelativeLayout: 515 | #Image: 516 | # source: "./Media/BlueCum.jpg" 517 | # allow_stretch: True 518 | # keep_ratio: False 519 | canvas.before: 520 | Color: 521 | rgba:(1,1,1,1) 522 | #rgba:(.5,.5,.5,.5) 523 | Rectangle: 524 | pos:root.pos 525 | size:root.size 526 | BoxLayout: 527 | pos_hint: {"center_x":.5,"center_y":.5} 528 | size_hint : .7,.4 529 | #padding:[20,20] 530 | #spacing:[0,20] 531 | orientation:"vertical" 532 | canvas.before: 533 | Color: 534 | rgba:(1,1,1,1) 535 | Rectangle: 536 | size:self.size 537 | pos:self.pos 538 | #BoxLayout: 539 | BoxLayout: 540 | orientation:"vertical" 541 | spacing:[0,20] 542 | padding:[20,20] 543 | #size_hint: (1,.8) 544 | BoxLayout: 545 | ColorLabel: 546 | text:"Time Value (t)" 547 | TextInput: 548 | id:t 549 | fill_color:(.5,.5,0,1) 550 | #hint_text: "Up stream Radius" 551 | #hint_text_color: (1,0,0,1) 552 | #BoxLayout: 553 | BoxLayout: 554 | orientation:"horizontal" 555 | #size_hint:(1,.2) 556 | RelativeLayout: 557 | MDFillRoundFlatButton: 558 | text:"Back" 559 | theme_text_color: "Custom" 560 | text_color: 1, 1, 1, 1 561 | md_bg_color: (0/255,155/255,133/255,1) 562 | size_hint : 0.7,0.4 563 | pos_hint:{'center_x':.5,'center_y':.5} 564 | on_release: 565 | app.root.current = "resultoption" 566 | RelativeLayout: 567 | 568 | MDFillRoundFlatButton: 569 | text:"Plot Graph" 570 | theme_text_color: "Custom" 571 | text_color: 1, 1, 1, 1 572 | md_bg_color: (0/255,155/255,133/255,1) 573 | size_hint : 0.7,0.4 574 | pos_hint:{'center_x':.5,'center_y':.5} 575 | on_release: 576 | root.flowgraph() 577 | : 578 | name:"flowoutput" 579 | #im:im 580 | box:box 581 | BoxLayout: 582 | orientation: "horizontal" 583 | SideBar: 584 | size_hint : 0.3,1 585 | RelativeLayout: 586 | #Image: 587 | # source: "./Media/BlueCum.jpg" 588 | # allow_stretch: True 589 | # keep_ratio: False 590 | canvas.before: 591 | Color: 592 | rgba:(1,1,1,1) 593 | #rgba:(.5,.5,.5,.5) 594 | Rectangle: 595 | pos:root.pos 596 | size:root.size 597 | BoxLayout: 598 | pos_hint: {"center_x":.5,"center_y":.5} 599 | size_hint : .7,.65 600 | #padding:[20,20] 601 | #spacing:[0,20] 602 | orientation:"vertical" 603 | canvas.before: 604 | Color: 605 | rgba:(1,1,1,1) 606 | Rectangle: 607 | size:self.size 608 | pos:self.pos 609 | #BoxLayout: 610 | BoxLayout: 611 | id:box 612 | size_hint:1,.8 613 | canvas.before: 614 | Color: 615 | rgba:(1,1,1,1) 616 | Rectangle: 617 | size:self.size 618 | pos:self.pos 619 | #Image: 620 | # id:im 621 | #source: root.graphimage 622 | # keep_ratio:False 623 | # allow_stretch:True 624 | #BoxLayout: 625 | RelativeLayout: 626 | size_hint:1,.2 627 | MDFillRoundFlatButton: 628 | text:"Back" 629 | theme_text_color: "Custom" 630 | text_color: 1, 1, 1, 1 631 | md_bg_color: (0/255,155/255,133/255,1) 632 | size_hint : 0.5,0.4 633 | pos_hint:{'center_x':.5,'center_y':.5} 634 | on_release: 635 | app.root.current = "resultoption" 636 | 637 | : 638 | name:"radiusoutput" 639 | #im:im 640 | BoxLayout: 641 | orientation: "horizontal" 642 | SideBar: 643 | size_hint : 0.3,1 644 | RelativeLayout: 645 | #Image: 646 | # source: "./Media/BlueCum.jpg" 647 | # allow_stretch: True 648 | # keep_ratio: False 649 | canvas.before: 650 | Color: 651 | rgba:(1,1,1,1) 652 | #rgba:(.5,.5,.5,.5) 653 | Rectangle: 654 | pos:root.pos 655 | size:root.size 656 | BoxLayout: 657 | pos_hint: {"center_x":.5,"center_y":.5} 658 | size_hint : .7,.6 659 | #padding:[20,20] 660 | #spacing:[0,20] 661 | orientation:"vertical" 662 | canvas.before: 663 | Color: 664 | rgba:(1,1,1,1) 665 | Rectangle: 666 | size:self.size 667 | pos:self.pos 668 | #BoxLayout: 669 | BoxLayout: 670 | size_hint:1,.7 671 | #Image: 672 | # id:im 673 | #source: root.graphimage 674 | # keep_ratio:False 675 | # allow_stretch:True 676 | #BoxLayout: 677 | RelativeLayout: 678 | size_hint:1,.3 679 | MDFillRoundFlatButton: 680 | text:"Back" 681 | theme_text_color: "Custom" 682 | text_color: 1, 1, 1, 1 683 | md_bg_color: (0/255,155/255,133/255,1) 684 | size_hint : 0.7,0.3 685 | pos_hint:{'center_x':.5,'center_y':.5} 686 | on_release: 687 | app.root.current = "resultoption" 688 | 689 | : 690 | name:"radiusinput" 691 | t:t 692 | BoxLayout: 693 | orientation: "horizontal" 694 | SideBar: 695 | size_hint : 0.3,1 696 | RelativeLayout: 697 | #Image: 698 | # source: "./Media/BlueCum.jpg" 699 | # allow_stretch: True 700 | # keep_ratio: False 701 | canvas.before: 702 | Color: 703 | rgba:(1,1,1,1) 704 | #rgba:(.5,.5,.5,.5) 705 | Rectangle: 706 | pos:root.pos 707 | size:root.size 708 | BoxLayout: 709 | pos_hint: {"center_x":.5,"center_y":.5} 710 | size_hint : .7,.4 711 | #padding:[20,20] 712 | #spacing:[0,20] 713 | orientation:"vertical" 714 | canvas.before: 715 | Color: 716 | rgba:(1,1,1,1) 717 | Rectangle: 718 | size:self.size 719 | pos:self.pos 720 | #BoxLayout: 721 | BoxLayout: 722 | orientation:"vertical" 723 | spacing:[0,20] 724 | padding:[20,20] 725 | #size_hint: (1,.8) 726 | BoxLayout: 727 | ColorLabel: 728 | text:"Time Value (t)" 729 | TextInput: 730 | id:t 731 | fill_color:(.5,.5,0,1) 732 | #hint_text: "Up stream Radius" 733 | #hint_text_color: (1,0,0,1) 734 | #BoxLayout: 735 | BoxLayout: 736 | orientation:"horizontal" 737 | #size_hint:(1,.2) 738 | RelativeLayout: 739 | MDFillRoundFlatButton: 740 | text:"Back" 741 | theme_text_color: "Custom" 742 | text_color: 1, 1, 1, 1 743 | md_bg_color: (0/255,155/255,133/255,1) 744 | size_hint : 0.7,0.4 745 | pos_hint:{'center_x':.5,'center_y':.5} 746 | on_release: 747 | app.root.current = "resultoption" 748 | RelativeLayout: 749 | 750 | MDFillRoundFlatButton: 751 | text:"Plot Graph" 752 | theme_text_color: "Custom" 753 | text_color: 1, 1, 1, 1 754 | md_bg_color: (0/255,155/255,133/255,1) 755 | size_hint : 0.7,0.4 756 | pos_hint:{'center_x':.5,'center_y':.5} 757 | on_release: 758 | root.radiusgraph() 759 | """) 760 | 761 | class InputScreen(Screen): 762 | upStr = ObjectProperty(None) 763 | downStr = ObjectProperty(None) 764 | timePeriod = ObjectProperty(None) 765 | length = ObjectProperty(None) 766 | def on_enter(self): 767 | print("Entered input") 768 | 769 | 770 | def on_submit(self): 771 | #create the model object and then pass it to the loading screen 772 | """head = ex.artery(Ru=float(self.upStr.text), Rd=float(self.downStr.text), timeperiod=float(self.timePeriod.text)) 773 | LoadingScreen.arteryObj = head""" 774 | #print(self.upStr.text) 775 | app = App.get_running_app() 776 | app.root.current = "load" 777 | 778 | class AdvancedInputScreen(Screen): 779 | upStr = ObjectProperty(None) 780 | downStr = ObjectProperty(None) 781 | timePeriod = ObjectProperty(None) 782 | length = ObjectProperty(None) 783 | deltab = ObjectProperty(None) 784 | reynold = ObjectProperty(None) 785 | e = ObjectProperty(None) 786 | h = ObjectProperty(None) 787 | qzer = ObjectProperty(None) 788 | activation = ObjectProperty(None) 789 | numsamp = ObjectProperty(None) 790 | def on_submit(self): 791 | if(self.upStr.text == ""): 792 | print("Empty") 793 | """head = ex.artery(Ru=float(self.upStr.text), Rd=float(self.downStr.text), timeperiod=float(self.timePeriod.text), L=float(self.length.text), 794 | delta_b=float(self.deltab.text), Reynolds_no=float(self.reynold.text), E=float(self.e.text), h=float(self.h.text), 795 | q_0=float(self.qzer.text), activation=float(self.activation.text), num_train_samples=float(self.numsamp.text)) 796 | LoadingScreen.arteryObj = head""" 797 | app = App.get_running_app() 798 | app.root.current = "load" 799 | 800 | class LoadingScreen(Screen): 801 | arteryObj = None 802 | """def on_enter(self): 803 | ResultOptionScreen.model = self.arteryObj.sci_train() 804 | ResultOptionScreen.arteryObj = self.arteryObj 805 | app = App.get_running_app() 806 | app.root.current = "resultoption""" 807 | def on_enter(self): 808 | PredictorScreen.arteryObj = self.arteryObj 809 | app = App.get_running_app() 810 | app.root.current = "resultoption" 811 | 812 | 813 | class ResultOptionScreen(Screen): 814 | arteryObj = None 815 | model = None 816 | def predictor(self): 817 | PredictorScreen.arteryObj = self.arteryObj 818 | app = App.get_running_app() 819 | app.root.current = "predictor" 820 | def flow(self): 821 | FlowInputScreen.arteryObj = self.arteryObj 822 | app = App.get_running_app() 823 | app.root.current = "flowinput" 824 | 825 | def radius(self): 826 | RadiusInputScreen.arteryObj = self.arteryObj 827 | app = App.get_running_app() 828 | app.root.current = "radiusinput" 829 | 830 | 831 | class PredictorScreen(Screen): 832 | arteryObj = None 833 | z = ObjectProperty(None) 834 | t = ObjectProperty(None) 835 | r = ObjectProperty(None) 836 | q = ObjectProperty(None) 837 | def predict(self): 838 | #print("predicting") 839 | """self.r.text=self.arteryObj.q_network[[float(self.z.text), float(self.t.text)]] 840 | self.q.text=self.arteryObj.R_network[[self.z.text, float(self.t.text)]]""" 841 | 842 | class FlowInputScreen(Screen): 843 | arteryObj = None 844 | t = ObjectProperty(None) 845 | def flowgraph(self): 846 | GraphWaitScreenFlow.arteryObj = self.arteryObj 847 | GraphWaitScreenFlow.t = self.t.text 848 | app = App.get_running_app() 849 | app.root.current = "graphwaitflow" 850 | 851 | class GraphWaitScreenFlow(Screen): 852 | arteryObj = None 853 | t = None 854 | def on_enter(self): 855 | """Write the code to generate x and y here 856 | FlowOutputScreen.x = 857 | FlowOutputScreen.y = 858 | """ 859 | app = App.get_running_app() 860 | app.root.current = "flowoutput" 861 | 862 | 863 | class FlowOutputScreen(Screen): 864 | box = ObjectProperty(None) 865 | x = None 866 | y = None 867 | def on_enter(self): 868 | #self.im.source = self.graphimage 869 | """self.box.add_widget(test_plot()) 870 | print(self.graphimage)""" 871 | view = ModalView(size_hint = (.8,.8)) 872 | view.add_widget(test_plot()) 873 | view.open() 874 | view.bind(on_dismiss = return_options) 875 | def on_leave(self): 876 | #self.box.remove_widget(self.box.children[0]) 877 | pass 878 | 879 | def return_options(instance): 880 | app = App.get_running_app() 881 | app.root.current = "resultoption" 882 | 883 | 884 | class RadiusInputScreen(Screen): 885 | arteryObj = None 886 | t = ObjectProperty(None) 887 | def radiusgraph(self): 888 | #name = plot(self.arteryObj.q_network, self.arteryObj.L, self.arteryObj.timeperiod, 'Radii') 889 | #RadiusOutputScreen.graphimage = "./" + name 890 | GraphWaitScreenRadius.arteryObj = self.arteryObj 891 | GraphWaitScreenRadius.t = self.t.text 892 | app = App.get_running_app() 893 | app.root.current = "graphwaitradius" 894 | 895 | class GraphWaitScreenRadius(Screen): 896 | arteryObj = None 897 | t = None 898 | def on_enter(self): 899 | """name = plot(self.arteryObj.q_network, self.arteryObj.L, float(self.t), 'Radii') 900 | RadiusOutputScreen.graphimage = "./" + name""" 901 | app = App.get_running_app() 902 | app.root.current = "radiusoutput" 903 | 904 | 905 | 906 | class RadiusOutputScreen(Screen): 907 | graphimage= "" 908 | #im = ObjectProperty(None) 909 | def on_enter(self): 910 | #self.im.source = self.graphimage 911 | print(self.graphimage) 912 | 913 | 914 | 915 | def test_plot(): 916 | y=[0.031950610693602964, 917 | 0.03194481197500933, 918 | 0.031839240899471946, 919 | 0.03261149720875123, 920 | 0.035318570120934784, 921 | 0.03878313701866755, 922 | 0.04238573613993061, 923 | 0.04602413486857117, 924 | 0.049741388844395724, 925 | 0.053591512586388015, 926 | 0.057606653444064085, 927 | 0.061798281482847446, 928 | 0.06616619371831864, 929 | 0.0707062524112668, 930 | 0.07541470788936075, 931 | 0.08028950738455903, 932 | 0.08532965250364388, 933 | 0.09053359512583906, 934 | 0.09589739645656445, 935 | 0.10141312243613443, 936 | 0.10706775198182189, 937 | 0.11284272335879741, 938 | 0.11871412956181746, 939 | 0.12465349436310197, 940 | 0.1306290141769961, 941 | 0.1366071294269646, 942 | 0.14255428226160094, 943 | 0.1484387168495126, 944 | 0.15423218045233464, 945 | 0.15991138889658346, 946 | 0.16545913220539737, 947 | 0.17086491832798104, 948 | 0.176125086824129, 949 | 0.18124236932291862, 950 | 0.18622492632543908, 951 | 0.19108494492368985, 952 | 0.19583693205010577, 953 | 0.20049587508848127, 954 | 0.2050754590083632, 955 | 0.2095865221197838, 956 | 0.21403590069691683, 957 | 0.2184257606264228, 958 | 0.22275345085200954, 959 | 0.22701185011711789, 960 | 0.23119012625285065, 961 | 0.23527479343151592, 962 | 0.23925093946222153, 963 | 0.24310349904366838, 964 | 0.2468184631414876, 965 | 0.25038393206695747, 966 | 0.25379093551614873, 967 | 0.2570339559133069, 968 | 0.26011110492845285, 969 | 0.2630239222658207, 970 | 0.2657767956181362, 971 | 0.26837604287000977, 972 | 0.2708287490501172, 973 | 0.2731415024832031, 974 | 0.27531921410167887, 975 | 0.2773642168267341, 976 | 0.27927581763589904, 977 | 0.2810504108810505, 978 | 0.28268216626034237, 979 | 0.28416419784337715, 980 | 0.28549002679100144, 981 | 0.28665509308698073, 982 | 0.2876580643255614, 983 | 0.2885017321566062, 984 | 0.2891933663280758, 985 | 0.2897444921164648, 986 | 0.29017014919693107, 987 | 0.29048776440199314, 988 | 0.2907158204324336, 989 | 0.29087252503362143, 990 | 0.290974677705853, 991 | 0.2910368879299887, 992 | 0.2910712155395291, 993 | 0.29108718966409003, 994 | 0.2910920569869775, 995 | 0.29109107980726506, 996 | 0.29108779054557926, 997 | 0.29108424496737106, 998 | 0.2910813563042657, 999 | 0.29107930058783893, 1000 | 0.29107789553986657, 1001 | 0.29107687143375244, 1002 | 0.2910760178074271, 1003 | 0.2910752294093475, 1004 | 0.291074487069738, 1005 | 0.2910738129705285, 1006 | 0.29107323261915635, 1007 | 0.29107275708711505, 1008 | 0.29107238191483087, 1009 | 0.2910720931782799, 1010 | 0.2910718738295515, 1011 | 0.29107170774258234, 1012 | 0.2910715814876797, 1013 | 0.29107148466392946, 1014 | 0.2910714095496088, 1015 | 0.29107135054217537] 1016 | x = [0.0, 1017 | 0.10101010101010101, 1018 | 0.20202020202020202, 1019 | 0.30303030303030304, 1020 | 0.40404040404040403, 1021 | 0.5050505050505051, 1022 | 0.6060606060606061, 1023 | 0.7070707070707071, 1024 | 0.8080808080808081, 1025 | 0.9090909090909091, 1026 | 1.0101010101010102, 1027 | 1.1111111111111112, 1028 | 1.2121212121212122, 1029 | 1.3131313131313131, 1030 | 1.4141414141414141, 1031 | 1.5151515151515151, 1032 | 1.6161616161616161, 1033 | 1.7171717171717171, 1034 | 1.8181818181818181, 1035 | 1.9191919191919191, 1036 | 2.0202020202020203, 1037 | 2.121212121212121, 1038 | 2.2222222222222223, 1039 | 2.323232323232323, 1040 | 2.4242424242424243, 1041 | 2.525252525252525, 1042 | 2.6262626262626263, 1043 | 2.727272727272727, 1044 | 2.8282828282828283, 1045 | 2.929292929292929, 1046 | 3.0303030303030303, 1047 | 3.131313131313131, 1048 | 3.2323232323232323, 1049 | 3.3333333333333335, 1050 | 3.4343434343434343, 1051 | 3.5353535353535355, 1052 | 3.6363636363636362, 1053 | 3.7373737373737375, 1054 | 3.8383838383838382, 1055 | 3.9393939393939394, 1056 | 4.040404040404041, 1057 | 4.141414141414141, 1058 | 4.242424242424242, 1059 | 4.343434343434343, 1060 | 4.444444444444445, 1061 | 4.545454545454545, 1062 | 4.646464646464646, 1063 | 4.747474747474747, 1064 | 4.848484848484849, 1065 | 4.94949494949495, 1066 | 5.05050505050505, 1067 | 5.151515151515151, 1068 | 5.252525252525253, 1069 | 5.353535353535354, 1070 | 5.454545454545454, 1071 | 5.555555555555555, 1072 | 5.656565656565657, 1073 | 5.757575757575758, 1074 | 5.858585858585858, 1075 | 5.959595959595959, 1076 | 6.0606060606060606, 1077 | 6.161616161616162, 1078 | 6.262626262626262, 1079 | 6.363636363636363, 1080 | 6.4646464646464645, 1081 | 6.565656565656566, 1082 | 6.666666666666667, 1083 | 6.767676767676767, 1084 | 6.8686868686868685, 1085 | 6.96969696969697, 1086 | 7.070707070707071, 1087 | 7.171717171717171, 1088 | 7.2727272727272725, 1089 | 7.373737373737374, 1090 | 7.474747474747475, 1091 | 7.575757575757575, 1092 | 7.6767676767676765, 1093 | 7.777777777777778, 1094 | 7.878787878787879, 1095 | 7.979797979797979, 1096 | 8.080808080808081, 1097 | 8.181818181818182, 1098 | 8.282828282828282, 1099 | 8.383838383838384, 1100 | 8.484848484848484, 1101 | 8.585858585858587, 1102 | 8.686868686868687, 1103 | 8.787878787878787, 1104 | 8.88888888888889, 1105 | 8.98989898989899, 1106 | 9.09090909090909, 1107 | 9.191919191919192, 1108 | 9.292929292929292, 1109 | 9.393939393939394, 1110 | 9.494949494949495, 1111 | 9.595959595959595, 1112 | 9.696969696969697, 1113 | 9.797979797979798, 1114 | 9.8989898989899, 1115 | 10.0] 1116 | 1117 | label_options = { 1118 | 'color': rgb('009B85'), # color of tick labels and titles 1119 | 'bold': True} 1120 | graph = Graph(xlabel='X', ylabel='Y', 1121 | x_ticks_major=(max(x)-min(x))/10, y_ticks_major=(max(y) - min(y))/5, 1122 | y_grid_label=True, x_grid_label=True, padding=5, 1123 | x_grid=True, y_grid=True, xmin=min(x), xmax=max(x) + 1, ymin=min(y), background_color = (1,1,1,.9), ymax=max(y) + .1,border_color = (0,0,0,1),label_options = label_options) 1124 | plot = LinePlot(color=[0/255,155/255,133/255,1]) 1125 | plot.line_width = "2px" 1126 | plot.points = list(zip(x,y)) 1127 | graph.add_plot(plot) 1128 | return graph 1129 | 1130 | class v1App(MDApp): 1131 | def build(self): 1132 | sm = ScreenManager(transition=CardTransition()) 1133 | sm.add_widget(InputScreen()) 1134 | sm.add_widget(LoadingScreen()) 1135 | sm.add_widget(ResultOptionScreen()) 1136 | sm.add_widget(PredictorScreen()) 1137 | sm.add_widget(FlowInputScreen()) 1138 | sm.add_widget(FlowOutputScreen()) 1139 | sm.add_widget(RadiusInputScreen()) 1140 | sm.add_widget(RadiusOutputScreen()) 1141 | sm.add_widget(AdvancedInputScreen()) 1142 | sm.add_widget(GraphWaitScreenRadius()) 1143 | sm.add_widget(GraphWaitScreenFlow()) 1144 | return sm 1145 | 1146 | 1147 | 1148 | if __name__ == "__main__": 1149 | v1App().run() 1150 | -------------------------------------------------------------------------------- /elixir app/v3: -------------------------------------------------------------------------------- 1 | from kivy.app import App 2 | from kivy.uix.widget import Widget 3 | from kivy.uix.boxlayout import BoxLayout 4 | from kivy.graphics import Rectangle 5 | from kivy.core.window import Window 6 | from kivy.uix.button import Button 7 | from kivy.uix.gridlayout import GridLayout 8 | from kivy.uix.textinput import TextInput 9 | from kivy.properties import ObjectProperty 10 | from kivy.uix.screenmanager import Screen,ScreenManager,CardTransition 11 | from kivy.lang import Builder 12 | from kivymd.app import MDApp 13 | from kivymd.uix.textfield import MDTextField 14 | from kivymd.uix.button import MDFillRoundFlatButton,MDIconButton 15 | from kivymd.uix.label import MDIcon 16 | import elixir as ex 17 | import seaborn as sns 18 | import matplotlib.pyplot as plt 19 | import numpy as np 20 | from kivy.uix.image import Image 21 | from kivy.uix.modalview import ModalView 22 | 23 | 24 | Builder.load_string(""" 25 | : 26 | background_color: (1, 1, 1, 1) 27 | canvas.before: 28 | Color: 29 | rgba: root.background_color 30 | Rectangle: 31 | size: self.size 32 | pos: self.pos 33 | : 34 | icon:"home-circle-outline" 35 | theme_text_color:"Custom" 36 | #text_color:(135/255,0,106/255,1) 37 | text_color:(1,1,1,1) 38 | user_font_size: "80sp" 39 | on_release: 40 | app.root.current = "input" 41 | : 42 | icon:"help" 43 | theme_text_color:"Custom" 44 | #text_color :(135/255,0,106/255,1) 45 | text_color:(1,1,1,1) 46 | user_font_size : "80sp" 47 | : 48 | orientation:"vertical" 49 | canvas.before: 50 | Color: 51 | rgba:(0/255,155/255,133/255,1) 52 | Rectangle: 53 | size:self.size 54 | pos:self.pos 55 | Label: 56 | size_hint:(1,0.3) 57 | text:"Elixir" 58 | font_size:"30sp" 59 | HomeButton: 60 | size_hint:(1,.5) 61 | #pos_hint:{"center_x":.5,"center_y":.5} 62 | #icon:"home-variant-outline" 63 | AboutButton: 64 | size_hint:(1,0.5) 65 | BoxLayout: 66 | : 67 | background_color:(0/255,155/255,133/255,1) 68 | color:(1,1,1,1) 69 | : 70 | background_color:(135/255,0,106/255,1) 71 | : 72 | name : "input" 73 | upStr:upStr 74 | downStr:downStr 75 | timePeriod:timePeriod 76 | length:length 77 | BoxLayout: 78 | orientation: "horizontal" 79 | SideBar: 80 | size_hint : 0.3,1 81 | 82 | RelativeLayout: 83 | Image: 84 | source: "./Media/BlueCum.jpg" 85 | allow_stretch: True 86 | keep_ratio: False 87 | #canvas.before: 88 | #Color: 89 | #rgba:(0,2/255,46/255,1) 90 | #rgba:(.5,.5,.5,.5) 91 | #Rectangle: 92 | #pos:root.pos 93 | #size:root.size 94 | 95 | BoxLayout: 96 | pos_hint: {"center_x":.5,"center_y":.5} 97 | size_hint : .6,.65 98 | orientation:"vertical" 99 | canvas.before: 100 | Color: 101 | rgba:(1,1,1,1) 102 | Rectangle: 103 | pos:self.pos 104 | size:self.size 105 | GridLayout: 106 | cols:2 107 | rows:4 108 | spacing:[0,20] 109 | padding:[20,20] 110 | size_hint: (1,.8) 111 | ColorLabel: 112 | text:"Upstream Radius (Ru)" 113 | TextInput: 114 | id:upStr 115 | fill_color:(.5,.5,0,1) 116 | #hint_text: "Up stream Radius" 117 | #hint_text_color: (1,0,0,1) 118 | ColorLabel: 119 | text:"Downstream Radius (Rd) " 120 | TextInput: 121 | id:downStr 122 | ColorLabel: 123 | text:"Time period" 124 | TextInput: 125 | id:timePeriod 126 | ColorLabel: 127 | text:"Length" 128 | TextInput: 129 | id:length 130 | BoxLayout: 131 | orientation:"horizontal" 132 | size_hint:1,0.1 133 | RelativeLayout: 134 | MDFillRoundFlatButton: 135 | text: "Advanced" 136 | #text_size:self.width, None 137 | theme_text_color: "Custom" 138 | text_color: 1, 1, 1, 1 139 | md_bg_color: (0/255,155/255,133/255,1) 140 | size_hint : 0.5,0.7 141 | pos_hint:{'center_x':.5,'center_y':.7} 142 | on_release: 143 | app.root.current = "advancedinput" 144 | RelativeLayout: 145 | MDFillRoundFlatButton: 146 | text: "Submit" 147 | theme_text_color: "Custom" 148 | text_color: 1, 1, 1, 1 149 | md_bg_color: (0/255,155/255,133/255,1) 150 | size_hint : 0.5,0.7 151 | pos_hint:{'center_x':.5,'center_y':.7} 152 | on_release: 153 | root.on_submit() 154 | : 155 | name : "advancedinput" 156 | upStr:upStr 157 | downStr:downStr 158 | timePeriod:timePeriod 159 | length:length 160 | deltab:deltab 161 | reynold:reynold 162 | e:e 163 | h:h 164 | qzer:qzer 165 | activation:activation 166 | numsamp:numsamp 167 | BoxLayout: 168 | orientation: "horizontal" 169 | SideBar: 170 | size_hint : 0.3,1 171 | 172 | RelativeLayout: 173 | Image: 174 | source: "./Media/BlueCum.jpg" 175 | allow_stretch: True 176 | keep_ratio: False 177 | #canvas.before: 178 | #Color: 179 | #rgba:(0,2/255,46/255,1) 180 | #rgba:(.5,.5,.5,.5) 181 | #Rectangle: 182 | #pos:root.pos 183 | #size:root.size 184 | 185 | BoxLayout: 186 | pos_hint: {"center_x":.5,"center_y":.5} 187 | size_hint : .7,.8 188 | orientation:"vertical" 189 | canvas.before: 190 | Color: 191 | rgba:(1,1,1,1) 192 | Rectangle: 193 | pos:self.pos 194 | size:self.size 195 | GridLayout: 196 | cols:2 197 | rows:11 198 | spacing:[0,10] 199 | padding:[20,20] 200 | size_hint: (1,.8) 201 | ColorLabel: 202 | text:"Upstream Radius (Ru)" 203 | TextInput: 204 | id:upStr 205 | fill_color:(.5,.5,0,1) 206 | #hint_text: "Up stream Radius" 207 | #hint_text_color: (1,0,0,1) 208 | 209 | ColorLabel: 210 | text:"Downstream Radius (Rd) " 211 | TextInput: 212 | id:downStr 213 | 214 | ColorLabel: 215 | text:"Time period" 216 | TextInput: 217 | id:timePeriod 218 | 219 | ColorLabel: 220 | text:"Length" 221 | TextInput: 222 | id:length 223 | 224 | ColorLabel: 225 | text:"Delta B" 226 | TextInput: 227 | id:deltab 228 | 229 | ColorLabel: 230 | text:"Reynold's Number" 231 | TextInput: 232 | id:reynold 233 | 234 | ColorLabel: 235 | text:"E" 236 | TextInput: 237 | id:e 238 | 239 | ColorLabel: 240 | text:"H" 241 | TextInput: 242 | id:h 243 | 244 | ColorLabel: 245 | text:"q_0" 246 | TextInput: 247 | id:qzer 248 | 249 | ColorLabel: 250 | text:"Activation" 251 | TextInput: 252 | id:activation 253 | 254 | ColorLabel: 255 | text:"Sample Count" 256 | TextInput: 257 | id:numsamp 258 | 259 | BoxLayout: 260 | orientation:"horizontal" 261 | size_hint:1,0.1 262 | RelativeLayout: 263 | MDFillRoundFlatButton: 264 | text: "Back" 265 | #text_size:self.width, None 266 | theme_text_color: "Custom" 267 | text_color: 1, 1, 1, 1 268 | md_bg_color: (0/255,155/255,133/255,1) 269 | size_hint : 0.5,0.7 270 | pos_hint:{'center_x':.5,'center_y':.7} 271 | on_release: 272 | app.root.current = "input" 273 | RelativeLayout: 274 | MDFillRoundFlatButton: 275 | text: "Submit" 276 | theme_text_color: "Custom" 277 | text_color: 1, 1, 1, 1 278 | md_bg_color: (0/255,155/255,133/255,1) 279 | size_hint : 0.5,0.7 280 | pos_hint:{'center_x':.5,'center_y':.7} 281 | on_release: 282 | root.on_submit() 283 | : 284 | name : "load" 285 | BoxLayout: 286 | orientation: "horizontal" 287 | SideBar: 288 | size_hint : 0.3,1 289 | RelativeLayout: 290 | Image: 291 | source: "./Media/BlueCum.jpg" 292 | allow_stretch: True 293 | keep_ratio: False 294 | Label: 295 | pos_hint: {"center_x":0.5, "center_y":0.5} 296 | size_hint: (1, 0.3) 297 | text: "Loading..." 298 | font_size: "30sp" 299 | : 300 | name : "graphwaitradius" 301 | BoxLayout: 302 | orientation: "horizontal" 303 | SideBar: 304 | size_hint : 0.3,1 305 | RelativeLayout: 306 | Image: 307 | source: "./Media/BlueCum.jpg" 308 | allow_stretch: True 309 | keep_ratio: False 310 | Label: 311 | pos_hint: {"center_x":0.5, "center_y":0.5} 312 | size_hint: (1, 0.3) 313 | text: "Loading..." 314 | font_size: "30sp" 315 | : 316 | name : "graphwaitflow" 317 | BoxLayout: 318 | orientation: "horizontal" 319 | SideBar: 320 | size_hint : 0.3,1 321 | RelativeLayout: 322 | Image: 323 | source: "./Media/BlueCum.jpg" 324 | allow_stretch: True 325 | keep_ratio: False 326 | Label: 327 | pos_hint: {"center_x":0.5, "center_y":0.5} 328 | size_hint: (1, 0.3) 329 | text: "Loading..." 330 | font_size: "30sp" 331 | : 332 | name : "resultoption" 333 | BoxLayout: 334 | orientation: "horizontal" 335 | SideBar: 336 | size_hint : 0.3,1 337 | RelativeLayout: 338 | Image: 339 | source: "./Media/BlueCum.jpg" 340 | allow_stretch: True 341 | keep_ratio: False 342 | #canvas.before: 343 | #Color: 344 | #rgba:(0,2/255,46/255,1) 345 | #rgba:(.5,.5,.5,.5) 346 | #Rectangle: 347 | #pos:root.pos 348 | #size:root.size 349 | BoxLayout: 350 | pos_hint: {"center_x":.5,"center_y":.5} 351 | size_hint : .6,.65 352 | #padding:[20,20] 353 | #spacing:[0,20] 354 | orientation:"vertical" 355 | canvas.before: 356 | Color: 357 | rgba:(1,1,1,1) 358 | Rectangle: 359 | size:self.size 360 | pos:self.pos 361 | RelativeLayout: 362 | MDFillRoundFlatButton: 363 | text: "Predictor" 364 | font_size:"20sp" 365 | theme_text_color: "Custom" 366 | text_color: 1, 1, 1, 1 367 | md_bg_color: (0/255,155/255,133/255,1) 368 | size_hint : 0.7,0.6 369 | pos_hint:{'center_x':.5,'center_y':.5} 370 | on_release: 371 | root.predictor() 372 | RelativeLayout: 373 | MDFillRoundFlatButton: 374 | text: "Flow Graph" 375 | font_size:"20sp" 376 | theme_text_color: "Custom" 377 | text_color: 1, 1, 1, 1 378 | md_bg_color: (0/255,155/255,133/255,1) 379 | size_hint : 0.7,0.6 380 | pos_hint:{'center_x':.5,'center_y':.5} 381 | on_release: 382 | root.flow() 383 | RelativeLayout: 384 | MDFillRoundFlatButton: 385 | text: "Radii Graph" 386 | font_size:"20sp" 387 | theme_text_color: "Custom" 388 | text_color: 1, 1, 1, 1 389 | md_bg_color: (0/255,155/255,133/255,1) 390 | size_hint : 0.7,0.6 391 | pos_hint:{'center_x':.5,'center_y':.5} 392 | on_release: 393 | root.radius() 394 | : 395 | name:"predictor" 396 | z:z 397 | t:t 398 | q:q 399 | r:r 400 | BoxLayout: 401 | orientation: "horizontal" 402 | SideBar: 403 | size_hint : 0.3,1 404 | RelativeLayout: 405 | Image: 406 | source: "./Media/BlueCum.jpg" 407 | allow_stretch: True 408 | keep_ratio: False 409 | #canvas.before: 410 | #Color: 411 | #rgba:(0,2/255,46/255,1) 412 | #rgba:(.5,.5,.5,.5) 413 | #Rectangle: 414 | #pos:root.pos 415 | #size:root.size 416 | BoxLayout: 417 | pos_hint: {"center_x":.5,"center_y":.5} 418 | size_hint : .6,.65 419 | #padding:[20,20] 420 | #spacing:[0,20] 421 | orientation:"vertical" 422 | canvas.before: 423 | Color: 424 | rgba:(1,1,1,1) 425 | Rectangle: 426 | size:self.size 427 | pos:self.pos 428 | GridLayout: 429 | cols:2 430 | rows:4 431 | spacing:[0,20] 432 | padding:[20,20] 433 | size_hint: (1,.8) 434 | ColorLabel: 435 | text:"Location (z)" 436 | TextInput: 437 | id:z 438 | fill_color:(.5,.5,0,1) 439 | #hint_text: "Up stream Radius" 440 | #hint_text_color: (1,0,0,1) 441 | ColorLabel: 442 | text:"Time (t) " 443 | TextInput: 444 | id:t 445 | ColorLabel: 446 | text:"Predicted q" 447 | ColorLabel: 448 | id:q 449 | background_color:(1,1,1,1) 450 | color:(0,0,0,1) 451 | #text:"" 452 | ColorLabel: 453 | text:"Predicted R" 454 | ColorLabel: 455 | id:r 456 | background_color:(1,1,1,1) 457 | color:(0,0,0,1) 458 | #text:"" 459 | BoxLayout: 460 | orientation:"horizontal" 461 | size_hint:(1,.2) 462 | RelativeLayout: 463 | MDFillRoundFlatButton: 464 | text:"Back" 465 | theme_text_color: "Custom" 466 | text_color: 1, 1, 1, 1 467 | md_bg_color: (0/255,155/255,133/255,1) 468 | size_hint : 0.7,0.6 469 | pos_hint:{'center_x':.5,'center_y':.5} 470 | on_release: 471 | #app.root.current = "resultoption" 472 | app.root.current = "resultoption" 473 | RelativeLayout: 474 | 475 | MDFillRoundFlatButton: 476 | text:"Compute" 477 | theme_text_color: "Custom" 478 | text_color: 1, 1, 1, 1 479 | md_bg_color: (0/255,155/255,133/255,1) 480 | size_hint : 0.7,0.6 481 | pos_hint:{'center_x':.5,'center_y':.5} 482 | on_release: 483 | root.predict() 484 | 485 | : 486 | name : "flowoption" 487 | BoxLayout: 488 | orientation: "horizontal" 489 | SideBar: 490 | size_hint : 0.3,1 491 | RelativeLayout: 492 | Image: 493 | source: "./Media/BlueCum.jpg" 494 | allow_stretch: True 495 | keep_ratio: False 496 | #canvas.before: 497 | #Color: 498 | #rgba:(0,2/255,46/255,1) 499 | #rgba:(.5,.5,.5,.5) 500 | #Rectangle: 501 | #pos:root.pos 502 | #size:root.size 503 | BoxLayout: 504 | pos_hint: {"center_x":.5,"center_y":.5} 505 | size_hint : .6,.65 506 | #padding:[20,20] 507 | #spacing:[0,20] 508 | orientation:"vertical" 509 | canvas.before: 510 | Color: 511 | rgba:(1,1,1,1) 512 | Rectangle: 513 | size:self.size 514 | pos:self.pos 515 | RelativeLayout: 516 | MDFillRoundFlatButton: 517 | text: "Time (t)" 518 | font_size:"20sp" 519 | theme_text_color: "Custom" 520 | text_color: 1, 1, 1, 1 521 | md_bg_color: (0/255,155/255,133/255,1) 522 | size_hint : 0.7,0.6 523 | pos_hint:{'center_x':.5,'center_y':.5} 524 | on_release: 525 | root.time() 526 | RelativeLayout: 527 | MDFillRoundFlatButton: 528 | text: "Length (z)" 529 | font_size:"20sp" 530 | theme_text_color: "Custom" 531 | text_color: 1, 1, 1, 1 532 | md_bg_color: (0/255,155/255,133/255,1) 533 | size_hint : 0.7,0.6 534 | pos_hint:{'center_x':.5,'center_y':.5} 535 | on_release: 536 | root.length() 537 | RelativeLayout: 538 | MDFillRoundFlatButton: 539 | text: "Back" 540 | font_size:"20sp" 541 | theme_text_color: "Custom" 542 | text_color: 1, 1, 1, 1 543 | md_bg_color: (0/255,155/255,133/255,1) 544 | size_hint : 0.7,0.6 545 | pos_hint:{'center_x':.5,'center_y':.5} 546 | on_release: 547 | app.root.current = "resultoption" 548 | : 549 | name:"flowinputtime" 550 | t:t 551 | BoxLayout: 552 | orientation: "horizontal" 553 | SideBar: 554 | size_hint : 0.3,1 555 | RelativeLayout: 556 | Image: 557 | source: "./Media/BlueCum.jpg" 558 | allow_stretch: True 559 | keep_ratio: False 560 | #canvas.before: 561 | #Color: 562 | #rgba:(0,2/255,46/255,1) 563 | #rgba:(.5,.5,.5,.5) 564 | #Rectangle: 565 | #pos:root.pos 566 | #size:root.size 567 | BoxLayout: 568 | pos_hint: {"center_x":.5,"center_y":.5} 569 | size_hint : .7,.4 570 | #padding:[20,20] 571 | #spacing:[0,20] 572 | orientation:"vertical" 573 | canvas.before: 574 | Color: 575 | rgba:(1,1,1,1) 576 | Rectangle: 577 | size:self.size 578 | pos:self.pos 579 | #BoxLayout: 580 | BoxLayout: 581 | orientation:"vertical" 582 | spacing:[0,20] 583 | padding:[20,20] 584 | #size_hint: (1,.8) 585 | BoxLayout: 586 | ColorLabel: 587 | text:"Time Value (t)" 588 | TextInput: 589 | id:t 590 | fill_color:(.5,.5,0,1) 591 | #hint_text: "Up stream Radius" 592 | #hint_text_color: (1,0,0,1) 593 | #BoxLayout: 594 | BoxLayout: 595 | orientation:"horizontal" 596 | #size_hint:(1,.2) 597 | RelativeLayout: 598 | MDFillRoundFlatButton: 599 | text:"Back" 600 | theme_text_color: "Custom" 601 | text_color: 1, 1, 1, 1 602 | md_bg_color: (0/255,155/255,133/255,1) 603 | size_hint : 0.7,0.4 604 | pos_hint:{'center_x':.5,'center_y':.5} 605 | on_release: 606 | app.root.current = "flowoption" 607 | RelativeLayout: 608 | 609 | MDFillRoundFlatButton: 610 | text:"Plot Graph" 611 | theme_text_color: "Custom" 612 | text_color: 1, 1, 1, 1 613 | md_bg_color: (0/255,155/255,133/255,1) 614 | size_hint : 0.7,0.4 615 | pos_hint:{'center_x':.5,'center_y':.5} 616 | on_release: 617 | root.flowgraph() 618 | : 619 | name:"flowinputlength" 620 | l:l 621 | BoxLayout: 622 | orientation: "horizontal" 623 | SideBar: 624 | size_hint : 0.3,1 625 | RelativeLayout: 626 | Image: 627 | source: "./Media/BlueCum.jpg" 628 | allow_stretch: True 629 | keep_ratio: False 630 | #canvas.before: 631 | #Color: 632 | #rgba:(0,2/255,46/255,1) 633 | #rgba:(.5,.5,.5,.5) 634 | #Rectangle: 635 | #pos:root.pos 636 | #size:root.size 637 | BoxLayout: 638 | pos_hint: {"center_x":.5,"center_y":.5} 639 | size_hint : .7,.4 640 | #padding:[20,20] 641 | #spacing:[0,20] 642 | orientation:"vertical" 643 | canvas.before: 644 | Color: 645 | rgba:(1,1,1,1) 646 | Rectangle: 647 | size:self.size 648 | pos:self.pos 649 | #BoxLayout: 650 | BoxLayout: 651 | orientation:"vertical" 652 | spacing:[0,20] 653 | padding:[20,20] 654 | #size_hint: (1,.8) 655 | BoxLayout: 656 | ColorLabel: 657 | text:"Length Value (z)" 658 | TextInput: 659 | id:l 660 | fill_color:(.5,.5,0,1) 661 | #hint_text: "Up stream Radius" 662 | #hint_text_color: (1,0,0,1) 663 | #BoxLayout: 664 | BoxLayout: 665 | orientation:"horizontal" 666 | #size_hint:(1,.2) 667 | RelativeLayout: 668 | MDFillRoundFlatButton: 669 | text:"Back" 670 | theme_text_color: "Custom" 671 | text_color: 1, 1, 1, 1 672 | md_bg_color: (0/255,155/255,133/255,1) 673 | size_hint : 0.7,0.4 674 | pos_hint:{'center_x':.5,'center_y':.5} 675 | on_release: 676 | app.root.current = "flowoption" 677 | RelativeLayout: 678 | 679 | MDFillRoundFlatButton: 680 | text:"Plot Graph" 681 | theme_text_color: "Custom" 682 | text_color: 1, 1, 1, 1 683 | md_bg_color: (0/255,155/255,133/255,1) 684 | size_hint : 0.7,0.4 685 | pos_hint:{'center_x':.5,'center_y':.5} 686 | on_release: 687 | root.flowgraph() 688 | : 689 | name:"flowoutput" 690 | im:im 691 | BoxLayout: 692 | orientation: "horizontal" 693 | SideBar: 694 | size_hint : 0.3,1 695 | RelativeLayout: 696 | Image: 697 | source: "./Media/BlueCum.jpg" 698 | allow_stretch: True 699 | keep_ratio: False 700 | #canvas.before: 701 | #Color: 702 | #rgba:(0,2/255,46/255,1) 703 | #rgba:(.5,.5,.5,.5) 704 | #Rectangle: 705 | #pos:root.pos 706 | #size:root.size 707 | BoxLayout: 708 | pos_hint: {"center_x":.5,"center_y":.5} 709 | size_hint : .7,.6 710 | #padding:[20,20] 711 | #spacing:[0,20] 712 | orientation:"vertical" 713 | canvas.before: 714 | Color: 715 | rgba:(1,1,1,1) 716 | Rectangle: 717 | size:self.size 718 | pos:self.pos 719 | #BoxLayout: 720 | BoxLayout: 721 | size_hint:1,.7 722 | Image: 723 | id:im 724 | #source: root.graphimage 725 | keep_ratio:False 726 | allow_stretch:True 727 | #BoxLayout: 728 | RelativeLayout: 729 | size_hint:1,.3 730 | MDFillRoundFlatButton: 731 | text:"Back" 732 | theme_text_color: "Custom" 733 | text_color: 1, 1, 1, 1 734 | md_bg_color: (0/255,155/255,133/255,1) 735 | size_hint : 0.7,0.3 736 | pos_hint:{'center_x':.5,'center_y':.5} 737 | on_release: 738 | app.root.current = "resultoption" 739 | 740 | : 741 | name : "radiusoption" 742 | BoxLayout: 743 | orientation: "horizontal" 744 | SideBar: 745 | size_hint : 0.3,1 746 | RelativeLayout: 747 | Image: 748 | source: "./Media/BlueCum.jpg" 749 | allow_stretch: True 750 | keep_ratio: False 751 | #canvas.before: 752 | #Color: 753 | #rgba:(0,2/255,46/255,1) 754 | #rgba:(.5,.5,.5,.5) 755 | #Rectangle: 756 | #pos:root.pos 757 | #size:root.size 758 | BoxLayout: 759 | pos_hint: {"center_x":.5,"center_y":.5} 760 | size_hint : .6,.65 761 | #padding:[20,20] 762 | #spacing:[0,20] 763 | orientation:"vertical" 764 | canvas.before: 765 | Color: 766 | rgba:(1,1,1,1) 767 | Rectangle: 768 | size:self.size 769 | pos:self.pos 770 | RelativeLayout: 771 | MDFillRoundFlatButton: 772 | text: "Time (t)" 773 | font_size:"20sp" 774 | theme_text_color: "Custom" 775 | text_color: 1, 1, 1, 1 776 | md_bg_color: (0/255,155/255,133/255,1) 777 | size_hint : 0.7,0.6 778 | pos_hint:{'center_x':.5,'center_y':.5} 779 | on_release: 780 | root.time() 781 | RelativeLayout: 782 | MDFillRoundFlatButton: 783 | text: "Length (z)" 784 | font_size:"20sp" 785 | theme_text_color: "Custom" 786 | text_color: 1, 1, 1, 1 787 | md_bg_color: (0/255,155/255,133/255,1) 788 | size_hint : 0.7,0.6 789 | pos_hint:{'center_x':.5,'center_y':.5} 790 | on_release: 791 | root.length() 792 | RelativeLayout: 793 | MDFillRoundFlatButton: 794 | text: "Back" 795 | font_size:"20sp" 796 | theme_text_color: "Custom" 797 | text_color: 1, 1, 1, 1 798 | md_bg_color: (0/255,155/255,133/255,1) 799 | size_hint : 0.7,0.6 800 | pos_hint:{'center_x':.5,'center_y':.5} 801 | on_release: 802 | app.root.current = "resultoption" 803 | : 804 | name:"radiusinputtime" 805 | t:t 806 | BoxLayout: 807 | orientation: "horizontal" 808 | SideBar: 809 | size_hint : 0.3,1 810 | RelativeLayout: 811 | Image: 812 | source: "./Media/BlueCum.jpg" 813 | allow_stretch: True 814 | keep_ratio: False 815 | #canvas.before: 816 | #Color: 817 | #rgba:(0,2/255,46/255,1) 818 | #rgba:(.5,.5,.5,.5) 819 | #Rectangle: 820 | #pos:root.pos 821 | #size:root.size 822 | BoxLayout: 823 | pos_hint: {"center_x":.5,"center_y":.5} 824 | size_hint : .7,.4 825 | #padding:[20,20] 826 | #spacing:[0,20] 827 | orientation:"vertical" 828 | canvas.before: 829 | Color: 830 | rgba:(1,1,1,1) 831 | Rectangle: 832 | size:self.size 833 | pos:self.pos 834 | #BoxLayout: 835 | BoxLayout: 836 | orientation:"vertical" 837 | spacing:[0,20] 838 | padding:[20,20] 839 | #size_hint: (1,.8) 840 | BoxLayout: 841 | ColorLabel: 842 | text:"Time Value (t)" 843 | TextInput: 844 | id:t 845 | fill_color:(.5,.5,0,1) 846 | #hint_text: "Up stream Radius" 847 | #hint_text_color: (1,0,0,1) 848 | #BoxLayout: 849 | BoxLayout: 850 | orientation:"horizontal" 851 | #size_hint:(1,.2) 852 | RelativeLayout: 853 | MDFillRoundFlatButton: 854 | text:"Back" 855 | theme_text_color: "Custom" 856 | text_color: 1, 1, 1, 1 857 | md_bg_color: (0/255,155/255,133/255,1) 858 | size_hint : 0.7,0.4 859 | pos_hint:{'center_x':.5,'center_y':.5} 860 | on_release: 861 | app.root.current = "radiusoption" 862 | RelativeLayout: 863 | 864 | MDFillRoundFlatButton: 865 | text:"Plot Graph" 866 | theme_text_color: "Custom" 867 | text_color: 1, 1, 1, 1 868 | md_bg_color: (0/255,155/255,133/255,1) 869 | size_hint : 0.7,0.4 870 | pos_hint:{'center_x':.5,'center_y':.5} 871 | on_release: 872 | root.radiusgraph() 873 | : 874 | name:"radiusinputlength" 875 | l:l 876 | BoxLayout: 877 | orientation: "horizontal" 878 | SideBar: 879 | size_hint : 0.3,1 880 | RelativeLayout: 881 | Image: 882 | source: "./Media/BlueCum.jpg" 883 | allow_stretch: True 884 | keep_ratio: False 885 | #canvas.before: 886 | #Color: 887 | #rgba:(0,2/255,46/255,1) 888 | #rgba:(.5,.5,.5,.5) 889 | #Rectangle: 890 | #pos:root.pos 891 | #size:root.size 892 | BoxLayout: 893 | pos_hint: {"center_x":.5,"center_y":.5} 894 | size_hint : .7,.4 895 | #padding:[20,20] 896 | #spacing:[0,20] 897 | orientation:"vertical" 898 | canvas.before: 899 | Color: 900 | rgba:(1,1,1,1) 901 | Rectangle: 902 | size:self.size 903 | pos:self.pos 904 | #BoxLayout: 905 | BoxLayout: 906 | orientation:"vertical" 907 | spacing:[0,20] 908 | padding:[20,20] 909 | #size_hint: (1,.8) 910 | BoxLayout: 911 | ColorLabel: 912 | text:"Length Value (z)" 913 | TextInput: 914 | id:l 915 | fill_color:(.5,.5,0,1) 916 | #hint_text: "Up stream Radius" 917 | #hint_text_color: (1,0,0,1) 918 | #BoxLayout: 919 | BoxLayout: 920 | orientation:"horizontal" 921 | #size_hint:(1,.2) 922 | RelativeLayout: 923 | MDFillRoundFlatButton: 924 | text:"Back" 925 | theme_text_color: "Custom" 926 | text_color: 1, 1, 1, 1 927 | md_bg_color: (0/255,155/255,133/255,1) 928 | size_hint : 0.7,0.4 929 | pos_hint:{'center_x':.5,'center_y':.5} 930 | on_release: 931 | app.root.current = "radiusoption" 932 | RelativeLayout: 933 | 934 | MDFillRoundFlatButton: 935 | text:"Plot Graph" 936 | theme_text_color: "Custom" 937 | text_color: 1, 1, 1, 1 938 | md_bg_color: (0/255,155/255,133/255,1) 939 | size_hint : 0.7,0.4 940 | pos_hint:{'center_x':.5,'center_y':.5} 941 | on_release: 942 | root.radiusgraph() 943 | : 944 | name:"radiusoutput" 945 | im:im 946 | BoxLayout: 947 | orientation: "horizontal" 948 | SideBar: 949 | size_hint : 0.3,1 950 | RelativeLayout: 951 | Image: 952 | source: "./Media/BlueCum.jpg" 953 | allow_stretch: True 954 | keep_ratio: False 955 | #canvas.before: 956 | #Color: 957 | #rgba:(0,2/255,46/255,1) 958 | #rgba:(.5,.5,.5,.5) 959 | #Rectangle: 960 | #pos:root.pos 961 | #size:root.size 962 | BoxLayout: 963 | pos_hint: {"center_x":.5,"center_y":.5} 964 | size_hint : .7,.6 965 | #padding:[20,20] 966 | #spacing:[0,20] 967 | orientation:"vertical" 968 | canvas.before: 969 | Color: 970 | rgba:(1,1,1,1) 971 | Rectangle: 972 | size:self.size 973 | pos:self.pos 974 | #BoxLayout: 975 | BoxLayout: 976 | size_hint:1,.7 977 | Image: 978 | id:im 979 | #source: root.graphimage 980 | keep_ratio:False 981 | allow_stretch:True 982 | #BoxLayout: 983 | RelativeLayout: 984 | size_hint:1,.3 985 | MDFillRoundFlatButton: 986 | text:"Back" 987 | theme_text_color: "Custom" 988 | text_color: 1, 1, 1, 1 989 | md_bg_color: (0/255,155/255,133/255,1) 990 | size_hint : 0.7,0.3 991 | pos_hint:{'center_x':.5,'center_y':.5} 992 | on_release: 993 | app.root.current = "resultoption" 994 | 995 | 996 | """) 997 | 998 | class InputScreen(Screen): 999 | upStr = ObjectProperty(None) 1000 | downStr = ObjectProperty(None) 1001 | timePeriod = ObjectProperty(None) 1002 | length = ObjectProperty(None) 1003 | def on_enter(self): 1004 | print("Entered input") 1005 | 1006 | 1007 | def on_submit(self): 1008 | #create the model object and then pass it to the loading screen 1009 | """head = ex.artery(Ru=float(self.upStr.text), Rd=float(self.downStr.text), timeperiod=float(self.timePeriod.text)) 1010 | LoadingScreen.arteryObj = head""" 1011 | #print(self.upStr.text) 1012 | app = App.get_running_app() 1013 | app.root.current = "load" 1014 | 1015 | class AdvancedInputScreen(Screen): 1016 | upStr = ObjectProperty(None) 1017 | downStr = ObjectProperty(None) 1018 | timePeriod = ObjectProperty(None) 1019 | length = ObjectProperty(None) 1020 | deltab = ObjectProperty(None) 1021 | reynold = ObjectProperty(None) 1022 | e = ObjectProperty(None) 1023 | h = ObjectProperty(None) 1024 | qzer = ObjectProperty(None) 1025 | activation = ObjectProperty(None) 1026 | numsamp = ObjectProperty(None) 1027 | def on_submit(self): 1028 | if(self.upStr.text == ""): 1029 | print("Empty") 1030 | """head = ex.artery(Ru=float(self.upStr.text), Rd=float(self.downStr.text), timeperiod=float(self.timePeriod.text), L=float(self.length.text), 1031 | delta_b=float(self.deltab.text), Reynolds_no=float(self.reynold.text), E=float(self.e.text), h=float(self.h.text), 1032 | q_0=float(self.qzer.text), activation=float(self.activation.text), num_train_samples=float(self.numsamp.text)) 1033 | LoadingScreen.arteryObj = head""" 1034 | app = App.get_running_app() 1035 | app.root.current = "load" 1036 | 1037 | class LoadingScreen(Screen): 1038 | arteryObj = None 1039 | """def on_enter(self): 1040 | ResultOptionScreen.model = self.arteryObj.sci_train() 1041 | ResultOptionScreen.arteryObj = self.arteryObj 1042 | app = App.get_running_app() 1043 | app.root.current = "resultoption""" 1044 | def on_enter(self): 1045 | PredictorScreen.arteryObj = self.arteryObj 1046 | app = App.get_running_app() 1047 | app.root.current = "resultoption" 1048 | 1049 | 1050 | class ResultOptionScreen(Screen): 1051 | arteryObj = None 1052 | model = None 1053 | def predictor(self): 1054 | PredictorScreen.arteryObj = self.arteryObj 1055 | app = App.get_running_app() 1056 | app.root.current = "predictor" 1057 | def flow(self): 1058 | FlowOptionScreen.arteryObj = self.arteryObj 1059 | app = App.get_running_app() 1060 | app.root.current = "flowoption" 1061 | 1062 | def radius(self): 1063 | RadiusOptionScreen.arteryObj = self.arteryObj 1064 | app = App.get_running_app() 1065 | app.root.current = "radiusoption" 1066 | 1067 | 1068 | class PredictorScreen(Screen): 1069 | arteryObj = None 1070 | z = ObjectProperty(None) 1071 | t = ObjectProperty(None) 1072 | r = ObjectProperty(None) 1073 | q = ObjectProperty(None) 1074 | def predict(self): 1075 | #print("predicting") 1076 | """self.r.text=self.arteryObj.q_network[[float(self.z.text), float(self.t.text)]] 1077 | self.q.text=self.arteryObj.R_network[[self.z.text, float(self.t.text)]]""" 1078 | pass 1079 | 1080 | 1081 | 1082 | class FlowOptionScreen(Screen): 1083 | arteryObj = None 1084 | def time(self): 1085 | FlowInputTimeScreen.arteryObj = self.arteryObj 1086 | app = App.get_running_app() 1087 | app.root.current = "flowinputtime" 1088 | def length(self): 1089 | FlowInputLengthScreen.arteryObj = self.arteryObj 1090 | app = App.get_running_app() 1091 | app.root.current = "flowinputlength" 1092 | 1093 | class FlowInputLengthScreen(Screen): 1094 | arteryObj = None 1095 | l = ObjectProperty(None) 1096 | def flowgraph(self): 1097 | """name = plot(self.arteryObj.R_network, self.arteryObj.L, self.arteryObj.timeperiod, 'Flow') 1098 | FlowOutputScreen.graphimage = "./" + name""" 1099 | GraphWaitScreenFlow.arteryObj = self.arteryObj 1100 | GraphWaitScreenFlow.l = self.l.text 1101 | GraphWaitScreenFlow.option = 'l' 1102 | app = App.get_running_app() 1103 | app.root.current = "graphwaitflow" 1104 | 1105 | class FlowInputTimeScreen(Screen): 1106 | arteryObj = None 1107 | t = ObjectProperty(None) 1108 | def flowgraph(self): 1109 | """name = plot(self.arteryObj.R_network, self.arteryObj.L, self.arteryObj.timeperiod, 'Flow') 1110 | FlowOutputScreen.graphimage = "./" + name""" 1111 | GraphWaitScreenFlow.arteryObj = self.arteryObj 1112 | GraphWaitScreenFlow.t = self.t.text 1113 | GraphWaitScreenFlow.option = 't' 1114 | app = App.get_running_app() 1115 | app.root.current = "graphwaitflow" 1116 | 1117 | class GraphWaitScreenFlow(Screen): 1118 | arteryObj = None 1119 | t = None 1120 | l = None 1121 | option = ' ' 1122 | def on_enter(self): 1123 | """name = plot(self.arteryObj.R_network, self.arteryObj.L, float(self.t), 'Flow') 1124 | FlowOutputScreen.graphimage = "./" + name""" 1125 | if(self.option == 't'): 1126 | print("t") 1127 | FlowOutputScreen.graphimage = './Media/graph.png' 1128 | pass 1129 | elif(self.option == 'l'): 1130 | print("l") 1131 | FlowOutputScreen.graphimage = './Media/graph.png' 1132 | pass 1133 | app = App.get_running_app() 1134 | app.root.current = "flowoutput" 1135 | 1136 | class FlowOutputScreen(Screen): 1137 | im = ObjectProperty(None) 1138 | option = ' ' 1139 | graphimage = ' ' 1140 | def on_enter(self): 1141 | view = ModalView(size_hint = (.8,.8)) 1142 | view.background_color = (1,1,1,1) 1143 | graphobj = Image() 1144 | graphobj.source = self.graphimage 1145 | graphobj.allow_stretch = True 1146 | graphobj.keep_ratio = False 1147 | view.add_widget(graphobj) 1148 | view.open() 1149 | view.bind(on_dismiss =self.return_options) 1150 | def return_options(self,instance): 1151 | app = App.get_running_app() 1152 | app.root.current = "flowoption" 1153 | 1154 | 1155 | 1156 | class RadiusOptionScreen(Screen): 1157 | arteryObj = None 1158 | def time(self): 1159 | RadiusInputTimeScreen.arteryObj = self.arteryObj 1160 | app = App.get_running_app() 1161 | app.root.current = "radiusinputtime" 1162 | def length(self): 1163 | FlowInputLengthScreen.arteryObj = self.arteryObj 1164 | app = App.get_running_app() 1165 | app.root.current = "radiusinputlength" 1166 | 1167 | class RadiusInputTimeScreen(Screen): 1168 | arteryObj = None 1169 | t = ObjectProperty(None) 1170 | def radiusgraph(self): 1171 | #name = plot(self.arteryObj.q_network, self.arteryObj.L, self.arteryObj.timeperiod, 'Radii') 1172 | #RadiusOutputScreen.graphimage = "./" + name 1173 | GraphWaitScreenRadius.arteryObj = self.arteryObj 1174 | GraphWaitScreenRadius.t = self.t.text 1175 | GraphWaitScreenRadius.option = 't' 1176 | app = App.get_running_app() 1177 | app.root.current = "graphwaitradius" 1178 | 1179 | class RadiusInputLengthScreen(Screen): 1180 | arteryObj = None 1181 | l = ObjectProperty(None) 1182 | def radiusgraph(self): 1183 | #name = plot(self.arteryObj.q_network, self.arteryObj.L, self.arteryObj.timeperiod, 'Radii') 1184 | #RadiusOutputScreen.graphimage = "./" + name 1185 | GraphWaitScreenRadius.arteryObj = self.arteryObj 1186 | GraphWaitScreenRadius.l = self.l.text 1187 | GraphWaitScreenRadius.option = 'l' 1188 | app = App.get_running_app() 1189 | app.root.current = "graphwaitradius" 1190 | 1191 | class GraphWaitScreenRadius(Screen): 1192 | arteryObj = None 1193 | t = None 1194 | l = None 1195 | option = ' ' 1196 | def on_enter(self): 1197 | """name = plot(self.arteryObj.q_network, self.arteryObj.L, float(self.t), 'Radii') 1198 | RadiusOutputScreen.graphimage = "./" + name""" 1199 | if(self.option == 't'): 1200 | print("t") 1201 | RadiusOutputScreen.graphimage = "./Media/graph.png" 1202 | elif(self.option == 'l'): 1203 | print("l") 1204 | RadiusOutputScreen.graphimage = "./Media/graph.png" 1205 | app = App.get_running_app() 1206 | app.root.current = "radiusoutput" 1207 | 1208 | class RadiusOutputScreen(Screen): 1209 | graphimage= "" 1210 | im = ObjectProperty(None) 1211 | def on_enter(self): 1212 | """self.im.source = self.graphimage 1213 | print(self.graphimage)""" 1214 | view = ModalView(size_hint = (.8,.8)) 1215 | view.background_color = (1,1,1,1) 1216 | graphobj = Image() 1217 | graphobj.source = self.graphimage 1218 | graphobj.allow_stretch = True 1219 | graphobj.keep_ratio = False 1220 | view.add_widget(graphobj) 1221 | view.open() 1222 | view.bind(on_dismiss =self.return_options) 1223 | def return_options(self,instance): 1224 | app = App.get_running_app() 1225 | app.root.current = "radiusoption" 1226 | 1227 | """def plot(network, length, time, plot_type): 1228 | x = np.linspace(0, int(length), int(length)*10) 1229 | print(x.shape) 1230 | y = [] 1231 | for i in x: 1232 | y.append(network.predict([[i, time]])) 1233 | y = np.asarray(y).reshape((int(length)*10, )) 1234 | print(y.shape) 1235 | sns.set_style('darkgrid') 1236 | sns.set(rc={'figure.figsize':(11.7, 8.27)}) 1237 | sns.set(font_scale=1.4) 1238 | d = {'Lenght':x, plot_type:y} 1239 | sns.lineplot(data=d, x='Lenght', y=plot_type, palette=('red',), linewidth=2.5).set_title(plot_type) 1240 | value = plot_type + '_t_' + str(time) + '.png' 1241 | plt.savefig(value) 1242 | return value """ 1243 | 1244 | 1245 | class v1App(MDApp): 1246 | def build(self): 1247 | sm = ScreenManager(transition=CardTransition()) 1248 | sm.add_widget(InputScreen()) 1249 | sm.add_widget(LoadingScreen()) 1250 | sm.add_widget(ResultOptionScreen()) 1251 | sm.add_widget(PredictorScreen()) 1252 | sm.add_widget(FlowOptionScreen()) 1253 | sm.add_widget(FlowInputTimeScreen()) 1254 | sm.add_widget(FlowInputLengthScreen()) 1255 | sm.add_widget(FlowOutputScreen()) 1256 | sm.add_widget(RadiusOptionScreen()) 1257 | sm.add_widget(RadiusInputTimeScreen()) 1258 | sm.add_widget(RadiusInputLengthScreen()) 1259 | sm.add_widget(RadiusOutputScreen()) 1260 | sm.add_widget(AdvancedInputScreen()) 1261 | sm.add_widget(GraphWaitScreenRadius()) 1262 | sm.add_widget(GraphWaitScreenFlow()) 1263 | return sm 1264 | 1265 | 1266 | 1267 | if __name__ == "__main__": 1268 | v1App().run() 1269 | -------------------------------------------------------------------------------- /elixir.egg-info/Na.md: -------------------------------------------------------------------------------- 1 | Watch our video that highlights the fundamental idea of the project. 2 | 3 | [![Project Elixir - Team Disrupt](photo.png)](https://youtu.be/8Q4nvnozVsI "Project Elixir - Team Disrupt") 4 | -------------------------------------------------------------------------------- /elixir.egg-info/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 2.1 2 | Name: elixir 3 | Version: 0.0.2 4 | Summary: A Python package for 1-D blood flow simulation 5 | Home-page: https://github.com/VANRao-Stack/ 6 | Author: Sanaul Shaheer, V Abhijith Narayan Rao 7 | Author-email: sanaulshaheer@gmail.com 8 | License: UNKNOWN 9 | Description: # Elixir 10 | 11 | Modeling blood flow and especially the propagation of the pulse wave in systemic 12 | arteries is a topic that is interesting to the medical society since the shape of the 13 | pressure profiles has diagnostic significance. We build a package that can 14 | simulate blood flow and pressure in large arteries by solving a nonlinear onedimensional 15 | model based on the incompressible Navier-Stokes equations for a 16 | Newtonian fluid in an elastic tube. Our method, however, does not require the 17 | usage of discretized methods for solving differential equations such as the 18 | popular Lax-Wendroff method (LW) but instead uses automatic differentiation to 19 | achieve a similar result. 20 | 21 | Modeling blood flow and pressure in the systemic arteries has been a topic of 22 | interest both to theoretical and clinical investigators. Thus, research in this area 23 | has a vital interdisciplinary aspect. This project aims to develop a package capable 24 | of performing such simulations using the models we develop to treat 25 | cardiovascular diseases better. This is important since most deaths in developed 26 | countries result from cardiovascular diseases, mostly associated with abnormal 27 | flow in the arteries. 28 | 29 | The original project's inspiration arose from previous and present efforts to 30 | develop an anaesthesia simulator based on mathematical models. An important 31 | part of which is having a good model for the cardiovascular system. 32 | However, as stated previously, the traditional focus of such projects generally is 33 | developing a good model. 34 | 35 | The choice of the method to be used to solve the associated equations generally 36 | comes from a standard list of such methods. 37 | 38 | We present a new method that, unlike its predecessors, offers a continuous 39 | solution, along with other benefits such as GPU support, a massive community, 40 | and such like. 41 | 42 | Platform: UNKNOWN 43 | Classifier: Programming Language :: Python :: 3 44 | Classifier: License :: OSI Approved :: MIT License 45 | Classifier: Operating System :: OS Independent 46 | Classifier: Development Status :: 3 - Alpha 47 | Classifier: Intended Audience :: Computational Biologists 48 | Classifier: Topic :: Blood Flow Simulator 49 | Requires-Python: >=3.6 50 | Description-Content-Type: text/markdown 51 | -------------------------------------------------------------------------------- /elixir.egg-info/SOURCES.txt: -------------------------------------------------------------------------------- 1 | README.md 2 | pyproject.toml 3 | setup.py 4 | elixir/__init__.py 5 | elixir/arterialNetwork.py 6 | elixir/artery.py 7 | elixir/solver.py 8 | elixir/utils.py 9 | elixir.egg-info/PKG-INFO 10 | elixir.egg-info/SOURCES.txt 11 | elixir.egg-info/dependency_links.txt 12 | elixir.egg-info/requires.txt 13 | elixir.egg-info/top_level.txt 14 | elixir/cantorProject/__init__.py 15 | elixir/cantorProject/network.py 16 | elixir/cantorProject/sci_trainer.py 17 | elixir/cantorProject/tfp_trainer.py -------------------------------------------------------------------------------- /elixir.egg-info/dependency_links.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /elixir.egg-info/requires.txt: -------------------------------------------------------------------------------- 1 | tensorflow>=2.4.0 2 | tensorflow_probability>=0.12.0 3 | numpy>=1.19.4 4 | scipy>=1.4.1 5 | plotly 6 | -------------------------------------------------------------------------------- /elixir.egg-info/top_level.txt: -------------------------------------------------------------------------------- 1 | elixir 2 | -------------------------------------------------------------------------------- /elixir/__init__.py: -------------------------------------------------------------------------------- 1 | from .arterialNetwork import arterialNetwork 2 | from .artery import artery 3 | from .solver import nn_solver 4 | from .utils import plot 5 | -------------------------------------------------------------------------------- /elixir/arterialNetwork.py: -------------------------------------------------------------------------------- 1 | class arterialNetwork: 2 | def __init__(self, head): 3 | self.head = head 4 | -------------------------------------------------------------------------------- /elixir/artery.py: -------------------------------------------------------------------------------- 1 | from .cantorProject.network import Network 2 | from .cantorProject.tfp_trainer import tfp_Trainer, set_weights 3 | from .cantorProject.sci_trainer import sci_Trainer 4 | from .utils import plot 5 | import tensorflow as tf 6 | import numpy as np 7 | import math 8 | from tensorflow.keras.layers import Lambda 9 | 10 | 11 | 12 | class GradientLayer(tf.keras.layers.Layer): 13 | """ 14 | Subclassed layer to compute general derivatives 15 | """ 16 | def __init__(self, R_model,q_model, **kwargs): 17 | """ 18 | Args: 19 | R_model: keras network model to simulate R 20 | q_model: keras network model to simulate q 21 | """ 22 | self.R_model = R_model 23 | self.q_model = q_model 24 | super().__init__(**kwargs) 25 | 26 | def call(self, tx): 27 | """ 28 | Computing 1st and 2nd derivatives of the neural net. 29 | Args: 30 | tx: (z,t) 31 | Returns: 32 | u: network output. 33 | du_dx: 1st derivative of x. 34 | d2u_dx2: 2nd derivative of x. 35 | Computing the first derivatives of the two neural networks 36 | Args: 37 | tx: (z,t) 38 | Returns: 39 | A : Area as computed from the output of R_model 40 | q : Output of q_model 41 | R : Output of R_model 42 | dA_dt : First derivative of A w.r.t t 43 | dq_dt : First derivative of q w.r.t t 44 | dq_dz : First derivatice of q w.r.t z 45 | """ 46 | #print(tx) 47 | #tx = tf.keras.layers.Concatenate(inputs) 48 | #z=inputs[0] 49 | #t=inputs[1] 50 | with tf.GradientTape() as g1: 51 | g1.watch(tx) 52 | R = self.R_model(tx) 53 | A = np.pi * (R**2) 54 | dA_dtx = g1.batch_jacobian(A,tx) 55 | dA_dt = dA_dtx[...,1] 56 | 57 | with tf.GradientTape() as g2: 58 | g2.watch(tx) 59 | q = self.q_model(tx) 60 | dq_dtx = g2.batch_jacobian(q,tx) 61 | dq_dz = dq_dtx[...,0] 62 | dq_dt = dq_dtx[...,1] 63 | 64 | return A,q,R,dA_dt,dq_dt,dq_dz 65 | 66 | 67 | class PINN: 68 | def __init__(self,R_network,q_network): 69 | """ 70 | Args : 71 | R_network : Keras network model to compute R 72 | q_network : Keras network model to compute q 73 | """ 74 | self.R_network = R_network 75 | self.q_network = q_network 76 | self.grad = GradientLayer(self.R_network,self.q_network) 77 | 78 | def build(self,delta_b,E,h,elasticity_func,R1,R2,CT,Ru,Rd,L,Reynolds_no,q_0): 79 | """ 80 | Builds the actual model 81 | Args: 82 | 83 | 84 | """ 85 | z=tf.keras.layers.Input(shape=(1,)) 86 | t=tf.keras.layers.Input(shape=(1,)) 87 | #print("PINN") 88 | #print(Ru) 89 | #print(Rd) 90 | concat_layer = tf.keras.layers.Concatenate()([z,t]) 91 | A,q,R,dA_dt,dq_dt,dq_dz=self.grad(concat_layer) 92 | A_0,dl_dz = find_derivatives_l(self.R_network,self.q_network,Ru,Rd,L)((z,t)) 93 | 94 | """ 95 | We divide the partial differential equation into two parts, p1 and p2 96 | p1 -> du/dt + dq/dt = 0 97 | p2 -> dq/dz + dl/dt = S1 98 | """ 99 | p1 = (dA_dt + dq_dz)**2 100 | 101 | r0_grad= find_derivatives_r0(self.R_network,Ru,Rd,L) 102 | dr0_dz,r0 = r0_grad(z) 103 | 104 | df_dr0 = find_derivatives_f0()(r0) 105 | 106 | t1 = Lambda(lambda ar: -(2*math.pi*ar[0]*ar[1])/(delta_b*Reynolds_no*ar[2]))((R,q,A)) 107 | 108 | #print(df_dr0) 109 | #print("T2") 110 | #t2 = Lambda(lambda ar: math.sqrt(math.pi) * elasticity_func(relaxed_radius_func(ar[0],ar[3],int(ar[4]),int(ar[5]))) + tf.math.sqrt(ar[1]) * ar[2])((z,A_0,df_dr0,float(Ru),Rd,L)) 111 | t2 = t2_class(Ru,Rd,L)((z,A_0,df_dr0)) 112 | S1 = Lambda(lambda ar: ar[3] + (2*tf.math.sqrt(ar[0])*(ar[4])-ar[0]*ar[1])*ar[2])((A,df_dr0,dr0_dz,t1,t2)) 113 | p2 = Lambda(lambda ar: tf.math.pow(ar[0] + ar[1] - ar[2],2))((dq_dt,dl_dz,S1)) 114 | u_eqn = p1 + p2 115 | 116 | #For the inflow condition 117 | z_inflow = tf.keras.layers.Input(shape=(1,)) 118 | t_inflow = tf.keras.layers.Input(shape = (1,)) 119 | concat_inflow = tf.keras.layers.Concatenate()([z_inflow,t_inflow]) 120 | q_bndry_inflow = self.q_network(concat_inflow) 121 | 122 | 123 | #For the outflow condition 124 | z_outflow = tf.keras.layers.Input(shape=(1,)) 125 | t_outflow = tf.keras.layers.Input(shape = (1,)) 126 | p_obj = p_class(self.R_network,self.q_network,Ru,Rd,L,E,h) 127 | dp_bo_dt,p,dq_bo_dt,q_bo = p_obj((z_outflow,t_outflow)) 128 | u_bndry_outflow = dp_bo_dt - (R1 * dq_bo_dt - (p/(R2*CT)) + q_bo*(R1+R2)/(R2*CT) ) 129 | 130 | 131 | #print(S1) 132 | #print(dq_dt) 133 | #print(dl_dz) 134 | #print(p2) 135 | return tf.keras.models.Model( 136 | inputs = [z,t,z_inflow,t_inflow,z_outflow,t_outflow], 137 | outputs = [u_eqn,q_bndry_inflow,u_bndry_outflow] 138 | ) 139 | 140 | 141 | class t2_class(tf.keras.layers.Layer): 142 | def __init__(self,Ru,Rd,L,**kwargs): 143 | super().__init__(self,**kwargs) 144 | self.Ru = Ru 145 | self.Rd = Rd 146 | self.L = L 147 | def call(self,input): 148 | z = input[0] 149 | A_0 = input[1] 150 | df_dr0 = input[2] 151 | return math.sqrt(math.pi) * elasticity_func(relaxed_radius_func(z,self.Ru,self.Rd,self.L)) + tf.math.sqrt(A_0) * df_dr0 152 | 153 | 154 | 155 | class find_derivatives_l(tf.keras.layers.Layer): 156 | """ 157 | Keras layers subclass to compute the derivative of l w.r.t z 158 | """ 159 | def __init__(self,R_network,q_network,Ru,Rd,L,**kwargs): 160 | super().__init__(self,**kwargs) 161 | #print("L") 162 | self.Ru = Ru 163 | self.Rd = Rd 164 | self.L = L 165 | self.grads = GradientLayer(R_network,q_network) 166 | def call(self,input): 167 | """ 168 | Computes relaxed radius area and dl_dz 169 | Returns: 170 | A_0 : Relaxed radius area computed from pi*square(relaxed_radius) 171 | dl_dz: The derivative of l w.r.t z 172 | """ 173 | z = input[0] 174 | t = input[1] 175 | #concat = tf.keras.layers.Concatenate()([z,t]) 176 | #print(z) 177 | with tf.GradientTape() as g3: 178 | g3.watch(z) 179 | concat = tf.keras.layers.Concatenate()([z,t]) 180 | A,q,_,_,_,_ = self.grads(concat) 181 | #print(tx[0]) 182 | r0 = relaxed_radius_func(z,self.Ru,self.Rd,self.L) 183 | A_0 = math.pi * (r0**2) 184 | l=(q**2)/A + elasticity_func(r0)*tf.sqrt(A_0*A) 185 | dl_dtx = g3.batch_jacobian(l,z) 186 | dl_dz = dl_dtx[...,0] 187 | return A_0,dl_dz 188 | 189 | 190 | 191 | class p_class(tf.keras.layers.Layer): 192 | """ 193 | Keras layers to compute the pressure, and related values 194 | """ 195 | def __init__(self,R_model,q_model,Ru,Rd,L,E,h,**kwargs): 196 | """ 197 | Args: 198 | R_model : Keras network model simulating R 199 | q_model : Keras network model simulating q 200 | """ 201 | super().__init__(self,**kwargs) 202 | self.R_model = R_model 203 | self.q_model = q_model 204 | self.Ru = Ru 205 | self.Rd = Rd 206 | self.L = L 207 | self.E = E 208 | self.h = h 209 | self.grad = GradientLayer(self.R_model,self.q_model) 210 | 211 | def call(self,input): 212 | """ 213 | Calculated the pressure, its derivative and related values 214 | Returns: 215 | dq_bo_dt : Derivative of q w.r.t t for the outflow boundary condition 216 | p : Pressure calculated at the outflow boundary condition 217 | dp_bo_dt : Derivative of p w.r.t t for the outflow boundary condition 218 | q_bo : q calculated at the outflow boundary condition 219 | """ 220 | #print("P") 221 | #print(type(self.Ru)) 222 | #print(type(self.Rd)) 223 | z_outflow = input[0] 224 | t_outflow = input[1] 225 | concat_layer = tf.keras.layers.Concatenate()([z_outflow,t_outflow]) 226 | with tf.GradientTape() as g: 227 | #L,A_bndry_outfow,q_bndry_outflow,_,_,dq_bo_dt,_,_=self.grads(tx_bndry_outflow,elasticity_func) 228 | g.watch(concat_layer) 229 | A_bo,q_bo,R_bo,_,dq_bo_dt,_ = self.grad(concat_layer) 230 | 231 | #A_bo_0 = Lambda(lambda x: math.pi * (relaxed_radius_func(x[0],int(x[1]),int(x[2]),int(x[3]))**2))((z_outflow,self.Ru,self.Rd,self.L)) 232 | A_bo_0 = math.pi * (relaxed_radius_func(z_outflow,self.Ru,self.Rd,self.L) ** 2) 233 | p = (4/3)*((self.E*self.h)/relaxed_radius_func(z_outflow,self.Ru,self.Rd,self.L)) * (1 - tf.sqrt(A_bo_0/A_bo)) 234 | #p=1 235 | dp_dtx_bo = g.batch_jacobian(p,concat_layer) 236 | dp_bo_dt = dp_dtx_bo[...,1] 237 | return dp_bo_dt,p,dq_bo_dt,q_bo 238 | 239 | 240 | 241 | class find_derivatives_r0(tf.keras.layers.Layer): 242 | def __init__(self,R_network,Ru,Rd,L,**kwargs): 243 | super().__init__(self,**kwargs) 244 | self.R_network = R_network 245 | self.Ru = Ru 246 | self.Rd = Rd 247 | self.L = L 248 | def call(self,z): 249 | with tf.GradientTape() as g: 250 | g.watch(z) 251 | r0 = relaxed_radius_func(z,self.Ru,self.Rd,self.L) 252 | dr0_dx = g.batch_jacobian(r0,z)[...,0] 253 | return dr0_dx,r0 254 | 255 | 256 | 257 | class find_derivatives_f0(tf.keras.layers.Layer): 258 | def __init__(self,**kwargs): 259 | super().__init__(self,**kwargs) 260 | 261 | def call(self,input): 262 | with tf.GradientTape() as g: 263 | f0 = elasticity_func(input) 264 | #print(f0) 265 | df0_dr0 = g.batch_jacobian(f0,input)[...,0] 266 | return df0_dr0 267 | 268 | 269 | class artery: 270 | def __init__(self, delta_b=2*math.pow(10,-3), Ru=0.37, Rd=0.37, L=20.8, Reynolds_no=4500, E=4.8, h=0.065, q_0=450, 271 | length_domain=(0, 20.8), time_domain = (0,0.8), tow=.3, timeperiod=0.8, 272 | layers=[50] * 9, activation='tanh', num_train_samples=100000): 273 | self.delta_b = delta_b 274 | self.Ru = Ru 275 | self.Rd = Rd 276 | self.L = L 277 | self.length_domain = (0,L) 278 | self.time_domain = (0,timeperiod) 279 | self.tow = tow 280 | self.q_0 = q_0 281 | self.timeperiod = timeperiod 282 | self.layers = layers 283 | #self.bnd_cond = bnd_cond 284 | self.activation = activation 285 | self.num_train_samples = num_train_samples 286 | 287 | self.R_network = Network.build(num_inputs = 2,layers=self.layers, activation=self.activation) 288 | self.q_network = Network.build(num_inputs = 2,layers = self.layers, activation = self.activation) 289 | self.pinn = PINN(self.R_network, self.q_network).build(self.delta_b, E, h, elasticity_func, 253/100, 139/100, 1.3384, Ru, Rd, L, Reynolds_no, q_0) 290 | self.pinn.summary() 291 | 292 | def create_dataset(self): 293 | z = np.random.rand(self.num_train_samples, 1)*self.length_domain[1] 294 | t = np.random.rand(self.num_train_samples,1)*self.time_domain[1] 295 | z_inflow = np.zeros((self.num_train_samples,1)) 296 | t_inflow = np.random.rand(self.num_train_samples,1)*self.time_domain[1] 297 | z_outflow = np.ones((self.num_train_samples, 1))*self.length_domain[1] 298 | t_outflow = np.random.rand(self.num_train_samples,1)*self.time_domain[1] 299 | #print(t_outflow) 300 | 301 | x_train = [z,t,z_inflow,t_inflow,z_outflow,t_outflow] 302 | #print(x_train.shape) 303 | 304 | 305 | u_zero = np.zeros((self.num_train_samples, 1)) 306 | q_bndry_inflow = initial_q(t_outflow, self.timeperiod, self.tow,self.q_0) 307 | #print(type(q_bndry_inflow)) 308 | #print(q_bndry_inflow.shape) 309 | #q_bndry_inflow = np.zeros((self.num_train_samples,1)) 310 | u_bndry_outflow = np.zeros((self.num_train_samples,1)) 311 | y_train = [u_zero,q_bndry_inflow,u_bndry_outflow] 312 | 313 | return x_train, y_train 314 | 315 | def sci_train(self, first_order_trainer='rmsprop', batch_size=128, first_order_epochs=10, 316 | factr=10, m=50, maxls=50, maxiter=15000): 317 | x_train, y_train = self.create_dataset() 318 | trainer = sci_Trainer(self.pinn, x_train, y_train, first_order_trainer=first_order_trainer, batch_size=batch_size, 319 | first_order_epochs=first_order_epochs, factr=factr, m=m, maxls=maxls, maxiter=maxiter) 320 | trainer.train() 321 | return self.R_network, self.q_network 322 | 323 | def tfp_trainer(self, first_order_trainer='rmsprop', batch_size=128, first_order_epochs=10, 324 | factr=10, m=50, maxls=50, maxiter=15000): 325 | x_train, y_train = self.create_dataset() 326 | tfp_trainer = tfp_Trainer(self.pinn, x_train, y_train, first_order_trainer=first_order_trainer, batch_size=batch_size, 327 | first_order_epochs=first_order_epochs, maxiter=maxiter) 328 | result = tfp_trainer.train() 329 | set_weights(tfp_trainer, self.pinn, result.position) 330 | return self.networking 331 | 332 | def plot_flow(self, num_test_samples=100): 333 | plot(self.R_network, (0, self.L), self.time_domain, 'flow', num_test_samples) 334 | 335 | def plot_radius(self, num_test_samples=100): 336 | plot(self.q_network, (0, self.L), self.time_domain, 'radii', num_test_samples) 337 | 338 | 339 | 340 | def initial_q(t,timeperiod,tow,q_0): 341 | t=np.fmod(t,timeperiod) 342 | #print(t) 343 | t1 = np.exp(-np.power(t,2) / (2*(tow**2))) 344 | #print(t1) 345 | return ((q_0*t)/( (tow**2) * t1))/1000000 346 | 347 | def relaxed_radius_func(z, Ru, Rd, L): 348 | #print(z) 349 | #print("Relrad") 350 | #print(type(Rd)) 351 | #print(type(Ru)) 352 | Ru = float(Ru) 353 | temp = tf.cast(tf.math.log(Rd/Ru),tf.float64,name=None) 354 | #print(temp) 355 | #print(type(temp)) 356 | return Ru*tf.exp(temp*(z/L)) 357 | 358 | def elasticity_func(r0): 359 | return 2/3*r0 360 | -------------------------------------------------------------------------------- /elixir/cantorProject/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .network import Network 3 | from .tfp_trainer import tfp_Trainer, set_weights 4 | from .sci_trainer import sci_Trainer 5 | -------------------------------------------------------------------------------- /elixir/cantorProject/network.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | 3 | class Network: 4 | """ 5 | Build a Neural Network that will be used to simulate a differential equation 6 | """ 7 | 8 | @classmethod 9 | def build(cls, num_inputs=1, layers=[20, 20, 20, 20, 20, 20, 20, 20], 10 | activation='tanh', num_outputs=1): 11 | """ 12 | Build a NN model for the differential equation. 13 | Args: 14 | num_inputs: number of input variables. Default is 1 for (x). 15 | layers: number of hidden layers. 16 | activation: activation function in hidden layers. 17 | num_outpus: number of output variables. Default is 1 for u(x). 18 | Returns: 19 | keras network model. 20 | """ 21 | 22 | # input layer 23 | inputs = tf.keras.layers.Input(shape=(num_inputs,)) 24 | # hidden layers 25 | x = inputs 26 | for layer in layers: 27 | # I have chosen to go with he_normal initialization here after a little experimentation, 28 | # although I do suggest we stich with glorot for the final rpoduct 29 | x = tf.keras.layers.Dense(layer, activation=activation, kernel_initializer='he_normal')(x) 30 | # output layer 31 | outputs = tf.keras.layers.Dense(num_outputs, 32 | kernel_initializer='he_normal')(x) 33 | 34 | return tf.keras.models.Model(inputs=inputs, outputs=outputs) 35 | -------------------------------------------------------------------------------- /elixir/cantorProject/sci_trainer.py: -------------------------------------------------------------------------------- 1 | # suppress tensorflow warnings (must be called before importing tensorflow) 2 | import os 3 | os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' 4 | import tensorflow as tf 5 | tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR) 6 | import scipy.optimize 7 | import numpy as np 8 | 9 | class sci_Trainer: 10 | """ 11 | Optimize the keras network model using L-BFGS-B algorithm. 12 | Attributes: 13 | model: optimization target model. 14 | samples: training samples. 15 | factr: convergence condition. typical values for factr are: 1e12 for low accuracy; 16 | 1e7 for moderate accuracy; 10 for extremely high accuracy. 17 | m: maximum number of variable metric corrections used to define the limited memory matrix. 18 | maxls: maximum number of line search steps (per iteration). 19 | maxiter: maximum number of iterations. 20 | metris: logging metrics. 21 | progbar: progress bar. 22 | """ 23 | 24 | def __init__(self, model, x_train, y_train, first_order_trainer='rmsprop', batch_size=128, first_order_epochs=10, 25 | factr=10, m=50, maxls=50, maxiter=15000): 26 | 27 | # set attributes 28 | self.model = model 29 | self.x_train = [ tf.constant(x, dtype=tf.float32) for x in x_train ] 30 | self.y_train = [ tf.constant(y, dtype=tf.float32) for y in y_train ] 31 | self.factr = factr 32 | self.m = m 33 | self.maxls = maxls 34 | self.maxiter = maxiter 35 | self.iter = tf.Variable(0) 36 | self.metrics = ['loss'] 37 | self.first_order_trainer = first_order_trainer 38 | self.batch_size = batch_size 39 | self.first_order_epochs = first_order_epochs 40 | # initialize the progress bar 41 | self.progbar = tf.keras.callbacks.ProgbarLogger( 42 | count_mode='steps', stateful_metrics=self.metrics) 43 | self.progbar.set_params( { 44 | 'verbose':1, 'epochs':1, 'steps':self.maxiter, 'metrics':self.metrics}) 45 | 46 | def set_weights(self, flat_weights): 47 | """ 48 | Set weights to the model. 49 | Args: 50 | flat_weights: flatten weights. 51 | """ 52 | 53 | # get model weights 54 | shapes = [ w.shape for w in self.model.get_weights() ] 55 | # compute splitting indices 56 | split_ids = np.cumsum([ np.prod(shape) for shape in [0] + shapes ]) 57 | # reshape weights 58 | weights = [ flat_weights[from_id:to_id].reshape(shape) 59 | for from_id, to_id, shape in zip(split_ids[:-1], split_ids[1:], shapes) ] 60 | # set weights to the model 61 | self.model.set_weights(weights) 62 | 63 | @tf.function 64 | def tf_evaluate(self, x, y): 65 | """ 66 | Evaluate loss and gradients for weights as tf.Tensor. 67 | Args: 68 | x: input data. 69 | Returns: 70 | loss and gradients for weights as tf.Tensor. 71 | """ 72 | 73 | with tf.GradientTape() as g: 74 | loss = tf.reduce_mean(tf.keras.losses.mse(self.model(x), y)) 75 | grads = g.gradient(loss, self.model.trainable_variables) 76 | return loss, grads 77 | 78 | def evaluate(self, weights): 79 | """ 80 | Evaluate loss and gradients for weights as ndarray. 81 | Args: 82 | weights: flatten weights. 83 | Returns: 84 | loss and gradients for weights as ndarray. 85 | """ 86 | 87 | # update weights 88 | self.set_weights(weights) 89 | # compute loss and gradients for weights 90 | loss, grads = self.tf_evaluate(self.x_train, self.y_train) 91 | # convert tf.Tensor to flatten ndarray 92 | loss = loss.numpy().astype('float64') 93 | grads = np.concatenate([ g.numpy().flatten() for g in grads ]).astype('float64') 94 | 95 | self.iter.assign_add(1) 96 | tf.print("Iterations:", self.iter, "Loss Value:", loss) 97 | 98 | return loss, grads 99 | 100 | def callback(self, weights): 101 | """ 102 | Callback that prints the progress to stdout. 103 | Args: 104 | weights: flatten weights. 105 | """ 106 | self.progbar.on_batch_begin(0) 107 | loss, _ = self.evaluate(weights) 108 | self.progbar.on_batch_end(0, logs=dict(zip(self.metrics, [loss]))) 109 | 110 | def train(self, use_second_order=False): 111 | """ 112 | Train the model using L-BFGS-B algorithm. 113 | """ 114 | 115 | # get initial weights as a flat vector 116 | initial_weights = np.concatenate( 117 | [ w.flatten() for w in self.model.get_weights() ]) 118 | self.model.compile(optimizer=self.first_order_trainer, loss='mse') 119 | print('Running First order optimizer: \n') 120 | self.model.fit(x=self.x_train, y=self.y_train, batch_size=self.batch_size, epochs=self.first_order_epochs) 121 | # optimize the weight vector 122 | if use_second_order: 123 | print('\nOptimizer: L-BFGS-B (maxiter={})'.format(self.maxiter)) 124 | self.progbar.on_train_begin() 125 | self.progbar.on_epoch_begin(1) 126 | scipy.optimize.fmin_l_bfgs_b(func=self.evaluate, x0=initial_weights, 127 | factr=self.factr, m=self.m, maxls=self.maxls, maxiter=self.maxiter, 128 | callback=self.callback) 129 | self.progbar.on_epoch_end(1) 130 | self.progbar.on_train_end() 131 | -------------------------------------------------------------------------------- /elixir/cantorProject/tfp_trainer.py: -------------------------------------------------------------------------------- 1 | # suppress tensorflow warnings (must be called before importing tensorflow) 2 | import os 3 | os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' 4 | import tensorflow as tf 5 | tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR) 6 | import numpy as np 7 | import tensorflow_probability as tfp 8 | 9 | tf.keras.backend.set_floatx("float64") 10 | 11 | class tfp_Trainer(object): 12 | def __init__(self, model, x_train, y_train, first_order_trainer='rmsprop', batch_size=128, 13 | first_order_epochs=10, maxiter=100): 14 | self.model = model 15 | self.x_train = x_train 16 | self.y_train = y_train 17 | self.first_order_trainer = first_order_trainer 18 | self.batch_size = batch_size 19 | self.first_order_epochs = first_order_epochs 20 | self.bfgs_iter = maxiter 21 | self.iter = tf.Variable(0) 22 | self.loss = tf.keras.losses.MeanSquaredError() 23 | self.shapes = tf.shape_n(self.model.trainable_variables) 24 | self.n_tensors = len(self.shapes) 25 | 26 | # we'll use tf.dynamic_stitch and tf.dynamic_partition later, so we need to 27 | # prepare required information first 28 | self.count = 0 29 | self.idx = [] # stitch indices 30 | self.part = [] # partition indices 31 | 32 | for i, shape in enumerate(self.shapes): 33 | n = np.product(shape) 34 | self.idx.append(tf.reshape(tf.range(self.count, self.count+n, dtype=tf.int32), shape)) 35 | self.part.extend([i]*n) 36 | self.count += n 37 | 38 | self.part = tf.constant(self.part) 39 | 40 | self.init_params = tf.dynamic_stitch(self.idx, self.model.trainable_variables) 41 | 42 | def set_weights(self, params_1d): 43 | params = tf.dynamic_partition(params_1d, self.part, self.n_tensors) 44 | for i, (shape, param) in enumerate(zip(self.shapes, params)): 45 | self.model.trainable_variables[i].assign(tf.reshape(param, shape)) 46 | 47 | def tf_evaluate(self, x, y): 48 | with tf.GradientTape() as g: 49 | loss = self.loss(self.model(x, training=True), y) 50 | grads = g.gradient(loss, self.model.trainable_variables) 51 | return loss, grads 52 | 53 | def grad_and_loss_func(self, weights): 54 | self.set_weights(weights) 55 | loss, grads = self.tf_evaluate(self.x_train, self.y_train) 56 | grads = tf.dynamic_stitch(self.idx, grads) 57 | 58 | self.iter.assign_add(1) 59 | tf.print("Iterations:", self.iter, "Loss Value:", loss) 60 | 61 | return loss, grads 62 | 63 | def train(self, use_second_order=False): 64 | self.model.compile(optimizer=self.first_order_trainer, loss='mse') 65 | print('Running First order optimizer: \n') 66 | self.model.fit(x=self.x_train, y=self.y_train, batch_size=self.batch_size, epochs=self.first_order_epochs) 67 | if use_second_order: 68 | print('\nRunning L-BFGS Optimizer: \n') 69 | results = tfp.optimizer.lbfgs_minimize(value_and_gradients_function=self.grad_and_loss_func, 70 | initial_position=self.init_params, max_iterations=self.bfgs_iter) 71 | self.set_weights(results.position) 72 | 73 | 74 | def set_weights(trainer, model, params_1d): 75 | params = tf.dynamic_partition(params_1d, trainer.part, trainer.n_tensors) 76 | for i, (shape, param) in enumerate(zip(trainer.shapes, params)): 77 | model.trainable_variables[i].assign(tf.reshape(param, shape)) 78 | -------------------------------------------------------------------------------- /elixir/solver.py: -------------------------------------------------------------------------------- 1 | from .cantorProject.network import Network 2 | from .cantorProject.tfp_trainer import tfp_Trainer, set_weights 3 | from .cantorProject.sci_trainer import sci_Trainer 4 | 5 | class nn_solver(object): 6 | def __init__(self, head): 7 | self.head = head 8 | 9 | def sci_train(self, artery=None, first_order_trainer='rmsprop', batch_size=128, first_order_epochs=10, 10 | factr=10, m=50, maxls=50, maxiter=15000): 11 | 12 | if artery == None: 13 | x_train, y_train = self.head.create_dataset() 14 | trainer = sci_Trainer(self.head.pinn, x_train, y_train, first_order_trainer=first_order_trainer, batch_size=batch_size, 15 | first_order_epochs=first_order_epochs, factr=factr, m=m, maxls=maxls, maxiter=maxiter) 16 | trainer.train() 17 | return self.head.R_network, self.head.q_network 18 | 19 | x_train, y_train = artery.create_dataset() 20 | trainer = sci_Trainer(artery.pinn, x_train, y_train, first_order_trainer=first_order_trainer, batch_size=batch_size, 21 | first_order_epochs=first_order_epochs, factr=factr, m=m, maxls=maxls, maxiter=maxiter) 22 | trainer.train() 23 | return artery.R_network, artery.q_network 24 | -------------------------------------------------------------------------------- /elixir/utils.py: -------------------------------------------------------------------------------- 1 | import plotly.graph_objects as go 2 | import numpy as np 3 | import plotly 4 | 5 | plotly.offline.init_notebook_mode() 6 | 7 | def plot(network, z, t, plot_type, num_test_samples=1000): 8 | # Creating dataset 9 | x = np.linspace(0, 20.8, 100) 10 | y = np.linspace(0, 0.8, 100) 11 | z = [] 12 | for i in range(100): 13 | temp = [] 14 | for j in range(100): 15 | temp.append(network.predict(np.asarray([[x[i], y[j]]]))) 16 | z.append(temp) 17 | for i in range(len(z)): 18 | z[i] = np.asarray(z[i]) 19 | z = np.asarray(z) 20 | z = z.reshape((100, 100)) 21 | fig = go.Figure(data=[go.Surface(x=x, y=y, z=z)]) 22 | fig.update_layout(title='Plot of {}'.format(plot_type)) 23 | fig.show() 24 | -------------------------------------------------------------------------------- /photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VANRao-Stack/elixir/6d4c5277c6918d052b6296d531bcd0e0bf523dc3/photo.png -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ 3 | "setuptools>=42", 4 | "wheel" 5 | ] 6 | build-backend = "setuptools.build_meta" -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open("README.md", "r", encoding="utf-8") as fh: 4 | long_description = fh.read() 5 | 6 | setuptools.setup( 7 | name="elixir", 8 | version="0.0.2", 9 | author="Sanaul Shaheer, V Abhijith Narayan Rao", 10 | author_email="sanaulshaheer@gmail.com", 11 | description="A Python package for 1-D blood flow simulation", 12 | long_description=long_description, 13 | long_description_content_type="text/markdown", 14 | url="https://github.com/VANRao-Stack/", 15 | packages=setuptools.find_packages(), 16 | classifiers=[ 17 | "Programming Language :: Python :: 3", 18 | "License :: OSI Approved :: MIT License", 19 | "Operating System :: OS Independent", 20 | 'Development Status :: 3 - Alpha', 21 | 'Intended Audience :: Computational Biologists', 22 | 'Topic :: Blood Flow Simulator' 23 | ], 24 | python_requires='>=3.6', 25 | install_requires=[ 26 | 'tensorflow>=2.4.0', 27 | 'tensorflow_probability>=0.12.0', 28 | 'numpy>=1.19.4', 29 | 'scipy>=1.4.1', 30 | 'plotly' 31 | ] 32 | ) 33 | --------------------------------------------------------------------------------