Files
bio-performx/app/services/__pycache__/graph_generator.cpython-312.pyc
T

302 lines
34 KiB
Plaintext
Raw Normal View History

Ë
ÊÞàh—tãóldZddlZddlmZddlmZddlmZ ddl
Z ddl Z
ddlZddlmZGdd«Zy)
Graph Generator Service
This service generates all the charts and visualizations required for the medical report.
Based on the analysis notebooks in services_dfdf/.
éN)ÚPath)ÚFancyBboxPatchc óžeZdZdZddefdZdedefdZ ddejde
defd „Z ddejde
defd
Z ddejde
defd Z
ddejde
defd Z ddejde
defd
Z ddejde
defdZ ddedede
defdZ ddededede
def
dZ ddejde
defdZy)ÚGraphGeneratorz'Generate all charts for medical reportsÚ
charts_dircó\t|«|_|jjd¬«y)z{
Initialize the graph generator.
Args:
charts_dir: Directory to save generated charts
T)Úexist_okN)rrÚmkdir)Úselfrs úU/home/oluwasanmi/Documents/Work/MKD/report_generation/app/services/graph_generator.pyÚ__init__zGraphGenerator.__init__s%ô˜zÓŒØ ×Ñ tÐÕÚ
image_pathÚreturncóÊ t|d«5}tj|j««j d«cddd«S#1swYyxYw#t
$rYywxYw)
Convert image file to base64 string.
Args:
image_path: Path to image file
Returns:
Base64 encoded string
Úrbzutf-8NÚ)ÚopenÚbase64Ú b64encodeÚreadÚdecodeÚFileNotFoundError)r rÚ
image_files r Ú_image_to_base64zGraphGenerator._image_to_base64 s]ð Üj 
K¨:Ü×
¯©Ó(9Ó:×AÀ'Ó
K÷
Kò
Kûä ò Ùð ús. AŽ2A
Á AÁ
AÁAÁAÁ A"Á!A"ÚdfÚsave_as_base64c
óš|jd¬«}|dj«}tjd¬«tj«}t j |ddd¬«|jd «|jd«|jd
d ¬ «|jd
td|dj«««|j«}|jtj d
|dj«dzd««t j |ddd|ddd¬«|jd«|jd
td|dj««dz«|j#«j%«|j#«j%«|j'«\}}|j'«\} }
|j)|| z||
zd¬«t+|«dk\rw|j-d
|ddd¬«|j-|d|ddd¬«|j-|d|ddd¬«|j-|d|dj«dd ¬«|j.d!z } tj0| d"d#¬$«tj2«|r|j5| «St7| «S)%a
Generate respiratory chart (VT and Speed over time).
Args:
df: Processed DataFrame with smoothed columns
save_as_base64: If True, return base64 string, else return file path
Returns:
Base64 string or file path
ÚPHASE©ÚsubsetúT(sec)©éé©ÚfigsizezVT(l)_smoothedzVT (L)©ÚdataÚlabelú
Time (sec)Tçš™™™™™¹?©ÚalpharééÈÚSpeedÚgreenú
steps-posté©r)r*r+ÚcolorÚaxÚ drawstyleÚ linewidthr,ééú
upper left©Úlocéçš™™™™™É?Ú lightblue©r0r8ÚpurpleéÚ
lightgreenÚbluezrespiratory.pngé,Útight©ÚdpiÚ bbox_inches)Údrop_duplicatesÚtolistÚpltÚfigureÚsubplotÚsnsÚlineplotÚ
set_xlabelÚ
set_ylabelÚgridÚset_ylimÚminÚmaxÚtwinxÚ
set_xticksÚnpÚarangeÚ
get_legendÚremoveÚget_legend_handles_labelsÚlegendÚlenÚaxvspanrÚsavefigÚcloserÚstr© r rrÚfirst_unique_phaseÚ phase_timesÚax1Úax2Úlines1Úlabels1Úlines2Úlabels2Ú
chart_paths r Úgenerate_respiratory_chartz)GraphGenerator.generate_respiratory_chart0sað ×/°wÐØÑ ä
˜7Õk‰kmˆô ˜" Ð,<ÀHÕ   Ø ˜SˆÔ ˜A˜rÐ"2Ñ3×i‰i‹kˆØ ”r—yy  B x¡L×$4Ñ$4Ó$6¸Ñ$<¸ ØØØØØØØõ
ð Ø ˜B  7¡ §¡Ó 1Ó2°QÑ Ó×ÑÔ Ó×ÑÔ×9‰ˆØ×9‰ˆØ
6˜F? G¨gÑ$5¸<ˆ
Ô ˆ{Ó ˜qÒ Ø K‰K˜˜; q™>°¸Kˆ K‰K˜  A™¨ °A©¸cȈKÔ K‰K˜  A™¨ °A©¸cȈKÔ K‰K˜  A™¨¨8© ×(8Ñ(8Ó(:À#ÈVˆ —__Ð'8Ñ8ˆ
Ü J C°WÕ ‰ Œ á4Bˆ$ ZÓÈJËÐWrc ó |jd«jd¬«jd«}|jdd}||jdk\|jdkz}t j d¬ «t
jjd
«tdt|«dz«Dcgc]}d |Œ }}tjt|««}|d |d
zdz }|d |dzdz } t j«}
|
j||dddd¬«|
j|| |dddd¬«|
jdd¬«|
j!dd¬«|
j#dd«t%t'|| |d ««D]r\}\} } }
| dkDr|
j)|| dz | d d!d!d"d#d$¬%«| dkDr!|
j)|| | dz z| d d!d!d"d#d$¬%«|
j)||
d&z|
d d'd!d(d)d#d*¬%«Œtt%|j«D]?\}}|
j)|d+|d d,d!d-d"¬.«|
j)|d/|d0zd d1d!d-d2d3¬4«ŒA|
j+«}|j-||d5d6d7d2d8d9¬:«|j!d;dd8¬<«|j/d=d8¬>«|j#dd?«t%|d5«D]-\}}|j)||d)zt1|«d@d!d(d)d#d8¬%«Œ/|
j3|«|
j5|dA¬«|
j7«\}}|j7«\}}|
j9||z||zdBddd¬C«|
j;dddDd&¬E«|
j=d«t j>«t j@dFdG¬H«|jBdIz }t jD|dJ¬K«t jF«|r|jI|«StK|«Scc}w)La
Generate fuel utilization chart (CHO vs FAT by stage).
Args:
df: Processed DataFrame with smoothed columns
save_as_base64: If True, return base64 string, else return file path
Returns:
Base64 string or file path
r3T)Ú numeric_onlyr=éÿÿÿÿg @g@)ér1r&ÚdefaultzStage z EE(kcal/min)zFAT(%)édzCARBS(%)z#1f77b4çš™™™™™é?ç333333ã?ÚFat)r8r0Úwidthr,z#ff7f0eÚCarbs)Úbottomr8r0r|r,ré ©ÚfontsizezFuel (kcal/min)rég333333Ó?r6ú.1fÚcenteré ÚboldÚwhite)ÚhaÚvarÚ
fontweightr8çà?z kcalr~é
Úblackgø¿z mphÚtop©rˆr‰rgffffffÀgX9´Èv¾ù?z min/kmr1Úgray©rˆr‰rr8zHR(bpm)ÚorFÚredz
Heart Rate)Úmarkerr;Ú
markersizer8r,úHeart Rate (bpm))rr8r+©ÚaxisÚ
labelcoloréÜÚbpmé r>)r@ÚframeonÚfancyboxÚshadowú-)r0Ú linestyler;r.çÍÌÌÌÌÌì?)r~zfuel_utilization_chart.pngrI)rL)&ÚgroupbyÚmeanÚroundÚilocÚindexrPrQÚstyleÚuseÚrangercr]r^ÚgcaÚbarrUrVrXÚ enumerateÚzipÚtextr[ÚplotÚ tick_paramsÚintr\Úset_xticklabelsrarbrWÚ
set_axisbelowÚ tight_layoutÚsubplots_adjustrrerfrrg)r rrÚ speed_groupsÚ
filtered_dataÚ stage_labelsÚ x_positionsÚfat_eeÚcarbs_eerkÚfat_valÚcarb_valÚ total_valÚspeedrlÚhrrmrnrorprqs r Úgenerate_fuel_utilization_chartz.GraphGenerator.generate_fuel_utilization_chartnð—zz *×/¸Ó ب2Ð ð
×
Ñ
 
