将通道组数据从现有 MDF 文件写入新 MDF 文件
此示例说明如何处理在 MDF 文件的通道组中记录的数据,并将更新后的数据写入新文件。此示例 VehicleData.mf4
中使用的 MDF 文件包含从两个通道组中的两个仿真记录的数据,但该示例仅处理通道组 2 中的数据。
首先需要将通道组 2 中的数据读入一个时间表,然后对数据副本执行后处理。最后,您需要创建一个与 VehicleData.mf4
具有相同文件元数据的新 MDF 文件,并将更新后的数据作为新通道组写入新 MDF 文件。
查看有关 MDF 文件及其通道组的详细信息
通过指定文件名,使用 mdfInfo
查看文件 VehicleData.mf4
的元数据。
mdfInfo("VehicleData.mf4")
ans = MDFInfo with properties: File Details Name: "VehicleData.mf4" Path: "/tmp/Bdoc24a_2511836_3090053/tpeb21c448/vnt-ex28629694/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
使用 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
读取包含元数据的通道组数据
使用可选参量 IncludeMetadata
设置为 true
的 mdfRead
函数从通道组 2 读取数据。输出时间表 chanGrp2TT
是通道组 2 中所有通道的数据的副本。
chanGrp2Data = mdfRead("VehicleData.mf4", GroupNumber=2, IncludeMetadata=true)
chanGrp2Data = 1x1 cell array
{92033x2 timetable}
chanGrp2TT = chanGrp2Data{1}
chanGrp2TT=92033×2 timetable
time AirFlow FuelRate
______________ _______ ________
0 sec 17.294 1.209
0.00056199 sec 17.263 1.209
0.0033719 sec 17.112 1.209
0.01 sec 16.776 1.1729
0.02 sec 16.316 1.1409
0.03 sec 15.907 1.1124
0.04 sec 15.546 1.0873
0.05 sec 15.228 1.0652
0.055328 sec 15.075 1.0652
0.055328 sec 15.075 1.0652
0.055328 sec 15.075 1.0652
0.06 sec 14.949 1.0458
0.064672 sec 14.832 1.0458
0.07 sec 14.707 1.0289
0.08 sec 14.497 1.0143
0.09 sec 14.317 1.0019
⋮
通道组 2 及其通道的元数据作为自定义属性显示在时间表中。一个通道组的元数据存储为整个表的时间表自定义属性,属性名称以“ChannelGroup”为前缀。各个通道的元数据存储为各变量的时间表自定义属性,属性名称以“Channel”为前缀。
查看通道组 2 和此组中所有通道的元数据。
chanGrp2TT.Properties.CustomProperties
ans = CustomProperties with properties: ChannelGroupAcquisitionName: "" ChannelGroupComment: "Simulation of engine gas dynamics." ChannelGroupSourceName: "" ChannelGroupSourcePath: "" ChannelGroupSourceComment: "" ChannelGroupSourceType: Unspecified ChannelGroupSourceBusType: Unspecified ChannelGroupSourceBusChannelNumber: 0 ChannelDisplayName: ["" ""] ChannelComment: ["" ""] ChannelUnit: ["g/s" "g/s"] ChannelType: [FixedLength FixedLength] ChannelDataType: [RealLittleEndian RealLittleEndian] ChannelNumBits: [64 64] ChannelComponentType: [None None] ChannelCompositionType: [None None] ChannelSourceName: ["" ""] ChannelSourcePath: ["" ""] ChannelSourceComment: ["" ""] ChannelSourceType: [Unspecified Unspecified] ChannelSourceBusType: [Unspecified Unspecified] ChannelSourceBusChannelNumber: [0 0] ChannelReadOption: [All All]
请注意,当调用 mdfRead
函数时,默认情况下,将 IncludeMetadata
设置为 false
。因此,如果您读取通道组数据的最终目标是写入新通道组,并保留通道组和通道元数据,则 IncludeMetadata
必须设置为 true
。
减少数据副本中的采样数
使用 stackedplot
创建一个堆叠图,以可视化通道 AirFlow
和 FuelRate
中的数据。
stackedplot(chanGrp2TT, ["AirFlow", "FuelRate"])
从该堆叠图中可以观察到,从大约 182.17 秒处到 900 秒处的记录结束位置,FuelRate
的值保持在 0,这表明在测量期间可能有故障。对于此特定应用,当 FuelRate
的值无效时,AirFlow
的记录值是无用的。因此,您决定丢弃 FuelRate
为零的无效数据采样。
减少通道组 2 中的数据采样,仅保留有效的非零值。
chanGrp2TT = chanGrp2TT(chanGrp2TT.FuelRate ~= 0, :)
chanGrp2TT=18634×2 timetable
time AirFlow FuelRate
______________ _______ ________
0 sec 17.294 1.209
0.00056199 sec 17.263 1.209
0.0033719 sec 17.112 1.209
0.01 sec 16.776 1.1729
0.02 sec 16.316 1.1409
0.03 sec 15.907 1.1124
0.04 sec 15.546 1.0873
0.05 sec 15.228 1.0652
0.055328 sec 15.075 1.0652
0.055328 sec 15.075 1.0652
0.055328 sec 15.075 1.0652
0.06 sec 14.949 1.0458
0.064672 sec 14.832 1.0458
0.07 sec 14.707 1.0289
0.08 sec 14.497 1.0143
0.09 sec 14.317 1.0019
⋮
在数据副本中添加通道
将气流量除以喷油量得到空燃比,并将计算出的值赋给一个名为 AirFuelRatio
的新时间表变量。
chanGrp2TT.AirFuelRatio = chanGrp2TT.AirFlow./chanGrp2TT.FuelRate
chanGrp2TT=18634×3 timetable
time AirFlow FuelRate AirFuelRatio
______________ _______ ________ ____________
0 sec 17.294 1.209 14.304
0.00056199 sec 17.263 1.209 14.278
0.0033719 sec 17.112 1.209 14.154
0.01 sec 16.776 1.1729 14.303
0.02 sec 16.316 1.1409 14.301
0.03 sec 15.907 1.1124 14.3
0.04 sec 15.546 1.0873 14.298
0.05 sec 15.228 1.0652 14.296
0.055328 sec 15.075 1.0652 14.152
0.055328 sec 15.075 1.0652 14.152
0.055328 sec 15.075 1.0652 14.152
0.06 sec 14.949 1.0458 14.294
0.064672 sec 14.832 1.0458 14.182
0.07 sec 14.707 1.0289 14.293
0.08 sec 14.497 1.0143 14.292
0.09 sec 14.317 1.0019 14.29
⋮
检查更新后的通道元数据,并注意新添加的通道的 missing
值。
chanGrp2TT.Properties.CustomProperties
ans = CustomProperties with properties: ChannelGroupAcquisitionName: "" ChannelGroupComment: "Simulation of engine gas dynamics." ChannelGroupSourceName: "" ChannelGroupSourcePath: "" ChannelGroupSourceComment: "" ChannelGroupSourceType: Unspecified ChannelGroupSourceBusType: Unspecified ChannelGroupSourceBusChannelNumber: 0 ChannelDisplayName: ["" "" <missing>] ChannelComment: ["" "" <missing>] ChannelUnit: ["g/s" "g/s" <missing>] ChannelType: [FixedLength FixedLength Missing] ChannelDataType: [RealLittleEndian RealLittleEndian Missing] ChannelNumBits: [64 64 NaN] ChannelComponentType: [None None Missing] ChannelCompositionType: [None None Missing] ChannelSourceName: ["" "" <missing>] ChannelSourcePath: ["" "" <missing>] ChannelSourceComment: ["" "" <missing>] ChannelSourceType: [Unspecified Unspecified Missing] ChannelSourceBusType: [Unspecified Unspecified Missing] ChannelSourceBusChannelNumber: [0 0 0] ChannelReadOption: [All All Missing]
自定义通道组元数据和通道元数据
更新通道组注释,以提供有关对数据所做处理的信息。
chanGrpComment = chanGrp2TT.Properties.CustomProperties.ChannelGroupComment
chanGrpComment = "Simulation of engine gas dynamics."
chanGrp2TT.Properties.CustomProperties.ChannelGroupComment = chanGrpComment + " Update: Removed invalid samples and added new channel ""AirFuelRatio"".";
更新 AirFlow
和 FuelRate
的通道注释,以提供有关通道的详细信息。您可以使用变量索引或变量名称对 ChannelComment
元数据进行索引。
chanGrp2TT.Properties.CustomProperties.ChannelComment(1) = "Air flow logged from simulation."; chanGrp2TT.Properties.CustomProperties.ChannelComment("FuelRate") = "Fuel rate logged from simulation.";
为 AirFuelRatio
添加一个通道注释。
chanGrp2TT.Properties.CustomProperties.ChannelComment(3) = "Air fuel ratio calculated by dividing air flow by fuel rate.";
检查通道元数据,并注意 ChannelGroupComment
和 ChannelComment
中更新后的值。如果不需要对该特定元数据进行自定义,可以保留 missing
值。稍后,当写入 MDF 文件时,将相应地应用默认值或派生的值。
chanGrp2TT.Properties.CustomProperties
ans = CustomProperties with properties: ChannelGroupAcquisitionName: "" ChannelGroupComment: "Simulation of engine gas dynamics. Update: Removed invalid samples and added new channel "AirFuelRatio"." ChannelGroupSourceName: "" ChannelGroupSourcePath: "" ChannelGroupSourceComment: "" ChannelGroupSourceType: Unspecified ChannelGroupSourceBusType: Unspecified ChannelGroupSourceBusChannelNumber: 0 ChannelDisplayName: ["" "" <missing>] ChannelComment: ["Air flow logged from simulation." "Fuel rate logged from simulation." "Air fuel ratio calculated by dividing air flow by fuel rate."] ChannelUnit: ["g/s" "g/s" <missing>] ChannelType: [FixedLength FixedLength Missing] ChannelDataType: [RealLittleEndian RealLittleEndian Missing] ChannelNumBits: [64 64 NaN] ChannelComponentType: [None None Missing] ChannelCompositionType: [None None Missing] ChannelSourceName: ["" "" <missing>] ChannelSourcePath: ["" "" <missing>] ChannelSourceComment: ["" "" <missing>] ChannelSourceType: [Unspecified Unspecified Missing] ChannelSourceBusType: [Unspecified Unspecified Missing] ChannelSourceBusChannelNumber: [0 0 0] ChannelReadOption: [All All Missing]
创建新 MDF 文件
在此步骤中,您需要创建一个名为 VehicleDataNew.mf4
的新 MDF 文件,该文件与原始文件 VehicleData.mf4
具有相同的文件元数据。
使用函数 mdfInfo
获取包含原始 MDF 文件 VehicleData.mf4
的文件元数据的 MDFInfo
对象。
info = mdfInfo("VehicleData.mf4")
info = MDFInfo with properties: File Details Name: "VehicleData.mf4" Path: "/tmp/Bdoc24a_2511836_3090053/tpeb21c448/vnt-ex28629694/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
调用函数 mdfCreate
,将可选参量 FileInfo
设置为刚刚获得的 MDFInfo
对象。这将在磁盘上创建一个新框架 MDF 文件 VehicleDataNew.mf4
,其文件元数据与 VehicleData.mf4
的元数据相同。
mdfCreate("VehicleDataNew.mf4", FileInfo=info)
ans = "/tmp/Bdoc24a_2511836_3090053/tpeb21c448/vnt-ex28629694/VehicleDataNew.mf4"
FileInfo
是可选的名称-值对组。如果未指定,mdfCreate
将使用默认文件元数据创建一个新的框架 MDF 文件。
请注意,mdfCreate
只会将适用的元数据应用到新创建的文件中。例如,像 Name
和 Path
等属性是特定于每个文件的,因此它们会被忽略。
检查文件元数据
要确认 mdfCreate
创建了正确应用文件元数据的 MDF 文件,请使用 mdfInfo
检查 VehicleDataNew.mf4
的文件元数据。请注意 ChannelGroupCount
是 0,因为该文件尚没有通道组。
mdfInfo("VehicleDataNew.mf4")
ans = MDFInfo with properties: File Details Name: "VehicleDataNew.mf4" Path: "/tmp/Bdoc24a_2511836_3090053/tpeb21c448/vnt-ex28629694/VehicleDataNew.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: "24.1.0.2498408 (R2024a) Prerelease Update 3" CreatorUserName: "" CreatorComment: "" File Contents Attachment: [0x7 table] ChannelGroupCount: 0
将更新后的数据写入新 MDF 文件中的新通道组
在未指定可选参量 GroupNumber
的情况下调用函数 mdfWrite
。以此种方式使用时,该函数会将输入时间表作为新通道组追加到目标文件的末尾。由于此时 VehicleDataNew.mf4
是没有通道组的框架文件,此操作会将 chanGrp2TT
写入通道组 1。
mdfWrite("VehicleDataNew.mf4", chanGrp2TT)
检查数据
要确认 mdfWrite
按预期更新了 MDF 文件,请再次查看 VehicleDataNew.mf4
的文件详细信息。请注意 ChannelGroupCount
现在是 1。
mdfInfo("VehicleDataNew.mf4")
ans = MDFInfo with properties: File Details Name: "VehicleDataNew.mf4" Path: "/tmp/Bdoc24a_2511836_3090053/tpeb21c448/vnt-ex28629694/VehicleDataNew.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: "24.1.0.2498408 (R2024a) Prerelease Update 3" CreatorUserName: "" CreatorComment: "" File Contents Attachment: [0x7 table] ChannelGroupCount: 1
从包含元数据的新 MDF 文件中读取通道组 1 的数据。请注意采样数的减少和新通道 AirFuelRatio
。
chanGrp1DataNew = mdfRead("VehicleDataNew.mf4", GroupNumber=1, IncludeMetadata=true)
chanGrp1DataNew = 1x1 cell array
{18634x3 timetable}
chanGrp1TTNew = chanGrp1DataNew{1}
chanGrp1TTNew=18634×3 timetable
time AirFlow FuelRate AirFuelRatio
______________ _______ ________ ____________
0 sec 17.294 1.209 14.304
0.00056199 sec 17.263 1.209 14.278
0.0033719 sec 17.112 1.209 14.154
0.01 sec 16.776 1.1729 14.303
0.02 sec 16.316 1.1409 14.301
0.03 sec 15.907 1.1124 14.3
0.04 sec 15.546 1.0873 14.298
0.05 sec 15.228 1.0652 14.296
0.055328 sec 15.075 1.0652 14.152
0.055328 sec 15.075 1.0652 14.152
0.055328 sec 15.075 1.0652 14.152
0.06 sec 14.949 1.0458 14.294
0.064672 sec 14.832 1.0458 14.182
0.07 sec 14.707 1.0289 14.293
0.08 sec 14.497 1.0143 14.292
0.09 sec 14.317 1.0019 14.29
⋮
检查通道组元数据和通道元数据
通过访问时间表自定义属性,检查通道组 1 和此组中通道的元数据。
chanGrp1TTNew.Properties.CustomProperties
ans = CustomProperties with properties: ChannelGroupAcquisitionName: "" ChannelGroupComment: "Simulation of engine gas dynamics. Update: Removed invalid samples and added new channel "AirFuelRatio"." ChannelGroupSourceName: "" ChannelGroupSourcePath: "" ChannelGroupSourceComment: "" ChannelGroupSourceType: Unspecified ChannelGroupSourceBusType: Unspecified ChannelGroupSourceBusChannelNumber: 0 ChannelDisplayName: ["" "" ""] ChannelComment: ["Air flow logged from simulation." "Fuel rate logged from simulation." "Air fuel ratio calculated by dividing air flow by fuel rate."] ChannelUnit: ["g/s" "g/s" ""] ChannelType: [FixedLength FixedLength FixedLength] ChannelDataType: [RealLittleEndian RealLittleEndian RealLittleEndian] ChannelNumBits: [64 64 64] ChannelComponentType: [None None None] ChannelCompositionType: [None None None] ChannelSourceName: ["" "" ""] ChannelSourcePath: ["" "" ""] ChannelSourceComment: ["" "" ""] ChannelSourceType: [Unspecified Unspecified Unspecified] ChannelSourceBusType: [Unspecified Unspecified Unspecified] ChannelSourceBusChannelNumber: [0 0 0] ChannelReadOption: [All All All]