Main Content

将通道组数据从现有 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 设置为 truemdfRead 函数从通道组 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 创建一个堆叠图,以可视化通道 AirFlowFuelRate 中的数据。

stackedplot(chanGrp2TT, ["AirFlow", "FuelRate"])

Figure contains an object of type stackedplot.

从该堆叠图中可以观察到,从大约 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"".";

更新 AirFlowFuelRate 的通道注释,以提供有关通道的详细信息。您可以使用变量索引或变量名称对 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.";

检查通道元数据,并注意 ChannelGroupCommentChannelComment 中更新后的值。如果不需要对该特定元数据进行自定义,可以保留 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 只会将适用的元数据应用到新创建的文件中。例如,像 NamePath 等属性是特定于每个文件的,因此它们会被忽略。

检查文件元数据

要确认 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]