Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.81 Add ME-ICC Scoring #46

Merged
merged 10 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 27 additions & 26 deletions docs/dsqitems_and_routes_map.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ Remember36comp: '/remember' <-> screener_views.page4 | remember | "Problems reme
#short_form (+11 qs)
Soreness15comp: '/short_form/soreness' <-> short_form.expem1 | sore | "Next day soreness or fatigue after non-strenuous, everyday activities"
Difficulty37comp: '/short_form/attention' <-> short_form.excog1 | attention | "Difficulty paying attention for a long period of time"
Musclepain25comp: '/short_form/musclepain' <-> short_form.musclepain | "Pain or aching in your muscles"
Bloating29comp: '/short_form/bloating' <-> short_form.bloating
Bowel46comp: '/short_form/bowel' <-> short_form.bowel
Unsteady48comp: '/short_form/unsteady' <-> short_form.unsteady
Limbs56comp: '/short_form/cold_limbs' <-> short_form.cold_limbs
Musclepain25comp: '/short_form/musclepain' <-> short_form.musclepain | muscle | "Pain or aching in your muscles"
Bloating29comp: '/short_form/bloating' <-> short_form.bloating | bloat | "Bloating"
Bowel46comp: '/short_form/bowel' <-> short_form.bowel | bowel | "Irritable bowel problems"
Unsteady48comp: '/short_form/unsteady' <-> short_form.unsteady | unsteady | "Feeling unsteady on your feet, like you might fall"
Limbs56comp: '/short_form/cold_limbs' <-> short_form.cold_limbs | limbs | "Cold limbs (e.g., arms, legs, hands)"
Hot58comp: '/short_form/hot_cold' <-> short_form.hot_cold | hot | "Feeling hot or cold for no reason"
Flu65comp: '/short_form/flu' <-> short_form.flu
Flu65comp: '/short_form/flu' <-> short_form.flu | flu | "Flu-like symptoms"
Smells66comp: '/short_form/smells' <-> short_form.smells | smell | "Some smells, foods, medications, or chemicals make you feel sick"
Reduction97: '/short_form/reduction' <-> short_form.reduction
'/short_form/short_form_dx' <-> short_form.graph2

