Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to create Array Channels #1148

Open
glaure opened this issue Feb 14, 2025 · 2 comments
Open

Trying to create Array Channels #1148

glaure opened this issue Feb 14, 2025 · 2 comments

Comments

@glaure
Copy link

glaure commented Feb 14, 2025

Hi,

I am trying the create "Array Channels" like described here:

https://www.asam.net/standards/detail/mdf/wiki/

[CG]
    - [CN]
      [CN]
       - [CA]

The given mf4_matrix_demo creates two channels.
One holds the result of an FFT, the other a spectrogram. The second one is also visualized with mathplotlib.

This is the way I tried:

import numpy as np
from asammdf import MDF, Signal
from scipy.signal import spectrogram
from scipy.io import wavfile
import matplotlib.pyplot as plt
import os
import sys

cycles = 100
sigs = []

mdf = MDF()

t = np.arange(cycles, dtype=np.float64)

# FFT spectrum for intensity diagram
fft_spectrum = np.abs(np.fft.fft2(np.sin(2 * np.pi * t / cycles).reshape((10, 10))))
sig = Signal(
    fft_spectrum,
    t[:10],  # Assuming the time base for the intensity diagram is the first 10 time points
    name="Channel_FFT_Spectrum",
    unit="Intensity",
    comment="FFT spectrum for intensity diagram",
)
sigs.append(sig)

# Spectrogram for order analysis
sf, audio = wavfile.read(os.path.join(os.path.dirname(sys.argv[0]), 'example.wav'))
if audio.ndim > 1:
    audio = np.mean(audio, axis=1)  # Ensure audio is a 1D array if it is multi-channel
frequencies, times, Sxx = spectrogram(audio, sf, scaling='density')
plt.pcolormesh(times, frequencies, np.log10(Sxx))
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()

# No need to transpose Sxx as we want frequencies on the x-axis
sig = Signal(
    Sxx,
    frequencies,
    name="Channel_Spectrogram",
    unit="dB",
    comment="Spectrogram for order analysis",
)
sigs.append(sig)

mdf.append(sigs, comment="matrix")

mdf.save("demo_matrix.mf4", overwrite=True)

MDF Validator displays it like this. I do not see the array information I would like to have. No dimensions etc

What am I missing?

My motivation is to export spectral data to FlexPro and currently failing at that.
FlexPro only seems to see 1 vector sample instead of the whole spectrum.

Best regards
Gunther

Update:
The script needs a example.wav file

example.zip

@danielhrisca
Copy link
Owner

It is not possible to have the master channel as frequency\Hz, it will show up as time|seconds

import numpy as np
from asammdf import MDF, Signal
from scipy.signal import spectrogram
from scipy.io import wavfile
import matplotlib.pyplot as plt
import os
import sys

cycles = 100
sigs = []

mdf = MDF()

t = np.arange(cycles, dtype=np.float64)

# FFT spectrum for intensity diagram
fft_spectrum = np.abs(np.fft.fft2(np.sin(2 * np.pi * t / cycles).reshape((10, 10))))

types = [
    ("Channel_FFT_Spectrum", "<f8", fft_spectrum.shape[1:]),  # same name as the signal name
]
fft_spectrum = np.rec.fromarrays([fft_spectrum], dtype=np.dtype(types))

sig = Signal(
    fft_spectrum,
    t[:10],  # Assuming the time base for the intensity diagram is the first 10 time points
    name="Channel_FFT_Spectrum",
    unit="Intensity",
    comment="FFT spectrum for intensity diagram",
)
# append the signals separately
mdf.append(sig, comment="FFT Spectrum")

# Spectrogram for order analysis
sf, audio = wavfile.read(os.path.join(os.path.dirname(sys.argv[0]), r'd:\TMP\output.wav'))
if audio.ndim > 1:
    audio = np.mean(audio, axis=1)  # Ensure audio is a 1D array if it is multi-channel
frequencies, times, Sxx = spectrogram(audio, sf, scaling='density')
plt.pcolormesh(times, frequencies, np.log10(Sxx))
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()

types = [
    ("Channel_Spectrogram", "<f4", fft_spectrum.shape[1:]),  # same name as the signal name
]
Sxx = np.rec.fromarrays([Sxx], dtype=np.dtype(types))

# No need to transpose Sxx as we want frequencies on the x-axis
sig = Signal(
    Sxx,
    frequencies,
    name="Channel_Spectrogram",
    unit="dB",
    comment="Spectrogram for order analysis",
)

mdf.append(sig, comment="Channel spectrogram")

mdf.save("demo_matrix.mf4", overwrite=True)

@glaure
Copy link
Author

glaure commented Feb 18, 2025

Hi,

thank you for your fast response.
Indeed your changes do now create Channel Arrays.
Still I see that the dimension of the spectrogram is 1 x 1169 instead of the 129x1169 matrix I expected:
ca_ndim = 1
ca_dim_size[0] = 1169

Do you have an idea why?

bye Gunther

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants