diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d1cf573 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +recordings filter=lfs diff=lfs merge=lfs -text diff --git a/.riahub/workflows/workflow.yaml b/.riahub/workflows/workflow.yaml index 1bb7de2..0d85d47 100644 --- a/.riahub/workflows/workflow.yaml +++ b/.riahub/workflows/workflow.yaml @@ -37,7 +37,7 @@ jobs: - name: 1. Build Dataset run: | - echo "building dataset" + python produce_dataset.py # Placeholder: implement conversion from raw .npy recordings → train/val sets diff --git a/data/dataset.h5 b/data/dataset.h5 new file mode 100644 index 0000000..2cbffa2 Binary files /dev/null and b/data/dataset.h5 differ diff --git a/data_gen.py b/data_gen.py new file mode 100644 index 0000000..5ca8563 --- /dev/null +++ b/data_gen.py @@ -0,0 +1,69 @@ +from utils.data import Recording +import numpy as np +from utils.signal import block_generator + +mods = { + "bpsk": {"num_bits_per_symbol": 1, "constellation_type": "psk"}, + "qpsk": {"num_bits_per_symbol": 2, "constellation_type": "psk"}, + "qam16": {"num_bits_per_symbol": 4, "constellation_type": "qam"}, + "qam64": {"num_bits_per_symbol": 6, "constellation_type": "qam"}, +} + + +def generate_modulated_signals(): + for modulation in ["bpsk", "qpsk", "qam16", "qam64"]: + for snr in np.arange(-6, 13, 3): + + recording_length = 1024 + beta = 0.3 # the rolloff factor, can be changed to add variety + sps = 4 # samples per symbol, or the relative bandwidth of the digital signal. Can also be changed. + + # blocks don't directly take the string 'qpsk' so we use the dict 'mods' to get parameters + constellation_type = mods[modulation]["constellation_type"] + num_bits_per_symbol = mods[modulation]["num_bits_per_symbol"] + + # construct the digital modulation blocks with these parameters + # we have bit source -> mapper -> upsampling -> pulse shaping + + bit_source = block_generator.RandomBinarySource() + mapper = block_generator.Mapper( + constellation_type=constellation_type, + num_bits_per_symbol=num_bits_per_symbol, + ) + upsampler = block_generator.Upsampling(factor=sps) + pulse_shaping_filter = block_generator.RaisedCosineFilter( + upsampling_factor=sps, beta=beta + ) + + pulse_shaping_filter.connect_input([upsampler]) + upsampler.connect_input([mapper]) + mapper.connect_input([bit_source]) + + modulation_recording = pulse_shaping_filter.record( + num_samples=recording_length + ) + + # add noise by calculating the power of the modulation recording and generating AWGN from the snr parameter + signal_power = np.mean(np.abs(modulation_recording.data[0] ** 2)) + awgn_source = block_generator.AWGNSource( + variance=(signal_power / 2) * (10 ** (((-1 * snr) / 20))) + ) + noise = awgn_source.record(num_samples=recording_length) + samples_with_noise = modulation_recording.data + noise.data + output_recording = Recording(data=samples_with_noise) + + # add metadata for ML later + output_recording.add_to_metadata(key="modulation", value=modulation) + output_recording.add_to_metadata(key="snr", value=int(snr)) + output_recording.add_to_metadata(key="beta", value=beta) + output_recording.add_to_metadata(key="sps", value=sps) + + # view if you want + # output_recording.view() + + # save to file + output_recording.to_npy() # optionally add path and filename parameters + + +if __name__ == "__main__": + generate_modulated_signals() diff --git a/produce_dataset.py b/produce_dataset.py new file mode 100644 index 0000000..30dd0a4 --- /dev/null +++ b/produce_dataset.py @@ -0,0 +1,43 @@ +import os, h5py, numpy as np + + +def generate_dataset(path_to_recordings, output_path, dataset_name="data"): + """ + Generates a dataset from a folder of .npy files and saves it to an HDF5 file + + Parameters: + path_to_recordings (str): Path to the folder containing .npy files + output_path (str): Path to the output HDF5 file + dataset_name (str): Name of the dataset in the HDF5 file (default: "data") + + Returns: + dset (h5py.Dataset): The created dataset object + """ + + parent = os.path.dirname(output_path) + if parent: + os.makedirs(parent, exist_ok=True) + + # we assume the recordings are in .npy format + files = os.listdir(path_to_recordings) + if not files: + raise ValueError("No files found in the specified directory.") + + sample = np.load(os.path.join(path_to_recordings, files[0])) + shape = sample.shape + dtype = sample.dtype + + with h5py.File(output_path, "w") as hf: + dset = hf.create_dataset( + dataset_name, shape=(len(files),) + shape, dtype=dtype, compression="gzip" + ) + + for idx, fname in enumerate(files): + data = np.load(os.path.join(path_to_recordings, fname)) + dset[idx, ...] = data + + return dset + + +if __name__ == "__main__": + print(generate_dataset("recordings", "data/dataset.h5")) diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_0264b4a.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_0264b4a.npy new file mode 100644 index 0000000..f8df17a Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_0264b4a.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_0b3b80f.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_0b3b80f.npy new file mode 100644 index 0000000..1609060 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_0b3b80f.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_1effc4c.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_1effc4c.npy new file mode 100644 index 0000000..6ab16b9 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_1effc4c.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_37a73db.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_37a73db.npy new file mode 100644 index 0000000..2c3837c Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_37a73db.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_3d557a9.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_3d557a9.npy new file mode 100644 index 0000000..7d7c73d Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_3d557a9.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_442fcb9.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_442fcb9.npy new file mode 100644 index 0000000..4546dea Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_442fcb9.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_491c457.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_491c457.npy new file mode 100644 index 0000000..84b517e Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_491c457.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_4fff84f.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_4fff84f.npy new file mode 100644 index 0000000..59799b3 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_4fff84f.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_6676600.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_6676600.npy new file mode 100644 index 0000000..2bb7aa7 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_6676600.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_6d35ff9.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_6d35ff9.npy new file mode 100644 index 0000000..17c31f6 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_6d35ff9.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_6d85f3e.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_6d85f3e.npy new file mode 100644 index 0000000..f5d8484 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_6d85f3e.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_85a8c83.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_85a8c83.npy new file mode 100644 index 0000000..32616b9 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_85a8c83.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_940988e.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_940988e.npy new file mode 100644 index 0000000..5968642 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_940988e.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_9f88dc2.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_9f88dc2.npy new file mode 100644 index 0000000..af0c74e Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_9f88dc2.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_a4a6ba6.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_a4a6ba6.npy new file mode 100644 index 0000000..57503da Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_a4a6ba6.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_a60964b.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_a60964b.npy new file mode 100644 index 0000000..a9329ef Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_a60964b.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_ad350fe.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_ad350fe.npy new file mode 100644 index 0000000..fc1056e Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_ad350fe.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_ae5224a.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_ae5224a.npy new file mode 100644 index 0000000..8502646 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_ae5224a.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_b68f080.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_b68f080.npy new file mode 100644 index 0000000..1a19e1b Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_b68f080.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_c00477b.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_c00477b.npy new file mode 100644 index 0000000..adf88cc Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_c00477b.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_cca57ca.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_cca57ca.npy new file mode 100644 index 0000000..fe93a89 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_cca57ca.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_db8a5b4.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_db8a5b4.npy new file mode 100644 index 0000000..f19aa74 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_db8a5b4.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_dd021f7.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_dd021f7.npy new file mode 100644 index 0000000..ea4bcb2 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_dd021f7.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_e0cc41d.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_e0cc41d.npy new file mode 100644 index 0000000..5fb0f02 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_e0cc41d.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_e61d9bf.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_e61d9bf.npy new file mode 100644 index 0000000..5ba2d8a Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_e61d9bf.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_f024082.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_f024082.npy new file mode 100644 index 0000000..96a6fde Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_f024082.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_f2013fa.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_f2013fa.npy new file mode 100644 index 0000000..b606b77 Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_f2013fa.npy differ diff --git a/recordings/rec_0Hz_2025-05-15_09-45-10_f2ae593.npy b/recordings/rec_0Hz_2025-05-15_09-45-10_f2ae593.npy new file mode 100644 index 0000000..537a7ac Binary files /dev/null and b/recordings/rec_0Hz_2025-05-15_09-45-10_f2ae593.npy differ