Migration Guide: DeepMIMO v3 to v4.¶
Tutorial Overview:
- Key differences between v3 and v4
- Channel generation changes
- Data access and format changes
- User selection changes
- Best practices for migration
Related Video: Migration Video
import deepmimo as dm
In [ ]:
Copied!
Overview¶
DeepMIMO v4 introduces significant changes for improved performance, storage efficiency, and expanded capabilities. This guide helps you migrate from v3 to v4.
v3 Workflow (Old)¶
In [1]:
Copied!
# V3 Example (DO NOT RUN - for reference only)
v3_example = """
# DeepMIMO v3 workflow:
import DeepMIMOv3
# Load default parameters
params = DeepMIMOv3.default_params()
# Configure scenario
params["dataset_folder"] = "."
params["scenario"] = "asu_campus1"
params["active_BS"] = np.array([1])
params["user_rows"] = np.arange(321)
# Configure antennas
params["ue_antenna"]["shape"] = np.array([1, 1])
params["bs_antenna"]["shape"] = np.array([8, 1])
# Generate dataset
dataset = DeepMIMOv3.generate_data(params)
# Access data
channels = dataset[0]["user"]["channel"]
"""
print("DeepMIMO v3 workflow (deprecated):")
print(v3_example)
# V3 Example (DO NOT RUN - for reference only)
v3_example = """
# DeepMIMO v3 workflow:
import DeepMIMOv3
# Load default parameters
params = DeepMIMOv3.default_params()
# Configure scenario
params["dataset_folder"] = "."
params["scenario"] = "asu_campus1"
params["active_BS"] = np.array([1])
params["user_rows"] = np.arange(321)
# Configure antennas
params["ue_antenna"]["shape"] = np.array([1, 1])
params["bs_antenna"]["shape"] = np.array([8, 1])
# Generate dataset
dataset = DeepMIMOv3.generate_data(params)
# Access data
channels = dataset[0]["user"]["channel"]
"""
print("DeepMIMO v3 workflow (deprecated):")
print(v3_example)
DeepMIMO v3 workflow (deprecated): # DeepMIMO v3 workflow: import DeepMIMOv3 # Load default parameters params = DeepMIMOv3.default_params() # Configure scenario params["dataset_folder"] = "." params["scenario"] = "asu_campus1" params["active_BS"] = np.array([1]) params["user_rows"] = np.arange(321) # Configure antennas params["ue_antenna"]["shape"] = np.array([1, 1]) params["bs_antenna"]["shape"] = np.array([8, 1]) # Generate dataset dataset = DeepMIMOv3.generate_data(params) # Access data channels = dataset[0]["user"]["channel"]
v4 Workflow (New)¶
In [2]:
Copied!
# DeepMIMO v4 workflow:
# Download and load scenario
scen_name = "asu_campus_3p5"
dm.download(scen_name)
dataset = dm.load(scen_name)
# Configure channel parameters
ch_params = dm.ChannelParameters()
ch_params.bs_antenna.shape = [8, 1]
ch_params.ue_antenna.shape = [1, 1]
# Generate channels
dataset.compute_channels(ch_params)
channels = dataset.channel
print("v4 Dataset loaded successfully")
print(f"Channel shape: {channels.shape}")
# DeepMIMO v4 workflow:
# Download and load scenario
scen_name = "asu_campus_3p5"
dm.download(scen_name)
dataset = dm.load(scen_name)
# Configure channel parameters
ch_params = dm.ChannelParameters()
ch_params.bs_antenna.shape = [8, 1]
ch_params.ue_antenna.shape = [1, 1]
# Generate channels
dataset.compute_channels(ch_params)
channels = dataset.channel
print("v4 Dataset loaded successfully")
print(f"Channel shape: {channels.shape}")
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[2], line 5 1 # DeepMIMO v4 workflow: 2 3 # Download and load scenario 4 scen_name = "asu_campus_3p5" ----> 5 dm.download(scen_name) 6 dataset = dm.load(scen_name) 8 # Configure channel parameters NameError: name 'dm' is not defined
In [3]:
Copied!
# v3: pip install deepmimov3
# v4: pip install --pre deepmimo
print("v3: pip install DeepMIMOv3")
print("v4: pip install --pre deepmimo")
# v3: pip install deepmimov3
# v4: pip install --pre deepmimo
print("v3: pip install DeepMIMOv3")
print("v4: pip install --pre deepmimo")
v3: pip install DeepMIMOv3 v4: pip install --pre deepmimo
2. Import Statements¶
In [4]:
Copied!
# v3: import DeepMIMOv3
# v4: import deepmimo as dm
print("v3: import DeepMIMOv3")
print("v4: import deepmimo as dm")
# v3: import DeepMIMOv3
# v4: import deepmimo as dm
print("v3: import DeepMIMOv3")
print("v4: import deepmimo as dm")
v3: import DeepMIMOv3 v4: import deepmimo as dm
3. Dataset Loading¶
In [5]:
Copied!
comparison = """
# v3:
params = DeepMIMOv3.default_params()
params["dataset_folder"] = "."
params["scenario"] = "asu_campus1"
dataset = DeepMIMOv3.generate_data(params)
# v4:
dm.download("asu_campus_3p5")
dataset = dm.load("asu_campus_3p5")
"""
print("Dataset Loading:")
print(comparison)
comparison = """
# v3:
params = DeepMIMOv3.default_params()
params["dataset_folder"] = "."
params["scenario"] = "asu_campus1"
dataset = DeepMIMOv3.generate_data(params)
# v4:
dm.download("asu_campus_3p5")
dataset = dm.load("asu_campus_3p5")
"""
print("Dataset Loading:")
print(comparison)
Dataset Loading:
# v3:
params = DeepMIMOv3.default_params()
params["dataset_folder"] = "."
params["scenario"] = "asu_campus1"
dataset = DeepMIMOv3.generate_data(params)
# v4:
dm.download("asu_campus_3p5")
dataset = dm.load("asu_campus_3p5")
Channel Generation¶
Channel generation is now explicit and on-demand.
v3: Implicit Generation¶
In [6]:
Copied!
v3_channel_gen = """
# v3: Channels generated during dataset loading
params["OFDM"]["subcarriers"] = 512
params["OFDM"]["bandwidth"] = 10e6
dataset = DeepMIMOv3.generate_data(params)
channels = dataset[0]["user"]["channel"]
"""
print("v3 channel generation (automatic):")
print(v3_channel_gen)
v3_channel_gen = """
# v3: Channels generated during dataset loading
params["OFDM"]["subcarriers"] = 512
params["OFDM"]["bandwidth"] = 10e6
dataset = DeepMIMOv3.generate_data(params)
channels = dataset[0]["user"]["channel"]
"""
print("v3 channel generation (automatic):")
print(v3_channel_gen)
v3 channel generation (automatic): # v3: Channels generated during dataset loading params["OFDM"]["subcarriers"] = 512 params["OFDM"]["bandwidth"] = 10e6 dataset = DeepMIMOv3.generate_data(params) channels = dataset[0]["user"]["channel"]
v4: Explicit Generation¶
In [7]:
Copied!
# v4: Channels generated on-demand
ch_params = dm.ChannelParameters()
ch_params.freq_domain = True # Frequency domain
ch_params.ofdm.subcarriers = 512
ch_params.ofdm.bandwidth = 10e6
dataset.compute_channels(ch_params)
channels = dataset.channel
print(f"v4 channel shape: {channels.shape}")
# v4: Channels generated on-demand
ch_params = dm.ChannelParameters()
ch_params.freq_domain = True # Frequency domain
ch_params.ofdm.subcarriers = 512
ch_params.ofdm.bandwidth = 10e6
dataset.compute_channels(ch_params)
channels = dataset.channel
print(f"v4 channel shape: {channels.shape}")
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[7], line 2 1 # v4: Channels generated on-demand ----> 2 ch_params = dm.ChannelParameters() 3 ch_params.freq_domain = True # Frequency domain 4 ch_params.ofdm.subcarriers = 512 NameError: name 'dm' is not defined
Data Access¶
Data access is simplified in v4.
v3: Nested Dictionary¶
In [8]:
Copied!
v3_data_access = """
# v3: Nested dictionary access
power = dataset[bs_idx]["user"]["power"]
delay = dataset[bs_idx]["user"]["delay"]
aoa = dataset[bs_idx]["user"]["DoA_phi"]
aod = dataset[bs_idx]["user"]["DoD_phi"]
"""
print("v3 data access (nested):")
print(v3_data_access)
v3_data_access = """
# v3: Nested dictionary access
power = dataset[bs_idx]["user"]["power"]
delay = dataset[bs_idx]["user"]["delay"]
aoa = dataset[bs_idx]["user"]["DoA_phi"]
aod = dataset[bs_idx]["user"]["DoD_phi"]
"""
print("v3 data access (nested):")
print(v3_data_access)
v3 data access (nested): # v3: Nested dictionary access power = dataset[bs_idx]["user"]["power"] delay = dataset[bs_idx]["user"]["delay"] aoa = dataset[bs_idx]["user"]["DoA_phi"] aod = dataset[bs_idx]["user"]["DoD_phi"]
v4: Direct Attributes¶
In [9]:
Copied!
# v4: Direct attribute access
power = dataset.power
delay = dataset.delay
aoa_az = dataset.aoa_az
aod_az = dataset.aod_az
print("v4 data access (direct):")
print(f" Power shape: {power.shape}")
print(f" Delay shape: {delay.shape}")
print(f" AOA (az) shape: {aoa_az.shape}")
# v4: Direct attribute access
power = dataset.power
delay = dataset.delay
aoa_az = dataset.aoa_az
aod_az = dataset.aod_az
print("v4 data access (direct):")
print(f" Power shape: {power.shape}")
print(f" Delay shape: {delay.shape}")
print(f" AOA (az) shape: {aoa_az.shape}")
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[9], line 2 1 # v4: Direct attribute access ----> 2 power = dataset.power 3 delay = dataset.delay 4 aoa_az = dataset.aoa_az NameError: name 'dataset' is not defined
User Selection¶
User selection methods have changed.
v3: Row/Column Selection¶
In [10]:
Copied!
v3_user_selection = """
# v3: Use row indices during parameter setup
params["user_rows"] = np.arange(0, 100, 10) # Every 10th row
dataset = DeepMIMOv3.generate_data(params)
"""
print("v3 user selection (pre-generation):")
print(v3_user_selection)
v3_user_selection = """
# v3: Use row indices during parameter setup
params["user_rows"] = np.arange(0, 100, 10) # Every 10th row
dataset = DeepMIMOv3.generate_data(params)
"""
print("v3 user selection (pre-generation):")
print(v3_user_selection)
v3 user selection (pre-generation): # v3: Use row indices during parameter setup params["user_rows"] = np.arange(0, 100, 10) # Every 10th row dataset = DeepMIMOv3.generate_data(params)
v4: Post-Loading Selection¶
In [11]:
Copied!
# v4: Select users after loading
row_idxs = dataset.get_idxs(mode="row", row_idxs=list(range(0, 100, 10)))
subset = dataset.trim(idxs=row_idxs)
print("v4 user selection (post-loading):")
print(f" Selected {len(row_idxs)} users")
# v4: Select users after loading
row_idxs = dataset.get_idxs(mode="row", row_idxs=list(range(0, 100, 10)))
subset = dataset.trim(idxs=row_idxs)
print("v4 user selection (post-loading):")
print(f" Selected {len(row_idxs)} users")
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[11], line 2 1 # v4: Select users after loading ----> 2 row_idxs = dataset.get_idxs(mode="row", row_idxs=list(range(0, 100, 10))) 3 subset = dataset.trim(idxs=row_idxs) 5 print("v4 user selection (post-loading):") NameError: name 'dataset' is not defined
Parameter Names¶
Many parameter names have changed.
In [12]:
Copied!
parameter_mapping = {
"DoA_phi / DoA_theta": "aoa_az / aoa_el",
"DoD_phi / DoD_theta": "aod_az / aod_el",
"active_BS": "tx_sets (in dm.load())",
"user_rows": "dataset.get_idxs(mode='row', row_idxs=...)",
"ue_antenna": "ant_ue (in ChannelParameters)",
"bs_antenna": "ant_bs (in ChannelParameters)",
}
print("Parameter name mapping (v3 -> v4):")
for v3_name, v4_name in parameter_mapping.items():
print(f" {v3_name:25s} -> {v4_name}")
parameter_mapping = {
"DoA_phi / DoA_theta": "aoa_az / aoa_el",
"DoD_phi / DoD_theta": "aod_az / aod_el",
"active_BS": "tx_sets (in dm.load())",
"user_rows": "dataset.get_idxs(mode='row', row_idxs=...)",
"ue_antenna": "ant_ue (in ChannelParameters)",
"bs_antenna": "ant_bs (in ChannelParameters)",
}
print("Parameter name mapping (v3 -> v4):")
for v3_name, v4_name in parameter_mapping.items():
print(f" {v3_name:25s} -> {v4_name}")
Parameter name mapping (v3 -> v4): DoA_phi / DoA_theta -> aoa_az / aoa_el DoD_phi / DoD_theta -> aod_az / aod_el active_BS -> tx_sets (in dm.load()) user_rows -> dataset.get_idxs(mode='row', row_idxs=...) ue_antenna -> ant_ue (in ChannelParameters) bs_antenna -> ant_bs (in ChannelParameters)
Storage Format¶
v4 uses more efficient storage.
In [13]:
Copied!
# v4 files are typically 50% smaller
print("Storage improvements:")
print(" - v3: Nested dictionaries in .mat files")
print(" - v4: Direct NumPy arrays in .npz files")
print(" - Average size reduction: ~50%")
# v4 files are typically 50% smaller
print("Storage improvements:")
print(" - v3: Nested dictionaries in .mat files")
print(" - v4: Direct NumPy arrays in .npz files")
print(" - Average size reduction: ~50%")
Storage improvements: - v3: Nested dictionaries in .mat files - v4: Direct NumPy arrays in .npz files - Average size reduction: ~50%
Migration Checklist¶
Use this checklist when migrating your code:
- Update installation:
pip install --pre deepmimo - Change import:
import deepmimo as dm - Replace
default_params()withdm.load() - Replace
generate_data()withdataset.compute_channels() - Update data access from
dataset[bs]["user"]["param"]todataset.param - Move user selection from params to
dataset.get_idxs()anddataset.trim() - Update parameter names (DoA/DoD -> aoa/aod, etc.)
- Update antenna configuration to ChannelParameters
- Test thoroughly with your existing workflows
Common Migration Patterns¶
Pattern 1: Basic Channel Generation¶
In [14]:
Copied!
print("Pattern 1: Basic Channel Generation")
print("\nv3:")
print("""
params = DeepMIMOv3.default_params()
params["scenario"] = "O1_60"
params["bs_antenna"]["shape"] = [4, 4]
dataset = DeepMIMOv3.generate_data(params)
ch = dataset[0]["user"]["channel"]
""")
print("\nv4:")
print("""
dataset = dm.load("city_18_denver_3p5")
ch_params = dm.ChannelParameters()
ch_params.bs_antenna.shape = [4, 4]
dataset.compute_channels(ch_params)
ch = dataset.channel
""")
print("Pattern 1: Basic Channel Generation")
print("\nv3:")
print("""
params = DeepMIMOv3.default_params()
params["scenario"] = "O1_60"
params["bs_antenna"]["shape"] = [4, 4]
dataset = DeepMIMOv3.generate_data(params)
ch = dataset[0]["user"]["channel"]
""")
print("\nv4:")
print("""
dataset = dm.load("city_18_denver_3p5")
ch_params = dm.ChannelParameters()
ch_params.bs_antenna.shape = [4, 4]
dataset.compute_channels(ch_params)
ch = dataset.channel
""")
Pattern 1: Basic Channel Generation
v3:
params = DeepMIMOv3.default_params()
params["scenario"] = "O1_60"
params["bs_antenna"]["shape"] = [4, 4]
dataset = DeepMIMOv3.generate_data(params)
ch = dataset[0]["user"]["channel"]
v4:
dataset = dm.load("city_18_denver_3p5")
ch_params = dm.ChannelParameters()
ch_params.bs_antenna.shape = [4, 4]
dataset.compute_channels(ch_params)
ch = dataset.channel
Pattern 2: OFDM Channels¶
In [15]:
Copied!
print("\nPattern 2: OFDM Channels")
print("\nv3:")
print("""
params["OFDM"]["subcarriers"] = 512
params["OFDM"]["bandwidth"] = 10e6
dataset = DeepMIMOv3.generate_data(params)
""")
print("\nv4:")
print("""
ch_params.freq_domain = True
ch_params.ofdm.subcarriers = 512
ch_params.ofdm.bandwidth = 10e6
dataset.compute_channels(ch_params)
ch = dataset.channel
""")
print("\nPattern 2: OFDM Channels")
print("\nv3:")
print("""
params["OFDM"]["subcarriers"] = 512
params["OFDM"]["bandwidth"] = 10e6
dataset = DeepMIMOv3.generate_data(params)
""")
print("\nv4:")
print("""
ch_params.freq_domain = True
ch_params.ofdm.subcarriers = 512
ch_params.ofdm.bandwidth = 10e6
dataset.compute_channels(ch_params)
ch = dataset.channel
""")
Pattern 2: OFDM Channels v3: params["OFDM"]["subcarriers"] = 512 params["OFDM"]["bandwidth"] = 10e6 dataset = DeepMIMOv3.generate_data(params) v4: ch_params.freq_domain = True ch_params.ofdm.subcarriers = 512 ch_params.ofdm.bandwidth = 10e6 dataset.compute_channels(ch_params) ch = dataset.channel
Pattern 3: User Sampling¶
In [16]:
Copied!
print("\nPattern 3: User Sampling")
print("\nv3:")
print("""
params["user_rows"] = [0, 10, 20]
dataset = DeepMIMOv3.generate_data(params)
""")
print("\nv4:")
print("""
dataset = dm.load(scenario)
row_idxs = dataset.get_idxs(mode='row', row_idxs=[0, 10, 20])
subset = dataset.trim(idxs=row_idxs)
""")
print("\nPattern 3: User Sampling")
print("\nv3:")
print("""
params["user_rows"] = [0, 10, 20]
dataset = DeepMIMOv3.generate_data(params)
""")
print("\nv4:")
print("""
dataset = dm.load(scenario)
row_idxs = dataset.get_idxs(mode='row', row_idxs=[0, 10, 20])
subset = dataset.trim(idxs=row_idxs)
""")
Pattern 3: User Sampling v3: params["user_rows"] = [0, 10, 20] dataset = DeepMIMOv3.generate_data(params) v4: dataset = dm.load(scenario) row_idxs = dataset.get_idxs(mode='row', row_idxs=[0, 10, 20]) subset = dataset.trim(idxs=row_idxs)
Benefits of v4¶
- Performance: Faster loading and processing
- Storage: 50% smaller dataset files
- Flexibility: On-demand channel generation
- Simplicity: Cleaner API and data access
- Features: New visualization, sampling, and converter tools
- Documentation: Comprehensive tutorials and examples
Need Help?¶
- Check the documentation
- Ask questions on GitHub Discussions
- Report bugs on GitHub Issues
- Join the community at deepmimo.net
Next Steps¶
Now that you've migrated to v4, explore:
- Tutorial 1: Getting Started - Learn v4 basics
- Tutorial 2: Visualization - Use new visualization features
- Tutorial 3: Channel Generation - Master channel generation