Applied Module 12 Β· AI-Powered Bioinformatics Tools

Skeletal Element Inventory Visualizer

What you'll learn

~25 min
  • Build a skeletal element inventory visualizer with a single AI prompt
  • Parse recovery inventory CSV and highlight elements on an interactive SVG skeleton diagram
  • Troubleshoot common issues with SVG rendering, element mapping, and MNI calculations
  • Customize the visualizer with condition scoring, side-by-side comparison, or printable inventory sheets

What you’re building

A forensic anthropologist opens a storage box at the DPAA laboratory. Inside are skeletal elements from a Pacific battlefield recovery β€” commingled remains from what the field team believes is at least two individuals. Every bone needs to be inventoried: which elements are present, which side they come from, what condition they are in, and critically, how many individuals are represented. Right now that inventory is recorded on a paper osteological form β€” a printed outline of a skeleton where the anthropologist shades in recovered elements by hand, then manually counts duplicated elements to estimate the minimum number of individuals.

A browser-based inventory visualizer that accepts a CSV CSV Comma-Separated Values β€” a text file where each line is a row and commas separate columns. Exportable from Excel, Google Sheets, etc. Full lesson → of recovered elements and highlights them on an interactive SVG skeleton diagram would let the analyst see completeness at a glance, calculate MNI automatically, and generate a printable inventory sheet β€” all from a single HTML file that runs on any lab computer.

That is what you will build in the next 25 minutes.

⚠Educational prototype only

This tool demonstrates osteological inventory concepts for training purposes. Real forensic work requires validated, accredited inventory systems that meet federal evidence standards and laboratory SOPs. This is a training prototype, not a validated forensic evidence system.

πŸ’¬Paper forms have real limits

Paper osteological inventory forms are the standard in forensic anthropology labs, but they fail in specific ways: they cannot be searched, they cannot calculate MNI automatically, they cannot be shared digitally without scanning, and when you shade in element 47 of 206, mistakes are permanent. A digital inventory does not replace the analyst’s expertise β€” it replaces the paper.

By the end of this lesson you will have a skeletal element inventory visualizer that runs entirely in the browser. It accepts a CSV upload of recovered elements, renders a simplified anterior-view SVG skeleton with highlighted regions for each recovered bone, calculates MNI from duplicate elements, and provides a detail sidebar for element-level metadata. You will build it by giving a single, carefully-crafted prompt to an LLM CLI tool.

β„ΉSoftware pattern: Upload β†’ map β†’ visualize

Parse structured data from a CSV, map each row to a visual region, and render an interactive diagram. This pattern works for any spatial inventory: anatomical specimens on a body map, equipment locations on a floor plan, sensor readings on a facility diagram.

πŸ”Domain Primer: Key osteological inventory terms

New to forensic osteology? Here are the key terms you will encounter:

  • Skeletal element β€” An individual bone in the human skeleton. The adult skeleton has 206 named bones. In forensic contexts, elements are identified by name, side (left/right for paired bones), and portion (complete, proximal, distal, fragment).
  • Osteological inventory β€” A systematic catalog of which skeletal elements have been recovered from a case. The inventory records element identity, side, completeness, condition, and any pathological or taphonomic observations.
  • MNI (Minimum Number of Individuals) β€” The smallest number of individuals that can account for all recovered elements. Determined by finding the most frequently duplicated element. Example: if you have 3 left femora, the MNI is at least 3 regardless of how many other bones are present.
  • Commingled remains β€” Skeletal elements from multiple individuals mixed together in the same context. Common in mass graves, battlefield recoveries, and mass disaster scenes. Sorting commingled remains is one of the most challenging tasks in forensic anthropology.
  • Side designation (L/R) β€” Whether a bone is from the left or right side of the body. Paired bones (femora, humeri, tibiae, etc.) must be sided. Midline bones (sacrum, sternum, cranium) have no side designation.
  • Condition score β€” A numeric or descriptive rating of bone preservation. Common scales range from 1 (excellent, complete) to 5 (poor, fragmentary). Condition affects what analyses can be performed β€” DNA extraction requires better preservation than morphological assessment.
  • DPAA (Defense POW/MIA Accounting Agency) β€” The U.S. Department of Defense organization responsible for recovering and identifying missing service members. DPAA laboratories process skeletal remains using standardized osteological inventory protocols.
  • Provenience β€” The precise three-dimensional location where an element was recovered. Links the inventory to field recovery data (grid square, depth, spatial relationships).
  • Taphonomy β€” The study of what happens to remains after death β€” weathering, root damage, animal scavenging, soil staining. Taphonomic observations are recorded in the inventory alongside condition scores.

