%% Work with Unfinalized and Unsorted MDF-Files
% This example shows how to work with unfinalized and unsorted MDF-files. The unfinalized MDF-file used in this example, MDFUnfinalized.MF4, was recorded by a CANedge2 CAN bus data logger from CSS Electronics.
%
%% Introduction to Unfinalized and Unsorted MDF-Files
% Sometimes an MDF-file creator tool can experience a premature termination caused by an unexpected power-down or an application error. In such cases, the MDF-file might be left in an unfinalized state, possibly violating certain format rules of the ASAM MDF standard or causing data loss during read operations.
% In general, a data group can be either sorted or unsorted. Some recording tools write unsorted MDF-files without sorting them after the recording completes. A sorted data group cannot contain more than one channel group, while an unsorted data group may contain several channel groups. If all data groups in an MDF-file are sorted, the MDF-file is sorted; if at least one data group is unsorted, the entire MDF-file is unsorted.
% An unfinalized MDF-file can be either sorted or unsorted. Conversely, an unsorted MDF-file can be either finalized or unfinalized.
%
%% Use Unfinalized MDF-Files in MATLAB
% Because unfinalized files can contain format issues and lead to unreliable read operations, an error is thrown when attempting to open an unfinalized MDF-file using the mdf function.

try
    m = mdf("MDFUnfinalized.MF4")
catch ME
    disp(ME.message)
end

% You can finalize an unfinalized MDF-file using the function mdfFinalize. If the MDF-file is both unfinalized and unsorted, mdfFinalize also attempts to sort the file as part of the finalization process.
%
%% Use Finalized but Unsorted MDF-Files in MATLAB
% If an MDF-file is finalized but unsorted, you can open the file using the mdf function, but an error might occur if you subsequently try to read data from the unsorted file using the read function.
% You can sort a finalized but unsorted MDF-file using function mdfSort. If the unsorted MDF-file is also unfinalized, using mdfSort on the file causes an error. Instead, use mdfFinalize to finalize and sort the file at the same time.
% This example continues to demonstrate the use of mdfFinalize with unfinalized MDF-files. However, you can follow a similar workflow to use the mdfSort function on finalized but unsorted MDF-files.
%
%% Finalize an MDF-File In-Place
% The mdfFinalize function allows you to finalize an unfinalized MDF-file in place by overwriting the source file with a finalized copy.
% For demonstration purposes, make a copy of the original file using copyfile, and use the extra copy MDFFinalizedInPlace.MF4 in the subsequent finalization operation.

copyfile("MDFUnfinalized.MF4", "MDFFinalizedInPlace.MF4")

% Use mdfFinalize with only the source file name MDFFinalizedInPlace.MF4 specified to create a finalized copy that overwrites itself. The function returns the full path of the finalized file.

finalizedPath1 = mdfFinalize("MDFFinalizedInPlace.MF4")

% MDFFinalizedInPlace.MF4 is now finalized and can be opened using the mdf function. You can specify the full path returned by mdfFinalize. Alternatively, specify the file name if it is located on MATLAB path.

m1 = mdf(finalizedPath1)

% Inspect the Sorted field of each channel group struct. Note that all channel groups are sorted now.

[m1.ChannelGroup.Sorted]

% When the MDF-file is finalized and sorted, you can proceed to use all MDF functionaly, such as extracting data using the read function.
%
%% Finalize an MDF-File Out-of-Place
% The mdfFinalize function also allows you to finalize an unfinalized MDF-file out-of-place by creating a separate finalized copy. Call the function specifying both the source file name and a destination file name.

finalizedPath2 = mdfFinalize("MDFUnfinalized.MF4", "MDFFinalizedOutOfPlace.MF4")

% MDFFinalizedOutOfPlace.MF4 is a newly created finalized copy and can be opened using the mdf function.

m2 = mdf(finalizedPath2)

% Inspect the Sorted field of each channel group struct. Note that all channel groups are sorted now.

[m2.ChannelGroup.Sorted]

% When the MDF-file is finalized and sorted, you can proceed to use all MDF functionality, such as extracting data using the read function.
%
%% Close and Delete Created MDF-Files
% Close access to the finalized MDF-files created in this example by clearing their variables from the workspace.

clear m1 m2

% Delete the MDF-files created in this example to clean up the working directory.

delete MDFFinalizedInPlace.MF4 MDFFinalizedOutOfPlace.MF4

%
%% Conclusion
% Similar to mdfFinalize, the mdfSort function supports sorting operations both in-place and out-of-place. You can apply the same workflow to sort unsorted MDF-files.
% To summarize:
% If an MDF-file is finalized and sorted, it can be opened using mdf and data can be read using read.
% If an MDF-file is finalized and unsorted, it can be opened using mdf but data cannot be read using read. Use mdfSort to sort the file.
% If an MDF-file is unfinalized and sorted, it cannot be opened using mdf. Use mdfFinalize to finalize the file.
% If an MDF-file is unfinalized and unsorted, it cannot be opened using mdf. Use mdfFinalize to finalize and sort the file.
%
% Copyright 2021 The MathWorks, Inc.