Overwrite Channel Group Data in an MDF File
This example shows how to process data logged in a channel group of an MDF file and write the updated data back to the same channel group. The MDF file used in this example VehicleData.mf4
contains data logged from two simulations in two channel groups, but the example only works with data in channel group 1.
You will first read data from channel group 1 into a timetable, then perform correction and reduction on the data copy, and lastly overwrite the same channel group with updated data.
View File and Channel Group Details
View metadata of the MDF file using mdfInfo
by specifying the file name.
mdfInfo("VehicleData.mf4")
ans = MDFInfo with properties: File Details Name: "VehicleData.mf4" Path: "/tmp/Bdoc24b_2725827_3770987/tpf6b9d6b0/vnt-ex75859393/VehicleData.mf4" Author: "" Department: "" Project: "" Subject: "" Comment: "Example file demonstrating workflows of writing to MDF files." Version: "4.10" InitialTimestamp: 2022-01-20 01:22:34.000000000 Creator Details ProgramIdentifier: "MATLAB" CreatorVendorName: "The MathWorks, Inc." CreatorToolName: "MATLAB" CreatorToolVersion: "9.12.0.1846952 (R2022a) Prerelease Update 1" CreatorUserName: "" CreatorComment: "" File Contents Attachment: [1x7 table] ChannelGroupCount: 2 Event: [0x8 eventtable]
Inspect details about the two channel groups using mdfChannelGroupInfo
.
mdfChannelGroupInfo("VehicleData.mf4")
ans=2×13 table
GroupNumber AcquisitionName Comment NumSamples DataSize Sorted SourceName SourcePath SourceComment SourceType SourceBusType SourceBusChannelNumber SourceSimulated
___________ _______________ ___________________________________________________________________________ __________ ________ ______ ___________ ___________ _____________ ___________ _____________ ______________________ _______________
1 <undefined> Simulation of an automatic transmission controller during passing maneuver. 751 43558 true <undefined> <undefined> <undefined> Unspecified Unspecified 0 false
2 <undefined> Simulation of engine gas dynamics. 92033 2208792 true <undefined> <undefined> <undefined> Unspecified Unspecified 0 false
Read Channel Group Data with Metadata Included
Read data from channel group 1 using the mdfRead
function with optional argument IncludeMetadata
set to true
. The output timetable chanGrp1TT
is a copy of data for all channels in channel group 1.
chanGrp1Data = mdfRead("VehicleData.mf4", GroupNumber=1, IncludeMetadata=true)
chanGrp1Data = 1x1 cell array
{751x8 timetable}
chanGrp1TT = chanGrp1Data{1}
chanGrp1TT=751×8 timetable
time EngineRPM Brake Throttle Gear ImpellerTorque OutputTorque TransmissionRPM VehicleSpeed
________ _________ _____ ________ ____ ______________ ____________ _______________ ____________
0 sec 1000 0 60 1 52.919 282.65 0 0
0.04 sec 1383.3 0 59.946 1 101.4 532.63 13.593 0
0.08 sec 1685.4 0 59.893 1 150.76 776.41 35.847 0
0.12 sec 1907.2 0 59.839 1 193.42 973.15 65.768 0
0.16 sec 2062 0 59.785 1 227.02 1117.6 101.53 0
0.2 sec 2161.2 0 59.732 1 251.11 1212.8 141.45 0
0.24 sec 2221.4 0 59.678 1 267.24 1264.3 183.86 0
0.28 sec 2257.2 0 59.624 1 276.35 1271.2 227.25 0
0.32 sec 2278.7 0 59.57 1 281.99 1259.5 270.52 0
0.36 sec 2292.4 0 59.517 1 283.39 1229 313.08 0
0.4 sec 2305.1 0 59.463 1 283.29 1193.4 354.43 0
0.44 sec 2317.4 0 59.409 1 282.91 1156.6 394.58 0
0.48 sec 2330.5 0 59.356 1 281.84 1112.8 433.27 0
0.52 sec 2344.5 0 59.302 1 281.19 1073.1 470.53 0
0.56 sec 2359.1 0 59.248 1 279.77 1032.9 506.43 0
0.6 sec 2376.4 0 59.195 1 277.89 993.97 540.92 0
⋮
Because IncludeMetadata
was set to true
during the mdfRead
function call, the output timetable also contains metadata for channel group 1 and all channels in this group. Metadata for a channel group are stored as the timetable's custom properties for the entire table, and the property names are prefixed with "ChannelGroup". Metadata for individual channels are stored as the timetable's custom properties for the variables, and the property names are prefixed with "Channel".
View metadata for channel group 1 and all channels in this group.
chanGrp1TT.Properties.CustomProperties
ans = CustomProperties with properties: Validity: [751x8 timetable] ChannelGroupAcquisitionName: "" ChannelGroupComment: "Simulation of an automatic transmission controller during passing maneuver." ChannelGroupSourceName: "" ChannelGroupSourcePath: "" ChannelGroupSourceComment: "" ChannelGroupSourceType: Unspecified ChannelGroupSourceBusType: Unspecified ChannelGroupSourceBusChannelNumber: 0 ChannelDisplayName: ["" "" "" "" "" "" "" ""] ChannelComment: ["" "" "" "" "" "" "" ""] ChannelUnit: ["rpm" "ft*lbf" "%" "" "ft*lbf" "ft*lbf" "rpm" "mph"] ChannelType: [FixedLength FixedLength FixedLength FixedLength FixedLength FixedLength FixedLength FixedLength] ChannelDataType: [RealLittleEndian IntegerUnsignedLittleEndian RealLittleEndian IntegerUnsignedLittleEndian RealLittleEndian RealLittleEndian RealLittleEndian RealLittleEndian] ChannelNumBits: [64 8 64 8 64 64 64 64] ChannelComponentType: [None None None None None None None None] ChannelCompositionType: [None None None None None None None None] ChannelSourceName: ["" "" "" "" "" "" "" ""] ChannelSourcePath: ["" "" "" "" "" "" "" ""] ChannelSourceComment: ["" "" "" "" "" "" "" ""] ChannelSourceType: [Unspecified Unspecified Unspecified Unspecified Unspecified Unspecified Unspecified Unspecified] ChannelSourceBusType: [Unspecified Unspecified Unspecified Unspecified Unspecified Unspecified Unspecified Unspecified] ChannelSourceBusChannelNumber: [0 0 0 0 0 0 0 0] ChannelReadOption: [All All All All All All All All]
Note that when calling the mdfRead
function, IncludeMetadata
is set to false
by default. IncludeMetadata
must be set to true
if your ultimate goal for reading channel group data is to overwrite the same channel group from which data is read.
Correct Selected Samples in the Data Copy
For this particular application, there are only 4 gears, so a valid value of Gear
should be an integer in the range of [1,4]
. However, the value of Gear
appears to have been reset to zero due to a possible fault whenever a gear shift takes place.
Create a stacked plot using stackedplot
to see how the abrupt drops to zero in Gear
coincide with the abrupt value changes in ImpellerTorque
and OutputTorque
.
stackedplot(chanGrp1TT, ["ImpellerTorque", "OutputTorque", "Gear"])
Find row indices where value of Gear
is equal to zero.
zeroIdx = find(chanGrp1TT.Gear == 0)
zeroIdx = 0x1 empty double column vector
Correct samples at the found indices to take the values immediately following the zeros.
chanGrp1TT.Gear(zeroIdx) = chanGrp1TT.Gear(zeroIdx + 1)
chanGrp1TT=751×8 timetable
time EngineRPM Brake Throttle Gear ImpellerTorque OutputTorque TransmissionRPM VehicleSpeed
________ _________ _____ ________ ____ ______________ ____________ _______________ ____________
0 sec 1000 0 60 1 52.919 282.65 0 0
0.04 sec 1383.3 0 59.946 1 101.4 532.63 13.593 0
0.08 sec 1685.4 0 59.893 1 150.76 776.41 35.847 0
0.12 sec 1907.2 0 59.839 1 193.42 973.15 65.768 0
0.16 sec 2062 0 59.785 1 227.02 1117.6 101.53 0
0.2 sec 2161.2 0 59.732 1 251.11 1212.8 141.45 0
0.24 sec 2221.4 0 59.678 1 267.24 1264.3 183.86 0
0.28 sec 2257.2 0 59.624 1 276.35 1271.2 227.25 0
0.32 sec 2278.7 0 59.57 1 281.99 1259.5 270.52 0
0.36 sec 2292.4 0 59.517 1 283.39 1229 313.08 0
0.4 sec 2305.1 0 59.463 1 283.29 1193.4 354.43 0
0.44 sec 2317.4 0 59.409 1 282.91 1156.6 394.58 0
0.48 sec 2330.5 0 59.356 1 281.84 1112.8 433.27 0
0.52 sec 2344.5 0 59.302 1 281.19 1073.1 470.53 0
0.56 sec 2359.1 0 59.248 1 279.77 1032.9 506.43 0
0.6 sec 2376.4 0 59.195 1 277.89 993.97 540.92 0
⋮
Remove Channels from the Data Copy
For this particular application, assume Brake
and VehicleSpeed
are no longer required for analysis. Remove these two variables from the timetable using removevars
.
chanGrp1TT = removevars(chanGrp1TT, ["Brake", "VehicleSpeed"])
chanGrp1TT=751×6 timetable
time EngineRPM Throttle Gear ImpellerTorque OutputTorque TransmissionRPM
________ _________ ________ ____ ______________ ____________ _______________
0 sec 1000 60 1 52.919 282.65 0
0.04 sec 1383.3 59.946 1 101.4 532.63 13.593
0.08 sec 1685.4 59.893 1 150.76 776.41 35.847
0.12 sec 1907.2 59.839 1 193.42 973.15 65.768
0.16 sec 2062 59.785 1 227.02 1117.6 101.53
0.2 sec 2161.2 59.732 1 251.11 1212.8 141.45
0.24 sec 2221.4 59.678 1 267.24 1264.3 183.86
0.28 sec 2257.2 59.624 1 276.35 1271.2 227.25
0.32 sec 2278.7 59.57 1 281.99 1259.5 270.52
0.36 sec 2292.4 59.517 1 283.39 1229 313.08
0.4 sec 2305.1 59.463 1 283.29 1193.4 354.43
0.44 sec 2317.4 59.409 1 282.91 1156.6 394.58
0.48 sec 2330.5 59.356 1 281.84 1112.8 433.27
0.52 sec 2344.5 59.302 1 281.19 1073.1 470.53
0.56 sec 2359.1 59.248 1 279.77 1032.9 506.43
0.6 sec 2376.4 59.195 1 277.89 993.97 540.92
⋮
Write Updated Data Back to the Same Channel Group
You will write updated data into channel group 1 of VehicleData.mf4
, which requires permission to modify the MDF file. Check if you have write access to the MDF file. If not, make the MDF file writable.
[~, values] = fileattrib("VehicleData.mf4"); if ~values.UserWrite fileattrib("VehicleData.mf4", "+w") end
Call function mdfWrite
with optional argument GroupNumber
set to 1 to overwrite channel group 1 with the updated data in chanGrp1TT
.
mdfWrite("VehicleData.mf4", chanGrp1TT, GroupNumber=1)
Warning: Channel "Brake" removed while overwriting an existing channel group. Data of the corresponding channel will be erased but the channel will still exist.
Warning: Channel "VehicleSpeed" removed while overwriting an existing channel group. Data of the corresponding channel will be erased but the channel will still exist.
Two variables Brake
and VehicleSpeed
were removed from the timetable chanGrp1TT
in the previous step. However, because MDF is a binary file format, altering the channel group structure can lead to file corruption. Therefore, it is not possible to truly remove channels from an existing channel group. Data of the removed channels are erased, but the channels still exist in the channel group.
Examine the Data
To verify that data was successfully written to file, read only the data from channel group 1 without metadata using mdfRead
. Inspect the updated values in variable Gear
. Also note that values have been erased and reset to zeros for the removed variables Brake
and VehicleSpeed
.
chanGrp1DataNew = mdfRead("VehicleData.mf4", GroupNumber=1)
chanGrp1DataNew = 1x1 cell array
{751x8 timetable}
chanGrp1TTNew = chanGrp1DataNew{1}
chanGrp1TTNew=751×8 timetable
time EngineRPM Brake Throttle Gear ImpellerTorque OutputTorque TransmissionRPM VehicleSpeed
________ _________ _____ ________ ____ ______________ ____________ _______________ ____________
0 sec 1000 0 60 1 52.919 282.65 0 0
0.04 sec 1383.3 0 59.946 1 101.4 532.63 13.593 0
0.08 sec 1685.4 0 59.893 1 150.76 776.41 35.847 0
0.12 sec 1907.2 0 59.839 1 193.42 973.15 65.768 0
0.16 sec 2062 0 59.785 1 227.02 1117.6 101.53 0
0.2 sec 2161.2 0 59.732 1 251.11 1212.8 141.45 0
0.24 sec 2221.4 0 59.678 1 267.24 1264.3 183.86 0
0.28 sec 2257.2 0 59.624 1 276.35 1271.2 227.25 0
0.32 sec 2278.7 0 59.57 1 281.99 1259.5 270.52 0
0.36 sec 2292.4 0 59.517 1 283.39 1229 313.08 0
0.4 sec 2305.1 0 59.463 1 283.29 1193.4 354.43 0
0.44 sec 2317.4 0 59.409 1 282.91 1156.6 394.58 0
0.48 sec 2330.5 0 59.356 1 281.84 1112.8 433.27 0
0.52 sec 2344.5 0 59.302 1 281.19 1073.1 470.53 0
0.56 sec 2359.1 0 59.248 1 279.77 1032.9 506.43 0
0.6 sec 2376.4 0 59.195 1 277.89 993.97 540.92 0
⋮