/// <summary> /// Finds the parent component of the provided channel. /// </summary> /// <param name="channel">The channel that belongs to the component to be searched for.</param> /// <returns>Returns the found <see cref="FamosFileComponent"/>.</returns> public FamosFileComponent FindComponent(FamosFileChannel channel) { return(this.FindFieldAndComponent(channel).Component); }
/// <summary> /// Finds the parent field and component of the provided channel. /// </summary> /// <param name="channel">The channel that belongs to the component and field to be searched for.</param> /// <returns>Returns the found <see cref="FamosFileField"/> and <see cref="FamosFileComponent"/>.</returns> public (FamosFileField Field, FamosFileComponent Component) FindFieldAndComponent(FamosFileChannel channel) { FamosFileField? foundField = null; FamosFileComponent?foundComponent = null; foreach (var field in this.Fields) { foreach (var component in field.Components) { if (component.Channels.Contains(channel)) { foundField = field; foundComponent = component; break; } } if (foundComponent != null) { break; } } if (foundField is null || foundComponent is null) { throw new FormatException($"The provided channel is not part of any {nameof(FamosFileField)} instance."); } return(foundField, foundComponent); }
/// <summary> /// Reads a partial dataset associated to the provided <paramref name="channel"/>. /// </summary> /// <param name="channel">The channel that describes the data to read.</param> /// <param name="start">The reading start offset.</param> /// <returns>Returns a <see cref="FamosFileChannelData"/> instance, which may consists of more than one dataset.</returns> public FamosFileChannelData ReadSingle(FamosFileChannel channel, int start) { return(this.ReadSingle(channel, start, 0)); }
/// <summary> /// Reads a partial dataset associated to the provided <paramref name="channel"/>. /// </summary> /// <param name="channel">The channel that describes the data to read.</param> /// <param name="start">The reading start offset.</param> /// <param name="length">The number of the values to read.</param> /// <returns>Returns a <see cref="FamosFileChannelData"/> instance, which may consists of more than one dataset.</returns> public FamosFileChannelData ReadSingle(FamosFileChannel channel, int start, int length) { (var foundField, var foundComponent) = this.FindFieldAndComponent(channel); List <FamosFileComponent> GetAlternatingComponents() { FamosFileComponentType filter; if (foundComponent.Type == FamosFileComponentType.Primary) { filter = FamosFileComponentType.Secondary; } else if (foundComponent.Type == FamosFileComponentType.Secondary) { filter = FamosFileComponentType.Primary; } else { throw new InvalidOperationException($"The component type '{foundComponent.Type}' is unknown."); } return(new List <FamosFileComponent> { foundComponent, foundField.Components.First(component => component.Type == filter) }); } var components = foundField.Type switch { FamosFileFieldType.MultipleYToSingleEquidistantTime => new List <FamosFileComponent>() { foundComponent }, FamosFileFieldType.MultipleYToSingleMonotonousTime => GetAlternatingComponents().OrderBy(current => current.Type).ToList(), FamosFileFieldType.MultipleYToSingleXOrViceVersa => GetAlternatingComponents().OrderBy(current => current.Type).ToList(), _ => foundField.Components.OrderBy(current => current.Type).ToList() }; var componentsData = new List <FamosFileComponentData>(); var cache = new Dictionary <FamosFileComponent, FamosFileComponentData>(); foreach (var currentComponent in components) { if (cache.ContainsKey(currentComponent)) { componentsData.Add(cache[currentComponent]); continue; } T?FindFirst <T>(FamosFileField field, FamosFileComponent component, T?defaultValue, Func <FamosFileComponent, T?> getPropertyValue) where T : class { var selfValue = getPropertyValue(component); var selfOrParentValue = selfValue ?? defaultValue; if (selfOrParentValue != null) { return(selfOrParentValue); } else { var index = field.Components.IndexOf(component); var siblingValue = field.Components.Take(index).FirstOrDefault(component => getPropertyValue(component) != null); return(siblingValue != null?getPropertyValue(siblingValue) : null); } } // find shared instances var xAxisScaling = FindFirst(foundField, currentComponent, foundField.XAxisScaling, current => current.XAxisScaling); var zAxisScaling = FindFirst(foundField, currentComponent, foundField.ZAxisScaling, current => current.ZAxisScaling); var triggerTime = FindFirst(foundField, currentComponent, foundField.TriggerTime, current => current.TriggerTime); // FamosFileComponentData componentData; var data = this.ReadComponentData(currentComponent, start, length); componentData = currentComponent.PackInfo.DataType switch { FamosFileDataType.UInt8 => new FamosFileComponentData <Byte>(currentComponent, xAxisScaling, zAxisScaling, triggerTime, data), FamosFileDataType.Int8 => new FamosFileComponentData <SByte>(currentComponent, xAxisScaling, zAxisScaling, triggerTime, data), FamosFileDataType.UInt16 => new FamosFileComponentData <UInt16>(currentComponent, xAxisScaling, zAxisScaling, triggerTime, data), FamosFileDataType.Int16 => new FamosFileComponentData <Int16>(currentComponent, xAxisScaling, zAxisScaling, triggerTime, data), FamosFileDataType.UInt32 => new FamosFileComponentData <UInt32>(currentComponent, xAxisScaling, zAxisScaling, triggerTime, data), FamosFileDataType.Int32 => new FamosFileComponentData <Int32>(currentComponent, xAxisScaling, zAxisScaling, triggerTime, data), FamosFileDataType.Float32 => new FamosFileComponentData <Single>(currentComponent, xAxisScaling, zAxisScaling, triggerTime, data), FamosFileDataType.Float64 => new FamosFileComponentData <Double>(currentComponent, xAxisScaling, zAxisScaling, triggerTime, data), FamosFileDataType.ImcDevicesTransitionalRecording => throw new NotSupportedException($"Reading data of type '{FamosFileDataType.ImcDevicesTransitionalRecording}' is not supported."), FamosFileDataType.AsciiTimeStamp => throw new NotSupportedException($"Reading data of type '{FamosFileDataType.AsciiTimeStamp}' is not supported."), FamosFileDataType.Digital16Bit => new FamosFileComponentData <UInt16>(currentComponent, xAxisScaling, zAxisScaling, triggerTime, data), FamosFileDataType.UInt48 => throw new NotSupportedException($"Reading data of type '{FamosFileDataType.UInt48}' is not supported."), _ => throw new NotSupportedException($"The specified data type '{currentComponent.PackInfo.DataType}' is not supported.") }; componentsData.Add(componentData); cache[currentComponent] = componentData; } return(new FamosFileChannelData(foundComponent.Name, foundField.Type, componentsData)); }
/// <summary> /// Reads the full length dataset associated to the provided <paramref name="channel"/>. /// </summary> /// <param name="channel">The channel that describes the data to read.</param> /// <returns>Returns a <see cref="FamosFileChannelData"/> instance, which may consists of more than one dataset.</returns> public FamosFileChannelData ReadSingle(FamosFileChannel channel) { return(this.ReadSingle(channel, 0, 0)); }