CHANGES: - Added MeasuredDate as first column in regional.csv - Added MeasuredDate as first column in muscle_balance.csv - Updated README to document new column structure BENEFITS: ✅ Track regional changes over time (e.g., Arms fat % across scans) ✅ Easy time-series analysis with pandas/Excel ✅ Filter by date range for progress tracking ✅ Consistent date column across all 3 CSV files ✅ Enables queries like: 'Show me trunk fat % over last 6 months' EXAMPLE USAGE: import pandas as pd regional = pd.read_csv('regional.csv') arms = regional[regional['Region'] == 'Arms'] # Now you can track Arms progress over time! Each scan now adds: - 1 row to overall.csv - 6 rows to regional.csv (one per region) - 6 rows to muscle_balance.csv (one per limb comparison) |
||
|---|---|---|
| data | ||
| .gitattributes | ||
| .gitignore | ||
| dexa_extract.py | ||
| README.md | ||
| requirements.txt | ||
BodySpec Insights
Body composition analytics for BodySpec DEXA scan PDFs
A Python tool to extract and analyze body composition data from BodySpec DEXA scan reports. Automatically parses measurements, computes 30+ derived metrics, and tracks your progress over time.
Note: This tool is specifically designed for BodySpec PDF reports and may not work with other DEXA providers (DexaFit, Hologic, etc.).
Features
- 📊 Comprehensive Data Extraction: Body fat %, lean mass, bone density, regional composition, and more
- 🧮 Derived Metrics: Automatically calculates FFMI, FMI, LSTI, SMI, and other body composition indices
- 📁 Multiple Output Formats: CSV (for spreadsheet analysis), JSON (for programmatic use), and Markdown (for readable summaries)
- 📈 Time-Series Ready: Append mode allows tracking progress across multiple scans
- 🎯 Regional Analysis: Breaks down composition by Arms, Legs, Trunk, Android, and Gynoid regions
- ⚖️ Muscle Balance: Tracks left/right limb symmetry
Installation
Prerequisites
- Python 3.7 or higher
- pip (Python package manager)
Setup
-
Clone or download this repository
-
Create a virtual environment (recommended):
python3 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate -
Install dependencies:
pip install -r requirements.txtThe script requires:
pdfplumber- PDF text extractionpandas- Data manipulation and CSV handling
Usage
Basic Command
python dexa_extract.py <PDF_PATH> --height-in <HEIGHT> [--weight-lb <WEIGHT>] [--outdir <OUTPUT_DIR>]
Required Arguments
PDF_PATH- Path to your DEXA scan PDF report--height-in- Your height in inches
Optional Arguments
--weight-lb- Body weight in pounds (used as fallback if PDF doesn't contain total mass)--outdir- Output directory for results (default:dexa_out)
Examples
Single scan:
python dexa_extract.py data/pdfs/2025-10-06-scan.pdf --height-in 74 --weight-lb 212 --outdir data/results
Batch process multiple scans:
# Process all PDFs in a directory (automatically skips already-processed dates)
python dexa_extract.py --batch data/pdfs --height-in 74 --outdir data/results
# Force reprocessing all files
python dexa_extract.py --batch data/pdfs --height-in 74 --outdir data/results --force
Individual scans (appends to existing files):
python dexa_extract.py data/pdfs/scan-2025-01.pdf --height-in 74 --outdir data/results
python dexa_extract.py data/pdfs/scan-2025-04.pdf --height-in 74 --outdir data/results
python dexa_extract.py data/pdfs/scan-2025-10.pdf --height-in 74 --outdir data/results
Height conversion (for reference):
- 5'8" = 68 inches
- 5'10" = 70 inches
- 6'0" = 72 inches
- 6'2" = 74 inches
- 6'4" = 76 inches
Directory Structure
bodyspec-insights/
├── dexa_extract.py # Main extraction script
├── requirements.txt # Python dependencies
├── README.md # This file
├── .gitignore # Git ignore patterns
├── data/ # Data directory (gitignored)
│ ├── pdfs/ # Place your BodySpec PDF reports here
│ └── results/ # Results will be saved here
└── venv/ # Virtual environment (gitignored)
Output Files
The script generates 5 files in the specified output directory:
1. overall.csv
Time-series data with one row per scan. Includes all primary metrics and derived indices.
Columns:
MeasuredDate- Scan date (YYYY-MM-DD)Height_in,Height_ft_in- Height measurementsWeight_lb_Input,DEXA_TotalMass_lb,Adjusted_Body_Weight_lb- Weight dataBodyFat_percent,LeanMass_percent- Body composition percentagesFatMass_lb,LeanSoftTissue_lb,BoneMineralContent_lb,FatFreeMass_lb- Mass measurementsBMI,FFMI,FMI,LST_Index,SMI,BMDI- Normalized indicesALM_lb- Appendicular lean mass (arms + legs)VAT_Mass_lb,VAT_Volume_in3,VAT_Index- Visceral adipose tissueAndroid_percent,Gynoid_percent,AG_Ratio- Fat distributionTrunk_to_Limb_Fat_Ratio- Central adiposity indicatorArms_Lean_pct,Legs_Lean_pct,Trunk_Lean_pct- Regional lean mass distributionArm_Symmetry_Index,Leg_Symmetry_Index- Left/right balance (50% = perfect)RMR_cal_per_day- Resting metabolic rate
2. regional.csv
Regional body composition breakdown (Arms, Legs, Trunk, Android, Gynoid, Total). Each scan adds 6 rows (one per region).
Columns:
MeasuredDate- Date of scan (YYYY-MM-DD)Region- Body region nameFatPercent- Fat percentage in this regionLeanPercent- Lean tissue percentage in this regionTotalMass_lb- Total mass of the regionFatTissue_lb- Fat mass in the regionLeanTissue_lb- Lean mass in the regionBMC_lb- Bone mineral content in the region
3. muscle_balance.csv
Left/right limb comparison for tracking muscle symmetry. Each scan adds 6 rows (one per region).
Columns:
MeasuredDate- Date of scan (YYYY-MM-DD)Region- Arms Total, Right Arm, Left Arm, Legs Total, Right Leg, Left LegFatPercent,TotalMass_lb,FatMass_lb,LeanMass_lb,BMC_lb
4. overall.json
Structured JSON format containing all extracted data in a hierarchical format.
Structure:
{
"measured_date": "2025-10-06",
"anthropometrics": { ... },
"composition": { ... },
"regional": [ ... ],
"muscle_balance": [ ... ],
"supplemental": { ... },
"bone_density": { ... }
}
5. summary.md
Human-readable Markdown summary of the scan results.
Extracted Metrics
Primary Measurements
- Body Fat % - Percentage of body weight that is fat
- Lean Mass % - Percentage of body weight that is lean tissue (complement of body fat %)
- Fat Mass - Total weight of fat tissue
- Lean Soft Tissue - Muscle, organs, and other non-bone lean tissue
- Bone Mineral Content (BMC) - Total bone mineral weight
- Fat-Free Mass - Total body weight minus fat mass
Derived Indices (Height-Normalized)
- BMI - Body Mass Index (standard weight-to-height ratio)
- FFMI - Fat-Free Mass Index (normalized muscle mass)
- FMI - Fat Mass Index (normalized fat mass)
- LSTI - Lean Soft Tissue Index (height-adjusted lean tissue)
- SMI - Skeletal Muscle Index (height-adjusted appendicular lean mass)
- BMDI - Bone Mineral Density Index (height-adjusted bone content)
- VAT Index - Visceral fat normalized by height
Regional Analysis
- Android - Abdominal/trunk fat (higher risk area)
- Gynoid - Hip/thigh fat (lower risk area)
- A/G Ratio - Android-to-Gynoid ratio (cardiovascular risk indicator)
- Trunk-to-Limb Fat Ratio - Ratio of trunk fat to limb fat (central adiposity indicator)
- Lean Mass Distribution - Percentage of total lean mass in arms, legs, and trunk
Symmetry & Balance
- Arm Symmetry Index - Right-to-left arm lean mass balance (50% = perfect symmetry)
- Leg Symmetry Index - Right-to-left leg lean mass balance (50% = perfect symmetry)
Supplemental
- VAT (Visceral Adipose Tissue) - Deep abdominal fat around organs
- RMR (Resting Metabolic Rate) - Estimated daily calorie burn at rest
- Adjusted Body Weight - Clinical weight used for medication dosing and nutrition calculations
- Bone Density - BMD (g/cm²), T-score, Z-score
Understanding Your Results
Body Fat % Ranges (by age and sex)
Men:
- Athletes: 6-13%
- Fitness: 14-17%
- Average: 18-24%
- Above Average: 25%+
Women:
- Athletes: 14-20%
- Fitness: 21-24%
- Average: 25-31%
- Above Average: 32%+
FFMI (Fat-Free Mass Index)
Normalized measure of muscle mass:
- 16-17: Below average
- 18-20: Average/athletic
- 21-23: Above average/very muscular
- 24-25: Elite natural bodybuilder range
- 26+: Typically requires enhanced training
A/G Ratio (Android/Gynoid Ratio)
Fat distribution indicator:
- < 1.0: Lower risk (more fat in hips/thighs)
- 1.0-1.5: Moderate
- > 1.5: Higher risk (more abdominal fat)
Trunk-to-Limb Fat Ratio
Central adiposity indicator:
- < 1.0: More peripheral fat distribution (healthier)
- 1.0-1.5: Moderate central fat
- > 1.5: High central fat (increased health risk)
Symmetry Indices
Muscle balance between left and right sides:
- 50%: Perfect symmetry
- 48-52%: Normal range (slight asymmetry is common)
- < 48% or > 52%: Notable imbalance (may indicate injury, overuse, or compensation patterns)
VAT Index
Visceral fat normalized by height:
- < 0.30: Low visceral fat
- 0.30-0.50: Moderate
- > 0.50: High (increased metabolic risk)
Lean Mass Distribution
Typical ranges for lean tissue distribution:
- Arms: 13-16% of total lean mass
- Legs: 32-38% of total lean mass
- Trunk: 46-54% of total lean mass
Higher trunk percentage may indicate good core development, while higher leg percentage suggests strong lower body development.
Tracking Progress
The script appends data to existing CSV files, making it easy to track changes over time:
Option 1: Batch Processing (Recommended)
# Place all your PDFs in one directory
data/pdfs/
├── scan-2025-01-15.pdf
├── scan-2025-04-20.pdf
└── scan-2025-10-06.pdf
# Process all at once (automatically skips already-processed dates)
python dexa_extract.py --batch data/pdfs --height-in 74 --outdir data/results
# Add new scans later - only new ones will be processed
cp ~/Downloads/scan-2025-12-15.pdf data/pdfs/
python dexa_extract.py --batch data/pdfs --height-in 74 --outdir data/results
Option 2: Individual Processing
# Process scans as you get them
python dexa_extract.py data/pdfs/scan-2025-01.pdf --height-in 74 --outdir data/results
python dexa_extract.py data/pdfs/scan-2025-04.pdf --height-in 74 --outdir data/results
python dexa_extract.py data/pdfs/scan-2025-10.pdf --height-in 74 --outdir data/results
Analyzing Results
- Open
overall.csvin Excel/Google Sheets to visualize trends - Compare
muscle_balance.csvto track left/right symmetry improvements - Review
summary.mdfor readable reports of each scan - Use
overall.jsonfor programmatic analysis
Privacy & Security
⚠️ Important: DEXA reports contain personal health information (PHI).
- All PDF files and results are excluded from git via
.gitignore - Keep your
data/directory private - Don't commit PDFs or output files to version control
- Consider encrypting your data directory if sharing the repository
Troubleshooting
"Total mass is missing" error
- Ensure your PDF contains a SUMMARY RESULTS table
- Provide
--weight-lbas a fallback
No data extracted or null values
- Verify your PDF is from BodySpec - This tool only works with BodySpec reports
- Ensure the PDF is text-based, not a scanned image
- Check that your BodySpec report includes the "SUMMARY RESULTS" table
- Open an issue with a sample (redacted) PDF for support
Import errors
- Ensure virtual environment is activated:
source venv/bin/activate - Reinstall dependencies:
pip install -r requirements.txt
Contributing
Contributions welcome! Areas for improvement:
- Automatic height detection from PDF
- Data visualization/plotting features
- GUI interface for non-technical users
- Export to additional formats (Excel, SQLite, etc.)
- Support for older BodySpec PDF formats
- Progress bar for batch processing
License
MIT License - feel free to use and modify for personal or commercial use.
Acknowledgments
Built for personal body composition tracking with BodySpec scans. Thanks to BodySpec for providing detailed, consistent DEXA scan reports that make automated analysis possible.
Disclaimer: This is an unofficial, independent tool and is not affiliated with or endorsed by BodySpec.
Questions or issues? Open an issue on GitHub or contact the maintainer.