Examples
Basic FFT Analysis
import mmpp
import matplotlib.pyplot as plt
# Load simulation data
result = mmpp.MMPP('simulation.zarr')[0]
# Compute FFT spectrum
fft = result.fft
spectrum = fft.spectrum(dset='m_z5-8')
# Plot results
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# Plot spectrum
fft.plot_spectrum(ax=ax1)
ax1.set_title('FFT Spectrum')
# Plot time domain data
time_data = result.root['m_z5-8']
ax2.plot(time_data)
ax2.set_title('Time Domain Signal')
ax2.set_xlabel('Time')
ax2.set_ylabel('Magnetization')
plt.tight_layout()
plt.show()
Batch Processing Workflow
import mmpp
import numpy as np
from pathlib import Path
# Setup paths
data_dir = Path('simulation_results/')
output_dir = Path('analysis_output/')
output_dir.mkdir(exist_ok=True)
# Load all simulations
op = mmpp.MMPP(data_dir)
batch = op[:]
print(f"Processing {len(batch.zarr_results)} simulation files...")
# Batch FFT analysis - use compute_all for batch operations
fft_results = batch.fft.compute_all(
dset='m_z5-8'
)
# Batch mode analysis
mode_results = batch.fft.modes.compute_modes(
dset='m_z5-8',
parallel=True,
progress=True
)
# Extract successful results
successful_ffts = [r for r in fft_results if r['success']]
successful_modes = [r for r in mode_results if r['success']]
print(f"\\nResults:")
print(f" Successful FFT computations: {len(successful_ffts)}")
print(f" Successful mode computations: {len(successful_modes)}")
# Save summary
summary = {
'total_files': len(batch.zarr_results),
'successful_ffts': len(successful_ffts),
'successful_modes': len(successful_modes),
'fft_results': successful_ffts,
'mode_results': successful_modes
}
import json
with open(output_dir / 'analysis_summary.json', 'w') as f:
json.dump(summary, f, indent=2, default=str)
Custom Analysis Function
import mmpp
import numpy as np
def analyze_peak_characteristics(zarr_result):
"""
Custom analysis function to extract peak characteristics
"""
try:
# Get FFT analyzer
fft = zarr_result.fft
# Compute spectrum
spectrum = fft.spectrum(dset='m_z5-8')
frequencies = fft.frequencies()
# Find peaks
from scipy.signal import find_peaks
peaks, properties = find_peaks(
np.abs(spectrum),
height=np.max(np.abs(spectrum)) * 0.1,
distance=10
)
# Extract characteristics
peak_freqs = frequencies[peaks]
peak_heights = np.abs(spectrum[peaks])
return {
'peak_frequencies': peak_freqs.tolist(),
'peak_heights': peak_heights.tolist(),
'dominant_frequency': peak_freqs[np.argmax(peak_heights)],
'num_peaks': len(peaks)
}
except Exception as e:
return {'error': str(e)}
# Apply custom analysis to all files
op = mmpp.MMPP('simulation_results/')
batch = op[:]
# Note: Custom analysis functions would need to be implemented
# For demonstration purposes - this feature may not be available
# custom_results = batch.process_custom(
# analyze_peak_characteristics,
# parallel=True,
# progress=True
# )
# Process results
for result in custom_results:
if 'error' not in result['result']:
analysis = result['result']
print(f"{result['file']}: {analysis['num_peaks']} peaks, "
f"dominant at {analysis['dominant_frequency']:.2f} GHz")
else:
print(f"{result['file']}: Error - {result['result']['error']}")
Advanced Mode Analysis
import mmpp
import matplotlib.pyplot as plt
import numpy as np
# Load data
result = mmpp.MMPP('complex_simulation.zarr')[0]
# Compute modes with different parameters
fft = result.fft
modes_analyzer = fft.modes
# Method 1: Basic mode computation
basic_modes = modes_analyzer.compute_modes(dset='m_z5-8')
# Method 2: Mode computation with custom parameters
advanced_modes = modes_analyzer.compute_modes(
dset='m_z5-8',
method='advanced', # if supported
threshold=0.05
)
# Analyze mode characteristics
print(f"Basic method found {len(basic_modes)} modes")
print(f"Advanced method found {len(advanced_modes)} modes")
# Plot comparison
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
# Plot spectrum
spectrum = fft.spectrum(dset='m_z5-8')
frequencies = fft.frequencies()
axes[0,0].plot(frequencies, np.abs(spectrum))
axes[0,0].set_title('FFT Spectrum')
axes[0,0].set_xlabel('Frequency (GHz)')
axes[0,0].set_ylabel('Amplitude')
# Plot basic modes
if basic_modes:
mode_freqs = [mode.frequency for mode in basic_modes]
mode_amps = [mode.amplitude for mode in basic_modes]
axes[0,1].scatter(mode_freqs, mode_amps, c='red', s=50)
axes[0,1].set_title('Basic Mode Detection')
axes[0,1].set_xlabel('Frequency (GHz)')
axes[0,1].set_ylabel('Amplitude')
# Plot advanced modes
if advanced_modes:
mode_freqs = [mode.frequency for mode in advanced_modes]
mode_amps = [mode.amplitude for mode in advanced_modes]
axes[1,0].scatter(mode_freqs, mode_amps, c='blue', s=50)
axes[1,0].set_title('Advanced Mode Detection')
axes[1,0].set_xlabel('Frequency (GHz)')
axes[1,0].set_ylabel('Amplitude')
# Mode comparison
axes[1,1].plot(frequencies, np.abs(spectrum), alpha=0.7, label='Spectrum')
if basic_modes:
basic_freqs = [mode.frequency for mode in basic_modes]
axes[1,1].axvline(x=freq, color='red', alpha=0.7, linestyle='--'
for freq in basic_freqs)
if advanced_modes:
advanced_freqs = [mode.frequency for mode in advanced_modes]
axes[1,1].axvline(x=freq, color='blue', alpha=0.7, linestyle=':'
for freq in advanced_freqs)
axes[1,1].set_title('Mode Comparison')
axes[1,1].legend()
plt.tight_layout()
plt.show()
Error Handling and Robustness
import mmpp
import logging
from pathlib import Path
# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def robust_batch_processing(data_directory):
"""
Robust batch processing with comprehensive error handling
"""
try:
# Load data
op = mmpp.MMPP(data_directory)
batch = op[:]
logger.info(f"Found {len(batch.zarr_results)} files to process")
# Process with error handling
results = {
'fft_spectra': [],
'modes': [],
'errors': []
}
# FFT computation
logger.info("Computing FFT spectra...")
fft_results = batch.fft.compute_all(
dset='m_z5-8'
)
# Separate successful and failed results
for result in fft_results:
if result['success']:
results['fft_spectra'].append(result)
else:
results['errors'].append({
'file': result['file'],
'operation': 'fft_spectrum',
'error': result['error']
})
# Mode computation (only for successful FFT results)
logger.info("Computing modes...")
if results['fft_spectra']:
mode_results = batch.fft.modes.compute_modes(
dset='m_z5-8',
parallel=True,
progress=True
)
for result in mode_results:
if result['success']:
results['modes'].append(result)
else:
results['errors'].append({
'file': result['file'],
'operation': 'modes',
'error': result['error']
})
# Summary
logger.info(f"Processing complete:")
logger.info(f" Successful FFT: {len(results['fft_spectra'])}")
logger.info(f" Successful modes: {len(results['modes'])}")
logger.info(f" Errors: {len(results['errors'])}")
# Log errors
if results['errors']:
logger.warning("Errors encountered:")
for error in results['errors']:
logger.warning(f" {error['file']} ({error['operation']}): {error['error']}")
return results
except Exception as e:
logger.error(f"Critical error in batch processing: {e}")
raise
# Usage
if __name__ == "__main__":
data_dir = "simulation_data/"
results = robust_batch_processing(data_dir)
# Save results
import pickle
with open("batch_analysis_results.pkl", "wb") as f:
pickle.dump(results, f)
These examples demonstrate the flexibility and power of MMPP for both single-file analysis and large-scale batch processing of simulation data.