You do not need to be an expert in forensic anthropology β€” the AI tool will handle the technical implementation. You just need to know what the visualizer is mapping and why MNI matters.

Who this is for

  • Forensic anthropologists and lab analysts who inventory skeletal remains and need a faster way to visualize recovery completeness and calculate MNI.
  • MIA recovery team members who need to communicate inventory status to case managers and family liaisons without mailing paper forms.
  • Students in forensic anthropology or bioarchaeology courses learning osteological inventory methods and MNI calculation.

The showcase

Here is what the finished visualizer looks like once you open the HTML file in a browser:

  • SVG skeleton diagram (anterior view) in the center, with labeled bone regions that light up green when a matching element is present in the uploaded CSV. Unrecovered elements stay gray.
  • Recovery progress bar at the top showing the percentage of standard skeletal elements accounted for (e.g., β€œ37 of 206 elements recovered β€” 18%”).
  • MNI calculation panel displaying the minimum number of individuals with the determining element (e.g., β€œMNI = 3, determined by Left Femur”).
  • Element detail sidebar β€” click any bone region on the SVG to see its metadata: case number, provenience, condition score, date recovered, and notes.
  • CSV upload area with drag-and-drop support and a β€œLoad Example” button with embedded sample data.
  • Case filter dropdown to show elements from a single case or all cases combined.

Everything runs client-side. No data leaves the browser. The sample data loads instantly so you can see the full workflow before uploading your own inventory.


The prompt

Open your terminal Terminal The app where you type commands. Mac: Cmd+Space, type "Terminal". Windows: open WSL (Ubuntu) from the Start menu. Full lesson → , navigate to a project folder project folder A directory on your computer where the tool lives. Create one with "mkdir my-project && cd my-project". Full lesson → , start your AI CLI tool AI CLI tool Claude Code, Gemini CLI, or Codex CLI β€” a command-line AI that reads files, writes code, and runs commands. Full lesson → (e.g., by typing claude), and paste this prompt:

Build a single self-contained HTML file called skeletal-inventory.html that serves
as an interactive skeletal element inventory visualizer for forensic anthropology
casework. Requirements:
1. PRELOADED SAMPLE DATA (embed as a JS array on page load)
CSV columns: Element_Name, Side, Case_Number, Provenience, Condition_Score,
Date_Recovered, Notes
Embed this dataset directly:
Element_Name,Side,Case_Number,Provenience,Condition_Score,Date_Recovered,Notes
Cranium,M,DPAA-2024-0147,N24-E15 depth 1.1m,2,2024-03-15,Frontal and parietals intact
Mandible,M,DPAA-2024-0147,N24-E15 depth 1.2m,3,2024-03-15,Right ramus fragmented
L_Humerus,L,DPAA-2024-0147,N24-E16 depth 1.3m,2,2024-03-15,Complete
R_Humerus,R,DPAA-2024-0147,N25-E15 depth 1.0m,2,2024-03-16,Complete
L_Femur,L,DPAA-2024-0147,N24-E15 depth 1.2m,3,2024-03-15,Proximal fragment only
R_Femur,R,DPAA-2024-0147,N24-E16 depth 1.4m,2,2024-03-16,Complete
L_Tibia,L,DPAA-2024-0147,N24-E16 depth 1.3m,2,2024-03-16,Complete
Sternum,M,DPAA-2024-0147,N24-E15 depth 1.0m,4,2024-03-15,Manubrium only
L_Clavicle,L,DPAA-2024-0147,N25-E15 depth 0.9m,2,2024-03-16,Complete
Sacrum,M,DPAA-2024-0147,N24-E16 depth 1.5m,3,2024-03-17,Partial - S1-S3 fused
C1_Vertebra,M,DPAA-2024-0147,N24-E15 depth 1.1m,2,2024-03-15,Complete atlas
C2_Vertebra,M,DPAA-2024-0147,N24-E15 depth 1.1m,2,2024-03-15,Complete axis
L_Radius,L,DPAA-2024-0147,N24-E16 depth 1.3m,3,2024-03-16,Distal third missing
R_Ulna,R,DPAA-2024-0147,N25-E15 depth 1.0m,2,2024-03-16,Complete
L_Femur,L,DPAA-2024-0152,S08-W22 depth 0.6m,2,2024-04-02,Complete - different size from 0147
R_Femur,R,DPAA-2024-0152,S08-W23 depth 0.7m,3,2024-04-02,Midshaft fragment
L_Tibia,L,DPAA-2024-0152,S09-W22 depth 0.7m,3,2024-04-02,Distal half only
Cranium,M,DPAA-2024-0152,S08-W22 depth 0.5m,4,2024-04-02,Calvarium only fragmented
R_Humerus,R,DPAA-2024-0152,S08-W23 depth 0.5m,3,2024-04-03,Proximal half
L_Femur,L,DPAA-2024-0193,T12-N04 depth 0.8m,1,2024-05-10,Complete excellent condition
R_Scapula,R,DPAA-2024-0193,T12-N04 depth 0.8m,2,2024-05-10,Glenoid fossa intact
Note: L_Femur appears 3 times (cases 0147, 0152, 0193) = MNI of at least 3.
Side "M" means midline (no left/right designation).
2. SVG SKELETON DIAGRAM
- Draw a simplified anterior-view human skeleton using SVG paths/shapes
- Include these labeled regions that can be individually highlighted:
Cranium, Mandible, L_Clavicle, R_Clavicle, Sternum, L_Scapula, R_Scapula,
L_Humerus, R_Humerus, L_Radius, R_Radius, L_Ulna, R_Ulna,
L_Hand, R_Hand, Cervical_Vertebrae, Thoracic_Vertebrae, Lumbar_Vertebrae,
Sacrum, L_Ilium, R_Ilium, L_Femur, R_Femur, L_Patella, R_Patella,
L_Tibia, R_Tibia, L_Fibula, R_Fibula, L_Foot, R_Foot, Ribs
- Each region is a clickable SVG group with a data-element attribute
- Default state: gray fill (#374151) with subtle outline
- Recovered state: green fill (#10b981) with brighter outline
- Hover state: lighter shade with tooltip showing element name
- Map CSV Element_Name values to SVG regions (handle C1_Vertebra, C2_Vertebra
mapping to Cervical_Vertebrae group, etc.)
3. RECOVERY PROGRESS
- Progress bar showing: "X of Y standard elements recovered (Z%)"
- Count unique element+side combinations from the CSV
- Y = total mappable skeleton regions (around 33 for this simplified diagram)
- Color gradient from red (< 25%) to yellow (25-75%) to green (> 75%)
4. MNI CALCULATION
- For each element+side combination, count how many times it appears across
all case numbers
- MNI = the highest count for any single element+side
- Display: "Minimum Number of Individuals: N" with the determining element
- Show a breakdown table: element, side, count β€” sorted by count descending
- Highlight any element with count > 1 in amber on the table
5. ELEMENT DETAIL SIDEBAR
- Click any SVG bone region to show its details in a right sidebar
- If multiple entries exist for that element (from different cases), show all
as stacked cards
- Each card shows: Case_Number, Provenience, Condition_Score (as colored badge:
1=green, 2=light green, 3=yellow, 4=orange, 5=red), Date_Recovered, Notes
- If no data exists for a clicked element, show "Not recovered" message
6. DATA INPUT
- File upload area (drag-and-drop) for CSV files
- "Load Example" button that populates with the embedded sample data
- "Clear" button to reset everything
- Case filter dropdown: "All Cases" plus one option per unique case number
- When a single case is selected, only that case's elements are highlighted
on the skeleton and MNI recalculates for the filtered set
7. DESIGN
- Dark theme: background #0f172a, cards #1e293b, text #e2e8f0, accent #10b981
- Clean sans-serif font (Inter from Google Fonts CDN)
- Layout: CSV upload top, SVG skeleton center-left, detail sidebar right,
MNI panel and progress bar below the skeleton
- SVG skeleton should be roughly 400px wide and 600px tall
- Responsive: sidebar collapses below skeleton on narrow screens
8. TECHNICAL
- Pure HTML/CSS/JS in one file, no build step
- No external libraries needed (SVG is hand-drawn, no Chart.js required)
- CSV parsing handles quoted fields and different line endings
- All data stored in JS arrays, no localStorage needed
- Element name mapping is case-insensitive and handles underscores vs spaces
πŸ’‘Copy-paste ready

That entire block is the prompt. Paste it as-is. The sample dataset uses realistic forensic recovery data across three case numbers with deliberately duplicated elements to demonstrate MNI calculation. The three left femora from three different cases produce an MNI of 3.


What you get

After the LLM finishes (typically 60-90 seconds), you will have a single file: skeletal-inventory.html. Open it in any browser.

Expected output structure

skeletal-inventory.html (~600-900 lines)

Click Load Example and you should see:

  1. An SVG skeleton with approximately 14 regions highlighted in green (the recovered elements from the sample data) and the remaining regions in gray.
  2. A progress bar showing roughly β€œ14 of 33 regions recovered (42%)” in yellow.
  3. An MNI panel displaying β€œMinimum Number of Individuals: 3” with β€œLeft Femur” as the determining element.
  4. The MNI breakdown table showing Left Femur with a count of 3 (highlighted in amber), Cranium with 2, Right Femur with 2, Right Humerus with 2, and Left Tibia with 2.
  5. Click any green region on the skeleton to see the element detail cards in the sidebar. Clicking the Left Femur region should show three cards β€” one for each case.
  6. Use the case filter to select DPAA-2024-0147 alone and watch the skeleton update to show only that case’s elements, with MNI recalculating to 1.

If something is off

ProblemFollow-up prompt
SVG skeleton regions do not highlight when data is loadedThe SVG bone regions are not updating when the CSV data loads. Make sure each SVG group has a data-element attribute that exactly matches the Element_Name values from the CSV. Use case-insensitive matching and map individual vertebrae (C1_Vertebra, C2_Vertebra) to the Cervical_Vertebrae group.
MNI shows 1 even though Left Femur appears 3 timesThe MNI calculation is not grouping by element+side correctly. Can you group the CSV rows by a normalized key of Element_Name + Side, count the number of unique Case_Numbers per group, and take the maximum count as MNI?
Clicking a bone region does nothingThe click handler is not attached to the SVG groups. Can you add click event listeners to each SVG group with a data-element attribute? When clicked, filter the loaded data for matching elements and display the results in the sidebar.

πŸ”§

When Things Go Wrong

Use the Symptom β†’ Evidence β†’ Request pattern: describe what you see, paste the error, then ask for a fix.

Symptom
SVG skeleton looks like a jumbled mess of shapes instead of a recognizable human form
Evidence
The SVG paths are rendering but overlapping or positioned incorrectly. Some bones are in the wrong location or scaled wrong.
What to ask the AI
"The SVG skeleton layout needs adjustment. Can you use a coordinate system of 400x600 and position the major elements anatomically: cranium at top center, clavicles below it, humeri flanking the ribcage, spine down the midline, pelvis at the waist, femora below the pelvis, tibiae below the knees, feet at the bottom? Use simple shapes β€” ellipses for the cranium and joints, rectangles for long bones, a trapezoid for the pelvis."
Symptom
MNI calculation counts total bones instead of duplicate elements
Evidence
The MNI shows 21 instead of 3. It is counting every row in the CSV instead of finding the most duplicated element+side combination.
What to ask the AI
"The MNI calculation is wrong. MNI should be: 1) group all rows by Element_Name + Side, 2) for each group count the number of distinct Case_Numbers, 3) the highest count across all groups is the MNI. Right now it seems to be counting total rows. Can you fix the grouping logic?"
Symptom
Individual vertebrae from the CSV do not highlight the vertebrae group on the SVG
Evidence
The CSV has C1_Vertebra and C2_Vertebra but the SVG only has a Cervical_Vertebrae group. Those two entries are being ignored.
What to ask the AI
"The element name mapping needs a lookup table. Can you add a mapping object that converts specific CSV element names to SVG region IDs? Map C1_Vertebra through C7_Vertebra to Cervical_Vertebrae, T1_Vertebra through T12_Vertebra to Thoracic_Vertebrae, L1_Vertebra through L5_Vertebra to Lumbar_Vertebrae. Apply this mapping when processing CSV data before matching to SVG regions."
Symptom
Case filter dropdown is empty or does not update the skeleton
Evidence
After loading the example data, the dropdown still only shows 'All Cases'. Or selecting a case does not change which elements are highlighted.
What to ask the AI
"The case filter is not being populated from the loaded data. Can you extract unique Case_Number values from the parsed CSV, populate the dropdown with an option for each one, and add an event listener that re-renders the skeleton highlighting and recalculates MNI when the selection changes?"

How it works (the 2-minute explanation)

You do not need to understand every line of the generated code, but here is the mental model:

  1. CSV parsing reads each row as a recovered skeletal element. The Element_Name and Side columns identify which bone region to highlight. Multiple rows can map to the same SVG region (duplicates from different cases), and that duplication is exactly what drives MNI calculation.
  2. SVG region mapping uses a lookup table to connect CSV element names to SVG group IDs. Each SVG group has a data-element attribute. When the CSV data loads, JavaScript iterates through the parsed rows, finds the matching SVG group, and changes its fill color from gray to green. Individual vertebrae (C1, C2, etc.) map to their respective vertebral group.
  3. MNI calculation groups elements by their normalized name+side key, counts unique case numbers per group, and reports the maximum count. This is the standard forensic method: the most-duplicated element determines the minimum number of individuals because you cannot have three left femora from fewer than three people.
  4. Click interaction attaches event listeners to each SVG group. When clicked, the sidebar filters the loaded data for elements that map to that region and displays metadata cards for each match. If multiple cases contributed elements to that region, all cards are shown.
πŸ”For Researchers: Why MNI matters in commingled cases

When remains from multiple individuals are recovered in the same context β€” a mass grave, a battlefield trench, a disaster site β€” the first question is always β€œhow many people are represented here?” MNI provides a defensible lower bound. It is conservative by design: three left femora means at least three individuals, but there could be more if some individuals are represented only by elements that are not duplicated. More sophisticated methods (pair-matching, osteometric sorting, DNA) can refine the count, but MNI from the inventory is always the starting point and is calculated before any laboratory analysis begins.


Customize it

The base visualizer handles the core inventory workflow, but real lab operations have additional needs. Each of these is a single follow-up prompt:

Add taphonomic modification annotations

Add a "Taphonomic Notes" dropdown to each element detail card with checkboxes
for common modifications: root etching, rodent gnawing, carnivore gnawing,
weathering stage (0-5), soil staining, thermal alteration, cut marks,
green bone fracture. When any taphonomic modification is selected, add a small
icon overlay on the corresponding SVG bone region (e.g., a tiny orange dot for
thermal alteration, a blue dot for soil staining). Include a legend below the
skeleton explaining the icons.

Add side-by-side comparison view

Add a "Compare Cases" button that displays two skeleton diagrams side by side,
one per selected case. Each skeleton highlights only that case's elements.
Between the two skeletons, show a comparison panel listing elements present
in both cases (potential commingling overlap), elements unique to Case A,
and elements unique to Case B. Color shared elements in amber on both diagrams.

Add printable inventory sheet

Add a "Print Inventory" button that generates a printable osteological
inventory form. Use CSS @media print to show: case number header, a table
of all recovered elements with columns for Element, Side, Condition,
Provenience, Date, and Notes. Include the SVG skeleton diagram scaled to
fit on the page with recovered elements highlighted. Add blank signature
lines for "Examined by" and "Date". Hide all interactive controls in print.

Add photo reference placeholders

Add a photo upload zone to each element detail card in the sidebar. Accept
JPG/PNG images via drag-and-drop. Display uploaded photos as thumbnails
(100x100px) in the card. Store images as base64 data URLs. When printing the
inventory sheet, show photo placeholders with "Photo on file - see digital
record" text instead of the actual images.
β„ΉThe customization loop

Notice the pattern: you start with a working inventory visualizer, then add features one prompt at a time. The taphonomic annotations transform it from a simple inventory into a preservation assessment tool. The printable sheet bridges digital and paper workflows. You never need to plan the entire tool upfront.


Try it yourself

  1. Open your CLI tool in an empty folder.
  2. Paste the main prompt from above.
  3. Open the generated skeletal-inventory.html in your browser.
  4. Click Load Example and verify the skeleton highlights the correct regions.
  5. Click the Left Femur region on the SVG β€” you should see three detail cards from three different cases.
  6. Check the MNI panel β€” it should show 3, determined by Left Femur.
  7. Use the case filter to select DPAA-2024-0152 alone β€” the skeleton should update to show only 5 highlighted regions and MNI should drop to 1.
  8. Pick one customization from the list above and add it.

Key takeaways

  • One prompt, one tool: a detailed, specific prompt produces a working skeletal inventory visualizer in under 2 minutes.
  • SVG diagrams make spatial data instantly comprehensible β€” a highlighted skeleton communicates recovery completeness faster than any table or spreadsheet.
  • MNI calculation is simple but critical β€” count duplicated elements by side, and the highest count is the minimum number of individuals. The tool automates a calculation that is tedious by hand when inventories are large.
  • Element name mapping is the hardest part β€” the prompt must specify how CSV names correspond to SVG regions, especially for grouped elements like vertebrae. Be explicit about the mapping in your prompt.
  • Case filtering turns one tool into a case comparison system β€” toggling between cases on the same skeleton diagram reveals which elements overlap and which are unique.

KNOWLEDGE CHECK

A recovery inventory contains 3 left femora, 2 right femora, 2 crania, and 1 sacrum, each from different case numbers. What is the MNI?

KNOWLEDGE CHECK

You filter the inventory to a single case and the skeleton shows 37 of 33 standard regions recovered (112%). What does this indicate?


What’s next

In the next lesson, you will build another forensic field tool that extends the inventory workflow β€” taking the recovered elements you have cataloged here and connecting them to the broader identification pipeline. Same pattern: one prompt, one working tool, then customize.