Files

141 lines
10 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- Common/DTS.Common.Serialization/FIAT_ASC/FIAT_Asc.File.cs
- Common/DTS.Common.Serialization/FIAT_ASC/FIAT_Asc.File.Writer.cs
generated_at: "2026-04-16T03:39:24.624240+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "7db16756696bba31"
---
# FIAT_ASC.File Module Documentation
## 1. Purpose
This module provides serialization support for exporting test data to the FIAT ASC (Automotive Signal Converter) format, a CSV-based file format used in automotive testing environments. It defines the `DTS.Serialization.FIAT_ASC.File` class, which represents a FIAT `.asc` file and encapsulates the logic for exporting `Test` objects to disk. The module handles per-channel file generation, data scaling/linearization, subsampling, filtering, progress reporting, cancellation support, and disk space validation prior to export. It is part of the broader DTS (Data Transfer System) serialization framework and integrates with existing channel, module, and test abstractions.
## 2. Public Interface
### `DTS.Serialization.FIAT_ASC.File`
- **`public bool UseFlatExportFolders { get; set; } = false;`**
Controls whether exported channel files are placed directly in the target directory (`true`) or in a subfolder (`false`). *Note: This property is set on the `File` instance but is only applied when initializing the `Exporter`.*
- **`public File()`**
Default constructor. Initializes the base class with `"ASC"` as the format identifier.
- **`public static string Extension => ".asc";`**
Returns the file extension used by this format (`.asc`).
- **`public IWriter<Test> Exporter { get; }`**
Lazily initializes and returns an `IWriter<Test>` instance (`FIAT_Asc.File.Writer`) configured with the current `File` instance and `DefaultEncoding`. The writers `UseFlatExportFolder` property is set from `UseFlatExportFolders`. Throws a wrapped exception if initialization fails.
### `DTS.Serialization.FIAT_ASC.File.Writer`
- **`internal Writer(File fileType, int encoding)`**
Internal constructor. Initializes the writer with the owning `File` instance and encoding index. Sets `WriterParent` to `fileType`.
- **`internal File WriterParent { get; }`**
Reference to the owning `File` instance.
- **`public event BeginEventHandler OnBegin;`**
Event raised when a write operation starts. Payload includes total expected ticks.
- **`public event EndEventHandler OnEnd;`**
Event raised when a write operation completes (successfully or not).
- **`public event TickEventHandler OnTick;`**
Event raised periodically during export to report progress. Payload is a percentage (0100).
- **`public event CancelEventHandler OnCancel;`**
Event raised if the write operation is cancelled.
- **`public event ErrorEventHandler OnError;`**
Event raised when a fatal error occurs during export.
- **`public Dictionary<string, FilteredData> FilteredChannelData { get; set; }`**
Gets or sets a dictionary mapping channel IDs to pre-filtered data (`FilteredData`). Used when exporting filtered data instead of raw ADC values.
- **`public void Write(string pathname, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength)`**
Convenience overload of `Write(...)`. Delegates to the full signature with most parameters set to `null` or defaults. Writes one `.asc` file per channel in `test.Channels`, each named after the channels description or ISO name.
- **`public void Write(string pathname, string id, string dataFolder, Test test, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler beginEventHandler, CancelEventHandler cancelEventHandler, EndEventHandler endEventHandler, TickEventHandler tickEventHandler, ErrorEventHandler errorEventHandler, CancelRequested cancelRequested, double minStartTime, int dataCollectionLength)`**
Main export method. Writes one `.asc` file per channel in `test.Channels`. For each channel:
- Creates the target directory if missing.
- Generates a channel-specific filename using `channel.ChannelName2`, `AIC.Description`, or fallbacks.
- Writes a header (start time, sample interval, sample count) followed by data rows.
- Applies scaling, linearization, subsampling (if `SubSampleInterval > 1`), and filtering (if `Filtered` is `true`).
- Dispatches progress ticks every `DataSamplesPerTick` (1000) samples.
- Supports cancellation via `cancelRequested`.
- Validates disk space before writing via `VerifyExportedFileWillFitOnDisk`.
- Raises `OnBegin`, `OnTick`, `OnEnd`, `OnCancel`, and `OnError` events.
- **`public void Initialize(...)`**
Empty stub method. No-op.
- **`public double Start { get; set; } = 0D;`**
Start time (in seconds) relative to the tests global trigger time. Used to clip data export.
- **`public double Stop { get; set; } = 0D;`**
Stop time (in seconds) relative to the tests global trigger time. Used to clip data export. *Default value of `0D` likely means "no clipping" or "use full data", but behavior depends on downstream logic.*
- **`public ushort SubSampleInterval { get; set; } = 1;`**
Subsampling factor. When `> 1`, data is decimated using `NHTSASubSample<T>` before export.
- **`public bool Filtered { get; set; } = true;`**
If `true`, uses `FilteredChannelData` for export; otherwise, uses raw `PersistentChannelInfo.Data`.
## 3. Invariants
- **File naming**: Each channel is written to a separate file named after `channel.ChannelName2` (or `AIC.Description` for `AnalogInputChannel`), with invalid path characters (`\`, `/`) replaced by `_`. Extension is `.asc`.
- **Data format**: Each `.asc` file begins with two header lines:
1. `startTime sampleInterval` (both formatted as `"F8"`, i.e., 8 decimal places).
2. `sampleCount` (integer).
- **Sample rate**: All channels in a single `Write` call are assumed to share the same sample rate (`sampleRate`) for time alignment, though per-channel metadata (`ChannelWithMeta`) stores individual rates.
- **Time alignment**: Data is aligned to a global `minStartTime` computed across channels. Missing data at a given time index is written as `NaN`.
- **Scaling**: Data is converted to engineering units (EU) using `DataScaler`, which applies linearization, offset, scaling factors, IEPE, digital mode, etc.
- **Subsampling**: Applied *before* export if `SubSampleInterval > 1`, regardless of `Filtered` flag. Modifies `channel.PersistentChannelInfo.Data` or `filteredData[channel.ChannelId].Data` in-place.
- **Disk space**: `VerifyExportedFileWillFitOnDisk` is called before writing. It estimates file size by subsampling the data and compares against available disk space. Throws `UserException` if insufficient space.
- **Cancellation**: The `cancelRequested` delegate is checked at multiple points (header computation, disk space check, data loop). If true, writing stops early and `OnCancel` is raised.
## 4. Dependencies
### Dependencies *of* this module:
- **Core abstractions**:
- `DTS.Serialization.Test`, `Test.Module`, `Test.Module.Channel`, `AnalogInputChannel`
- `DTS.Serialization.File` (base class)
- `IWriter<Test>` interface
- **Data structures**:
- `FilteredData` (type not shown; assumed to contain `double[] Data`)
- `ChannelWithMeta` (type not shown; assumed to hold channel, scaler, sample rate, start time)
- `DataScaler` (type not shown; handles EU conversion)
- `NHTSASubSample<T>` (type not shown; performs decimation)
- **Utilities**:
- `DTS.Common.Utilities.FileUtils.GetEncoding`
- `DTS.Common.Utilities.Logging.APILogger`
- `DTS.Common.DAS.Concepts.Sensors.SensorConstants` (for `BridgeType`)
- `DTS.Common.DAS.Concepts.Sensors.ZeroMethodType`
- `DiskUtility.GetDiskFreeSpaceEx`, `GetHumanReadableBytes`
- `System.IO.Path`, `Directory`, `FileStream`, `StreamWriter`
- `System.Text.Encoding`
- **Event handlers**:
- `BeginEventHandler`, `EndEventHandler`, `TickEventHandler`, `CancelEventHandler`, `ErrorEventHandler` (types not shown; assumed delegate signatures)
- `CancelRequested` delegate (returns `bool`)
### Dependencies *on* this module:
- Likely consumed by higher-level export services (e.g., `TestSerializer`, UI export dialogs) that instantiate `FIAT_ASC.File` and call `Exporter.Write(...)`.
- Not directly referenced in source, but implied by `IWritable<Test>` interface implementation.
## 5. Gotchas
- **`Stop = 0D` behavior**: The `Stop` property defaults to `0D`. Its semantics are unclear—likely means "no clipping" (use full data), but this must be verified against `ChannelWithMeta.GetMinStopTime` logic.
- **In-place data modification**: Subsampling modifies `channel.PersistentChannelInfo.Data` or `filteredData[...]` *in-place*. This may cause side effects if the same `Test` object is reused.
- **`Filtered` flag default**: `Filtered` defaults to `true`, meaning the writer expects `FilteredChannelData` to be populated. If not, `NaN` values will be written for missing entries.
- **`UseFlatExportFolder` not used in `Write`**: The `UseFlatExportFolder` property on `Writer` is set only during `Exporter` initialization. The `Write(...)` method ignores it and always writes directly to `destFolder` (derived from `pathname`).
- **`Initialize` is a no-op**: The `Initialize(...)` method has no implementation. Its purpose is unclear.
- **`ISOViewMode` fallback**: Channel name resolution falls back to ISO/user code modes only if `OriginalChannelName` is null/empty. This is explicitly noted as a workaround for SQUIB channel issues.
- **`VerifyExportedFileWillFitOnDisk` subsampling heuristic**: The disk space check subsamples data (`segmentSize = dataCollectionLength / 2000000`) to avoid expensive computation. This may underestimate file size for small datasets.
- **`DataSamplesPerTick` hard-coded**: Progress ticks are dispatched every 1000 samples. This may be too coarse/fine for some use cases.
- **`System.Windows.Forms.Application.DoEvents()`**: Used in the data loop to keep UI responsive. This implies a dependency on WinForms and may cause reentrancy issues if not handled carefully.
- **`NUMBER_FORMAT = "F8"`**: All numeric output uses 8 decimal places. This may cause precision issues or large file sizes for high-resolution data.
- **`FilteredChannelData` keying**: Uses `channel.ChannelId` as the dictionary key. Ensure channel IDs are stable and unique across tests.