#dsq (+41 qs)
Viral98: '/viral' <-> viral
#dsq (+42 qs)
Viral98: '/viral' <-> viral | viral | Do you experience frequent viral infections with prolonged recovery periods?
Heavy14comp: '/heavy' <-> expem3 | heavy | "Dead, heavy feeling after starting to exercise"
Mental16comp: '/mentally' <-> expem4 | mental | "Mentally tired after the slightest effort"
Drained18comp: '/drained' <-> expem2 | drained | "Physically drained or sick after mild activity"
Expand All @@ -43,12 +43,12 @@ Falling21comp: '/falling' <-> exsleep3 | fall | "Problems falling asleep"
Staying22comp: '/staying' <-> exsleep1 | stay | "Problems staying asleep"
Early23comp: '/early' <-> early | early | "Waking up early in the morning (e.g. 3am)"
Allday24comp: '/allday' <-> exsleep4 | allday | "Sleep all day and stay awake all night"
Jointpain26comp: '/jointpain' <-> jointpain
Eyepain27comp: '/eyepain' <-> eyepain
Chestpain28comp: '/chestpain' <-> chestpain
Stomach30comp: '/stomach' <-> stomach
Headaches31comp: '/headaches' <-> headaches
Twitches32comp: '/twitches' <-> twitches
Jointpain26comp: '/jointpain' <-> jointpain | jointpain | "Pain/stiffness/tenderness in more than one joint without swelling or redness"
Eyepain27comp: '/eyepain' <-> eyepain | eyepain | "Eye pain"
Chestpain28comp: '/chestpain' <-> chestpain | chestpain | "Chest pain"
Stomach30comp: '/stomach' <-> stomach | stomach | "Abdomen/stomach pain"
Headaches31comp: '/headaches' <-> headaches | headaches | "Headaches"
Twitches32comp: '/twitches' <-> twitches | twitches | "Muscle twitches"
Weakness33comp: '/weakness' <-> weakness | weak | "Muscle weakness"
Noise34comp: '/noise' <-> noise | noise | "Sensitivity to noise"
Lights35comp: '/lights' <-> lights | lights | "Sensitivity to bright lights"
Expand All @@ -59,22 +59,23 @@ Unable41comp: '/vision' <-> vision | vision | "Unable to focus vision and/or att
Depth42comp: '/depth' <-> depth | depth | "Loss of depth perception"
Slowness43comp: '/slowness' <-> slowness | slow | "Slowness of thought"
Absent44comp: '/absent' <-> absent | absent | "Absent-mindedness or forgetfulness"
Bladder45comp: '/bladder' <-> bladder
Nausea47comp: '/nausea' <-> nausea
Bladder45comp: '/bladder' <-> bladder | bladder | "Bladder problems"
Nausea47comp: '/nausea' <-> nausea | nausea | "Nausea"
Shortness49comp: '/shortness' <-> shortness | short | "Shortness of breath or trouble catching your breath"
Dizzy50comp: '/dizzy' <-> dizzy
Dizzy50comp: '/dizzy' <-> dizzy | dizzy | "Dizziness or fainting"
Irregular51comp: '/heart' <-> heart | heart | "Irregular heart beats"
Weight52comp: '/weight' <-> weight | weight | "Losing or gaining weight without trying"
Appetite53comp: '/appetite' <-> appetite
Sweating54comp: '/sweating' <-> sweating
Night55comp: '/night' <-> night
Chills57comp: '/chills' <-> chills
HTemp59comp: '/hitemp' <-> hitemp
LTemp60comp: '/lotemp' <-> lotemp
Alcohol61comp: '/alcohol' <-> alcohol
SoreThroat62comp: '/throat' <-> throat
LympthNodes63comp: '/lymphnodes' <-> lymphnodes
Fever64comp: '/fever' <-> fever
Sweating54comp: '/sweating' <-> sweating | sweat | "Sweating hands"
Night55comp: '/night' <-> night | night | "Night sweats"
Chills57comp: '/chills' <-> chills | chills | "Feeling chills or shivers"
HTemp59comp: '/hitemp' <-> hitemp | hitemp | "Feeling like you have a high temperature"
LTemp60comp: '/lotemp' <-> lotemp | lotemp | "Feeling like you have a low temperature"
Alcohol61comp: '/alcohol' <-> alcohol | alcohol | "Alcohol intolerance"
SoreThroat62comp: '/throat' <-> throat | throat | "Sore throat"
LympthNodes63comp: '/lymphnodes' <-> lymphnodes | lymphnodes | "Tender/sore lymph nodes"
Fever64comp: '/fever' <-> fever | fever | "Fever"
Intolerant99: '/intolerant' <-> intolerant | intolerant | "Are you intolerant of extremes of temperatures (when it is extremeley hot or cold)?
'/dsq_dx' <-> graph3

#other
Expand Down
18 changes: 13 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,6 @@ def chills():
@app.route('/hitemp', methods=['post', 'get'])
def hitemp():
global end

form = FlaskForm()
if request.method == "POST":
hitempf = request.form.get("hitempf")
Expand All @@ -723,7 +722,6 @@ def hitemp():
@app.route('/lotemp', methods=['post', 'get'])
def lotemp():
global end

form = FlaskForm()
if request.method == "POST":
lotempf = request.form.get("lotempf")
Expand All @@ -741,7 +739,6 @@ def lotemp():
@app.route('/alcohol', methods=['post', 'get'])
def alcohol():
global end

form = FlaskForm()
if request.method == "POST":
alcoholf = request.form.get("alcoholf")
Expand Down Expand Up @@ -800,12 +797,23 @@ def fever():
if feverf is not None and fevers is not None:
session["feverf"] = feverf
session["fevers"] = fevers
session['pagenum'] += 1
return redirect(url_for("graph3"))
return redirect(url_for("intolerant"))
else:
return render_template("dsq/fever64.html", message=message, pagenum=session['pagenum'])
return render_template("dsq/fever64.html", message='', pagenum=session['pagenum'])

