SiLA2.AnIML 10.2.2

dotnet add package SiLA2.AnIML --version 10.2.2
                    
NuGet\Install-Package SiLA2.AnIML -Version 10.2.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SiLA2.AnIML" Version="10.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SiLA2.AnIML" Version="10.2.2" />
                    
Directory.Packages.props
<PackageReference Include="SiLA2.AnIML" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SiLA2.AnIML --version 10.2.2
                    
#r "nuget: SiLA2.AnIML, 10.2.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SiLA2.AnIML@10.2.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SiLA2.AnIML&version=10.2.2
                    
Install as a Cake Addin
#tool nuget:?package=SiLA2.AnIML&version=10.2.2
                    
Install as a Cake Tool

SiLA2.AnIML Module

AnIML (Analytical Information Markup Language) Support for SiLA2 C# Servers

AnIML Homepage https://www.animl.org
Official Schemas https://github.com/AnIML/schemas
SiLA2 Wiki https://gitlab.com/SiLA2/sila_csharp/-/wikis/home
License MIT

Overview

SiLA2.AnIML is an optional module for the SiLA2 C# implementation that enables standardized storage and exchange of analytical laboratory data. AnIML (Analytical Information Markup Language) is an ASTM standard (E2874-12) widely used in pharmaceutical, biotechnology, and analytical chemistry laboratories for representing experimental data, methods, and results in a vendor-neutral XML format.

This module provides:

  • C# Domain Models: Auto-generated from official AnIML XML schemas (Core and Technique)
  • Document Builder API: Fluent interface for creating AnIML documents with series data
  • XML Serialization & Validation: Automatic XSD validation against embedded AnIML schemas
  • NoSQL Persistence: LiteDB-based repository for storing AnIML documents in BSON format
  • Extension Methods: Helper methods for common operations (series manipulation, XML export)
  • SiLA2 Integration: Seamless integration with SiLA2 servers for scientific data storage

Key Features

  • C# classes generated from official AnIML Core and AnIML Technique schemas
  • ISeriesTypeBuilder for creating AnIML document structures with sample sets and experiment steps
  • ISeriesTypeProvider for adding strongly-typed data series (numeric, string, DateTime, PNG images)
  • AnIMLExtensions for working with series (GetAnIMLSeries, CreateAnIMLSeries, GetAnIMLXml)
  • Automatic XSD validation when serializing to XML (animl-core.xsd, xmldsig-core-schema.xsd)
  • NoSQL repository implementation (IAnIMLRepository) using LiteDB for data persistence
  • Support for both AnIML Core documents and AnIML Technique extensions
  • Independent and dependent variable series with metadata support

Installation

NuGet Package

Install via NuGet Package Manager:

Install-Package SiLA2.AnIML

Or via .NET CLI:

dotnet add package SiLA2.AnIML

Prerequisites

  • .NET 10.0 or later
  • SiLA2.Database.NoSQL (automatically installed as dependency)
  • protobuf-net (automatically installed as dependency)

This module is optional and not required for basic SiLA2 server functionality.

Quick Start

Creating an AnIML Document

using SiLA2.AnIML.Services;
using SiLA2.AnIML.Services.Builder;
using SiLA2.AnIML.Services.Provider;
using AnIMLCore;

// 1. Build the AnIML document structure
var builder = new SeriesTypeBuilder();
var animl = builder.Build(new[] { "Sample 1", "Sample 2" });

// 2. Create series for data storage
animl.CreateAnIMLSeries(numberOfSeries: 2);

// 3. Add data to series using provider
var provider = new SeriesTypeProvider();
var timestamps = new[] { DateTime.Now, DateTime.Now.AddSeconds(1), DateTime.Now.AddSeconds(2) };
var temperatures = new[] { 25.5, 30.2, 35.8 };

var seriesSet = animl.ExperimentStepSet.ExperimentStep[0].Result[0].SeriesSet;
seriesSet.Series[0] = provider.GetSeriesType(timestamps, DependencyType.independent);
seriesSet.Series[1] = provider.GetSeriesType(temperatures, DependencyType.dependent);

// 4. Serialize to validated XML
string xml = animl.GetAnIMLXml();  // Automatically validates against XSD

// 5. Persist to database (requires IAnIMLRepository)
var repository = new AnIMLRepository(liteDatabase);
repository.Create(animl);

Using Extension Methods

using SiLA2.AnIML;

// Get a specific series from the document
var series = animl.GetAnIMLSeries(experimentStep: 0, result: 0, focusedSeries: 1);

// Create multiple series at once
var seriesSet = animl.CreateAnIMLSeries(numberOfSeries: 3);

// Export to validated XML
string validatedXml = animl.GetAnIMLXml();

