# 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 1. **Clone or download this repository** 2. **Create a virtual environment** (recommended): ```bash python3 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate ``` 3. **Install dependencies**: ```bash pip install -r requirements.txt ``` The script requires: - `pdfplumber` - PDF text extraction - `pandas` - Data manipulation and CSV handling ## Usage ### Basic Command ```bash python dexa_extract.py --height-in [--weight-lb ] [--outdir ] ``` ### 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:** ```bash python dexa_extract.py data/pdfs/2025-10-06-scan.pdf --height-in 74 --weight-lb 212 --outdir data/results ``` **Batch process multiple scans:** ```bash # 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): ```bash 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 measurements - `Weight_lb_Input`, `DEXA_TotalMass_lb`, `Adjusted_Body_Weight_lb` - Weight data - `BodyFat_percent`, `LeanMass_percent` - Body composition percentages - `FatMass_lb`, `LeanSoftTissue_lb`, `BoneMineralContent_lb`, `FatFreeMass_lb` - Mass measurements - `BMI`, `FFMI`, `FMI`, `LST_Index`, `SMI`, `BMDI` - Normalized indices - `ALM_lb` - Appendicular lean mass (arms + legs) - `VAT_Mass_lb`, `VAT_Volume_in3`, `VAT_Index` - Visceral adipose tissue - `Android_percent`, `Gynoid_percent`, `AG_Ratio` - Fat distribution - `Trunk_to_Limb_Fat_Ratio` - Central adiposity indicator - `Arms_Lean_pct`, `Legs_Lean_pct`, `Trunk_Lean_pct` - Regional lean mass distribution - `Arm_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 name - `FatPercent` - Fat percentage in this region - `LeanPercent` - Lean tissue percentage in this region - `TotalMass_lb` - Total mass of the region - `FatTissue_lb` - Fat mass in the region - `LeanTissue_lb` - Lean mass in the region - `BMC_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 Leg - `FatPercent`, `TotalMass_lb`, `FatMass_lb`, `LeanMass_lb`, `BMC_lb` ### 4. `overall.json` Structured JSON format containing all extracted data in a hierarchical format. **Structure:** ```json { "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) ```bash # 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 ```bash # 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 1. Open `overall.csv` in Excel/Google Sheets to visualize trends 2. Compare `muscle_balance.csv` to track left/right symmetry improvements 3. Review `summary.md` for readable reports of each scan 4. Use `overall.json` for 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-lb` as 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.