@app.route('/intolerant', methods=['post', 'get'])
def intolerant():
msg_intolerant = "Please select one of the options before continuing"
if request.method == 'POST':
intolerant = request.form.get('intolerant')
if intolerant is not None:
session['intolerant'] = intolerant
return redirect(url_for('graph3'))
else:
return render_template("dsq/intolerant99.html", message=msg_intolerant, pagenum=session['pagenum'])
return render_template('dsq/intolerant99.html', message='', pagenum=session['pagenum'])

@app.route('/dsq_dx', methods=['get'])
def graph3():
return dsq_utils.dsq_diagnose()
Expand Down
3 changes: 2 additions & 1 deletion utils/back_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ def previous_page(current_route):
'/throat',
'/lymphnodes',
'/fever',
'/intolerant',
'/dsq_dx',
'/about',
'/aboutmecfs'
)
)
156 changes: 147 additions & 9 deletions utils/dsq_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# see dsqitems_and_routes_map.txt for info on each section of the screener

def dsq_diagnose():
# IOM assessment
#---IOM Scoring----------------------------
iomfatiguecheck = "No"
iomreductioncheck = "No"
iompemcheck = "No"
Expand Down Expand Up @@ -52,13 +52,13 @@ def dsq_diagnose():
iomorthocheck = "Yes"

if iomfatiguecheck == "Yes" and iomreductioncheck == "Yes" and iompemcheck == "Yes" and iomsleepcheck == "Yes" and (iomcogcheck == "Yes" or iomorthocheck == "Yes"):
iom_msg = "Your responses suggest you meet the IOM Criteria for ME/CFS."
iom_msg = "Your responses suggest that you meet the IOM criteria for ME/CFS."
iomdxcheck = "Met"
else:
iom_msg = "Your responses do not meet the IOM Criteria for ME/CFS."
iom_msg = "Your responses do not meet the IOM criteria for ME/CFS."
iomdxcheck = "Not met"

# Canadian criteria assessment
#---CCC Scoring----------------------------
ccc_dx = False

if get_score('fatiguescoref') >= 2 and get_score('fatiguescores') >= 2:
Expand Down Expand Up @@ -178,23 +178,156 @@ def dsq_diagnose():
else:
ccc_dx = "Not met"
ccc_msg = "Your responses do not meet the Canadian Consensus Criteria for ME/CFS."

#---ME-ICC Scoring----------------------------
meicc_sr = "No"
meicc_pene = "No"
meicc_cognitive = "No"
meicc_pain = "No"
meicc_sleep = "No"
meicc_sensory = "No"
meicc_flu = "No"
meicc_gastro = "No"
meicc_urinary = "No"
meicc_sensitivity = "No"
meicc_viral = "No"
meicc_cardio = "No"
meicc_respiratory = "No"
meicc_thermo = "No"
meicc_temp = "No"

# substantial reduction in functioning: dsq 97
if get_score('reduction') == 1:
meicc_sr = "Yes"

# PENE/PEM: 14-18
if (get_score("heavyf") >= 2 and get_score("heavys") >= 2) or (
get_score("soref") >= 2 and get_score("sores") >= 2) or (
get_score("mentalf") >= 2 and get_score("mentals") >= 2) or (
get_score("minexf") >= 2 and get_score("minexs") >= 2) or (
get_score("drainedf") >= 2 and get_score("draineds") >= 2):
meicc_pene = "Yes"

# neurcognitive: 36-44
if (get_score("rememberf") >= 2 and get_score("remembers") >= 2) or (
get_score("attentionf") >= 2 and get_score("attentions") >= 2) or (
get_score("wordf") >= 2 and get_score("words") >= 2) or (
get_score("understandf") >= 2 and get_score("understands") >= 2) or (
get_score("focusf") >= 2 and get_score("focuss") >= 2) or (
get_score("visionf") >= 2 and get_score("visions") >= 2) or (
get_score("depthf") >= 2 and get_score("depths") >= 2) or (
get_score("slowf") >= 2 and get_score("slows") >= 2) or (
get_score("absentf") >= 2 and get_score("absents") >= 2):
meicc_cognitive = "Yes"

# pain: 25-28; 31
if (get_score("musclef") >= 2 and get_score("muscles") >= 2) or (
get_score("jointpainf") >= 2 and get_score("jointpains") >= 2) or (
get_score("eyepainf") >= 2 and get_score("eyepains") >= 2) or (
get_score("chestpainf") >= 2 and get_score("chestpains") >= 2) or (
get_score("headachesf") >= 2 and get_score("headachess") >= 2):
meicc_pain = "Yes"