Integration with SiLA2 Servers

Dependency Injection Setup

In your SiLA2 server's Program.cs:

using SiLA2.AnIML.Services;
using SiLA2.AnIML.Services.Builder;
using SiLA2.AnIML.Services.Provider;
using LiteDB;

var builder = WebApplication.CreateBuilder(args);

// Register LiteDB database
builder.Services.AddSingleton<ILiteDatabase>(sp =>
    new LiteDatabase("AnIMLData.db"));

// Register AnIML services
builder.Services.AddSingleton<IAnIMLRepository, AnIMLRepository>();
builder.Services.AddSingleton<IAnIMLTechniqueRepository, AnIMLTechniqueRepository>();
builder.Services.AddSingleton<ISeriesTypeBuilder, SeriesTypeBuilder>();
builder.Services.AddSingleton<ISeriesTypeProvider, SeriesTypeProvider>();

var app = builder.Build();

Using in a SiLA2 Feature Service

using AnIMLCore;
using SiLA2.AnIML.Services;
using SiLA2.AnIML.Services.Builder;
using SiLA2.AnIML.Services.Provider;

public class MyFeatureService : MyFeature.MyFeatureBase
{
    private readonly IAnIMLRepository _anIMLRepository;
    private readonly ISeriesTypeBuilder _builder;
    private readonly ISeriesTypeProvider _provider;

    public MyFeatureService(
        IAnIMLRepository anIMLRepository,
        ISeriesTypeBuilder builder,
        ISeriesTypeProvider provider)
    {
        _anIMLRepository = anIMLRepository;
        _builder = builder;
        _provider = provider;
    }

    public async Task SaveExperimentData(List<double> values, List<DateTime> timestamps)
    {
        // Build AnIML document
        var animl = _builder.Build(new[] { $"Experiment_{DateTime.Now}" });
        animl.CreateAnIMLSeries(2);

        var seriesSet = animl.ExperimentStepSet.ExperimentStep[0].Result[0].SeriesSet;
        seriesSet.Series[0] = _provider.GetSeriesType(timestamps, DependencyType.independent);
        seriesSet.Series[1] = _provider.GetSeriesType(values, DependencyType.dependent);

        // Persist to database
        _anIMLRepository.Create(animl);
    }

    public IEnumerable<AnIMLType> GetAllExperiments()
    {
        return _anIMLRepository.All();
    }
}

Architecture

Domain Models

The module includes C# classes auto-generated from official AnIML schemas:

  • AnIMLCore namespace: Core AnIML types (AnIMLType, SeriesType, ExperimentStepType, etc.)
  • AnIMLTechnique namespace: Technique-specific extensions

Located in: Domain/animl-core.cs and Domain/animl-technique.cs

Services

Repositories
  • IAnIMLRepository / AnIMLRepository: Persistence layer for AnIML Core documents
  • IAnIMLTechniqueRepository / AnIMLTechniqueRepository: Persistence layer for AnIML Technique documents

Both repositories extend IBaseRepository<T> from SiLA2.Database.NoSQL and support:

  • Create(T entity): Save new document
  • Update(T entity): Update existing document
  • Delete(int id): Remove document
  • FindById(int id): Retrieve by ID
  • All(): Get all documents
Builders
  • ISeriesTypeBuilder / SeriesTypeBuilder: Constructs AnIML document structure
    • Build(string[] sampleSetNames): Creates document with sample sets, experiment steps, results, and series
Providers
  • ISeriesTypeProvider / SeriesTypeProvider: Creates typed series data
    • GetSeriesType<T>(IEnumerable<T> items, DependencyType): For numeric/bool/DateTime values
    • GetSeriesStringType(IEnumerable<string>, ParameterTypeType, DependencyType): For string data
    • GetSeriesPNGType(IEnumerable<byte[]>, DependencyType): For PNG images

Supported types: bool, int, long, float, double, DateTime, string, byte[] (PNG)

Extension Methods

AnIMLExtensions class provides helper methods:

  • GetAnIMLSeries(experimentStep, result, focusedSeries): Navigate to specific series
  • CreateAnIMLSeries(numberOfSeries, experimentStep, result): Create multiple series
  • GetAnIMLXml(): Serialize and validate to XML
  • ValidateAnIMLCoreDocument(): Validate XDocument against AnIML schema

Schema Validation

The module embeds AnIML schemas as resources:

  • Resources/schemas/animl-core.xsd (AnIML Core schema)
  • Resources/xmldsig-core-schema.xsd (XML Digital Signature schema)

When GetAnIMLXml() is called, the serialized XML is automatically validated. Validation errors throw exceptions with detailed error messages.

Data Types and Series

Creating Series with Different Data Types

var provider = new SeriesTypeProvider();

