โ† Iliya Angelov Radulov โ€” portfolio

Materials Science ยท Personal Infrastructure Project ยท Stage 1

A Personal Lab Database for Experimental Alloys stage 1

A complete research infrastructure โ€” composition calculator, literature cross-checking against three independent public databases, and multi-instrument characterization import โ€” built to replace years of scattered spreadsheets and a genuinely messy desktop research folder.

PostgreSQL Docker Python Metabase customtkinter Materials Project API OQMD Alexandria
3
Independent literature databases cross-checked per composition
3
Characterization techniques integrated โ€” XRD, VSM, SEM
690
Real SEM images imported into the database

Background

Why this project

As a materials researcher working on novel alloys, my experimental results were scattered across spreadsheets, Origin project files, raw instrument output, and โ€” if I'm honest โ€” a genuinely messy desktop folder accumulated over years. Two things motivated building a proper system, in roughly equal measure.

Motive 1 โ€” Practical

A real lab database

One place to record what was made, how, and what it measured โ€” usable later as training data for machine learning.

Motive 2 โ€” Personal

Plain curiosity

Could this be built solo? And could the desktop folder finally be tamed after years of neglect? Both turned out to matter as much as the practical goal.

Workflow

The researcher's routine

The system was built to directly support this routine โ€” not to replace it.

๐Ÿ”
Check literature
Is this composition already known?
โ†’
โš–๏ธ
Screen & calculate
Feasibility check, then exact grams to weigh
โ†’
๐Ÿ”ฅ
Synthesize
Melt, cast, heat-treat
โ†’
๐Ÿ”ฌ
Characterize
XRD, VSM, SEM
โ†’
๐Ÿ—„๏ธ
Store & connect
Permanently linked, queryable

Engineering

What was planned vs. what was built

The original design sketch was considerably more ambitious than what actually shipped โ€” a full Docker Compose stack with MinIO/S3 object storage, Redis caching, a Jupyter analysis environment, and a file-watcher service auto-ingesting instrument output. Real use quickly showed that a leaner system โ€” Postgres, a Python API layer, and a proper desktop interface โ€” covered everything actually needed, without the operational overhead of running five services to enter one sample.

Knowing what to cut turned out to matter more than the original breadth of the plan. Every sample's full story โ€” composition, how it was made, and what it measured โ€” still stays connected, just through a considerably simpler path than first imagined.

Docker containers running Screenshot: Docker containers running
alloy_lab
โ”œโ”€โ”€ samples            composition (JSONB), lineage, VEC/ฮด/ฮ”H_mix
โ”œโ”€โ”€ synthesis          method, temperature, atmosphere, duration
โ”œโ”€โ”€ characterization   one row per XRD/VSM/SEM measurement
โ”œโ”€โ”€ properties         extracted numeric results per measurement
โ”œโ”€โ”€ literature_checks  deduped matches from 3 external databases
โ””โ”€โ”€ material_classes

Tooling

From formula to grams

Type a formula. Get exactly what to weigh.

This was, by a wide margin, the most-iterated part of the whole project. Every feature that looked simple at first revealed a real edge case once tested against actual formulas โ€” most memorably, distinguishing a genuine typo from valid chemistry: Cp looks like a mistake, but is actually two real, valid one-letter elements (C and P) run together. There's no purely syntactic way to know which was intended, so the parser now requires an explicit number after every element and raises a clear error on anything ambiguous, rather than silently guessing.

Fe65Nd30Co5 โ†’ 10 g target

Fe   4.40 g
Nd   5.24 g
Co   0.36 g
New Entry with options to calculate from pre-alloy and skip literature checks Screenshot: Updated New Entry tab, with options to calculate from a pre-alloy, synthesis feasibility check and skip literature checks

Physics

A cheap first filter

Before any melting: four composition-only numbers, computed instantly, no lab work required.

VEC

Valence Electron Concentration

Predicts likely crystal structure โ€” solid solution type (BCC / FCC).

ฮด (delta)

Atomic size mismatch

Small ฮด favors a solid solution; large ฮด favors intermetallic phases.

ฮ”H_mix

Mixing enthalpy

Predicts compound-forming tendency between elements.

Stage 2 addition

Synthesis feasibility

A different question from the other three: not "will this form a solid solution," but "can this even be melted together" โ€” using each element's melting and boiling point.

