From abbf6d2884d2015622de4a55037da07719aa6dd5 Mon Sep 17 00:00:00 2001 From: Janet <41528500+Janetxxx@users.noreply.github.com> Date: Tue, 5 Oct 2021 02:12:35 +1100 Subject: [PATCH 01/11] Update challenge_september_2021.py --- challenge_september_2021.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/challenge_september_2021.py b/challenge_september_2021.py index 76d0d78..ca87ce5 100644 --- a/challenge_september_2021.py +++ b/challenge_september_2021.py @@ -34,6 +34,6 @@ figure=fig ) ]) - +#### if __name__ == '__main__': app.run_server(debug=True) From 6d510e9e65a3f50447aa4be2f3e45386bad30933 Mon Sep 17 00:00:00 2001 From: Janet <41528500+Janetxxx@users.noreply.github.com> Date: Tue, 5 Oct 2021 02:12:56 +1100 Subject: [PATCH 02/11] Delete challenge_september_2021.py --- challenge_september_2021.py | 39 ------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 challenge_september_2021.py diff --git a/challenge_september_2021.py b/challenge_september_2021.py deleted file mode 100644 index ca87ce5..0000000 --- a/challenge_september_2021.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2020 University of New South Wales, University of Sydney, Ingham Institute - -# Licensed under the MIT Licence; -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -import dash -from dash import dcc -from dash import html -import plotly.express as px -import pandas as pd - -app = dash.Dash(__name__) - -hnscc_csv = "data/hnscc.csv" - -df = pd.read_csv(hnscc_csv) - -fig = px.histogram(df, x="Site", color="Stage") - -app.layout = html.Div(children=[ - html.H1(children='Ingham Medical Physics Coding Challenge Dashboard'), - - html.Div(children=''' - HNSCC Dataset: Histogram of patients by Site and Stage - '''), - - dcc.Graph( - id='stage-graph', - figure=fig - ) -]) -#### -if __name__ == '__main__': - app.run_server(debug=True) From 8cafea84999260f0df1f418ec8043ff92408081b Mon Sep 17 00:00:00 2001 From: Janet <41528500+Janetxxx@users.noreply.github.com> Date: Tue, 5 Oct 2021 02:14:24 +1100 Subject: [PATCH 03/11] src added need to run python under this src file --- src/__pycache__/styles.cpython-37.pyc | Bin 0 -> 268 bytes src/__pycache__/styles.cpython-38.pyc | Bin 0 -> 275 bytes src/challenge_september_2021.py | 371 ++++++++++++++++++++++++++ src/styles.py | 7 + 4 files changed, 378 insertions(+) create mode 100644 src/__pycache__/styles.cpython-37.pyc create mode 100644 src/__pycache__/styles.cpython-38.pyc create mode 100644 src/challenge_september_2021.py create mode 100644 src/styles.py diff --git a/src/__pycache__/styles.cpython-37.pyc b/src/__pycache__/styles.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..272d76247fbf77c8cb6113492257ccc950a2d822 GIT binary patch literal 268 zcmZ?b<>g`k0>Hb)L<&O+V+vCW^Bm?Vh7^`y22Iu~ZbMZC z7^;#rP%tT|P_O`E5M7j>l&E2#1BQA=npMJvdZs|tD1;_+6njBpN=jy4dKFhveuZvv zMq)~Sc@$f2Vo`c#o}VV;Ef#0TAeWU4MNB{!fQesD`k}?CMaBAAiFv6d$)%b4E~&-Y zCHV#VKvOajb9Hl5QwlOFi*=LpLFVe_CKi{Z7U>rkCF>WLROX}>>lIYq;;_lhPbtkw PwFCLE7(_5JGBE-G?e9ZN literal 0 HcmV?d00001 diff --git a/src/__pycache__/styles.cpython-38.pyc b/src/__pycache__/styles.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..274034f867ee375f46f3e89900c5e504d03889bb GIT binary patch literal 275 zcmWIL<>g`k0>OS^-O`PQ3y@uDE5NHl$6Z8^eV2T{0iOT zjKq}u@+h|4#G>@fJU>mwTP)6wK`tv9ikN^d029BQ^+StOi;DFV^U_O;D@#-J^j%Vm zvrF;|^nu1?B low) & (dataframe['Age'] < high) + fig = px.scatter( + dataframe[mask], x="Age", y="Total RT treatment time (days)", + color="Sex", size='Total RT treatment time (days)', + title="Age Distribution of Total RT treatment time (days)", + hover_data=['Age']) + fig.update_layout(title_x=0.5) + return fig + + return age_RT + + +def Receive_Concurrent_Chemoradiotherapy(dataframe): + df_concurrent = dataframe.groupby(['Sex', 'Received Concurrent Chemoradiotherapy?']).size() + df_concurrent = df_concurrent.to_frame(name='occurance').reset_index() + + occ = df_concurrent.loc[:,'occurance'] + fig = make_subplots(rows=1, cols=2, specs=[[{"type": "pie"}, {"type": "pie"}]]) + + fig.add_trace(go.Pie( + values=occ[:2], + labels=["No","YES"], + domain=dict(x=[0, 0.2]), + name="Female", + title="Female", + marker_colors=['crimson','lightskyblue']), + row=1, col=1) + + fig.add_trace(go.Pie( + values=occ[2:4], + labels=["No","YES"], + domain=dict(x=[0.2, 0.4]), + name="Male", + title="Male", + marker_colors=['crimson','lightskyblue']), + row=1, col=2) + + fig.update_traces(hole=.4, hoverinfo="label+percent+name") + fig.update(layout_title_text='Received Concurrent Chemoradiotherapy ratio by Gender', layout_title_x = 0.49) + + fig.update_layout(legend=dict( + orientation="h", + yanchor="bottom", + y=1.02, + xanchor="right", + x=1 + )) + + return dcc.Graph(id='concurrent-gender', figure=fig) + +def BMI_difference(dataframe): + df['difference']=df['BMI start treat (kg/m2)']-df['BMI stop treat (kg/m2)'] + diff_BMI = df[['Age','Sex','difference']] + + fig = px.scatter(df, x="Age", y="difference", + title="The difference in BMI before and after treatment (>0 means an increase in BMI)", + color="Sex", + log_x=True) + fig.update_layout(title_x=0.5) + + bmi_diff = html.Div([ + dcc.Graph(id='bmi-difference', figure=fig), + html.P("Age Range Slider:"), + dcc.RangeSlider( + id='range-slider1', + min=20, max=95, step=0.1, + marks={20: '20', 95: '95'}, + value=[20, 95]), + ]) + + @app.callback( + Output("bmi-difference", "figure"), + [Input("range-slider1", "value")]) + + def update_bar_chart(slider_range): + low, high = slider_range + mask = (diff_BMI['Age'] > low) & (diff_BMI['Age'] < high) + fig = px.scatter( + diff_BMI[mask], x="Age", y="difference", + color="Sex", + hover_data=['Age'], + title="The difference in BMI before and after treatment (>0 means an increase in BMI)") + fig.update_layout(title_x=0.5) + return fig + + return bmi_diff + +app.layout = html.Div(children=[ + header, + html.Div(className="container", children=[ + html.Div(className="row", children=[ + html.Div([ + survival_by_stage(df) + ], className="col-lg", style=CARD) + ]), + html.Div(className="row", children=[ + html.Div([ + survival_by_age(df) + ], className="col-lg", style=CARD) + ]), + html.Div(className="row", children=[ + html.Div([ + average_follow_up_duration_by_site(df) + ], className="col-sm", style=CARD), + html.Div([ + causation_of_death(df) + ], className="col-sm", style=CARD) + ]), + html.Div(className="row", children=[ + html.Div([ + age_filter(df) + ], className="col-sm", style=CARD) + ]), + html.Div(className="row", children=[ + html.Div([ + age_RT_distribution(df) + ], className="col-lg", style=CARD) + ]), + html.Div(className="row", children=[ + html.Div([ + Receive_Concurrent_Chemoradiotherapy(df) + ], className="col-lg", style=CARD) + ]), + html.Div(className="row", children=[ + html.Div([ + BMI_difference(df) + ], className="col-lg", style=CARD) + ]) + ]) +]) + +if __name__ == '__main__': + app.run_server(debug=True) diff --git a/src/styles.py b/src/styles.py new file mode 100644 index 0000000..baa28b1 --- /dev/null +++ b/src/styles.py @@ -0,0 +1,7 @@ +#!/usr/bin/python3 + +CARD = { + 'padding': '1% 1% 1% 1%', + 'box-shadow': '0 4px 8px 4px rgba(0,0,0,0.2)', + 'margin': '1.5% 1.5% 1.5% 1.5%' +} \ No newline at end of file From a5febf1887e7dae8ce4705496ebeda571e1164d6 Mon Sep 17 00:00:00 2001 From: Janet <41528500+Janetxxx@users.noreply.github.com> Date: Tue, 5 Oct 2021 02:15:01 +1100 Subject: [PATCH 04/11] Update requirements.txt --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 7233fd3..7bc2ea5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ pandas dash +dash-bootstrap-components From 377fe8e434cb8bc6902abf5f992601b08b94ce26 Mon Sep 17 00:00:00 2001 From: Janet <41528500+Janetxxx@users.noreply.github.com> Date: Tue, 5 Oct 2021 02:19:47 +1100 Subject: [PATCH 05/11] instructions for running the dashboard --- README.md | 59 ++++++++++++------------------------------------------- 1 file changed, 13 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 4243a65..7eef9c5 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,23 @@ # Ingham Medical Physics Coding Challenge -## Welcome +## Janet Cui workload -Welcome to the Ingham/UNSW Medical Physics Coding Challenge for September/October 2021. Thank you for your interest in joining our team. Before we progress with the hiring process, we'd like to ask you to complete this challenge. This is a chance for you to showcase your skills to us, there is no correct or incorrect solution to this challenge. +## 1. create dash-env +conda create -n dash-dev python=3.7 -y -## Task +## 2. activate dash-env +conda activate dash-dev -We've included some data for approximately 200 patients treated for Head and Neck Cancer extracted from the publicly available [HNSCC dataset](https://wiki.cancerimagingarchive.net/display/Public/HNSCC). This is a comprehensive dataset with a number of different attributes typically tracked for patients receiving cancer treatment. +## 3. make sure to run python file under "src" file +cd ingham-medphys-coding +cd src -Your task is to implement a web-based dashboard/GUI which can visualise some of this data. It's up to you what you would like to display and what kind of functionality you want to provide to a user to explore the data. You may also use the programming language of your choice and any libraries/frameworks you like. See below for a few tips in case you need some help getting started. +## 4. run python file +python3 challenge_september_2021.py -> #### Important: The are many different attributes in the dataset, we do not expect your dashboard to deal with and visualise all of them. Pick out some key attributes which you think would be most interesting to display. +## 5. open the URL shows in Terminal (copy and paste it in Google Chrome) -## Submission +## (6. If error shows address occupied, need to kill current process, and redo step5) +pkill -9 python -Since we commonly use GitHub for collaborating on open source code, ideally you will fork this repository and add your code directly in there. Best to follow up with a GitHub Pull Request back into our repo so we can see your code. This would require making your submission public, if you would prefer to keep your code private, please add it to a private GitHub repository and add GitHub user `pchlap` with read permissions. -In addition, it would be great if you can make your dashboard really easy to run/access. Think about how you might best package your tool and include some instructions in your submission on how to run your dashboard. - -> ### Please submit by 10am on Tuesday 5th October 2021. - -## Tips - -Here are a few tips to help you get started with the challenge: - -1. Python is commonly used in research thanks to its ease of use. [Dash](https://dash.plotly.com/) is one of many Python libraries which can be used to easily create web-based dashboards. - -2. See `challenge_september_2021.py` for some code on getting started using Python and Dash. Use the following commands in your Python environment to run the example: - -```bash -pip install -r requirements.txt -python challenge_september_2021.py -``` - -3. At diagnosis, the patient's disease is assigned a stage (I, II, III, IVA, IVB). Typically one can expect poorer overall survival the higher the stage at diagnosis. A good starting point for the dashboard could be to visualise the overall survival based on the stage. Additionally you could allow the user to filter by gender or an age bracket. - -4. Web applications are often deployed using Docker. Perhaps you might like to build or even deploy ([Heroku](https://www.heroku.com/) has a free plan) a Docker image which runs your dashboard. - -## Data - -You can find the clinical data for this challenge in the `data/hnscc.csv` file. - -This data was extracted from the HNSCC dataset: https://wiki.cancerimagingarchive.net/display/Public/HNSCC: -- Grossberg A, Elhalawani H, Mohamed A, Mulder S, Williams B, White AL, Zafereo J, Wong AJ, Berends JE, AboHashem S, Aymard JM, Kanwar A, Perni S, Rock CD, Chamchod S, Kantor M, Browne T, Hutcheson K, Gunn GB, Frank SJ, Rosenthal DI, Garden AS, Fuller CD, M.D. Anderson Cancer Center Head and Neck Quantitative Imaging Working Group. (2020) HNSCC [ Dataset ]. The Cancer Imaging Archive. DOI: https://doi.org/10.7937/k9/tcia.2020.a8sh-7363 - -- Grossberg A, Mohamed A, Elhalawani H, Bennett W, Smith K, Nolan T, Williams B, Chamchod S, Heukelom J, Kantor M, Browne T, Hutcheson K, Gunn G, Garden A, Morrison W, Frank S, R osenthal D, Freymann J, Fuller C. (2018) Imaging and Clinical Data Archive for Head and Neck Squamous Cell Carcinoma Patients Treated with Radiotherapy. Scientific Data 5 :180173 (2018) DOI: 10.1038/sdata.2018.173 - -- Elhalawani, H., Mohamed, A., White, A. et al. Matched computed tomography segmentation and demographic data for oropharyngeal cancer radiomics challenges. Sci Data 4, 170077 (2017). DOI: 10.1038/sdata.2017.77 -TCIA Citation - -- Clark K, Vendt B, Smith K, Freymann J, Kirby J, Koppel P, Moore S, Phillips S, Maffitt D, Pringle M, Tarbox L, Prior F. The Cancer Imaging Archive (TCIA): Maintaining and Operating a Public Information Repository, Journal of Digital Imaging, Volume 26, Number 6, December, 2013, pp 1045-1057. DOI: 10.1007/s10278-013-9622-7 - -## Good luck - -Thanks for participating, we look forward to you submission! If you have any questions please contact: **Phillip Chlap**: [phillip.chlap@unsw.edu.au](phillip.chlap@unsw.edu.au). From ff6a06089f39e7e4f6c2e06b6d76cd798e5c3e84 Mon Sep 17 00:00:00 2001 From: Janet <41528500+Janetxxx@users.noreply.github.com> Date: Tue, 5 Oct 2021 02:20:15 +1100 Subject: [PATCH 06/11] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7eef9c5..e60fce3 100644 --- a/README.md +++ b/README.md @@ -2,20 +2,20 @@ ## Janet Cui workload -## 1. create dash-env +## 1. Create dash-env conda create -n dash-dev python=3.7 -y -## 2. activate dash-env +## 2. Activate dash-env conda activate dash-dev -## 3. make sure to run python file under "src" file +## 3. Make sure to run python file under "src" file cd ingham-medphys-coding cd src -## 4. run python file +## 4. Run python file python3 challenge_september_2021.py -## 5. open the URL shows in Terminal (copy and paste it in Google Chrome) +## 5. Open the URL shows in Terminal (copy and paste it in Google Chrome) ## (6. If error shows address occupied, need to kill current process, and redo step5) pkill -9 python From 063caba5a2bb2ead460fae0ca7c9c307e7c89fb6 Mon Sep 17 00:00:00 2001 From: Janet <41528500+Janetxxx@users.noreply.github.com> Date: Tue, 5 Oct 2021 02:22:50 +1100 Subject: [PATCH 07/11] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e60fce3..5fa7cdd 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ conda create -n dash-dev python=3.7 -y conda activate dash-dev ## 3. Make sure to run python file under "src" file -cd ingham-medphys-coding +cd ingham-medphys-coding \n cd src ## 4. Run python file From 7c2a986960fb1396a0f585151033224f1b79c73b Mon Sep 17 00:00:00 2001 From: Janet <41528500+Janetxxx@users.noreply.github.com> Date: Tue, 5 Oct 2021 02:23:25 +1100 Subject: [PATCH 08/11] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5fa7cdd..ad41bc6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ conda create -n dash-dev python=3.7 -y conda activate dash-dev ## 3. Make sure to run python file under "src" file -cd ingham-medphys-coding \n +cd ingham-medphys-coding
cd src ## 4. Run python file From 9a7c6593323def6a7b71f82a0c6a458fef69d84c Mon Sep 17 00:00:00 2001 From: Janet <41528500+Janetxxx@users.noreply.github.com> Date: Tue, 5 Oct 2021 02:30:15 +1100 Subject: [PATCH 09/11] update commands --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ad41bc6..12216a7 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,16 @@ conda activate dash-dev cd ingham-medphys-coding
cd src -## 4. Run python file +## 4. Download dash module, dash-bootstrap-components, pandas +pip install dash -U +pip install dash-bootstrap-components +pip install pandas + +## 5. Run python file python3 challenge_september_2021.py -## 5. Open the URL shows in Terminal (copy and paste it in Google Chrome) +## 6. Open the URL shows in Terminal (copy and paste it in Google Chrome) +e.g.,"Dash is running on http://127.0.0.1:8050/" -## (6. If error shows address occupied, need to kill current process, and redo step5) +## (7. If error shows address occupied, need to kill current process, and redo step5) pkill -9 python - - From 75192bbd70faa1f4f8212c2180453377b58f3167 Mon Sep 17 00:00:00 2001 From: Janet <41528500+Janetxxx@users.noreply.github.com> Date: Tue, 5 Oct 2021 02:31:26 +1100 Subject: [PATCH 10/11] update commands --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 12216a7..3d23422 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ cd ingham-medphys-coding
cd src ## 4. Download dash module, dash-bootstrap-components, pandas -pip install dash -U -pip install dash-bootstrap-components +pip install dash -U
+pip install dash-bootstrap-components
pip install pandas ## 5. Run python file From baee60c28566f06bb07dfc74094cbb27abbc3174 Mon Sep 17 00:00:00 2001 From: Janet <41528500+Janetxxx@users.noreply.github.com> Date: Tue, 5 Oct 2021 02:32:09 +1100 Subject: [PATCH 11/11] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d23422..c074f16 100644 --- a/README.md +++ b/README.md @@ -23,5 +23,5 @@ python3 challenge_september_2021.py ## 6. Open the URL shows in Terminal (copy and paste it in Google Chrome) e.g.,"Dash is running on http://127.0.0.1:8050/" -## (7. If error shows address occupied, need to kill current process, and redo step5) +## (7. If error shows address occupied, it needs to kill current process on terminal, and redo step6) pkill -9 python