All skills
anthropics avatar

/instrument-data-to-allotrope

@7c35640

Convert laboratory instrument output files (PDF, CSV, Excel, TXT) to Allotrope Simple Model (ASM) JSON format or flattened 2D CSV. Use this skill when scientists need to standardize instrument data for LIMS systems, data lakes, or downstream analysis. Supports auto-detection of instrument types. Outputs include full ASM JSON, flattened CSV for easy import, and exportable Python code for data engineers. Common triggers include converting instrument files, standardizing lab data, preparing data for upload to LIMS/ELN systems, or generating parser code for production pipelines.

Use this Skill: https://skilld.dev/gh/anthropics/knowledge-work-plugins/instrument-data-to-allotrope

This session only. Nothing lands on disk.

referencesflattening_guide.md

≈1.9k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Flattening ASM to 2D CSV

Converting hierarchical ASM JSON to flat 2D tables for LIMS import, spreadsheet analysis, or data engineering pipelines.

Why Flatten?

ASM is semantically rich but hierarchical. Many systems need flat tables:

  • LIMS import (Benchling, STARLIMS, LabWare)
  • Excel/CSV analysis
  • Database loading
  • Quick visual inspection

Flattening Strategy

Core Principle

Each measurement becomes one row. Metadata is repeated per row.

What's Excluded

The flattening intentionally omits top-level ASM metadata such as:

  • $asm.manifest (model version, schema URIs)
  • Root-level fields outside the technique aggregate document

This keeps the output focused on experimental data. If you need schema version tracking for compliance or audit purposes, consider storing the original ASM JSON alongside the flattened CSV, or modify the flattening script to include these fields.

Hierarchy to Columns

ASM Hierarchy                    → Flat Column
─────────────────────────────────────────────────
device-system-document.
  device-identifier              → instrument_serial_number
  model-number                   → instrument_model
  
measurement-aggregate-document.
  analyst                        → analyst
  measurement-time               → measurement_datetime
  
measurement-document[].
  sample-identifier              → sample_id
  viable-cell-density.value      → viable_cell_density
  viable-cell-density.unit       → viable_cell_density_unit
  viability.value                → viability_percent

Column Naming Convention

Use snake_case with descriptive suffixes:

ASM Field Flat Column
viable-cell-density viable_cell_density
.value _value (or omit if obvious)
.unit _unit
measurement-time measurement_datetime

Example: Cell Counting

ASM Input (simplified)

{
  "cell-counting-aggregate-document": {
    "device-system-document": {
      "device-identifier": "VCB001",
      "model-number": "Vi-CELL BLU"
    },
    "cell-counting-document": [{
      "measurement-aggregate-document": {
        "analyst": "jsmith",
        "measurement-time": "2024-01-15T10:30:00Z",
        "measurement-document": [
          {
            "sample-identifier": "Sample_A",
            "viable-cell-density": {"value": 2500000, "unit": "(cell/mL)"},
            "viability": {"value": 95.2, "unit": "%"}
          },
          {
            "sample-identifier": "Sample_B",
            "viable-cell-density": {"value": 1800000, "unit": "(cell/mL)"},
            "viability": {"value": 88.7, "unit": "%"}
          }
        ]
      }
    }]
  }
}

Flattened Output

sample_id,viable_cell_density,viable_cell_density_unit,viability_percent,analyst,measurement_datetime,instrument_serial_number,instrument_model
Sample_A,2500000,(cell/mL),95.2,jsmith,2024-01-15T10:30:00Z,VCB001,Vi-CELL BLU
Sample_B,1800000,(cell/mL),88.7,jsmith,2024-01-15T10:30:00Z,VCB001,Vi-CELL BLU

Example: Plate Reader

ASM Input (simplified)

{
  "plate-reader-aggregate-document": {
    "plate-reader-document": [{
      "measurement-aggregate-document": {
        "plate-identifier": "ELISA_001",
        "measurement-document": [
          {"well-location": "A1", "absorbance": {"value": 0.125, "unit": "mAU"}},
          {"well-location": "A2", "absorbance": {"value": 0.892, "unit": "mAU"}},
          {"well-location": "A3", "absorbance": {"value": 1.456, "unit": "mAU"}}
        ]
      }
    }]
  }
}