# diagnostic message true if ccc OR iom
if ccc_dx == "Met" or iomdxcheck == "Met":
# sleep: 19-24
if (get_score("sleepf") >= 2 and get_score("sleeps") >= 2) or (
get_score("napf") >= 2 and get_score("naps") >= 2) or (
get_score("fallf") >= 2 and get_score("falls") >= 2) or (
get_score("stayf") >= 2 and get_score("stays") >= 2) or (
get_score("earlyf") >= 2 and get_score("earlys") >= 2) or (
get_score("alldayf") >= 2 and get_score("alldays") >= 2):
meicc_sleep = "Yes"

# neurosensory, perceptual, motor: 32-35; 48
if (get_score("twitchesf") >= 2 and get_score("twitchess") >= 2) or (
get_score("weakf") >= 2 and get_score("weaks") >= 2) or (
get_score("noisef") >= 2 and get_score("noises") >= 2) or (
get_score("lightsf") >= 2 and get_score("lightss") >= 2) or (
get_score("unsteadyf") >= 2 and get_score("unsteadys") >= 2):
meicc_sensory = "Yes"

# flu-like: 62-65
if (get_score("throatf") >= 2 and get_score("throats") >= 2) or (
get_score("lymphnodesf") >= 2 and get_score("lymphnodess") >= 2) or (
get_score("feverf") >= 2 and get_score("fevers") >= 2) or (
get_score("fluf") >= 2 and get_score("flus") >= 2):
meicc_flu = "Yes"

# gastrointestinal: 29-30; 46-47
if (get_score("bloatf") >= 2 and get_score("bloats") >= 2) or (
get_score("stomachf") >= 2 and get_score("stomachs") >= 2) or (
get_score("bowelf") >= 2 and get_score("bowels") >= 2) or (
get_score("nauseaf") >= 2 and get_score("nauseas") >= 2):
meicc_gastro = "Yes"

# genitourinary: 45
if get_score("bladderf") >= 2 and get_score("bladders") >= 2:
meicc_urinary = "Yes"

# sensitivities: 61, 66
if (get_score("alcoholf") >= 2 and get_score("alcohols") >= 2) or (
get_score("smellf") >= 2 and get_score("smells") >= 2):
meicc_sensitivity = "Yes"

# viral: 98
if get_score("viral") == 1:
meicc_viral = "Yes"

# cardio: 50-51
if (get_score("dizzyf") >= 2 and get_score("dizzys") >= 2) or (
get_score("heartf") >= 2 and get_score("hearts") >= 2):
meicc_cardio = "Yes"

# respiratory: 49
if get_score("shortf") >= 2 and get_score("shorts") >= 2:
meicc_respiratory = "Yes"

# thermostatic: 54-60
if (get_score("sweatf") >= 2 and get_score("sweats") >= 2) or (
get_score("nightf") >= 2 and get_score("nights") >= 2) or (
get_score("limbsf") >= 2 and get_score("limbss") >= 2) or (
get_score("chillsf") >= 2 and get_score("chillss") >= 2) or (
get_score("hotf") >= 2 and get_score("hots") >= 2) or (
get_score("hitempf") >= 2 and get_score("hitemps") >= 2) or (
get_score("lotempf") >= 2 and get_score("lotemps") >= 2):
meicc_thermo = "Yes"

# temp intollerance: 99
if (get_score("intolerant")) == 1:
meicc_temp = "Yes"

meicc_neuro = np.sum([yes_to_one(meicc_cognitive), yes_to_one(meicc_pain), yes_to_one(meicc_sleep), yes_to_one(meicc_sensory)]) >= 3
meicc_igg = np.sum([yes_to_one(meicc_flu), yes_to_one(meicc_gastro), yes_to_one(meicc_urinary), yes_to_one(meicc_sensitivity), yes_to_one(meicc_viral)]) >= 3
meicc_energy = np.sum([yes_to_one(meicc_cardio), yes_to_one(meicc_respiratory), yes_to_one(meicc_thermo), yes_to_one(meicc_temp)]) >= 1