&¨<×+=Ñ+=ÀÑ+DÑ 
ˆ
ô
˜
 ä.3°A´s¸=Ó7IÈAÑ7MÓ.NÖ˜&  š РЗi‘i¤ MÓ 2Ó ð˜~ѸxÑ1HÑHÈ3ÑØ  Ñ0°=ÀÑ3LÑLÈsÑäg‰g‹iˆð Ø Ø ØØØØð
ô
ð Ø Ø ØØØØØð ô
ð r BˆÔ Ð(°2ˆÔ Ôô2;Ü ˜ Ñ"?Ó 2
ò" Ñ -ˆ-˜ 9ð˜Š}ØØØ˜a‘KؘsØØØô ð˜#Š~ØØØ˜h¨™lÑ ØØØô ð
H‰HØØ˜CؘSÐØØØð
õ
ð3" ôJ" -×"5Ñ"5Ó ‰HˆAˆ H‰HØ4˜E #˜; ¸UÈQð
ô
ð
H‰HØØØ˜‘;˜sÐ# 7ÐØØØð
õ
ð ði‰i‹kˆØ Ø Ø ˜)Ñ ØØØØð ô
ð Ð)°B¸eˆÔ ˜S¨UˆÔ Ôô˜}¨YÑ
‰EˆAˆrØ H‰HØØR‘Ür“7)˜3ØØØØð
õ
ð
ð  ×јL°2ÐÔ×9‰ˆØ×9‰ˆØ
Ø V‰OØ  ØØØØð
ô
ð ˜S¨C¸3ˆÔ ×ј$Ôä ×ÑÔÜ ×Ñ 3¨CÕ—__Ð'CÑCˆ
Ü J CÕ ‰ Œ á4Bˆt×$ ZÓÈJËÐWùòUPsÂ1 P c
ó˜|jd¬«}|dj«}tjd¬«tj«}t j |dddd¬ «|jd
«|jd«|jd |dj««|jd d
¬«|j«}t j |ddd|dd¬«|jdd¬«|jdd¬«|jd |dj«dz«|j«}|jdjd«t j |ddd|ddd¬«|jdd¬«|jdd¬«|jd |dj«dz«|j!t#j$d |dj«dzd««|j'«r|j'«j)«|j'«r|j'«j)«|j'«r|j'«j)«|j+«\}} |j+«\}
} |j+«\} }
|j-||
z| z| | z|
zd¬ «t/|«d!k\rw|j1d |dd"d#¬$«|j1|d|dd"d%¬$«|j1|d|d&d"d'¬$«|j1|d&|dj«d"d¬$«|j2d(z }tj4|d)d*¬+«tj6«|r|j9|«St;|«S),a
Generate VO2 Pulse chart with HR and Speed.
Args:
df: Processed DataFrame with smoothed columns
save_as_base64: If True, return base64 string, else return file path
Returns:
Base64 string or file path
rr r"r#r&zVO2 Pulse_smoothedúVO2 Pulse (mL/beat)rH©r)r*r+r,r8r-rTr.r/úHR(bpm)_smoothedr“r6r©r)r*r+r8r9r;r,©r8r+r—r=Úright©Úoutwardé<r3r4r5r7r2r>r?rArBrCrDrErFrGzvo2_pulse_chart.pngrJrI©rMrL)rNrOrPrQrRrSrTrUrVrXrZrWr[ÚspinesÚ set_positionr\r]r^r_r`rarbrcrdrrerfrrg©r rrrirjrkrlÚax3rmrnrorpÚlines3Úlabels3rqs r Úgenerate_vo2_pulse_chartz'GraphGenerator.generate_vo2_pulse_chartsOð ×/°wÐØÑ ä
˜7Õk‰k‹mˆô ØØØõ 
ð  Ð Ð ˜SˆÔi‰i‹kˆÜ ØØØ ØØØØ
ð ÐˆÔ ˜S¨UˆÔ Ð4°qÑi‰i‹kˆØ
×Ô ØØØØØØØõ
ð w gˆÔ ˜S¨WˆÔ ˜7™ ŸÓ)¨AÑ ”r—yy  B x¡L×$4Ñ$4Ó$6¸Ñ$<¸ >‰>Ô Ø N‰NÓ × >‰>Ô Ø N‰NÓ × >‰>Ô Ø N‰NÓ × ×9‰ˆØ×9‰ˆØ×9‰ˆØ
Ø V‰O˜ $ Ñ&7¸'Ñ&AÀ|ð ô
ô
ˆ{Ó ˜qÒ Ø K‰K˜˜; q™>°¸Kˆ K‰K˜  A™¨ °A©¸cȈKÔ K‰K˜  A™¨ °A©¸cȈKÔ K‰K˜  A™¨¨8© ×(8Ñ(8Ó(:À#ÈVˆ —__Ð'<Ñ<ˆ
Ü J¨G¸Õ ‰ Œ á4Bˆt×$ ZÓÈJËÐWrc
óx|jd¬«}|dj«}tjd¬«tj«}t j |ddd¬«|jd «|jd«|jd
|dj«d z«|jd d
¬«|j«}|jtjd
|dj«dzd««t j |ddd|ddd¬«|jd
|dj«d z«|jd«|j!«j#«|j!«j#«|j%«\}}|j%«\} }
|j'|| z||
zd¬«t)|«dk\rw|j+d
|d dd¬«|j+|d |ddd¬«|j+|d|ddd¬«|j+|d|dj«dd¬«|j,dz } tj.| d d!¬"«tj0«|r|j3| «St5| «S)#a
Generate VO2 per Breath chart.
Args:
df: Processed DataFrame with smoothed columns
save_as_base64: If True, return base64 string, else return file path
Returns:
Base64 string or file path
rr r"r#r&zVO2 Breath_smoothedzVO2 per Breath (mL/breath)r(r-rr=Tr.r/r2r3r4r5r6r7r>r?rArBrCrDrErFrGrHzvo2_breath_chart.pngrJrI)rNrOrPrQrRrSrTrUrVrXrZrWr[r\r]r^r_r`rarbrcrdrrerfrrgrhs r Úgenerate_vo2_breath_chartz(GraphGenerator.generate_vo2_breath_chartqs^ð ×/°wÐØÑ ä
˜7Õk‰k‹mˆä ØØØ
ð  Ð Ð1×7¸ ˜SˆÔi‰i‹kˆØ ”r—yy  B x¡L×$4Ñ$4Ó$6¸Ñ$<¸ ØØØØØØØõ
ð ˜7™ ŸÓ)¨AÑ ð Ó×ÑÔ Ó×ÑÔ×9‰ˆØ×9‰ˆØ
6˜F? G¨gÑ$5¸<ˆ
Ô ˆ{Ó ˜qÒ Ø K‰K˜˜; q™>°¸Kˆ K‰K˜  A™¨ °A©¸cȈKÔ K‰K˜  A™¨ °A©¸cȈKÔ K‰K˜  A™¨¨8© ×(8Ñ(8Ó(:À#ÈVˆ —__Ð'=Ñ=ˆ
Ü J¨G¸Õ ‰ Œ á4Bˆt×$ ZÓÈJËÐWrcó|jd¬«}|dj«}tjd¬«tj«}t j |ddd¬«|jd «|jd
«|jd d ¬
«|j«}|jtjd|dj«dzd««t j |ddd|d¬«|jd«|jdd«|j!«j#«|j!«j#«|j%«\}}|j%«\} }
|j'|| z||
zd¬«t)|«dk\rw|j+d|ddd¬«|j+|d|ddd¬«|j+|d|ddd¬«|j+|d|dj«dd ¬«|j,d!z } tj.| d"d#¬$«tj0«|r|j3| «St5| «S)%a
Generate fat metabolism chart (CHO vs FAT over time).
Args:
df: Processed DataFrame with smoothed columns
save_as_base64: If True, return base64 string, else return file path
Returns:
Base64 string or file path
rr r"r#r&Ú CHO_smoothedzCHO (kcal/min)r(r-z CHO (g/min)Tr.r/rr2Ú FAT_smoothedr4zFAT (kcal/min))r)r*r+r8r9r,rvr>r?rAr=rBrCrDr6rErFrGrHzfat_metabolism_chart.pngrJrI)rNrOrPrQrRrSrTrUrVrWr[r\r]r^rZrXr_r`rarbrcrdrrerfrrgrhs r Úgenerate_fat_metabolism_chartz,GraphGenerator.generate_fat_metabolism_chart³s!ð ×/°wÐØÑ ä
˜7Õk‰kmˆô ˜" ¨NÐBRÕ   ˜SˆÔi‰i‹kˆØ ”r—yy  B x¡L×$4Ñ$4Ó$6¸Ñ$<¸ ØØØØØØ