// Numeric data
var temperatures = new[] { 25.5, 30.2, 35.8 };
var tempSeries = provider.GetSeriesType(temperatures, DependencyType.dependent);

// DateTime data (timestamps)
var timestamps = new[] { DateTime.Now, DateTime.Now.AddSeconds(1) };
var timeSeries = provider.GetSeriesType(timestamps, DependencyType.independent);

// Boolean data
var flags = new[] { true, false, true };
var flagSeries = provider.GetSeriesType(flags, DependencyType.dependent);

// String data
var labels = new[] { "Start", "Middle", "End" };
var labelSeries = provider.GetSeriesStringType(labels,
    ParameterTypeType.String, DependencyType.independent);

// PNG images
var imageBytes = File.ReadAllBytes("chart.png");
var imageSeries = provider.GetSeriesPNGType(new[] { imageBytes },
    DependencyType.dependent);

Independent vs Dependent Variables

  • Independent: Input variables (time, wavelength, sample ID)
  • Dependent: Output variables (temperature, absorbance, concentration)
seriesSet.Series[0] = provider.GetSeriesType(
    timePoints, DependencyType.independent);  // X-axis
seriesSet.Series[1] = provider.GetSeriesType(
    measurements, DependencyType.dependent);   // Y-axis

Working Example: Temperature Controller

The Temperature Controller Web Frontend example demonstrates full AnIML integration:

Location: src/Examples/TemperatureController/SiLA2.Temperature.Server.App.Webfrontend

Features:

  • Real-time temperature monitoring with live charts
  • "Save Data as AnIML" button stores temperature readings
  • AnIML viewer page displays saved experiments
  • Demonstrates series creation, data population, and persistence

Run the Example:

dotnet run --project src/Examples/TemperatureController/SiLA2.Temperature.Server.App.Webfrontend/SiLA2.Temperature.Server.App.Webfrontend.csproj

Navigate to:

  • Temperature Monitoring: https://localhost:5011/temperature
  • AnIML Data Viewer: https://localhost:5011/animl

Code Snippet (from Temperature.razor):

private async Task SaveDataAsAnIML()
{
    var ts = DateTime.Now;

    // Build AnIML document
    var animl = SeriesTypeBuilder.Build(new string[] { $"Temperature Sample {ts}" });

    // Create 2 series: timestamps and temperature values
    var seriesSet = animl.CreateAnIMLSeries(2);
    var values = _temperatureData.ToList();  // List<Tuple<double, DateTime>>

    seriesSet.Series[0] = SeriesTypeProvider.GetSeriesType(
        values.Select(x => x.Item2), DependencyType.dependent);  // Timestamps
    seriesSet.Series[1] = SeriesTypeProvider.GetSeriesType(
        values.Select(x => Math.Round(x.Item1, 5)), DependencyType.dependent);  // Temps

    animl.ExperimentStepSet.id = $"ExperimentStepSetId_{ts}";

    // Save to database
    AnIMLRepository.Create(animl);
    NavigationManager.NavigateTo("/animl");
}

Validation

Automatic XSD Validation

When calling GetAnIMLXml(), the module automatically:

  1. Serializes the AnIML document to XML
  2. Loads embedded schemas (animl-core.xsd, xmldsig-core-schema.xsd)
  3. Validates the XML against the schemas
  4. Throws an exception if validation fails
try
{
    string xml = animl.GetAnIMLXml();
    // XML is valid
}
catch (Exception ex)
{
    // Validation error
    Console.WriteLine($"Invalid AnIML document: {ex.Message}");
}

Manual Validation

using System.Xml.Linq;

var xdoc = XDocument.Parse(xmlString);
xdoc.ValidateAnIMLCoreDocument();  // Throws on validation errors

Additional Resources

Contribution

This module is Open Source (MIT License). Contributions are welcome.

Issues: https://gitlab.com/SiLA2/sila_csharp/-/issues

License

MIT License - See repository root for full license text.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.2.2 93 2/12/2026
10.2.1 98 1/25/2026
10.2.0 196 12/23/2025
10.1.0 148 11/29/2025
10.0.0 310 11/11/2025
9.0.4 249 6/25/2025
9.0.3 176 6/21/2025
9.0.2 197 1/6/2025
9.0.1 214 11/17/2024
9.0.0 200 11/13/2024
8.1.2 210 10/20/2024
8.1.1 292 8/31/2024
8.1.0 346 2/11/2024
8.0.0 634 11/15/2023
7.5.4 269 10/27/2023
7.5.3 438 7/19/2023
7.5.2 323 7/3/2023
7.5.1 399 6/2/2023
7.4.6 310 5/21/2023
7.4.5 312 5/7/2023
Loading failed