The insight behind the fourth check: melting-point spread alone isn't the right signal. What actually matters is whether homogenizing the melt requires heating past the boiling point of the most volatile constituent โ€” at that point, the element doesn't just risk some evaporation, it boils away before the alloy can homogenize. Three tiers, deliberately not collapsed into one confidence level: a hard physical block (suggests mechanical alloying or sintering instead), a flagged "genuinely uncertain" zone (pure composition data isn't sufficient โ€” check literature or run a small test melt), and a comfortable "no concern" case.

Example compositionResultWhy
W + Mg๐Ÿšซ BlockedMelting W (3695 K) is far above Mg's boiling point (1363 K)
Fe + Nbโš ๏ธ CautionOnly 384 K margin โ€” pure-element numbers alone can't call this either way
Fe + Co + Niโœ… OKComfortable margin, no volatility concern

Cross-Validation

Is this already known?

Every composition is checked against three independent public materials databases.

Tier 1KnownExact match found
Tier 2SimilarSame elements, different ratio
Tier 3PartialOnly part of the system is known
Tier 4UnknownNothing found โ€” genuinely novel territory
0.001
eV / atom

Two fully independent databases (Materials Project and OQMD) agreed on a compound's stability within 0.001 eV/atom โ€” strong cross-validation that the result reflects real physics, not one group's specific settings.

Databases used: Materials Project ยท OQMD ยท Alexandria

A fourth database (AFLOW) was evaluated and deliberately dropped after hitting an unmaintained client library, a dead API endpoint, and unresolved query-semantics ambiguity โ€” three independent reasons was enough to redirect effort toward Alexandria instead, which turned out to be the stronger choice regardless.

Instruments

From data to discovery

Real characterization data now flows directly into the database โ€” no manual transcription.

SampleXRD peaksLattice a (ร…)
RP1a10115.627
RP2a9615.630
RP3a9815.744
VSM property (sample RP1a)Value
Saturation moment (Ms)6.883 emu
Remanence (Mr)โˆ’0.024 emu
Coercivity (Hc)198.6 Oe
Ms per gram137.65 emu/g

The VSM pipeline caught a genuine data-quality problem, not just a code bug: the instrument's own recorded sample mass was an obviously wrong placeholder value, with the real mass only available encoded in the filename. Normalizing by the wrong mass would have silently corrupted every derived magnetic property โ€” the fix was parsing mass from the filename convention instead of trusting the instrument's own metadata field.

VSM hysteresis loop and XRD pattern fast visualization Screenshot: XRD pattern and VSM hysteresis loop rendered in the Data Viewer

SEM metadata extraction

The instrument (Zeiss) stores its real metadata inside proprietary compressed binary TIFF tags rather than standard fields โ€” a custom binary string-extraction routine was needed to recover magnification, accelerating voltage, working distance, and detector channel.

Scale problem, not a parsing problem

Importing 690 real SEM files one at a time was correct but slow โ€” 5โ€“10 minutes for the full set. Solved with batch import, without touching the parser itself.

SEM metadata (example)Value
Magnification1.00 KX
EHT (voltage)10.00 kV
Working distance7.1 mm
Pixel size277.3 nm
DetectorSE2 / InLens

Interface

A real desktop application

Everything above, in one application โ€” not a collection of scripts.

Query interface for OQMD Screenshot: New Entry tab, and the three literature database selectors with common cutoff slider
Data import interface Screenshot: Data import interface โ€” XRD, VSM, and SEM characterization data imported directly into the database
SEM image viewer Screenshot: SEM image viewer โ€” fast visualization of SEM images directly in the application
Metabase table view Screenshot: Metabase dashboard โ€” browsing the database without writing SQL

Retrospective

What this project taught

๐Ÿ”

Credentials, twice

A hardcoded password was found and "fixed" once, then found again as a commented-out leftover copy. Grepping for a secret isn't done until it returns nothing at all, comments included.

๐Ÿงญ

Cutting scope on purpose

A fourth literature database (AFLOW) was abandoned after three independent red flags โ€” an unmaintained library, a dead endpoint, unresolved query semantics. Stopping was the correct call, not a failure to push through.

๐Ÿงช

Instrument metadata isn't automatically trustworthy

Both the VSM sample-mass field and the SEM binary tags looked like reliable structured data. Neither was, in different ways โ€” worth verifying, not assuming.

โœ…

Test the path that changed

A dedup-logic regression shipped because the fix was verified in isolation rather than through the actual full call chain it belonged to. Caught only by running it for real.

๐Ÿ“

Which venv has the package?

Prototyping in one virtual environment and integrating in another is an easy way to get a clean import error later โ€” worth checking pip list in the venv that will actually run the script.

๐Ÿ—‚๏ธ

The messy folder, tamed

A standalone sorter utility, tested against the real multi-year desktop folder, correctly routed hundreds of files โ€” XRD, ICP, Origin projects โ€” into organized subfolders in one pass. The second motivation for this project, resolved.

๐Ÿ”ฌ

One matching criterion isn't enough

Two XRD peaks looked like a textbook Kฮฑ1/Kฮฑ2 instrumental doublet โ€” their positions matched the predicted split to within 0.1ยฐ. But their independently-fit intensity ratio was ~1.1, not the physically fixed ~0.5 the real effect requires. A second, independent check caught what position matching alone would have called a confirmed doublet โ€” more likely a real crystallographic feature instead.

๐Ÿ“ฆ

.gitignore doesn't undo the past

A large folder of raw data (and, more importantly, some unpublished drafts) turned out to still be fully committed to git โ€” even though it was correctly listed in .gitignore. Adding a rule only stops new files from being tracked; it does nothing for files already committed before the rule existed. Caught and fixed with a full history rewrite before the repository stayed public.

Status

Where things stand

โœ… Working now

  • Core database, credentials & schema
  • Mass calculator (pre-alloys, excess %)
  • Composition screening (VEC / ฮด / ฮ”H_mix)
  • Three literature databases, deduped & cross-checked
  • XRD, VSM, and SEM characterization import
  • Desktop GUI, five tabs, end to end
  • Data sorter, tested on real files

Resources

Additional Resources

Here you can download the presentation of the project in pdf format :