Under the hood

How Muscel turns
logs into direction.

Six connected steps — from estimating your baseline strength to projecting where you're headed and adjusting your plan after every session.

1
Baseline 1RM
2
Projection bounds
3
Strength projection
4
Level Recalculation
5
Zero-Sum Rebalancing
6
Routine Generation
Stage 01 + 04
Baseline strength
Estimates your 1RM per exercise from age, bodyweight, gender, and experience level. Updates after every session as your numbers change.
Stage 02 + 06
Plans & bounds
Builds symmetric Conservative and Reach paths around each Realistic target, then assembles a full weekly routine matched to your goal and schedule.
Stage 03 + 05
Progression & balance
Fits your training history and projects it forward. Rebalances volume so weaker lifts get more attention without changing total work for the day.

1 Stage One

Estimating your baseline 1RM

Before any projection can be built, Muscel needs your estimated one-rep max for each exercise. A regression model trained on structured baseline data predicts it from five inputs.

Exercise — one of 49 preset lifts across 6 muscle groups
Age — normalized against dataset max for scale invariance
Bodyweight — converted to kg and normalized; missing values are filled from related patterns in the data
Gender — encoded as a categorical feature
Level — a decimal 1.0–5.0 scale mapping Beginner through Elite
Regression model 500 estimators lr = 0.05 max_depth = 6 70/15 train/val split
predict_user_1rm()
Inputs
exercise = "Barbell Bench Press"
user_level = 2.5 # 1.0 → 5.0
age = 22
bodyweight = 180 # lbs
gender = "Male"
Model config
baseline_model = XGBRegressor(
  n_estimators=500,
  learning_rate=0.05,
  max_depth=6,
  subsample=0.8
)
Output
predicted_1rm_lbs = 187.40
Level 1.0
Beginner
Level 2.0
Novice
Level 3.0
Intermediate
Level 4.0
Advanced

2 Stage Two

Building your projection bounds

Once the Realistic 1RM baseline is set, Muscel defines mathematically symmetric Conservative and Reach bounds around it. An appropriate variance (typically 7–10%) is chosen per exercise so the gap between Conservative and Realistic always matches the gap between Realistic and Reach.

Symmetric spacing — Conservative and Reach sit equally far from Realistic
Per-exercise variance — tuned to the movement, not one-size-fits-all
Variance: 7–10% — applied based on each lift's profile
Fallback — if bounds can't be generated, a fixed ±8% is applied automatically
Conservative · Realistic · Reach Symmetric bounds Per-exercise variance ±7–10%
generate_symmetric_1rm_stages()
The symmetry rule
Reach Realistic == Realistic Conservative
Calculation (example: 8.5% variance)
Realistic  = 187.40 lbs
Conservative = 187.40 × 0.915 = 171.47 lbs
Reach         = 187.40 × 1.085 = 203.33 lbs
Projection bounds — Barbell Bench Press
Conservative 171.47 lbs
Realistic 187.40 lbs
Reach 203.33 lbs

3 Stage Three

Projecting your curve forward

As you log workouts, Muscel calculates your average estimated 1RM per session using the Epley formula, then fits a logarithmic curve to your history. That curve is extrapolated forward across all three projection tracks. EMA (Exponential Moving Average) determines the expected gap between your sessions to space predictions correctly in time.

Epley 1RM — weight × (1 + reps ÷ 30), computed per set, averaged per day
Log curve — f(t) = a · ln(t + 1) + b, fitted via SciPy curve_fit
EMA spacing — predicts your next session date from training frequency history
Three tracks — Conservative, Realistic, and Reach curves projected simultaneously
Epley formula Logarithmic regression SciPy curve_fit EMA session timing
Projection math
Epley 1RM (per set)
1RM = weight × (1 + reps / 30)
Logarithmic progression curve
def log_component(t, a, b):
  return a × log(t + 1) + b
Mini chart — workout days vs avg 1RM
today

4 Stage Four

Your level adapts after every session

After you log a workout, Muscel doesn't just record the numbers — it compares how you actually performed against what was prescribed. That ratio updates your experience level on a 1.0–5.0 decimal scale, then refreshes 1RM estimates for all your exercises.

Target percentage — the 1RM% the routine was built around (e.g. 80% for hypertrophy)
Actual ratio — actual weight lifted ÷ predicted 1RM = your real intensity
Performance ratio — actual% ÷ target% shows whether you over- or under-performed
New level — performance ratio × current level, clamped between 1.0 and 5.0
Reverse calculation Per-exercise level Clamped 1.0 – 5.0 1RM refresh
calculate_dynamic_levels_and_1rm()
Actual intensity vs target
actual_pct = weight_lifted / predicted_1rm
perf_ratio = actual_pct / target_pct
Level update
new_level = clip(
  perf_ratio × current_level,
  min=1.0, max=5.0
)
1
You log sets. Actual weight ÷ 1RM = actual intensity %
2
Compare to the target % the routine was built on
3
Ratio scales your level up or down proportionally
4
Baseline estimates run again. All 1RM predictions refresh.

5 Stage Five

Shifting volume from strong to weak lifts

After updating your levels, Muscel rebalances your routine using a zero-sum algorithm. It measures relative volume for each exercise — how much work you did relative to your 1RM — and redistributes sets from your strongest lifts to your weakest ones. Total daily volume stays constant. Your weakest movements get more sets; your strongest give some up.

Relative Volume — (weight × reps) ÷ 1RM, averaged across all sets
Daily ranking — exercises sorted weakest to strongest within each training day
Zero-sum transfer — sets move from above-average to below-average exercises
Cap — maximum 3 sets transferred per day to prevent extreme swings
Relative Volume metric Zero-sum pool Max 3 sets shifted/day Per-day ranking
rebalance_routine_from_logs()
Relative volume per set
rv_set = (weight × reps) / predicted_1rm
Example — Tuesday session
Barbell Squat — RV 0.41  ·  Weak → gains 2 sets
Leg Press       — RV 0.67  ·  Strong → gives 2 sets
=
Total volume unchanged. Focus shifted where it's needed.

6 Stage Six

Building your weekly routine

With 1RM values in place, Muscel assembles a full weekly plan from your goal mode and schedule — Conservative, Realistic, and Reach weights and reps for every set, checked against strict rules before anything reaches the app.

Goal modes — Pure Strength, Hypertrophy, Endurance, Power — each with different set/rep/intensity rules
Validated output — every routine must pass structural checks before use
Weight rounding — all generated weights rounded to the nearest 5 lbs for real-world use
Volume balancing — daily relative volume equalized across exercises within each session
Weekly plan Structured output 4 goal modes Rounded to 5 lbs
Goal mode rules
S
Pure Strength — 3–5 sets · 1–5 reps · 90% 1RM · 180–300s rest
H
Hypertrophy   — 3–4 sets · 6–12 reps · 80% 1RM · 60–90s rest
E
Endurance     — 2–3 sets · 15–25 reps · 46% 1RM · 30–45s rest
P
Power         — 3–5 sets · 3–5 reps · 75% 1RM · 120–180s rest
Pydantic schema (excerpt)
class ExerciseRow(BaseModel):
  Exercise: AllowedExercises
  Conservative_Weights: List[int]
  Realistic_Weights: List[int]
  Reach_Weights: List[int]
  Target_Percentage: float

See it in action.

Download Muscel on iPhone and log your first session.

Download on iPhone Back to home