Flattened Output

plate_id,well_position,absorbance,absorbance_unit
ELISA_001,A1,0.125,mAU
ELISA_001,A2,0.892,mAU
ELISA_001,A3,1.456,mAU

Handling Data Cubes

Data cubes (time series, spectra) need special handling:

Option 1: Expand to rows

Each point becomes a row:

sample_id,time_seconds,absorbance
Sample_A,0,0.100
Sample_A,60,0.125
Sample_A,120,0.150

Option 2: Wide format

Measurements as columns:

sample_id,abs_0s,abs_60s,abs_120s
Sample_A,0.100,0.125,0.150

Option 3: JSON array in cell

Keep as array (some systems support this):

sample_id,absorbance_timeseries
Sample_A,"[0.100,0.125,0.150]"

Standard Column Sets by Technique

Cell Counting

sample_id, viable_cell_density, viable_cell_density_unit, total_cell_count,
viability_percent, average_cell_diameter, average_cell_diameter_unit,
analyst, measurement_datetime, instrument_serial_number

Spectrophotometry

sample_id, wavelength_nm, absorbance, pathlength_cm, concentration,
concentration_unit, a260_a280_ratio, a260_a230_ratio,
analyst, measurement_datetime, instrument_serial_number

Plate Reader / ELISA

plate_id, well_position, sample_type, sample_id, absorbance, absorbance_unit,
concentration, concentration_unit, dilution_factor, cv_percent,
analyst, measurement_datetime, instrument_serial_number

qPCR

sample_id, target_name, well_position, ct_value, ct_mean, ct_sd,
quantity, quantity_unit, amplification_efficiency,
analyst, measurement_datetime, instrument_serial_number

Python Implementation

import json
import pandas as pd

def flatten_asm(asm_dict, technique="cell-counting"):
    """
    Flatten ASM JSON to pandas DataFrame.
    
    Args:
        asm_dict: Parsed ASM JSON
        technique: ASM technique type
        
    Returns:
        pandas DataFrame with one row per measurement
    """
    rows = []
    
    # Get aggregate document
    agg_key = f"{technique}-aggregate-document"
    agg_doc = asm_dict.get(agg_key, {})
    
    # Extract device info
    device = agg_doc.get("device-system-document", {})
    device_info = {
        "instrument_serial_number": device.get("device-identifier"),
        "instrument_model": device.get("model-number")
    }
    
    # Get technique documents
    doc_key = f"{technique}-document"
    for doc in agg_doc.get(doc_key, []):
        meas_agg = doc.get("measurement-aggregate-document", {})
        
        # Extract common metadata
        common = {
            "analyst": meas_agg.get("analyst"),
            "measurement_datetime": meas_agg.get("measurement-time"),
            **device_info
        }
        
        # Extract each measurement
        for meas in meas_agg.get("measurement-document", []):
            row = {**common}
            
            # Flatten measurement fields
            for key, value in meas.items():
                if isinstance(value, dict) and "value" in value:
                    # Value datum pattern
                    col = key.replace("-", "_")
                    row[col] = value["value"]
                    if "unit" in value:
                        row[f"{col}_unit"] = value["unit"]
                else:
                    row[key.replace("-", "_")] = value
            
            rows.append(row)
    
    return pd.DataFrame(rows)

# Usage
with open("asm_output.json") as f:
    asm = json.load(f)

df = flatten_asm(asm, "cell-counting")
df.to_csv("flattened_output.csv", index=False)

LIMS Import Considerations

When importing flattened data into a LIMS:

  • Match column names to your LIMS schema field names
  • Use ISO 8601 date format for timestamps
  • Ensure sample IDs match existing LIMS sample identifiers
  • Check if your LIMS expects units in separate columns or embedded in values

Source: SKILL.md on GitHub

1 warning16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides tools for converting laboratory instrument data into standardized Allotrope Simple Model (ASM) formats. It uses established scientific libraries and includes features for data validation and provenance tracking, which align with security best practices for data integrity.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    11/11 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 7c35640. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last week.

Activeupdated 8 months ago

README badge

README badge for anthropics/knowledge-work-plugins/instrument-data-to-allotrope