ð Ð Ôð Ó×ÑÔ Ó×ÑÔ×9‰ˆØ×9‰ˆØ
6˜F? G¨gÑ$5¸<ˆ
Ô ˆ{Ó ˜qÒ Ø K‰K˜˜; q™>°¸Kˆ K‰K˜  A™¨ °A©¸cȈKÔ K‰K˜  A™¨ °A©¸cȈKÔ K‰K˜  A™¨¨8© ×(8Ñ(8Ó(:À#ÈVˆ —__Ð'AÑAˆ
Ü J¨G¸Õ ‰ Œ á4Bˆt×$ ZÓÈJËÐWrc ó¸|jd¬«}|dj«}tjd¬«tj«}t j |dddd¬ «|jd
«|jd «|jd |d
j««|jdd¬«|j«}t j |ddd|dd¬«|jdd¬«|j|dj«|dj«dz«|jdd¬«|j«}|jdj!d«t j |ddd|dd¬«|jdd¬«|jdd¬«|jd |dj«dz«|j#t%j&d |dj«dzd««|j)«r|j)«j+«|j)«r|j)«j+«|j)«r|j)«j+«|j-«\}} |j-«\}
} |j-«\} }
|j/||
z| z| | z|
zd ¬!«t1|«d"k\rw|j3d |dd#d$¬%«|j3|d|dd#d&¬%«|j3|d|d'd#d(¬%«|j3|d'|dj«d#d¬%«|j4d)z }tj6|d*d+¬,«tj8«|r|j;|«St=|«S)-a
Generate recovery chart (VCO2, HR, and BF).
Args:
df: Processed DataFrame with smoothed columns
save_as_base64: If True, return base64 string, else return file path
Returns:
Base64 string or file path
rr r"r#r&zVCO2(ml/min)_smoothedz
VCO2 (ml/min)rHr-rz VCO2(ml/min)Tr.r/r“r6rr=r+r—zBF(bpm)_smoothedr4zBF (bpm)r2r>r?rArBrCrDrErFrGzrecovery_chart.pngrJrI)rNrOrPrQrRrSrTrUrVrXrZrWr[rYr\r]r^r_r`rarbrcrdrrerfrrgs r Úgenerate_recovery_chartz&GraphGenerator.generate_recovery_chartîs_ð ×/°wÐØÑ ä
˜7Õk‰k‹mˆô ØØØõ 
ð  Ð ˜>Ñ ˜SˆÔi‰i‹kˆÜ ØØØ ØØØØ
ð ÐˆÔ +×1°2Ð6HÑ3I×3MÑ3MÓ3OÐRSÑ3SÔ ˜S¨UˆÔi‰i‹kˆØ
×Ô ØØØ ØØØØõ
ð ˆÔ ˜S¨WˆÔ Ð4°qÑ ”r—yy  B x¡L×$4Ñ$4Ó$6¸Ñ$<¸ >‰>Ô Ø N‰NÓ × >‰>Ô Ø N‰NÓ × >‰>Ô Ø N‰NÓ × ×9‰ˆØ×9‰ˆØ×9‰ˆØ
Ø V‰O˜ $ Ñ&7¸'Ñ&AÀ|ð ô
ô
ˆ{Ó ˜qÒ Ø K‰K˜˜; q™>°¸Kˆ K‰K˜  A™¨ °A©¸cȈKÔ K‰K˜  A™¨ °A©¸cȈKÔ K‰K˜  A™¨¨8© ×(8Ñ(8Ó(:À#ÈVˆ —__Ð';Ñ;ˆ
Ü J¨G¸Õ ‰ Œ á4Bˆt×$ ZÓÈJËÐWrÚ fat_mass_lbsÚ
lean_mass_lbscó\||z}||z dz}||z dz}||g}ddg}tjd¬«tj|ddtdd ¬
«|ddg¬ «tjd d
d|dd|ddddddtddd¬«¬«tjd
d d|dd|ddddddtddd¬«¬«tj
d«|j dz } tj| dd¬«tj«|r|j| «St| «S) a-
Generate body composition donut chart.
Args:
fat_mass_lbs: Fat mass in pounds
lean_mass_lbs: Lean mass in pounds
save_as_base64: If True, return base64 string, else return file path
Returns:
Base64 string or file path
rxz#fde3acz#ff9966)r1r1r&réZrÚw)r|Ú edgecolor)ÚautopctÚ
startangleÚ
wedgepropsÚcolorsÚlabelsrur=z
Fat Mass (rƒzlbs)
úr†r„z
round,pad=0.3r‡ry)ÚboxstyleÚ facecolorr0)rrˆr‰Úbboxz Lean Mass (Úequalzbody_composition_chart.pngrJiX) rPrQÚpieÚdictr¯r˜rrerfrrg)
r rÚ total_weightÚfat_percentageÚlean_percentageÚsizesrçrqs
r Úgenerate_body_composition_chartz.GraphGenerator.generate_body_composition_chartJsQð$ 3ˆ ØÑ5¸Ñ<ˆØ(¨<Ñ7¸>ˆà Ð1ˆØ˜'ˆä
˜ Ø ØØÜ #°Ôؘ

ô Ø Ø
ؘ *¨&°ÀÐ0DÀAÐ ØØØÜ˜¸'ÈÔ
ô Ø
Ø Ø˜-¨Ð,¨F°?À3Ð2GÀqÐ ØØØÜ˜¸'ÈÔ
ô Ôà—__Ð'CÑCˆ
Ü J¨G¸Õ ‰ Œ á4Bˆt×$ ZÓÈJËÐWrÚageÚgenderc
ó.d|cxkrdkrnnd}n$d|cxkrdkrnnd}nd|cxkrdkrnnd }nd}|d
|d j«d }|j«d
k(rgd¢}ngd¢}tjd¬«\}} |D]\}
} } | j d | | d|
dd¬«Œ | j |ddddd| j
«¬«| jd d«| jtd dd««| jg«| jdd || j«dd d!¬"«td dd«}
| j|
«|
Dcgc]}|d#Œ }}| j|«| jd jd«| jd$jd«| jd%jd«| jd&jd'«td dd«D]*}| j ||gdd(gd| j
«d¬)«Œ,tj «|j"d*z }tj$|d+d,¬-«tj&«|r|j)|«St+|«Scc}w).aS
Generate body fat percentage chart.
Args:
fat_percentage: Body fat percentage
age: Patient age
gender: Patient gender ('male' or 'female')
save_as_base64: If True, return base64 string, else return file path