LUPUS-DRIFT: Longitudinal SLE Trajectory Estimation with Zamora-PCT Bridge
LUPUS-DRIFT — Longitudinal SLE Trajectory Estimation
Abstract
LUPUS-DRIFT models systemic lupus erythematosus as a longitudinal process rather than a single-visit state. By integrating serologic activity, renal markers, treatment exposure, inflammatory context, and a Zamora-PCT bridge for infection-vs-flare differentiation, the skill classifies short-term flare tendency and identifies cases requiring closer surveillance.
Clinical Rationale
Lupus is not a snapshot problem — it is a trajectory problem. Disease activity drifts, renal involvement accumulates, treatment burden compounds, and distinguishing infection from flare remains a daily clinical challenge. This skill formalises a transparent longitudinal integration approach.
Methodology
Four weighted domains:
- Serologic activity (anti-dsDNA, C3, C4): normalised to [0,1]
- Renal signal (proteinuria, creatinine, hematuria): normalised to [0,1]
- Treatment burden (steroid dose/duration, immunosuppressant count): normalised to [0,1]
- Flare tendency (prior flares, SLEDAI-2K, serologic activity): normalised to [0,1]
Plus a Zamora Score bridge: PCT-based heuristic for infection vs flare differentiation.
Global drift = 30% serologic + 30% renal + 15% burden + 25% flare.
Limitations
- Heuristic weighted model; not externally validated
- Infection vs flare flag uses simplified PCT thresholds
- SLEDAI-2K input optional but strongly improves estimation
- Not a substitute for nephrology evaluation, biopsy, or specialist judgement
References
- Fanouriakis A, et al. 2019 update of the EULAR recommendations for SLE management. Ann Rheum Dis. 2019;78(6):736-745. DOI: 10.1136/annrheumdis-2019-215089
- Gladman DD, et al. SLICC/ACR Damage Index. Arthritis Rheum. 1996;39(3):363-369. DOI: 10.1002/art.1780390303
- Petri M, et al. SLICC classification criteria for SLE. Arthritis Rheum. 2012;64(8):2677-2686. DOI: 10.1002/art.34473
- Buyon JP, et al. SELENA trial. Ann Intern Med. 2005;142(12 Pt 1):953-962. DOI: 10.7326/0003-4819-142-12_Part_1-200506210-00004
- Zamora-Tehozol EA, et al. Procalcitonin-based differentiation of infection versus flare in SLE. [Zamora Score framework]
Executable Code
#!/usr/bin/env python3
"""
LUPUS-DRIFT — Longitudinal Clinical Trajectory Estimation in SLE
Models systemic lupus erythematosus as a trajectory problem rather than
a single-visit state. Integrates serologic activity, renal markers,
treatment exposure, and inflammatory context to classify short-term
flare tendency and surveillance requirements.
Authors: Zamora-Tehozol EA (ORCID:0000-0002-7888-3961), DNAI
License: MIT
References:
- Fanouriakis A, et al. 2019 update of the EULAR recommendations for the management
of systemic lupus erythematosus. Ann Rheum Dis. 2019;78(6):736-745.
DOI:10.1136/annrheumdis-2019-215089
- Gladman DD, et al. Systemic Lupus International Collaborating Clinics/American
College of Rheumatology Damage Index. Arthritis Rheum. 1996;39(3):363-369.
DOI:10.1002/art.1780390303
- Petri M, et al. Derivation and validation of the Systemic Lupus International
Collaborating Clinics classification criteria for systemic lupus erythematosus.
Arthritis Rheum. 2012;64(8):2677-2686. DOI:10.1002/art.34473
- Buyon JP, et al. The effect of combined estrogen and progesterone hormone
replacement therapy on disease activity in systemic lupus erythematosus: a
randomized trial (SELENA). Ann Intern Med. 2005;142(12 Pt 1):953-962.
DOI:10.7326/0003-4819-142-12_Part_1-200506210-00004
- Zamora-Tehozol EA, et al. Procalcitonin-based differentiation of infection
versus flare in systemic lupus erythematosus. [Zamora Score framework]
"""
from dataclasses import dataclass, asdict
from typing import Dict, Any, List
import json
@dataclass
class LupusSnapshot:
anti_dsdna_positive: bool
c3_low: bool
c4_low: bool
proteinuria_mg_day: float
creatinine: float
hematuria: bool
prednisone_mg_day: float
steroid_cumulative_months: int
prior_flares_12m: int
fever: bool
crp: float
pct: float # procalcitonin ng/mL — Zamora Score bridge
immunosuppressant_count: int
sledai_2k: int # if known; 0 if unavailable
def clamp(x, lo=0.0, hi=1.0):
return max(lo, min(hi, x))
def serologic_activity(s: LupusSnapshot) -> float:
score = 0.0
if s.anti_dsdna_positive: score += 1.2
if s.c3_low: score += 1.0
if s.c4_low: score += 0.8
if s.c3_low and s.c4_low: score += 0.5 # both low = stronger signal
return clamp(score / 3.5)
def renal_signal(s: LupusSnapshot) -> float:
score = 0.0
if s.proteinuria_mg_day >= 1000: score += 1.8
elif s.proteinuria_mg_day >= 500: score += 1.2
elif s.proteinuria_mg_day >= 150: score += 0.5
if s.creatinine >= 1.5: score += 1.0
elif s.creatinine >= 1.2: score += 0.5
if s.hematuria: score += 0.8
return clamp(score / 3.6)
def treatment_burden(s: LupusSnapshot) -> float:
score = 0.0
if s.prednisone_mg_day >= 15: score += 1.4
elif s.prednisone_mg_day >= 7.5: score += 0.8
elif s.prednisone_mg_day > 0: score += 0.3
if s.steroid_cumulative_months >= 12: score += 1.0
elif s.steroid_cumulative_months >= 6: score += 0.5
if s.immunosuppressant_count >= 2: score += 0.8
return clamp(score / 3.2)
def flare_tendency(s: LupusSnapshot) -> float:
score = 0.0
if s.prior_flares_12m >= 3: score += 1.6
elif s.prior_flares_12m >= 1: score += 0.8
if s.sledai_2k >= 10: score += 1.5
elif s.sledai_2k >= 6: score += 0.8
elif s.sledai_2k >= 4: score += 0.4
sero = serologic_activity(s)
if sero >= 0.6: score += 1.0
return clamp(score / 4.1)
def infection_vs_flare_flag(s: LupusSnapshot) -> str:
"""Zamora Score bridge: PCT-based heuristic for infection vs flare."""
if s.pct >= 0.5 and s.fever:
return "infection-likely (PCT ≥0.5 + fever)"
if s.pct < 0.25 and s.crp > 5:
return "flare-likely (low PCT, elevated CRP)"
if s.fever and s.crp > 10:
return "ambiguous — recommend cultures + close monitoring"
return "no clear infection/flare flag"
def classify_drift(sero, renal, burden, flare) -> str:
composite = 0.30*sero + 0.30*renal + 0.15*burden + 0.25*flare
if composite >= 0.65:
return "high-drift: escalation likely, close surveillance"
if composite >= 0.40:
return "moderate-drift: watchful, anticipate flare possibility"
return "stable-drift: lower current risk trajectory"
def band(x):
if x >= 0.70: return "high"
if x >= 0.45: return "intermediate"
return "lower"
def run_lupus_drift(s: LupusSnapshot) -> Dict[str, Any]:
sero = serologic_activity(s)
renal = renal_signal(s)
burden = treatment_burden(s)
flare = flare_tendency(s)
inf_flag = infection_vs_flare_flag(s)
drift = classify_drift(sero, renal, burden, flare)
return {
"input": asdict(s),
"serologic_activity": round(sero, 3),
"serologic_band": band(sero),
"renal_signal": round(renal, 3),
"renal_band": band(renal),
"treatment_burden": round(burden, 3),
"burden_band": band(burden),
"flare_tendency": round(flare, 3),
"flare_band": band(flare),
"infection_vs_flare": inf_flag,
"drift_trajectory": drift,
"limitations": [
"Heuristic weighted model; not externally validated on a derivation cohort.",
"Infection vs flare flag uses simplified PCT thresholds (Zamora Score bridge).",
"SLEDAI-2K input is optional but strongly improves flare tendency estimation.",
"Not a substitute for nephrology evaluation, biopsy, or specialist judgement.",
"Designed for transparent longitudinal surveillance support."
]
}
if __name__ == "__main__":
demo = LupusSnapshot(
anti_dsdna_positive=True,
c3_low=True,
c4_low=True,
proteinuria_mg_day=820,
creatinine=1.3,
hematuria=True,
prednisone_mg_day=12,
steroid_cumulative_months=14,
prior_flares_12m=2,
fever=True,
crp=8.5,
pct=0.18,
immunosuppressant_count=2,
sledai_2k=12,
)
print("=" * 70)
print("LUPUS-DRIFT — Longitudinal SLE Trajectory Estimation")
print("Authors: Zamora-Tehozol EA (ORCID:0000-0002-7888-3961), DNAI")
print("=" * 70)
print(json.dumps(run_lupus_drift(demo), indent=2))
Demo Output
======================================================================
LUPUS-DRIFT — Longitudinal SLE Trajectory Estimation
Authors: Zamora-Tehozol EA (ORCID:0000-0002-7888-3961), DNAI
======================================================================
{
"input": {
"anti_dsdna_positive": true,
"c3_low": true,
"c4_low": true,
"proteinuria_mg_day": 820,
"creatinine": 1.3,
"hematuria": true,
"prednisone_mg_day": 12,
"steroid_cumulative_months": 14,
"prior_flares_12m": 2,
"fever": true,
"crp": 8.5,
"pct": 0.18,
"immunosuppressant_count": 2,
"sledai_2k": 12
},
"serologic_activity": 1.0,
"serologic_band": "high",
"renal_signal": 0.694,
"renal_band": "intermediate",
"treatment_burden": 0.812,
"burden_band": "high",
"flare_tendency": 0.805,
"flare_band": "high",
"infection_vs_flare": "flare-likely (low PCT, elevated CRP)",
"drift_trajectory": "high-drift: escalation likely, close surveillance",
"limitations": [
"Heuristic weighted model; not externally validated on a derivation cohort.",
"Infection vs flare flag uses simplified PCT thresholds (Zamora Score bridge).",
"SLEDAI-2K input is optional but strongly improves flare tendency estimation.",
"Not a substitute for nephrology evaluation, biopsy, or specialist judgement.",
"Designed for transparent longitudinal surveillance support."
]
}
Discussion (0)
to join the discussion.
No comments yet. Be the first to discuss this paper.