Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -317,6 +317,17 @@ def find_float_after_label(text: str, label: str, max_numbers: int = 2, window:
|
|
| 317 |
pass
|
| 318 |
return out
|
| 319 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 320 |
|
| 321 |
def parse_zebris_pdf(uploaded_pdf):
|
| 322 |
text = extract_text_from_pdf(uploaded_pdf)
|
|
@@ -347,90 +358,71 @@ def parse_zebris_pdf(uploaded_pdf):
|
|
| 347 |
"fore_peak_time_pct_d": np.nan,
|
| 348 |
}
|
| 349 |
|
| 350 |
-
|
|
|
|
|
|
|
|
|
|
| 351 |
|
| 352 |
def to_float(x):
|
| 353 |
return float(x.replace(",", "."))
|
| 354 |
|
| 355 |
-
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
| 362 |
-
|
| 363 |
-
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
|
| 367 |
-
|
| 368 |
-
|
| 369 |
-
|
| 370 |
-
|
| 371 |
-
r"Heel \(Three zones\) Gauche Droite (\d+,\d+|\d+\.\d+)\±.*?(\d+,\d+|\d+\.\d+)\±",
|
| 372 |
-
text_flat,
|
| 373 |
-
flags=re.S
|
| 374 |
-
)
|
| 375 |
-
if m:
|
| 376 |
-
data["fore_force_g"] = to_float(m.group(1))
|
| 377 |
-
data["fore_force_d"] = to_float(m.group(2))
|
| 378 |
-
data["mid_force_g"] = to_float(m.group(3))
|
| 379 |
-
data["mid_force_d"] = to_float(m.group(4))
|
| 380 |
-
data["heel_force_g"] = to_float(m.group(5))
|
| 381 |
-
data["heel_force_d"] = to_float(m.group(6))
|
| 382 |
-
|
| 383 |
-
# 3) Pression maximale, N/cm²
|
| 384 |
-
m = re.search(
|
| 385 |
-
r"Pression maximale, N/cm² .*?"
|
| 386 |
-
r"Forefoot \(Three zones\) Gauche Droite (\d+,\d+|\d+\.\d+)\±.*?(\d+,\d+|\d+\.\d+)\±.*?"
|
| 387 |
-
r"Midfoot \(Three zones\) Gauche Droite (\d+,\d+|\d+\.\d+)\±.*?(\d+,\d+|\d+\.\d+)\±.*?"
|
| 388 |
-
r"Heel \(Three zones\) Gauche Droite (\d+,\d+|\d+\.\d+)\±.*?(\d+,\d+|\d+\.\d+)\±",
|
| 389 |
-
text_flat,
|
| 390 |
-
flags=re.S
|
| 391 |
-
)
|
| 392 |
-
if m:
|
| 393 |
-
data["fore_pressure_g"] = to_float(m.group(1))
|
| 394 |
-
data["fore_pressure_d"] = to_float(m.group(2))
|
| 395 |
-
data["mid_pressure_g"] = to_float(m.group(3))
|
| 396 |
-
data["mid_pressure_d"] = to_float(m.group(4))
|
| 397 |
-
data["heel_pressure_g"] = to_float(m.group(5))
|
| 398 |
-
data["heel_pressure_d"] = to_float(m.group(6))
|
| 399 |
-
|
| 400 |
-
# 4) Instant pic de force, % de phase d'appui
|
| 401 |
-
m = re.search(
|
| 402 |
-
r"Instant pic de force, % de phase d'appui .*?"
|
| 403 |
-
r"Forefoot \(Three zones\) Gauche Droite (\d+,\d+|\d+\.\d+)\±.*?(\d+,\d+|\d+\.\d+)\±.*?"
|
| 404 |
-
r"Midfoot \(Three zones\) Gauche Droite (\d+,\d+|\d+\.\d+)\±.*?(\d+,\d+|\d+\.\d+)\±.*?"
|
| 405 |
-
r"Heel \(Three zones\) Gauche Droite (\d+,\d+|\d+\.\d+)\±.*?(\d+,\d+|\d+\.\d+)\±",
|
| 406 |
-
text_flat,
|
| 407 |
-
flags=re.S
|
| 408 |
-
)
|
| 409 |
-
if m:
|
| 410 |
-
data["fore_peak_time_pct_g"] = to_float(m.group(1))
|
| 411 |
-
data["fore_peak_time_pct_d"] = to_float(m.group(2))
|
| 412 |
-
data["mid_peak_time_pct_g"] = to_float(m.group(3))
|
| 413 |
-
data["mid_peak_time_pct_d"] = to_float(m.group(4))
|
| 414 |
-
data["heel_peak_time_pct_g"] = to_float(m.group(5))
|
| 415 |
-
data["heel_peak_time_pct_d"] = to_float(m.group(6))
|
| 416 |
|
| 417 |
-
|
| 418 |
-
|
|
|
|
| 419 |
|
|
|
|
|
|
|
| 420 |
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
r"Personne:\s*([A-Za-zÀ-ÿ\- ]+)",
|
| 425 |
-
]
|
| 426 |
|
| 427 |
-
|
| 428 |
-
|
| 429 |
-
|
| 430 |
-
|
| 431 |
|
| 432 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 433 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 434 |
|
| 435 |
def estimate_attack_from_pdf(pdf_data: dict):
|
| 436 |
heel_peak_t = avg(pdf_data.get("heel_peak_time_pct_g"), pdf_data.get("heel_peak_time_pct_d"))
|
|
@@ -1216,6 +1208,7 @@ if uploaded_pdfs:
|
|
| 1216 |
for pdf in uploaded_pdfs:
|
| 1217 |
try:
|
| 1218 |
pdfs_data.append(parse_zebris_pdf(pdf))
|
|
|
|
| 1219 |
except Exception as e:
|
| 1220 |
st.warning(f"{pdf.name} : erreur lecture PDF ({e})")
|
| 1221 |
|
|
|
|
| 317 |
pass
|
| 318 |
return out
|
| 319 |
|
| 320 |
+
def extract_pdf_name(text: str):
|
| 321 |
+
patterns = [
|
| 322 |
+
r"Personne:\s*([A-Za-zÀ-ÿ\- ]+),\s*\d{2}/\d{2}/\d{4}",
|
| 323 |
+
r"Personne:\s*([A-Za-zÀ-ÿ\- ]+)",
|
| 324 |
+
]
|
| 325 |
+
for pattern in patterns:
|
| 326 |
+
m = re.search(pattern, text, flags=re.S)
|
| 327 |
+
if m:
|
| 328 |
+
return m.group(1).strip()
|
| 329 |
+
return None
|
| 330 |
+
|
| 331 |
|
| 332 |
def parse_zebris_pdf(uploaded_pdf):
|
| 333 |
text = extract_text_from_pdf(uploaded_pdf)
|
|
|
|
| 358 |
"fore_peak_time_pct_d": np.nan,
|
| 359 |
}
|
| 360 |
|
| 361 |
+
# On normalise le texte pour éviter les problèmes de retours ligne / espaces
|
| 362 |
+
text_flat = re.sub(r"\s+", " ", text).replace("\xa0", " ").strip()
|
| 363 |
+
|
| 364 |
+
num = r"(\d+,\d+|\d+\.\d+|\d+)"
|
| 365 |
|
| 366 |
def to_float(x):
|
| 367 |
return float(x.replace(",", "."))
|
| 368 |
|
| 369 |
+
def extract_pair(section_label, sub_label=None):
|
| 370 |
+
"""
|
| 371 |
+
Extrait une paire Gauche / Droite du type :
|
| 372 |
+
... Gauche Droite 1066,5±67,8 1040,5±49,3 ...
|
| 373 |
+
"""
|
| 374 |
+
if sub_label:
|
| 375 |
+
pattern = (
|
| 376 |
+
rf"{re.escape(section_label)}.*?"
|
| 377 |
+
rf"{re.escape(sub_label)}\s+Gauche\s+Droite\s+"
|
| 378 |
+
rf"{num}\s*±\s*{num}\s+{num}\s*±\s*{num}"
|
| 379 |
+
)
|
| 380 |
+
else:
|
| 381 |
+
pattern = (
|
| 382 |
+
rf"{re.escape(section_label)}\s+Gauche\s+Droite\s+"
|
| 383 |
+
rf"{num}\s*±\s*{num}\s+{num}\s*±\s*{num}"
|
| 384 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 385 |
|
| 386 |
+
m = re.search(pattern, text_flat, flags=re.S)
|
| 387 |
+
if not m:
|
| 388 |
+
return np.nan, np.nan
|
| 389 |
|
| 390 |
+
# groupes 1 et 3 = valeurs moyennes G / D
|
| 391 |
+
return to_float(m.group(1)), to_float(m.group(3))
|
| 392 |
|
| 393 |
+
# 1) Transition (section spécifique)
|
| 394 |
+
tg, td = extract_pair("Instant du passage du talon vers l'avant-pied, s")
|
| 395 |
+
data["transition_g"], data["transition_d"] = tg, td
|
|
|
|
|
|
|
| 396 |
|
| 397 |
+
# 2) Forces max
|
| 398 |
+
fg, fd = extract_pair("Force maximale, N", "Forefoot (Three zones)")
|
| 399 |
+
mg, md = extract_pair("Force maximale, N", "Midfoot (Three zones)")
|
| 400 |
+
hg, hd = extract_pair("Force maximale, N", "Heel (Three zones)")
|
| 401 |
|
| 402 |
+
data["fore_force_g"], data["fore_force_d"] = fg, fd
|
| 403 |
+
data["mid_force_g"], data["mid_force_d"] = mg, md
|
| 404 |
+
data["heel_force_g"], data["heel_force_d"] = hg, hd
|
| 405 |
+
|
| 406 |
+
# 3) Pressions max
|
| 407 |
+
fpg, fpd = extract_pair("Pression maximale, N/cm²", "Forefoot (Three zones)")
|
| 408 |
+
mpg, mpd = extract_pair("Pression maximale, N/cm²", "Midfoot (Three zones)")
|
| 409 |
+
hpg, hpd = extract_pair("Pression maximale, N/cm²", "Heel (Three zones)")
|
| 410 |
+
|
| 411 |
+
data["fore_pressure_g"], data["fore_pressure_d"] = fpg, fpd
|
| 412 |
+
data["mid_pressure_g"], data["mid_pressure_d"] = mpg, mpd
|
| 413 |
+
data["heel_pressure_g"], data["heel_pressure_d"] = hpg, hpd
|
| 414 |
|
| 415 |
+
# 4) Timing pic de force
|
| 416 |
+
ftg, ftd = extract_pair("Instant pic de force, % de phase d'appui", "Forefoot (Three zones)")
|
| 417 |
+
mtg, mtd = extract_pair("Instant pic de force, % de phase d'appui", "Midfoot (Three zones)")
|
| 418 |
+
htg, htd = extract_pair("Instant pic de force, % de phase d'appui", "Heel (Three zones)")
|
| 419 |
+
|
| 420 |
+
data["fore_peak_time_pct_g"], data["fore_peak_time_pct_d"] = ftg, ftd
|
| 421 |
+
data["mid_peak_time_pct_g"], data["mid_peak_time_pct_d"] = mtg, mtd
|
| 422 |
+
data["heel_peak_time_pct_g"], data["heel_peak_time_pct_d"] = htg, htd
|
| 423 |
+
|
| 424 |
+
data["attaque_pdf"] = estimate_attack_from_pdf(data)
|
| 425 |
+
return data
|
| 426 |
|
| 427 |
def estimate_attack_from_pdf(pdf_data: dict):
|
| 428 |
heel_peak_t = avg(pdf_data.get("heel_peak_time_pct_g"), pdf_data.get("heel_peak_time_pct_d"))
|
|
|
|
| 1208 |
for pdf in uploaded_pdfs:
|
| 1209 |
try:
|
| 1210 |
pdfs_data.append(parse_zebris_pdf(pdf))
|
| 1211 |
+
st.write(pdfs_data[-1])
|
| 1212 |
except Exception as e:
|
| 1213 |
st.warning(f"{pdf.name} : erreur lecture PDF ({e})")
|
| 1214 |
|