if np.sum([yes_to_one(meicc_sr), yes_to_one(meicc_pene), meicc_neuro, meicc_igg, meicc_energy]) == 5:
meicc_dx = "Met"
meicc_msg = "Your responses suggest that you meet the ME-ICC criteria for ME/CFS."
else:
meicc_dx = "Not Met"
meicc_msg = "Your responses do not meet the ME-ICC criteria for ME/CFS."

# diagnostic message True if ccc OR iom OR meicc
if ccc_dx == "Met" or iomdxcheck == "Met" or meicc_dx == "Met":
dsq_message = "Based on your responses there is a chance you might have MECFS. <br> Please consult with your doctor for next steps."
else:
dsq_message = "Based on your responses it does not appear you have MECFS."

graphJSON = dsq_graph()

return render_template("results/graph3.html", graphJSON=graphJSON,
return render_template("results/graph3.html", graphJSON=graphJSON, dsq_message=dsq_message,
ccc_msg=ccc_msg, ccc_fatiguecheck=ccc_fatiguecheck,
ccc_pemcheck=ccc_pemcheck, ccc_paincheck=ccc_paincheck, ccc_sleepcheck=ccc_sleepcheck,
ccc_cogcheck=ccc_cogcheck, ccc_autocheck=ccc_autocheck, ccc_immunecheck=ccc_immunecheck,
ccc_neurocheck=ccc_neurocheck, ccc_dx=ccc_dx, ccc_reductioncheck=ccc_reductioncheck, ccc_poly=ccc_poly,
iomfatiguecheck=iomfatiguecheck, iomreductioncheck=iomreductioncheck,
iompemcheck=iompemcheck, iomdxcheck=iomdxcheck, iom_msg=iom_msg,
iomsleepcheck=iomsleepcheck, iomcogcheck=iomcogcheck, iomorthocheck=iomorthocheck, dsq_message=dsq_message)
iomsleepcheck=iomsleepcheck, iomcogcheck=iomcogcheck, iomorthocheck=iomorthocheck,
meicc_sr=meicc_sr, meicc_pene=meicc_pene, meicc_cognitive=meicc_cognitive, meicc_pain=meicc_pain,
meicc_sleep=meicc_sleep, meicc_sensory=meicc_sensory, meicc_flu=meicc_flu,
meicc_gastro=meicc_gastro, meicc_urinary=meicc_urinary, meicc_sensitivity=meicc_sensitivity,
meicc_viral=meicc_viral, meicc_cardio=meicc_cardio, meicc_respiratory=meicc_respiratory,
meicc_thermo=meicc_thermo, meicc_temp=meicc_temp, meicc_energy=meicc_energy, meicc_msg=meicc_msg,
meicc_igg=meicc_igg, meicc_neuro=meicc_neuro, meicc_dx=meicc_dx)

def dsq_graph():
fatigue_score = (get_score("fatiguescoref") + get_score("fatiguescores")) / 2
Expand Down Expand Up @@ -264,4 +397,9 @@ def dsq_graph():
fig.update_layout(yaxis_title='Averaged Frequency and Severity Scores',
xaxis_title='Symptom Domains')
fig.update_yaxes(range=[0, 100], dtick=25)
return json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
return json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)

def yes_to_one(domain_result):
if domain_result == "Yes":
return 1
return 0
4 changes: 2 additions & 2 deletions utils/short_form_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ def short_form_diagnose():
iomorthocheck = "Yes"

if iomfatiguecheck == "Yes" and iomreductioncheck == "Yes" and iompemcheck == "Yes" and iomsleepcheck == "Yes" and (iomcogcheck == "Yes" or iomorthocheck == "Yes"):
iom_msg = "Your responses suggest you meet the IOM Criteria for ME/CFS. To improve the accuracy" \
iom_msg = "Your responses suggest you meet the IOM criteria for ME/CFS. To improve the accuracy" \
" of your assessment with more questions continue to the next section."
iomdxcheck = "Met"
else:
iom_msg = "Your responses do not meet the IOM Criteria for ME/CFS."
iom_msg = "Your responses do not meet the IOM criteria for ME/CFS."
iomdxcheck = "Not met"

# This assesses the Canadian Consensus Criteria, one of the three major case definitions we use
Expand Down
Loading