个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证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.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗A personal experimental database for alloy research: store samples, synthesis conditions, and characterization results in a structured, queryable way, cross-check every new composition against public materials databases, and build toward using all of it as training data for ML models that predict whether a novel composition is known — and if not, how to try synthesizing it.
This document is the narrative overview. Detailed technical write-ups for
each component live in docs/. For a more detailed statement of
the principles behind how AI/ML is used in this project, see
MANIFESTO.md.
As a materials scientist working on novel alloys for practical applications, experimental results were scattered across spreadsheets, Origin project files, raw instrument output, and a genuinely messy desktop folder — the kind every researcher accumulates over years. Two motives drove this project, in roughly equal measure:
In scope for Stage 1:
Explicitly deferred to Stage 2 (data preparation for ML):
The original plan was much simpler than what actually got built: a
Postgres database, a Python interface, and a calculator script. Nearly
every component grew in scope once real use revealed a gap — the
calculator in particular went through the most iterations of anything in
the project (see docs/calculator.md). The general
pattern across the whole project was: build the simplest version, use it
for real, let the first real failure define the next iteration. That
pattern is documented explicitly in
docs/ as try → result → next chains, rather than presented as a
single clean design that was right from the start — it wasn't, and
pretending otherwise would make the docs less useful to future-me.
Full detail, including the specific bugs and dead ends, lives in the linked pages. This section is the short version.
docs/database_schema.mdPostgres, with samples (JSONB composition, parent_sample_id for
lineage/family-tree tracking, plus real vec/delta/delta_h_mix
columns added later), synthesis, characterization, properties,
literature_checks, and supporting tables. Credentials were originally
hardcoded in plaintext — found and fixed via .env + .gitignore,
before the repo's first commit, so nothing ever entered git history.
docs/calculator.mdConverts alloy formula strings and atomic/weight percent into grams to weigh out. The single most-iterated component in the project: the formula parser had to be rewritten to properly reject ambiguous input (e.g. "Cp," which looks like a typo but is actually the valid elements C and P run together), atomic%/weight% conversion needed a real unit-selector fix rather than a silently-defaulting text field, and lab-realistic features (pre-alloys as components, excess% to compensate evaporation losses during melting) each needed their own design pass.
docs/screening.mdVEC / atomic size mismatch (δ) / mixing enthalpy (ΔH_mix) as a
composition-only feasibility pre-screen. Started with 12 elements'
properties hardcoded; expanded to full periodic table coverage. A silent
bug (unlisted elements were quietly skipped rather than raising an error,
giving a confidently wrong VEC) was found and replaced with an explicit
IncompleteElementDataError.
docs/literature_databases.mdThree working integrations — Materials Project, OQMD, and Alexandria — normalized into one common tier system (exact match / similar / partial subsystem match / nothing found) and one dedup pipeline. A fourth (AFLOW) was attempted and deliberately abandoned after hitting an unmaintained library, a live 404, and unresolved query-semantics ambiguity — a real example of a dead end that was correctly cut rather than pushed through. Alexandria's much larger dataset surfaced a genuine volume problem (dozens of barely-related matches), solved with a per-database, adjustable distance cutoff, now live in the GUI.
docs/characterization.mdXRD (peak detection, lattice parameter), VSM (saturation moment,
remanence, coercivity), and SEM (magnification, accelerating voltage,
working distance, pixel size) modules — all built as custom parsers,
after a library (magnetopy, for VSM) turned out to be unusable. Two
genuine data-quality/format catches, not just code bugs: the VSM file's
own recorded sample mass was wrong (an instrument placeholder), with the
real mass only available encoded in the filename; and the SEM instrument
(Zeiss) stores its actual metadata inside proprietary compressed binary
TIFF tags rather than standard fields, requiring a custom binary-string
extractor. A practical, non-parsing problem also showed up at SEM scale —
690 files imported one at a time took 5-10 minutes — solved with batch
import rather than a parser change. A standalone data-sorter utility was
also built to bring order to the real, years-accumulated messy desktop
research folder — successfully routing hundreds of real files (XRD, ICP,
Origin projects, presentations) into organized subfolders in one pass.
docs/gui.mdA proper interface on top of everything above, with five tabs — New
Entry, Quick Lookup, Summary, Import (auto-detecting XRD/VSM/SEM, with
batch import), and a Data Viewer that displays XRD patterns, VSM
hysteresis loops, and SEM images directly in-app. Went through many
iterations (alloy_desktop.py → _fixed → _fixed2 → _fixed3 →
_with_db_classes.py → _complete.py) before stabilizing.
The notable ones that didn't feed back into an existing component above (full list of smaller issues is in each linked page):
aflow python package turned out unmaintained
(last touched ~2017-2019), hit a live HTTP 404 suggesting its endpoint
moved or died, and separately had a real bug (its keyword objects are
mutable singletons — repeated .filter() calls on the same keyword
silently corrupt earlier values instead of erroring). Combined with an
unresolved AND/OR query-semantics ambiguity that couldn't be verified
without a live server, this was cut rather than pushed through — a
deliberate, correct call, not a failure.stage_one/lookup/lookup_common_v1.py
accidentally deleted a function's signature while leaving its body
behind as dead code, breaking deduplication for all three literature
databases at once. It shipped because the fix was verified by testing
the wrong function in isolation rather than the actual full call chain.
Caught only because it was run for real. A useful reminder that
"syntax parses" and "logic works" are different bars, and that testing
the specific path that changed matters more than testing nearby code
that happens to still parse.Stage 2 transformed the lab-book foundation into a validated research platform. Every instrument pipeline was built on real data, not synthetic tests. The schema was designed for machine learning. The infrastructure was migrated to a dedicated home server shared by all machines.
Stage 2 is complete as of September 2026.
stage_two/tools/xrd_analyzer_dev1.py — a general-purpose peak-fitting
pipeline, validated against NIST SRM 660c (LaB₆ certified reference
material). Lattice parameter converges to within 0.0001 Å of the certified
value.
xrd_peaks (long format, one row per peak) and
xrd_features (wide format, ML-ready, one row per sample)xrd_analyzer_standalone.py): live
sensitivity controls, per-peak accept/reject, Save to DBxrd_integration_v2.py) tested end-to-end against real
production database with real samplesA full multi-component pipeline replacing the Stage 1 single-value parser.
vsm_files, vsm_segments, vsm_mh_details,
vsm_mt_details, vsm_mt_candidates, vsm_temperature_coefficients,
vsm_entropy_changevsm_mh_analyzer_standalone.py):
multi-segment, adjustable branch-detection sensitivity, optional BHmax
(density + dimensions, Aharoni factor shown for comparison),
per-segment accept/reject, Save to DBThree manufacturers, three completely different metadata conventions — unified into one schema, auto-detected per file.
'25.00 K X').txt file, $KEY value format — confirmed directly
on real files; calibration from $$SM_MICRON_BAR/$$SM_MICRON_MARKER;
footer height from $CM_FULL_SIZE vs actual TIFF height, no
brightness-heuristic guessing needed.hdr file, standard INI format — PixelSizeX
directly in metres, the most direct calibration of the three; 16-bit
image data handled throughoutformat='unknown' rather than guessing —
confirmed to occur on real JEOL files uploaded without their sidecarsem_grain_analyzer.py) with adaptive per-image
Canny thresholds, validated on 16 real images across formats; correctly
flagged 2 deliberately low-quality test images as unreliable rather than
forcing a confident wrong answersem_grain_analyzer.py updated to use
sem_metadata_universal internally, and parse_pixel_size() extended
to handle both float (universal parser) and string ('11.09 nm', Zeiss
parser) inputssem_phase_fraction_standalone.py): live
threshold slider, Otsu suggestion, optional invert, calibrated area
readout in µm², Save to DBcompositions table extended with composition_type column:
'aimed' (nominal, set at sample creation) / 'measured' (EDX/ICP
result) / 'reference' (literature data added manually)add_compositions() method added to alloy_db_v2.py: called
automatically after every new sample entry, stores both wt% and at%
from the calculator's output — no separate computation needed, the mass
calculator already has bothcompute_atomic_percent.py, inline) used to populate
atomic_percent for the three samples entered before this was wired in,
using IUPAC atomic weights from alloy_calculator_v2.ATOMIC_WEIGHTSelement_fraction_table.py: wide-format reshaping for ML consumption —
one row per sample, one column per element, zero-filled for absent elementsalloy_screening_v2.py) already computed
synthesis_feasibility with suggested_routes — this information was
previously display-onlysynthesis table after every new sample entry,
one row per suggested route, with the full screening reasoning (status
notes columnOn 3 September 2026, the database was migrated from a local Docker
container on the development Mac to a dedicated home server
(192.168.2.42). Migration: pg_dump (compressed format) → scp →
pg_restore. One session, zero data loss.
postgres:17 container with persistent volume at ~/docker/postgres/datawol g); systemd service
persists the setting across reboots; BIOS Power On By PCI-E/PCI
enabled. Server wakes from cold poweroff in ~60 seconds via
wakeonlan 2c:56:dc:74:c4:ffpg_hba.conf allows 192.168.2.0/24; listen_addresses = '*'
in postgresql.conf.env changed to POSTGRES_HOST=192.168.2.42
on Mac and ML Desktop. SSH installed on ML Desktop during this sessionpath_repair.py: scans characterization.file_path and
vsm_files.file_path for broken paths, auto-searches by filename under
a given root, handles ambiguous matches interactively. Run post-migration:
zero broken pathsPost-migration database state: 50 samples, 16 tables, 170 XRD peaks, 92 characterization records, 4 synthesis route records.
All three standalone tools now launch from the Data Viewer with the current file pre-loaded and auto-analysed:
plot_xrd() and plot_vsm() updated to accept a master tkinter
frame, embedding canvas + launch button directly — same pattern as the
existing SEM viewerxrd_analyzer_standalone.py (pre-loaded, auto-analyzed)vsm_mh_analyzer_standalone.py (pre-loaded, auto-analyzed)sem_phase_fraction_standalone.py (pre-loaded)viewer_plot_label, causing the Data Viewer to break after
the first plot was loadedstage_one/outdated/ and stage_two/outdated/ removed entirely —
dozens of intermediate development versions (parse_vsm_fixed3.py,
alloy_desktop_fixed2.py, etc.). All history preserved in gitsem_analyzer_gui_v6.py) retired and removedvsm_entropy_integration.py copied to stage_two/tools/ to resolve
a ModuleNotFoundError when VSM standalone was launched as a subprocessparse_sem_v2 import failures as subprocess: when standalone tools
are launched via subprocess.Popen, Python's sys.path doesn't
include the project's parsers/ directory. Fixed with sys.path.insert
using pathlib.Path(__file__).resolve().parent in each affected module.viewer_plot_label destroyed by plot functions: the child-clearing
loop inside plot_xrd/plot_vsm/plot_sem was destroying all widgets
in the frame including the error-display label the app needed for
subsequent "file not found" messages. Removed — the app already clears
the frame before calling the plot functions.sample_id NULL: characterization.sample_id was
NULL for existing records (imported before the FK was fully wired).
Fixed by prompting the operator for the sample ID string at save time,
then looking up the integer PK from the samples table.pixel_size_nm None despite correct metadata: parse_pixel_size()
used a regex expecting a string like '11.09 nm', but
sem_metadata_universal returns a plain float. Fixed by checking the
type before regex extraction.screening.get('suggested_routes')
was wrong — suggested_routes is nested inside
screening['synthesis_feasibility']. Fixed by extracting _synth first.'FFFFFF99' (hex + alpha) is not
supported and silently produces black. Fixed by using a plain 6-digit
equivalent.\dt in psql searched the
public schema by default; all tables live in the alloy_lab schema.
Fixed by using \dt alloy_lab.*.Stage 1: complete. Stage 2: complete as of September 2026.
Working end-to-end, verified with real data:
path_repair.py for broken-path recovery after file movesStage 3 is about closing the loop: composition → measurement → prediction → new composition recommendation.
Feature matrix (X):
compositions — element fractions wt% + at%, all samplesxrd_features — n_peaks, mean R², crystallite size, d-spacingvsm_mh_details — Hc, Mr, BHmax per segmentvsm_temperature_coefficients — α(Hc), β(Mr)properties — SEM phase fractionTarget properties (y):
Planned ML workflow:
element_fraction_table.py + joinsInfrastructure:
192.168.2.42, always-on, wake-on-LANVerbatim reference commands, configs, and the schema migration SQL are
collected in docs/appendix_commands.md.