--- source_files: - DataPRO/SensorDB/TDM/TDMCSVImport.cs generated_at: "2026-04-16T04:04:16.780744+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "c16790456aa03ce4" --- # TDMCSVImport Documentation ## 1. Purpose The `TDMCSVImport` class provides logic for importing sensor configuration data from a CSV file into the system’s internal `SensorData` representation. It parses CSV rows (one per sensor) using a predefined set of column labels, maps string values to strongly-typed enums and properties, and constructs a fully initialized `SensorData` object. This module serves as the ingestion layer for legacy TDM (Test Data Manager) CSV exports, supporting a wide range of sensor types (full/half bridge, voltage, IRTRACC, potentiometers, angular rate sensors), calibration parameters, zeroing methods, filtering options, and Toyota-specific calculations. It is part of the `DTS.SensorDB.TDM` namespace and is used in contexts where CSV-based sensor metadata must be ingested into the sensor database. ## 2. Public Interface ### `public static TAGS LabelToTag(string label)` - **Signature**: `public static TAGS LabelToTag(string label)` - **Behavior**: Converts a CSV column header string (e.g., `"Serial No"`, `"Filter Type"`) into the corresponding `TAGS` enum value. Throws `NotSupportedException` if the label is unrecognized. - **Note**: This is the only public method in the class. ### Nested Types (used internally) The following enums are declared as `private` but are essential to understanding the mapping logic: - **`MeasurementTypes`**: Internal enum representing sensor measurement types (e.g., `MEASTYPE_FULLBRIDGE`, `MEASTYPE_IRTRACC`, `MEASTYPE_ARS_ANGLE`). Used to determine bridge type and calibration behavior. - **`FilterTypes`**: Internal enum representing filter types (e.g., `FILTERTYPE_CFC60`, `FILTERTYPE_FIR100`, `FILTERTYPE_USEFREQ`). Maps to `FilterClassType` or `FilterClass` constructor overloads. - **`ZeroMethods`**: Internal enum representing zeroing strategies (`ZMETHOD_PREZERO`, `ZMETHOD_AVGTIME`, `ZMETHOD_EQUALS0MV`). - **`TAGS`**: Public enum listing all supported CSV column labels (e.g., `SENSOR_CSV_LABEL_SERIAL_NO`, `SENSOR_CSV_LABEL_FILTER_TYPE`). Includes an `UNKNOWN` entry for unrecognized columns. ### Private Helper Methods (not part of public interface, but documented for completeness) - `private static MeasurementTypes LabelToMeasurementType(string label)` Converts CSV string labels (e.g., `"Full Bridge"`) to `MeasurementTypes`. - `private static string MeasurementTypeToLabel(MeasurementTypes mt)` Converts `MeasurementTypes` back to CSV labels. - `private static string TagToLabel(TAGS tag)` Converts `TAGS` enum to CSV column header strings. ### `public static DTS.SensorDB.SensorData GetSensor(...)` - **Signature**: ```csharp public static DTS.SensorDB.SensorData GetSensor( string[] tokens, TAGS[] tagOrder, ref List errors, Dictionary sensorTypeToDimension) ``` - **Behavior**: Parses a single CSV row (`tokens`) using the column order specified in `tagOrder`. Populates a new `SensorData` instance with values from the row. Errors encountered during parsing (e.g., invalid numbers, unrecognized labels) are appended to the `errors` list. The `sensorTypeToDimension` dictionary maps sensor type strings (e.g., `"Accelerometer"`) to physical dimension strings (e.g., `"Acceleration"`), which are used to set `sd.PhysicalDimension`. Key behaviors: - Trims and normalizes string tokens (removes leading `=`, surrounding quotes). - Handles date parsing for `"Calibration Date"` (supports `/` or `-` separators). - Defaults excitation voltage to 5V if `0` is provided in CSV. - Sets `sd.UUID = sd.SerialNumber`. - Applies default values for missing `Capacity` (→ 1) and `DisplayUnit` (→ `"g"`), logging warnings. - For `MEASTYPE_IRTRACC`, sets `NonLinear = true` and configures non-linear calibration parameters. - Maps `FilterTypes.FILTERTYPE_FIR100` to `CFC180` with a warning (unsupported). - Stores Toyota calculation strings (`calc1`, `calc2`, `calc3`) concatenated into `sd.UserValue3`. ## 3. Invariants - **`SensorData` must always be initialized**: A new `SensorData` and `SensorCalibration` are created unconditionally at the start of `GetSensor`. - **`Bridge` type is always set**: Based on `MeasurementType`, `sd.Bridge` is assigned one of `FullBridge`, `HalfBridge_SigPlus`, or (implicitly) defaults to one of these. - **`Calibration.Records.Records[0]` is always populated**: The first calibration record is always initialized and updated with sensitivity, units, and other fields. - **`DisplayUnit` and `EngineeringUnits` are always set**: If missing in CSV, defaults to `"g"` and applies to all calibration records (per FB16398). - **`Capacity` is always ≥ 1**: If `Capacity < 1`, it is set to `1` and a warning is logged. - **`UUID` is always set to `SerialNumber`**: `sd.UUID = sd.SerialNumber` is applied unconditionally. - **Filter is always assigned**: Even if `FILTERTYPE_FIR100` is unsupported, a fallback filter (`CFC180`) is assigned. - **`Invert`, `Shunt`, `RemoveOffset` are always set**: Boolean fields default to `false` if parsing fails, but are never left uninitialized. ## 4. Dependencies ### Module Dependencies (from `using` directives and type references): - `DTS.Common.Classes.Sensors` — Provides `SensorData`, `SensorCalibration`, `SensorConstants`. - `DTS.Common.DAS.Concepts` — Provides `ExcitationVoltageOptions`, `Test.Module.Channel.Sensor.GetExcitationVoltageEnumFromMagnitude`. - `DTS.Common.Enums`, `DTS.Common.Enums.Sensors` — Provides `NonLinearStyles`, `ShuntMode`, `ZeroMethodType`, `SensorConstants.SensUnits`. - `System`, `System.Collections.Generic`, `System.Linq`, `System.Text` — Standard .NET types. ### External Dependencies (inferred): - `DTS.SensorDB.SensorData` — The primary output type; implies a dependency on the `DTS.SensorDB` assembly. - `FilterClass` and `FilterClassType` — Used to instantiate filters; implies a dependency on a filtering subsystem. - `InitialOffsets`, `InitialOffset` — Used for zeroing; implies a dependency on zeroing-related types. ### Inbound Dependencies: - This module is used by callers that provide CSV rows and a `sensorTypeToDimension` mapping (likely derived from a sensor type catalog). - Requires `SensorData` and related types to be fully defined and compatible with the properties being set. ### Outbound Dependencies: - None explicitly declared beyond the above; this module is a leaf in the data ingestion pipeline. ## 5. Gotchas - **`FILTERTYPE_FIR100` is unsupported**: The code maps it to `CFC180` and logs a warning, but this may cause unexpected filter behavior if FIR100 was intended. - **Zeroing parameters are only applied to `Methods[0]`**: `ZeroTimeStartMsec`, `ZeroTimeEndMsec`, and `ZeroInitialEU` only populate the first zero method (`Methods[0]`). If multiple zero methods are expected, this may be incomplete. - **`Range_3` is commented out**: The `SENSOR_CSV_LABEL_RANGE_3` case is present but commented out; it does not set `sd.Capacity` despite the comment suggesting it might. - **Excitation voltage `0` is treated as 5V**: This is explicitly handled as a special case for “Voltage Insertion” mode, but may be non-obvious to callers. - **Date parsing is fragile**: Supports only `MM/DD/YYYY` or `YYYY-MM-DD` formats; other formats (e.g., `DD/MM/YYYY`) will fail unless the CSV uses unambiguous separators or ISO 8601. - **`UNKNOWN` tag is silently ignored**: Any CSV column not in `TAGS` is mapped to `TAGS.UNKNOWN` and skipped. - **`UserValue1`/`UserValue2`/`UserValue3` are repurposed**: `JCODE` → `UserValue1`, `CODE` → `UserValue2`, and concatenated Toyota calcs → `UserValue3`. This may conflict with other uses of these fields elsewhere. - **`SensorType` validation is dictionary-dependent**: If `sensorTypeToDimension` does not contain the provided sensor type string, an error is logged but `PhysicalDimension` remains unset (defaulting to `null` or empty). - **No validation of `SensitivityUnits` consistency**: The code sets `IsProportional` based on units, but does not validate whether the combination of `SensitivityUnits`, `BridgeType`, and `MeasurementType` is physically meaningful. - **`RemoveOffset` parsing is case-insensitive but not robust**: Accepts `"1"/"T"/"Y"` and `"0"/"F"/"N"` but not `"true"/"false"` or `"yes"/"no"` explicitly. - **`Invert` parsing is case-insensitive but limited**: Accepts `"0"/"F"/"N"` and `"1"/"Y"/"T"` but not `"true"/"false"`. None identified beyond those listed above.