Troubleshooting & FAQ
Common issues and solutions.
Installation Issues
Q: ImportError: No module named ‘mpspline’
A: Make sure mpspline is installed:
pip install mpspline
Or verify installation:
pip list | grep mpspline
Q: ModuleNotFoundError when importing
A: You may have multiple Python environments. Check you’re using the right one:
which python # See which Python is active
python -m pip install mpspline
Q: Version conflicts with dependencies
A: Install in a clean virtual environment:
python -m venv venv
source venv/bin/activate
pip install mpspline
Data Input Issues
Q: KeyError: ‘horizons’
A: Your input doesn’t have a ‘horizons’ key. The correct structure is:
# ✗ Wrong - no 'horizons' key
data = {'cokey': 123, 'clay': 25}
# ✓ Correct - has 'horizons' key
data = {
'cokey': 123,
'horizons': [
{'upper': 0, 'lower': 20, 'clay': 25}
]
}
Q: KeyError: ‘upper’ or ‘lower’
A: Your horizons don’t have recognized depth fields. Use one of these names:
# These all work:
{'upper': 0, 'lower': 20} # Recommended
{'top': 0, 'bottom': 20}
{'start': 0, 'end': 20}
{'depth_min': 0, 'depth_max': 20}
{'hzdept_r': 0, 'hzdepb_r': 20} # SSURGO standard
# This does NOT work:
{'depth': 0, 'lower': 20} # 'depth' not recognized
Q: ValueError: Horizons must be ordered by depth
A: Your horizons have gaps, overlaps, or invalid depths. Check that:
# ✗ Wrong - overlapping
{'upper': 0, 'lower': 30}
{'upper': 20, 'lower': 50}
# ✓ Correct - sequential
{'upper': 0, 'lower': 20}
{'upper': 20, 'lower': 50}
# ✗ Wrong - inverted
{'upper': 20, 'lower': 10}
# ✓ Correct - ordered
{'upper': 10, 'lower': 20}
Q: TypeError: unhashable type: ‘dict’
A: You may have passed a single profile incorrectly. For a single profile, pass it directly (not in a list):
# ✓ Correct - single profile (dict)
result = mpspline(profile)
# ✗ Don't pass single profile in list
result = mpspline([profile]) # Returns DataFrame, not dict
Output Issues
Q: Output contains NaN values
A: This usually happens when the profile doesn’t extend to those depths:
# Profile only goes to 80cm
profile = {
'horizons': [
{'upper': 0, 'lower': 20, 'clay': 20},
{'upper': 20, 'lower': 80, 'clay': 30}, # Stops at 80cm
]
}
result = mpspline(profile)
# Result will have NaN for 100-200cm because profile doesn't go that deep
Solution: Either extend your profile or use custom depths:
# Option 1: Only use depths your profile covers
result = mpspline(
profile,
target_depths=[(0, 5), (5, 15), (15, 30), (30, 60), (60, 80)]
)
# Option 2: Extend profile with lower horizon
profile['horizons'].append({
'upper': 80,
'lower': 120,
'clay': 28,
})
Q: Predicted values seem unrealistic
A: You may need to add value constraints:
# ✗ Without constraints, clay might go above 100%
result = mpspline(profile)
# ✓ With constraints
result = mpspline(
profile,
var_name=['clay'],
vlow=0.0,
vhigh=100.0
)
Q: Some properties missing from output
A: Non-numeric properties are skipped. Check that your properties are numbers:
horizon = {
'upper': 0,
'lower': 20,
'clay': 25.0, # ✓ Numeric - included
'texture': 'loam', # ✗ String - skipped
'sand': '40.0', # ? String number - may or may not work
}
Solution: Convert to numeric or specify in var_name:
# Option 1: Ensure numeric
horizon['sand'] = float(horizon['sand'])
# Option 2: Specify what to process
result = mpspline(profile, var_name=['clay', 'sand'])
Processing Issues
Q: Processing is very slow
A: Enable parallel processing and optimize batch size:
# Enable parallel processing
df = mpspline(
profiles,
parallel=True, # Use multiple cores
batch_size=500, # Tune batch size
var_name=['clay'], # Process only needed properties
)
Q: Memory error with large dataset
A: Reduce batch size or use parallel processing:
# Smaller batches = less memory
df = mpspline(
profiles,
batch_size=50, # Reduce from default 100
parallel=False, # Single process
)
Q: Parallel processing doesn’t work on Windows
A: Wrap your code in if __name__ == ‘__main__’::
from mpspline import mpspline
if __name__ == '__main__':
df = mpspline(profiles, parallel=True)
Q: Getting errors like “RuntimeError: An attempt has been made…”
A: This usually means the above issue on Windows. Use the if __name__ pattern.
Validation Errors
Q: What does “strict mode” mean?
A:
# Lenient mode (default, strict=False)
# Logs warnings, skips bad profiles, returns results for valid ones
df = mpspline(profiles, strict=False)
# Strict mode (strict=True)
# Raises exception on first error
df = mpspline(profiles, strict=True)
Use strict=True when debugging, strict=False for production.
Q: How do I see validation warnings?
A: Configure Python logging:
import logging
logging.basicConfig(level=logging.WARNING)
result = mpspline(profile, strict=False)
Advanced Issues
Q: Why are results slightly different between runs?
A: Due to floating-point arithmetic, tiny differences (~0.001%) are normal.
Q: How do I compare results with the R mpspline2?
A: Results should be nearly identical (within 0.01%). Small differences are due to: - Python vs R numerical differences - Different random seeds if parallel - Rounding differences in display
Q: What’s the meaning of the ‘lam’ parameter?
A: It’s the smoothing parameter in the spline algorithm. See Parameters for details.
Still Having Issues?
If you’ve tried the above solutions:
Check the full documentation: https://py-mpspline.readthedocs.io
Review the examples in the examples/ directory
Look at the docstrings: help(mpspline.mpspline)
Open an issue on GitHub: https://github.com/brownag/mpspline/issues
When reporting an issue, please include: - Python version: python –version - mpspline version: python -c “import mpspline; print(mpspline.__version__)” - Minimal code that reproduces the issue - Full error message and traceback