-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Types: Improve
typecast_spectra_to_mhkit_python
documentation
- Loading branch information
Showing
1 changed file
with
74 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,87 @@ | ||
function df = typecast_spectra_to_mhkit_python(S) | ||
% Initialize empty python list for column names | ||
column_names = py.list(); | ||
|
||
% Validate frequency is 1D and make row-wise | ||
freq_dims = size(S.frequency); | ||
if length(freq_dims) > 2 || (freq_dims(1) ~= 1 && freq_dims(2) ~= 1) | ||
error('Frequency must be a 1D array. Current dimensions are %s', mat2str(freq_dims)); | ||
end | ||
freq_length = length(S.frequency); | ||
if freq_dims(1) ~= 1 | ||
S.frequency = S.frequency(:)'; | ||
end | ||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
% | ||
% Typecast input spectra struct into a MHKiT-Python compatible | ||
% pandas DataFrame. | ||
% | ||
% Parameters | ||
% ---------- | ||
% S : struct | ||
% A structure containing: | ||
% - frequency : (1D array) Frequency values (Hz) | ||
% - spectrum : (1D or 2D matrix) Spectral density values (m^2/Hz) | ||
% - type (optional) : (cell array of strings) Names for each spectrum column, | ||
% e.g., 'JONSWAP', 'Pierson Moskowitz', etc. | ||
% | ||
% Returns | ||
% ------- | ||
% df : Python pandas.DataFrame | ||
% A Pandas DataFrame with frequencies (Hz) as the index and | ||
% spectral density values (m^2/Hz) as columns. Column names are either | ||
% provided by S.type or automatically generated as 'spectrum_N'. | ||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
|
||
% Get initial spectrum dimensions | ||
[spec_rows, spec_cols] = size(S.spectrum); | ||
% Initialize empty Python list for column names | ||
column_names = py.list(); | ||
|
||
% Case 1: Square matrix matching frequency length | ||
if spec_rows == spec_cols && spec_rows == freq_length | ||
warning('Input spectrum is square (%d×%d) and matches frequency length. Unable to determine orientation. Assuming input orientation is correct.', spec_rows, spec_cols); | ||
% Validate that frequency is a 1D array and convert it to a row vector if needed | ||
freq_dims = size(S.frequency); | ||
if length(freq_dims) > 2 || (freq_dims(1) ~= 1 && freq_dims(2) ~= 1) | ||
error('Frequency must be a 1D array. Current dimensions are %s', mat2str(freq_dims)); | ||
end | ||
freq_length = length(S.frequency); | ||
if freq_dims(1) ~= 1 | ||
S.frequency = S.frequency(:)'; % Ensure frequency is row-wise | ||
end | ||
|
||
% Get initial spectrum dimensions | ||
[spec_rows, spec_cols] = size(S.spectrum); | ||
|
||
% Case 2: Already correct shape (rows match frequency length) | ||
elseif spec_cols == freq_length | ||
% No action needed, already correct | ||
% Handle different spectrum shapes and orientations | ||
if spec_rows == spec_cols && spec_rows == freq_length | ||
% Case 1: Square matrix where rows = cols = frequency length | ||
warning('Spectrum is square (%d×%d) and matches frequency length. Assuming input orientation is correct.', ... | ||
spec_rows, spec_cols); | ||
elseif spec_cols == freq_length | ||
% Case 2: Spectrum already correctly shaped (rows = M, cols = frequency length) | ||
% No transformation needed | ||
elseif spec_rows == freq_length | ||
% Case 3: Spectrum has incorrect orientation (transpose needed) | ||
S.spectrum = S.spectrum'; | ||
[spec_rows, spec_cols] = size(S.spectrum); | ||
else | ||
% Case 4: Invalid dimensions that cannot be reconciled | ||
error('Spectrum dimensions (%d×%d) do not match frequency length (%d). Expected 1×%d or M×%d.', ... | ||
spec_rows, spec_cols, freq_length, freq_length, freq_length); | ||
end | ||
|
||
% Case 3: Wrong orientation but can be fixed | ||
elseif spec_rows == freq_length | ||
S.spectrum = S.spectrum'; | ||
[spec_rows, spec_cols] = size(S.spectrum); | ||
% Convert frequency array to Python NumPy array for Pandas index | ||
freq_index = py.numpy.array(S.frequency); | ||
|
||
% Case 4: Invalid dimensions | ||
% Convert spectrum data to NumPy array | ||
if spec_rows == 1 | ||
% Case: Single spectrum | ||
spectrum_data = py.numpy.array(S.spectrum); | ||
if isfield(S, 'type') | ||
column_names.append(py.str(S.type)); % Use provided type as column name | ||
else | ||
error('Spectrum dimensions (%d×%d) cannot be reconciled with frequency length (%d). Spectrum should be either 1×%d or M×%d.', ... | ||
spec_rows, spec_cols, freq_length, freq_length, freq_length); | ||
column_names.append(py.str('spectrum')); % Default column name | ||
end | ||
|
||
% Create the frequency index | ||
freq_index = py.numpy.array(S.frequency); | ||
|
||
% Handle single or multiple spectra | ||
if spec_rows == 1 | ||
% Single spectrum case | ||
spectrum_data = py.numpy.array(S.spectrum); | ||
% Use type as column name, default to 'spectrum' if not provided | ||
if isfield(S, 'type') | ||
column_names.append(py.str(S.type)); | ||
else | ||
% Case: Multiple spectra | ||
spectrum_data = py.numpy.zeros([spec_rows, spec_cols]); | ||
for i = 1:spec_rows | ||
spectrum_data(:, i) = py.numpy.array(S.spectrum(i, :)); % Convert each row | ||
if isfield(S, 'type') && length(S.type) >= i | ||
column_names.append(py.str(S.type{i})); % Use provided type name | ||
else | ||
column_names.append(py.str('spectrum')); | ||
end | ||
else | ||
% Multiple spectra case | ||
% Convert all columns to numpy arrays and store column names | ||
spectrum_data = py.numpy.zeros([spec_rows, spec_cols]); | ||
for i = 1:spec_rows | ||
spectrum_data(:,i) = py.numpy.array(S.spectrum(i,:)); | ||
% Generate column name for each spectrum | ||
if isfield(S, 'type') && length(S.type) >= i | ||
column_names.append(py.str(S.type{i})); | ||
else | ||
column_names.append(py.str(sprintf('spectrum_%d', i))); | ||
end | ||
column_names.append(py.str(sprintf('spectrum_%d', i))); % Generate name | ||
end | ||
end | ||
|
||
% Create pandas DataFrame with frequency as index | ||
df = py.pandas.DataFrame(data=spectrum_data, ... | ||
index=freq_index, ... | ||
columns=column_names); | ||
end | ||
|
||
% Create a Pandas DataFrame with frequency as the index | ||
df = py.pandas.DataFrame(data=spectrum_data, ... | ||
index=freq_index, ... | ||
columns=column_names); |